lib.rs

104.2 kB · rust · 2493 lines

1#![allow(non_camel_case_types, non_snake_case, clippy::too_many_arguments)]23mod hand;45use wasm_bindgen::prelude::*;67/// The bilinear form `B(u, v) = (sum u)(sum v) - 2 sum u v` that the reflection preserves.8#[wasm_bindgen]9pub fn apollonian_form(u: JsValue, v: JsValue) -> Result<JsValue, JsValue> {10    let u = hand::array_from_js::<_, 4>(&u, hand::i64_from_js)?;11    let v = hand::array_from_js::<_, 4>(&v, hand::i64_from_js)?;12    let value = mrlyrs::num::apollonian::form(u, v);13    Ok(JsValue::from_str(&value.to_string()))14}1516/// The box the packing is drawn in: one period of the strip, or the box of the circle that contains a bounded packing.17#[wasm_bindgen]18pub fn apollonian_frame(p: JsValue) -> Result<Vec<f64>, JsValue> {19    let p = hand::from_js::<mrlyrs::num::apollonian::Packing>(&p)?;20    let value = mrlyrs::num::apollonian::frame(&p);21    Ok(value.to_vec())22}2324/// Grows the named packing to the curvature cap, one circle per node of the reflection tree and the root quadruple excluded, so `circles.len()` is the census `N(T)`. On the strip only the two root swaps that replace a line are taken, which are exactly the two that stay inside one period.25#[wasm_bindgen]26pub fn apollonian_grow(name: &str, cap: JsValue) -> Result<JsValue, JsValue> {27    let cap = hand::i64_from_js(&cap)?;28    let value = mrlyrs::num::apollonian::grow(name, cap).map_err(hand::throw)?;29    hand::to_js(&value)30}3132/// Whether the circle is the Ford circle over its own tangency point: curvature `2 b^2` and abscissa `2 a b` at the reduced `a/b`.33#[wasm_bindgen]34pub fn apollonian_is_ford(c: &apollonian_Circle) -> Result<bool, JsValue> {35    let value = mrlyrs::num::apollonian::is_ford(c.inner);36    Ok(value)37}3839/// Whether the circle has positive curvature and is tangent to the line `y = 0`, which in these coordinates reads `k > 0` and `k y = 1`: the curvature guard is what excludes the line `y = 1`, which is `(0, 0, 1)`.40#[wasm_bindgen]41pub fn apollonian_on_line(c: &apollonian_Circle) -> Result<bool, JsValue> {42    let value = mrlyrs::num::apollonian::on_line(c.inner);43    Ok(value)44}4546/// Reflects the circle at the seat through the other three, `v' = 2(v_1 + v_2 + v_3) - v` on all three coordinates at once, which is the second root of the Descartes quadratic and needs no square root.47#[wasm_bindgen]48pub fn apollonian_reflect(q: JsValue, at: usize) -> Result<apollonian_Circle, JsValue> {49    let q = hand::array_from_js::<_, 4>(&q, |x1| hand::from_js::<mrlyrs::num::apollonian::Circle>(&hand::plain(x1)?))?;50    let value = mrlyrs::num::apollonian::reflect(&q, at);51    Ok(apollonian_Circle { inner: value })52}5354/// The named root quadruple: `strip` is the two lines a unit apart holding the circles at `0` and `1`, and the rest are bounded packings named by their four curvatures.55#[wasm_bindgen]56pub fn apollonian_root(name: &str) -> Result<JsValue, JsValue> {57    let value = mrlyrs::num::apollonian::root(name).map_err(hand::throw)?;58    hand::list_to_js(&value, |x1| Ok(JsValue::from(apollonian_Circle { inner: *x1 })))59}6061/// Reads the Farey stack of the order against the packing: the nodes lit inside the open period against the tangency points of the line-tangent circles of curvature at most `2 Q^2`, and the brightness `floor(Q/b)` summed on the nodes against `Q(Q + 1)/2`. Off the strip there is no line and every count is zero.62#[wasm_bindgen]63pub fn apollonian_shadow(p: JsValue, order: usize) -> Result<JsValue, JsValue> {64    let p = hand::from_js::<mrlyrs::num::apollonian::Packing>(&p)?;65    let value = mrlyrs::num::apollonian::shadow(&p, order).map_err(hand::throw)?;66    hand::to_js(&value)67}6869/// Whether the quadruple carries all six exact invariants: Descartes `B(k, k) = 0`, the position half `B(k, kx) = B(k, ky) = B(kx, ky) = 0`, and the frame `B(kx, kx) = B(ky, ky) = -4`.70#[wasm_bindgen]71pub fn apollonian_sound(q: JsValue) -> Result<bool, JsValue> {72    let q = hand::array_from_js::<_, 4>(&q, |x1| hand::from_js::<mrlyrs::num::apollonian::Circle>(&hand::plain(x1)?))?;73    let value = mrlyrs::num::apollonian::sound(&q);74    Ok(value)75}7677/// The quadruple with the circle at the seat replaced by its reflection.78#[wasm_bindgen]79pub fn apollonian_swap(q: JsValue, at: usize) -> Result<JsValue, JsValue> {80    let q = hand::array_from_js::<_, 4>(&q, |x1| hand::from_js::<mrlyrs::num::apollonian::Circle>(&hand::plain(x1)?))?;81    let value = mrlyrs::num::apollonian::swap(&q, at);82    hand::list_to_js(&value, |x1| Ok(JsValue::from(apollonian_Circle { inner: *x1 })))83}8485/// The tangency points on the line `y = 0`, ascending: one per circle of the packing with `k y = 1`, the root excluded. Empty off the strip.86#[wasm_bindgen]87pub fn apollonian_touches(p: JsValue) -> Result<JsValue, JsValue> {88    let p = hand::from_js::<mrlyrs::num::apollonian::Packing>(&p)?;89    let value = mrlyrs::num::apollonian::touches(&p);90    hand::to_js(&value)91}9293/// Adds two sequences term by term over their shared length.94#[wasm_bindgen]95pub fn blend_add(a: JsValue, b: JsValue) -> Result<JsValue, JsValue> {96    let a = hand::list_from_js(&a, hand::i128_from_js)?;97    let b = hand::list_from_js(&b, hand::i128_from_js)?;98    let value = mrlyrs::num::blend::add(&a, &b);99    hand::list_to_js(&value, |x1| Ok(JsValue::from_str(&x1.to_string())))100}101102/// Convolves two sequences, keeping the exact prefix their shared length affords.103#[wasm_bindgen]104pub fn blend_cauchy(a: JsValue, b: JsValue) -> Result<JsValue, JsValue> {105    let a = hand::list_from_js(&a, hand::i128_from_js)?;106    let b = hand::list_from_js(&b, hand::i128_from_js)?;107    let value = mrlyrs::num::blend::cauchy(&a, &b).map_err(hand::throw)?;108    hand::list_to_js(&value, |x1| Ok(JsValue::from_str(&x1.to_string())))109}110111/// Returns the monic characteristic polynomial of a recurrence, highest power first.112#[wasm_bindgen]113pub fn blend_characteristic(coefficients: JsValue) -> Result<JsValue, JsValue> {114    let coefficients = hand::list_from_js(&coefficients, |x1| Ok((hand::i128_from_js(&hand::item(x1, 0)?)?, hand::i128_from_js(&hand::item(x1, 1)?)?)))?;115    let value = mrlyrs::num::blend::characteristic(&coefficients);116    hand::list_to_js(&value, |x1| Ok(hand::tuple_to_js(&[JsValue::from_str(&x1.0.to_string()), JsValue::from_str(&x1.1.to_string())])))117}118119/// Keeps every step-th term from the offset onward.120#[wasm_bindgen]121pub fn blend_decimate(a: JsValue, step: usize, offset: usize) -> Result<JsValue, JsValue> {122    let a = hand::list_from_js(&a, hand::i128_from_js)?;123    let value = mrlyrs::num::blend::decimate(&a, step, offset).map_err(hand::throw)?;124    hand::list_to_js(&value, |x1| Ok(JsValue::from_str(&x1.to_string())))125}126127/// Returns the first differences of a sequence, one term shorter.128#[wasm_bindgen]129pub fn blend_delta(a: JsValue) -> Result<JsValue, JsValue> {130    let a = hand::list_from_js(&a, hand::i128_from_js)?;131    let value = mrlyrs::num::blend::delta(&a);132    hand::list_to_js(&value, |x1| Ok(JsValue::from_str(&x1.to_string())))133}134135/// Returns the largest positive real root of a recurrence's characteristic polynomial, the growth rate, or a not-a-number where no real root lands.136#[wasm_bindgen]137pub fn blend_growth(coefficients: JsValue) -> Result<f64, JsValue> {138    let coefficients = hand::list_from_js(&coefficients, |x1| Ok((hand::i128_from_js(&hand::item(x1, 0)?)?, hand::i128_from_js(&hand::item(x1, 1)?)?)))?;139    let value = mrlyrs::num::blend::growth(&coefficients);140    Ok(value)141}142143/// Multiplies two sequences term by term over their shared length.144#[wasm_bindgen]145pub fn blend_hadamard(a: JsValue, b: JsValue) -> Result<JsValue, JsValue> {146    let a = hand::list_from_js(&a, hand::i128_from_js)?;147    let b = hand::list_from_js(&b, hand::i128_from_js)?;148    let value = mrlyrs::num::blend::hadamard(&a, &b);149    hand::list_to_js(&value, |x1| Ok(JsValue::from_str(&x1.to_string())))150}151152/// Finds the smallest linear constant-coefficient recurrence that fits every supplied term.153#[wasm_bindgen]154pub fn blend_recurrence(terms: JsValue) -> Result<JsValue, JsValue> {155    let terms = hand::list_from_js(&terms, hand::i128_from_js)?;156    let value = mrlyrs::num::blend::recurrence(&terms);157    hand::option_to_js(value.as_ref(), |x1| hand::list_to_js(x1, |x2| Ok(hand::tuple_to_js(&[JsValue::from_str(&x2.0.to_string()), JsValue::from_str(&x2.1.to_string())]))))158}159160/// Multiplies every term of a sequence by the factor.161#[wasm_bindgen]162pub fn blend_scale(a: JsValue, factor: JsValue) -> Result<JsValue, JsValue> {163    let a = hand::list_from_js(&a, hand::i128_from_js)?;164    let factor = hand::i128_from_js(&factor)?;165    let value = mrlyrs::num::blend::scale(&a, factor);166    hand::list_to_js(&value, |x1| Ok(JsValue::from_str(&x1.to_string())))167}168169/// Drops the first terms of a sequence.170#[wasm_bindgen]171pub fn blend_shift(a: JsValue, count: usize) -> Result<JsValue, JsValue> {172    let a = hand::list_from_js(&a, hand::i128_from_js)?;173    let value = mrlyrs::num::blend::shift(&a, count);174    hand::list_to_js(&value, |x1| Ok(JsValue::from_str(&x1.to_string())))175}176177/// Returns the partial sums of a sequence.178#[wasm_bindgen]179pub fn blend_sigma(a: JsValue) -> Result<JsValue, JsValue> {180    let a = hand::list_from_js(&a, hand::i128_from_js)?;181    let value = mrlyrs::num::blend::sigma(&a).map_err(hand::throw)?;182    hand::list_to_js(&value, |x1| Ok(JsValue::from_str(&x1.to_string())))183}184185/// Subtracts the second sequence from the first over their shared length.186#[wasm_bindgen]187pub fn blend_sub(a: JsValue, b: JsValue) -> Result<JsValue, JsValue> {188    let a = hand::list_from_js(&a, hand::i128_from_js)?;189    let b = hand::list_from_js(&b, hand::i128_from_js)?;190    let value = mrlyrs::num::blend::sub(&a, &b);191    hand::list_to_js(&value, |x1| Ok(JsValue::from_str(&x1.to_string())))192}193194/// Reports whether the packed function outputs one on exactly half of its inputs.195#[wasm_bindgen]196pub fn boolean_is_balanced(code: JsValue, n: usize) -> Result<bool, JsValue> {197    let code = hand::u128_from_js(&code)?;198    let value = mrlyrs::num::boolean::is_balanced(code, n);199    Ok(value)200}201202/// Returns how far the packed function sits from every affine function, zero when it is one.203#[wasm_bindgen]204pub fn boolean_nonlinearity(code: JsValue, n: usize) -> Result<i64, JsValue> {205    let code = hand::u128_from_js(&code)?;206    let value = mrlyrs::num::boolean::nonlinearity(code, n);207    Ok(value)208}209210/// Returns the mean chance that flipping one input bit flips the output, 0.5 at full avalanche.211#[wasm_bindgen]212pub fn boolean_sac(code: JsValue, n: usize) -> Result<f64, JsValue> {213    let code = hand::u128_from_js(&code)?;214    let value = mrlyrs::num::boolean::sac(code, n);215    Ok(value)216}217218/// Returns the Walsh spectrum of an n-input boolean function packed as a truth-table code.219#[wasm_bindgen]220pub fn boolean_walsh_spectrum(code: JsValue, n: usize) -> Result<Vec<i64>, JsValue> {221    let code = hand::u128_from_js(&code)?;222    let value = mrlyrs::num::boolean::walsh_spectrum(code, n);223    Ok(value)224}225226/// Returns the digits a bitmask names inside the base, ascending.227#[wasm_bindgen]228pub fn design_digits_of(mask: u32, base: JsValue) -> Result<Vec<u64>, JsValue> {229    let base = hand::u64_from_js(&base)?;230    let value = mrlyrs::num::design::digits_of(mask, base);231    Ok(value)232}233234/// Returns the density echo, the sum of mu(n) A_F(n)/n over the whole numbers up to each grid point divided by x to the exponent, sieving the Mobius values to the largest element.235#[wasm_bindgen]236pub fn design_echo_series(values: JsValue, log_x: &[f64], exponent: f64) -> Result<Vec<f64>, JsValue> {237    let values = hand::list_from_js(&values, hand::u64_from_js)?;238    let value = mrlyrs::num::design::echo_series(&values, log_x, exponent);239    Ok(value)240}241242/// Returns the elements of the digit design below the base raised to the depth, ascending: the whole numbers of at most that many base digits, every digit drawn from the set and the leading digit nonzero.243#[wasm_bindgen]244pub fn design_elements(base: JsValue, digits: JsValue, depth: usize) -> Result<Vec<u64>, JsValue> {245    let base = hand::u64_from_js(&base)?;246    let digits = hand::list_from_js(&digits, hand::u64_from_js)?;247    let value = mrlyrs::num::design::elements(base, &digits, depth);248    Ok(value)249}250251/// Returns the log grid uniform over the span of the elements, from the log of the first to the log of the last.252#[wasm_bindgen]253pub fn design_log_grid(values: JsValue, samples: usize) -> Result<Vec<f64>, JsValue> {254    let values = hand::list_from_js(&values, hand::u64_from_js)?;255    let value = mrlyrs::num::design::log_grid(&values, samples);256    Ok(value)257}258259/// Returns the running median of the power over a window of the given width, the window clamped at the ends.260#[wasm_bindgen]261pub fn design_median_floor(power: &[f64], width: usize) -> Result<Vec<f64>, JsValue> {262    let value = mrlyrs::num::design::median_floor(power, width);263    Ok(value)264}265266/// Returns the running design Mobius meter, the partial sums of the Mobius values along the elements.267#[wasm_bindgen]268pub fn design_meter(mu: &[i8]) -> Result<Vec<i64>, JsValue> {269    let value = mrlyrs::num::design::meter(mu);270    Ok(value)271}272273/// Returns the distance from the ordinate to the nearest entry of the list, infinite when the list is empty.274#[wasm_bindgen]275pub fn design_nearest(value: f64, list: &[f64]) -> Result<f64, JsValue> {276    let value = mrlyrs::num::design::nearest(value, list);277    Ok(value)278}279280/// Returns the bins inside the band that rise above both neighbours and clear the score threshold, strongest first.281#[wasm_bindgen]282pub fn design_peaks(gamma: &[f64], score: &[f64], band: JsValue, threshold: f64) -> Result<Vec<usize>, JsValue> {283    let band = hand::from_js::<(f64, f64)>(&band)?;284    let value = mrlyrs::num::design::peaks(gamma, score, band, threshold).map_err(hand::throw)?;285    Ok(value)286}287288/// Returns the design's pole lattice below the top, the ordinates 2 pi j over log q of the poles its Dirichlet series carries.289#[wasm_bindgen]290pub fn design_pole_lattice(base: JsValue, top: f64) -> Result<Vec<f64>, JsValue> {291    let base = hand::u64_from_js(&base)?;292    let value = mrlyrs::num::design::pole_lattice(base, top);293    Ok(value)294}295296/// Reads the running meter at every point of the log grid and divides by x to the exponent.297#[wasm_bindgen]298pub fn design_resample(values: JsValue, running: JsValue, exponent: f64, log_x: &[f64]) -> Result<Vec<f64>, JsValue> {299    let values = hand::list_from_js(&values, hand::u64_from_js)?;300    let running = hand::list_from_js(&running, hand::i64_from_js)?;301    let value = mrlyrs::num::design::resample(&values, &running, exponent, log_x);302    Ok(value)303}304305/// Returns the power over its local median floor, the score a peak is read against.306#[wasm_bindgen]307pub fn design_score(power: &[f64], width: usize) -> Result<Vec<f64>, JsValue> {308    let value = mrlyrs::num::design::score(power, width);309    Ok(value)310}311312/// Returns the count of elements the design holds at the depth, the length [`elements`] returns without building them.313#[wasm_bindgen]314pub fn design_size(digits: JsValue, depth: usize) -> Result<JsValue, JsValue> {315    let digits = hand::list_from_js(&digits, hand::u64_from_js)?;316    let value = mrlyrs::num::design::size(&digits, depth);317    Ok(JsValue::from_str(&value.to_string()))318}319320/// Returns the frequency axis and the power spectrum of the series: the mean removed, a Hann window laid on, a real transform taken, and bin j read as the ordinate 2 pi j over the log range.321#[wasm_bindgen]322pub fn design_spectrum(log_x: &[f64], series: &[f64]) -> Result<JsValue, JsValue> {323    let value = mrlyrs::num::design::spectrum(log_x, series).map_err(hand::throw)?;324    Ok(hand::tuple_to_js(&[hand::typed(&(value.0)[..]), hand::typed(&(value.1)[..])]))325}326327/// Returns the root mean square of the upper half of the series, the size the echo and the meter are compared at.328#[wasm_bindgen]329pub fn design_upper_rms(series: &[f64]) -> Result<f64, JsValue> {330    let value = mrlyrs::num::design::upper_rms(series);331    Ok(value)332}333334/// Returns the sum of the proper divisors of the number, its divisor sum less itself, zero for zero and for one.335#[wasm_bindgen]336pub fn factor_aliquot(number: usize) -> Result<usize, JsValue> {337    let value = mrlyrs::num::factor::aliquot(number);338    Ok(value)339}340341/// Returns whether two numbers share no divisor above one.342#[wasm_bindgen]343pub fn factor_coprime(a: usize, b: usize) -> Result<bool, JsValue> {344    let value = mrlyrs::num::factor::coprime(a, b);345    Ok(value)346}347348/// Builds every divisor of a wide number from its factorization, ascending, empty for zero.349#[wasm_bindgen]350pub fn factor_divisors(number: JsValue) -> Result<Vec<u64>, JsValue> {351    let number = hand::u64_from_js(&number)?;352    let value = mrlyrs::num::factor::divisors(number);353    Ok(value)354}355356/// Returns the factorial of the number, the product of one through it, erring past thirty-four.357#[wasm_bindgen]358pub fn factor_factorial(number: usize) -> Result<JsValue, JsValue> {359    let value = mrlyrs::num::factor::factorial(number).map_err(hand::throw)?;360    Ok(JsValue::from_str(&value.to_string()))361}362363/// Returns the prime and exponent pairs of the number in ascending primes, by trial division on the six-step wheel.364#[wasm_bindgen]365pub fn factor_factorize(number: usize) -> Result<JsValue, JsValue> {366    let value = mrlyrs::num::factor::factorize(number);367    hand::to_js(&value)368}369370/// Returns the prime and exponent pairs of a wide number in ascending primes, by trial division on the six-step wheel.371#[wasm_bindgen]372pub fn factor_factorize_wide(number: JsValue) -> Result<JsValue, JsValue> {373    let number = hand::u64_from_js(&number)?;374    let value = mrlyrs::num::factor::factorize_wide(number);375    hand::list_to_js(&value, |x1| Ok(hand::tuple_to_js(&[JsValue::from(x1.0), hand::to_js(&x1.1)?])))376}377378/// Returns the greatest common divisor of two numbers by the Euclidean algorithm, zero for two zeroes.379#[wasm_bindgen]380pub fn factor_gcd(a: JsValue, b: JsValue) -> Result<JsValue, JsValue> {381    let a = hand::u128_from_js(&a)?;382    let b = hand::u128_from_js(&b)?;383    let value = mrlyrs::num::factor::gcd(a, b);384    Ok(JsValue::from_str(&value.to_string()))385}386387/// Returns the least common multiple of two numbers, zero when either side is zero.388#[wasm_bindgen]389pub fn factor_lcm(a: usize, b: usize) -> Result<usize, JsValue> {390    let value = mrlyrs::num::factor::lcm(a, b);391    Ok(value)392}393394/// Returns the Mobius value of the number: zero for zero or a squared factor, else minus one to the count of primes.395#[wasm_bindgen]396pub fn factor_mobius(number: usize) -> Result<i8, JsValue> {397    let value = mrlyrs::num::factor::mobius(number);398    Ok(value)399}400401/// Sieves the Mobius values of zero through the limit in one pass.402#[wasm_bindgen]403pub fn factor_mobius_sieve(limit: usize) -> Result<Vec<i8>, JsValue> {404    let value = mrlyrs::num::factor::mobius_sieve(limit);405    Ok(value)406}407408/// Returns the radical of the number, the product of its distinct primes, zero for zero and one for one.409#[wasm_bindgen]410pub fn factor_radical(number: usize) -> Result<usize, JsValue> {411    let value = mrlyrs::num::factor::radical(number);412    Ok(value)413}414415/// Reduces a fraction to its lowest terms, a zero numerator and denominator reading as zero over one.416#[wasm_bindgen]417pub fn factor_reduce(numerator: JsValue, denominator: JsValue) -> Result<JsValue, JsValue> {418    let numerator = hand::u128_from_js(&numerator)?;419    let denominator = hand::u128_from_js(&denominator)?;420    let value = mrlyrs::num::factor::reduce(numerator, denominator);421    Ok(hand::tuple_to_js(&[JsValue::from_str(&value.0.to_string()), JsValue::from_str(&value.1.to_string())]))422}423424/// Returns the sum of every divisor of the number raised to the power, so power zero counts them.425#[wasm_bindgen]426pub fn factor_sigma(number: usize, power: u32) -> Result<JsValue, JsValue> {427    let value = mrlyrs::num::factor::sigma(number, power);428    Ok(JsValue::from_str(&value.to_string()))429}430431/// Returns whether no prime squares into the number, true for one and false for zero.432#[wasm_bindgen]433pub fn factor_squarefree(number: usize) -> Result<bool, JsValue> {434    let value = mrlyrs::num::factor::squarefree(number);435    Ok(value)436}437438/// Returns the Euler totient of the number from its factorization, zero for zero and one for one.439#[wasm_bindgen]440pub fn factor_totient(number: usize) -> Result<usize, JsValue> {441    let value = mrlyrs::num::factor::totient(number);442    Ok(value)443}444445/// Sieves the Euler totients of zero through n in one pass, the run beside the single value.446#[wasm_bindgen]447pub fn factor_totients(n: usize) -> Result<Vec<u64>, JsValue> {448    let value = mrlyrs::num::factor::totients(n);449    Ok(value)450}451452/// Returns the divisor sum with a periodic rhythm painted on each divisor, zero for zero and for an empty rhythm.453#[wasm_bindgen]454pub fn factor_twisted(number: usize, rhythm: &[i8]) -> Result<i64, JsValue> {455    let value = mrlyrs::num::factor::twisted(number, rhythm);456    Ok(value)457}458459/// Circularly convolves a size-square field on the torus by a kernel of the same shape through fft2 both ways.460#[wasm_bindgen]461pub fn fft_convolve(field: &[f64], kernel: &[f64], size: usize) -> Result<Vec<f64>, JsValue> {462    let value = mrlyrs::num::fft::convolve(field, kernel, size).map_err(hand::throw)?;463    Ok(value)464}465466/// Convolves a size-square field on the torus by a kernel already transformed by fft2, the inverse scaled back by size squared.467#[wasm_bindgen]468pub fn fft_convolve_with(field: &[f64], kernel_re: &[f64], kernel_im: &[f64], size: usize) -> Result<Vec<f64>, JsValue> {469    let value = mrlyrs::num::fft::convolve_with(field, kernel_re, kernel_im, size).map_err(hand::throw)?;470    Ok(value)471}472473/// Lays an odd-side mask into a size-square kernel with the mask centre at index (0, 0) and negative offsets wrapped; the cell at offset (dr, dc) lands at (-dr, -dc) modulo size, so convolving a field by the kernel reads at every site the mask-weighted sum over its neighbours, the neighbour count the life step counts.474#[wasm_bindgen]475pub fn fft_embed_kernel(mask: &[u8], side: usize, size: usize) -> Result<Vec<f64>, JsValue> {476    let value = mrlyrs::num::fft::embed_kernel(mask, side, size).map_err(hand::throw)?;477    Ok(value)478}479480/// Returns the centred magnitude spectrum of a size-square field through log(1 + magnitude), the DC bin included at the centre.481#[wasm_bindgen]482pub fn fft_log_spectrum(field: &[f64], size: usize) -> Result<Vec<f64>, JsValue> {483    let value = mrlyrs::num::fft::log_spectrum(field, size).map_err(hand::throw)?;484    Ok(value)485}486487/// Returns the magnitudes of a square field's transform, shifted so zero frequency sits at the centre.488#[wasm_bindgen]489pub fn fft_magnitude_spectrum(field: &[f64], size: usize) -> Result<Vec<f64>, JsValue> {490    let value = mrlyrs::num::fft::magnitude_spectrum(field, size).map_err(hand::throw)?;491    Ok(value)492}493494/// Finds the ring past the centre where a radial profile peaks, a tie broken at the smaller ring; zero when the profile holds no ring past ring 0.495#[wasm_bindgen]496pub fn fft_peak_ring(profile: &[f64]) -> Result<usize, JsValue> {497    let value = mrlyrs::num::fft::peak_ring(profile);498    Ok(value)499}500501/// Reads the wavelength in cells at a radial profile's peak, size over the peak ring with a tie broken at the smaller ring; zero when the profile holds no ring past ring 0.502#[wasm_bindgen]503pub fn fft_peak_wavelength(profile: &[f64], size: usize) -> Result<f64, JsValue> {504    let value = mrlyrs::num::fft::peak_wavelength(profile, size);505    Ok(value)506}507508/// Averages a centred size-square spectrum over rings of integer radius from the centre bin, a bin joining the ring its distance rounds to, rings 0 through size over two; ring k holds the frequencies near k cycles per field.509#[wasm_bindgen]510pub fn fft_radial_profile(spectrum: &[f64], size: usize) -> Result<Vec<f64>, JsValue> {511    let value = mrlyrs::num::fft::radial_profile(spectrum, size).map_err(hand::throw)?;512    Ok(value)513}514515/// Transforms a real size-square field forward by fft2, returning the real and imaginary parts.516#[wasm_bindgen]517pub fn fft_transform(field: &[f64], size: usize) -> Result<JsValue, JsValue> {518    let value = mrlyrs::num::fft::transform(field, size).map_err(hand::throw)?;519    Ok(hand::tuple_to_js(&[hand::typed(&(value.0)[..]), hand::typed(&(value.1)[..])]))520}521522/// Lists one point per associate class of the nonzero points of norm at most the bound: canonical associates, in order of norm and then of coordinates.523#[wasm_bindgen]524pub fn gauss_classes(ring: JsValue, bound: JsValue) -> Result<JsValue, JsValue> {525    let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;526    let bound = hand::u64_from_js(&bound)?;527    let value = mrlyrs::num::gauss::classes(ring, bound);528    hand::list_to_js(&value, |x1| Ok(hand::tuple_to_js(&[JsValue::from(x1.0), JsValue::from(x1.1)])))529}530531/// Returns the norm from one through the limit with the most points and that count, the earliest on a tie.532#[wasm_bindgen]533pub fn gauss_peak(ring: JsValue, limit: usize) -> Result<JsValue, JsValue> {534    let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;535    let value = mrlyrs::num::gauss::peak(ring, limit);536    hand::to_js(&value)537}538539/// Counts the points of every norm from zero through the limit, by enumeration: the ring weights of the lattice.540#[wasm_bindgen]541pub fn gauss_shells(ring: JsValue, limit: usize) -> Result<Vec<u32>, JsValue> {542    let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;543    let value = mrlyrs::num::gauss::shells(ring, limit);544    Ok(value)545}546547/// Returns the Lyndon cofactor `Z(s) = zeta_F(s) (1 - k q^(-s))` and the bound it is known to.548#[wasm_bindgen]549pub fn ladder_cofactor(design: &ladder_Design, s: &zeta_Complex, tolerance: f64) -> Result<JsValue, JsValue> {550    let value = mrlyrs::num::ladder::cofactor(&design.inner, s.inner, tolerance).map_err(hand::throw)?;551    Ok(hand::tuple_to_js(&[JsValue::from(zeta_Complex { inner: value.0 }), hand::to_js(&value.1)?]))552}553554/// Returns the residue of `zeta_F` at `s_(m,j) = alpha - m + 2 pi i j / log q` and the bound it is known to.555#[wasm_bindgen]556pub fn ladder_residue(design: &ladder_Design, m: usize, j: JsValue, tolerance: f64) -> Result<JsValue, JsValue> {557    let j = hand::i64_from_js(&j)?;558    let value = mrlyrs::num::ladder::residue(&design.inner, m, j, tolerance).map_err(hand::throw)?;559    Ok(hand::tuple_to_js(&[JsValue::from(zeta_Complex { inner: value.0 }), hand::to_js(&value.1)?]))560}561562/// Returns `zeta_F(s)` and the bound it is known to.563#[wasm_bindgen]564pub fn ladder_zeta(design: &ladder_Design, s: &zeta_Complex, tolerance: f64) -> Result<JsValue, JsValue> {565    let value = mrlyrs::num::ladder::zeta(&design.inner, s.inner, tolerance).map_err(hand::throw)?;566    Ok(hand::tuple_to_js(&[JsValue::from(zeta_Complex { inner: value.0 }), hand::to_js(&value.1)?]))567}568569/// Counts the ordered pairs of coprime coordinates between one and n: twice the totient sum less one.570#[wasm_bindgen]571pub fn lattice_coprime_pairs(n: usize) -> Result<u64, JsValue> {572    let value = mrlyrs::num::lattice::coprime_pairs(n);573    Ok(value)574}575576/// Walks the Farey sequence of the order by the Stern-Brocot mediant recurrence from zero over one to one over one: every reduced fraction with denominator at most the order, ascending.577#[wasm_bindgen]578pub fn lattice_farey(order: usize) -> Result<JsValue, JsValue> {579    let value = mrlyrs::num::lattice::farey(order);580    hand::to_js(&value)581}582583/// Lists the grid crossings of a window's nodes, row-major over the ascending axis nodes.584#[wasm_bindgen]585pub fn lattice_grid(n: usize) -> Result<JsValue, JsValue> {586    let value = mrlyrs::num::lattice::grid(n);587    hand::to_js(&value)588}589590/// Counts the nodes window n lights that window n minus one lacked: two at window one, phi of n after.591#[wasm_bindgen]592pub fn lattice_new_nodes(n: usize) -> Result<u64, JsValue> {593    let value = mrlyrs::num::lattice::new_nodes(n);594    Ok(value)595}596597/// Estimates pi from visibility: the density of coprime pairs in the n-by-n window tends to six over pi squared.598#[wasm_bindgen]599pub fn lattice_pi_estimate(n: usize) -> Result<f64, JsValue> {600    let value = mrlyrs::num::lattice::pi_estimate(n);601    Ok(value)602}603604/// Recovers the constant the dimension hides from the visible count of the window, pi at an even dimension and zeta of the dimension at an odd one.605#[wasm_bindgen]606pub fn lattice_recovered(n: usize, dimension: u32) -> Result<f64, JsValue> {607    let value = mrlyrs::num::lattice::recovered(n, dimension).map_err(hand::throw)?;608    Ok(value)609}610611/// The density the visible count of a window in the dimension walks to, one over zeta of the dimension.612#[wasm_bindgen]613pub fn lattice_visible_density(dimension: u32) -> Result<f64, JsValue> {614    let value = mrlyrs::num::lattice::visible_density(dimension).map_err(hand::throw)?;615    Ok(value)616}617618/// The rational factor r with zeta of the dimension equal to r times pi to the dimension, read off the Bernoulli fraction; none at an odd dimension or past twelve.619#[wasm_bindgen]620pub fn lattice_zeta_factor(dimension: u32) -> Result<JsValue, JsValue> {621    let value = mrlyrs::num::lattice::zeta_factor(dimension);622    hand::to_js(&value)623}624625/// The value zeta takes at a whole argument above one, the exact Bernoulli form at an even one and the Euler-Maclaurin sum at an odd one.626#[wasm_bindgen]627pub fn lattice_zeta_whole(s: u32) -> Result<f64, JsValue> {628    let value = mrlyrs::num::lattice::zeta_whole(s).map_err(hand::throw)?;629    Ok(value)630}631632/// Returns the count of allowed windows `card W`, the bits the code sets inside its window range.633#[wasm_bindgen]634pub fn memory_allowed_windows(rule: &memory_Rule) -> Result<usize, JsValue> {635    let value = mrlyrs::num::memory::allowed_windows(&rule.inner);636    Ok(value)637}638639/// Returns the accepted words of the level as cell indices of the `2^L` grid, `x` from bit `0` of every digit, `y` from bit `1`, `z` from bit `2`, coarsest digit first.640#[wasm_bindgen]641pub fn memory_cells(rule: &memory_Rule, level: usize) -> Result<Vec<u64>, JsValue> {642    let value = mrlyrs::num::memory::cells(&rule.inner, level);643    Ok(value)644}645646/// Returns `N_W(L)`, the count of accepted words, for `L = 1 ..= levels`, and stops early on the level whose count overruns a `u64`.647#[wasm_bindgen]648pub fn memory_counts(rule: &memory_Rule, levels: usize) -> Result<Vec<u64>, JsValue> {649    let value = mrlyrs::num::memory::counts(&rule.inner, levels);650    Ok(value)651}652653/// Returns the growth exponent `log_2 rho`, the growth per digit of the accepted word count.654#[wasm_bindgen]655pub fn memory_exponent(rule: &memory_Rule) -> Result<f64, JsValue> {656    let value = mrlyrs::num::memory::exponent(&rule.inner);657    Ok(value)658}659660/// Returns the memory number `kappa(W) = log_2(card W) / k - log_2 rho`, the bits a digit spends on memory.661#[wasm_bindgen]662pub fn memory_kappa(rule: &memory_Rule) -> Result<f64, JsValue> {663    let value = mrlyrs::num::memory::kappa(&rule.inner);664    Ok(value)665}666667/// Returns the Perron root of the transfer matrix, the count's growth per level.668#[wasm_bindgen]669pub fn memory_perron(rule: &memory_Rule) -> Result<f64, JsValue> {670    let value = mrlyrs::num::memory::perron(&rule.inner);671    Ok(value)672}673674/// Returns the transfer matrix on the `(k - 1)`-windows: entry `(s, t)` is one when the window that overlaps state `s` onto state `t` is allowed.675#[wasm_bindgen]676pub fn memory_transfer(rule: &memory_Rule) -> Result<JsValue, JsValue> {677    let value = mrlyrs::num::memory::transfer(&rule.inner);678    hand::list_to_js(&value, |x1| Ok(hand::typed(&(*x1)[..])))679}680681/// Returns the run-boundary word, one wherever a letter differs from the next.682#[wasm_bindgen]683pub fn morse_boundary(word: &[u8]) -> Result<Vec<u8>, JsValue> {684    let value = mrlyrs::num::morse::boundary(word);685    Ok(value)686}687688/// Exclusive-ors two grids of the same length, site by site.689#[wasm_bindgen]690pub fn morse_difference(a: &[u8], b: &[u8]) -> Result<Vec<u8>, JsValue> {691    let value = mrlyrs::num::morse::difference(a, b);692    Ok(value)693}694695/// Builds the first letters of the Thue-Morse word by the digit rule.696#[wasm_bindgen]697pub fn morse_digits(length: usize) -> Result<Vec<u8>, JsValue> {698    let value = mrlyrs::num::morse::digits(length);699    Ok(value)700}701702/// Builds the period-doubling word by the substitution `1 -> 10`, `0 -> 11`, from the seed 1.703#[wasm_bindgen]704pub fn morse_doubling(length: usize) -> Result<Vec<u8>, JsValue> {705    let value = mrlyrs::num::morse::doubling(length);706    Ok(value)707}708709/// Counts the sites where two grids of the same length differ.710#[wasm_bindgen]711pub fn morse_faults(a: &[u8], b: &[u8]) -> Result<usize, JsValue> {712    let value = mrlyrs::num::morse::faults(a, b);713    Ok(value)714}715716/// Tests a grid against the Kronecker power of its own corner tile.717#[wasm_bindgen]718pub fn morse_fold(grid: &[u8], side: usize, number: usize) -> Result<JsValue, JsValue> {719    let value = mrlyrs::num::morse::fold(grid, side, number).map_err(hand::throw)?;720    hand::to_js(&value)721}722723/// Returns the Thue-Morse letter at the place, the parity of its binary digit sum.724#[wasm_bindgen]725pub fn morse_letter(place: JsValue) -> Result<u8, JsValue> {726    let place = hand::u64_from_js(&place)?;727    let value = mrlyrs::num::morse::letter(place);728    Ok(value)729}730731/// Builds a lift as a row-major sign grid of the side, zero for plus one and one for minus one.732#[wasm_bindgen]733pub fn morse_lift(kind: JsValue, side: usize) -> Result<Vec<u8>, JsValue> {734    let kind = hand::from_js::<mrlyrs::num::morse::Lift>(&kind)?;735    let value = mrlyrs::num::morse::lift(kind, side);736    Ok(value)737}738739/// Folds a tile of the side into its Kronecker power at the level, one bit per site.740#[wasm_bindgen]741pub fn morse_power(tile: &[u8], number: usize, level: usize) -> Result<Vec<u8>, JsValue> {742    let value = mrlyrs::num::morse::power(tile, number, level).map_err(hand::throw)?;743    Ok(value)744}745746/// Repeats a tile until it fills a grid of the side.747#[wasm_bindgen]748pub fn morse_repeat(tile: &[u8], number: usize, side: usize) -> Result<Vec<u8>, JsValue> {749    let value = mrlyrs::num::morse::repeat(tile, number, side);750    Ok(value)751}752753/// Returns the lengths of the maximal blocks of one repeated letter, in order.754#[wasm_bindgen]755pub fn morse_runs(word: &[u8]) -> Result<Vec<usize>, JsValue> {756    let value = mrlyrs::num::morse::runs(word);757    Ok(value)758}759760/// Returns the substitution stage after the rounds, a word of length two to the rounds.761#[wasm_bindgen]762pub fn morse_stage(rounds: usize) -> Result<Vec<u8>, JsValue> {763    let value = mrlyrs::num::morse::stage(rounds);764    Ok(value)765}766767/// Builds the first letters of the Thue-Morse word by the substitution `0 -> 01`, `1 -> 10`.768#[wasm_bindgen]769pub fn morse_substitution(length: usize) -> Result<Vec<u8>, JsValue> {770    let value = mrlyrs::num::morse::substitution(length);771    Ok(value)772}773774/// Blows a grid up by the scale, every site becoming a scale-by-scale block.775#[wasm_bindgen]776pub fn morse_upsample(grid: &[u8], side: usize, scale: usize) -> Result<Vec<u8>, JsValue> {777    let value = mrlyrs::num::morse::upsample(grid, side, scale);778    Ok(value)779}780781/// Reads the prime count against x over ln x and li at evenly spaced points from two up to the top, at most the given count of them, the top always last.782#[wasm_bindgen]783pub fn prime_chart(top: usize, bins: usize) -> Result<JsValue, JsValue> {784    let value = mrlyrs::num::prime::chart(top, bins);785    hand::to_js(&value)786}787788/// Returns whether every number from zero through the limit is prime, the finished sieve read flag by flag.789#[wasm_bindgen]790pub fn prime_flags(limit: usize) -> Result<JsValue, JsValue> {791    let value = mrlyrs::num::prime::flags(limit);792    hand::to_js(&value)793}794795/// Returns the count of unordered pairs of primes summing to the number, zero below four.796#[wasm_bindgen]797pub fn prime_goldbach(number: usize) -> Result<usize, JsValue> {798    let value = mrlyrs::num::prime::goldbach(number);799    Ok(value)800}801802/// Returns the count of prime pairs at every even number from four up to the top, one entry per even number.803#[wasm_bindgen]804pub fn prime_goldbach_record(top: usize) -> Result<Vec<usize>, JsValue> {805    let value = mrlyrs::num::prime::goldbach_record(top);806    Ok(value)807}808809/// Returns whether the number is prime, by trial division on the six-step wheel.810#[wasm_bindgen]811pub fn prime_is_prime(number: usize) -> Result<bool, JsValue> {812    let value = mrlyrs::num::prime::is_prime(number);813    Ok(value)814}815816/// Reads a wide number as a pile of stones, its rectangles built from the divisors of its factorization.817#[wasm_bindgen]818pub fn prime_pile(number: JsValue) -> Result<JsValue, JsValue> {819    let number = hand::u64_from_js(&number)?;820    let value = mrlyrs::num::prime::pile(number);821    hand::to_js(&value)822}823824/// Returns the count of primes at or below n.825#[wasm_bindgen]826pub fn prime_prime_count(n: usize) -> Result<usize, JsValue> {827    let value = mrlyrs::num::prime::prime_count(n);828    Ok(value)829}830831/// Returns the smallest prime at or above the number.832#[wasm_bindgen]833pub fn prime_prime_from(number: usize) -> Result<usize, JsValue> {834    let value = mrlyrs::num::prime::prime_from(number);835    Ok(value)836}837838/// Returns the primes up to the limit, the finished sieve read as a list.839#[wasm_bindgen]840pub fn prime_primes(limit: usize) -> Result<Vec<usize>, JsValue> {841    let value = mrlyrs::num::prime::primes(limit);842    Ok(value)843}844845/// Returns every rectangle of the number as a pair of sides, the shorter first, ascending: the divisors at or below the root.846#[wasm_bindgen]847pub fn prime_rectangles(number: usize) -> Result<JsValue, JsValue> {848    let value = mrlyrs::num::prime::rectangles(number);849    hand::to_js(&value)850}851852/// Returns every pair of primes summing to the number, odd numbers included, the smaller first, ascending.853#[wasm_bindgen]854pub fn prime_splits(number: usize) -> Result<JsValue, JsValue> {855    let value = mrlyrs::num::prime::splits(number);856    hand::to_js(&value)857}858859/// Returns the smallest pair of positive sides whose squares sum to the number, when one exists.860#[wasm_bindgen]861pub fn prime_squares(number: usize) -> Result<JsValue, JsValue> {862    let value = mrlyrs::num::prime::squares(number);863    hand::to_js(&value)864}865866/// Returns one prime object for every prime up to and including the limit.867#[wasm_bindgen]868pub fn prime_study(limit: usize) -> Result<JsValue, JsValue> {869    let value = mrlyrs::num::prime::study(limit);870    hand::to_js(&value)871}872873/// Returns the flowsnake as a radix design: base `3 + omega` of norm seven on the hexagonal lattice, the full residue system, code `127`.874#[wasm_bindgen]875pub fn radix_flowsnake() -> Result<radix_Radix, JsValue> {876    let value = mrlyrs::num::radix::flowsnake().map_err(hand::throw)?;877    Ok(radix_Radix { inner: value })878}879880/// Returns the Sierpinski gasket as a radix design: base `2` on the hexagonal lattice, three of the four residues, code `7`.881#[wasm_bindgen]882pub fn radix_gasket() -> Result<radix_Radix, JsValue> {883    let value = mrlyrs::num::radix::gasket().map_err(hand::throw)?;884    Ok(radix_Radix { inner: value })885}886887/// Returns the Koch curve as a radix design: base `3` on the hexagonal lattice, digits `0, 1, 2 + omega, 2`, twists `1, e^(i pi/3), e^(-i pi/3), 1`.888#[wasm_bindgen]889pub fn radix_koch() -> Result<radix_Radix, JsValue> {890    let value = mrlyrs::num::radix::koch().map_err(hand::throw)?;891    Ok(radix_Radix { inner: value })892}893894/// Returns the terdragon as a radix design: base `2 + omega` on the hexagonal lattice, the full residue system, code `7`, twisted by `1, omega, 1`.895#[wasm_bindgen]896pub fn radix_terdragon() -> Result<radix_Radix, JsValue> {897    let value = mrlyrs::num::radix::terdragon().map_err(hand::throw)?;898    Ok(radix_Radix { inner: value })899}900901/// Returns the plane design of a cell code as a radix design: base the rational integer `m`, of norm `m^2`, on the square lattice, no twist, digits the box residues `{x + y i : 0 <= x, y < m}`.902#[wasm_bindgen]903pub fn radix_tile(m: JsValue, code: JsValue) -> Result<radix_Radix, JsValue> {904    let m = hand::u64_from_js(&m)?;905    let code = hand::u128_from_js(&code)?;906    let value = mrlyrs::num::radix::tile(m, code).map_err(hand::throw)?;907    Ok(radix_Radix { inner: value })908}909910/// Returns the twindragon as a radix design: base `1 + i` on the square lattice, the full residue system, code `3`.911#[wasm_bindgen]912pub fn radix_twindragon() -> Result<radix_Radix, JsValue> {913    let value = mrlyrs::num::radix::twindragon().map_err(hand::throw)?;914    Ok(radix_Radix { inner: value })915}916917/// Returns the Basel sum of the reciprocal squares over n terms, walking to pi squared over six.918#[wasm_bindgen]919pub fn series_basel(n: usize) -> Result<f64, JsValue> {920    let value = mrlyrs::num::series::basel(n);921    Ok(value)922}923924/// Builds the first Bernoulli numbers as exact reduced fractions on the minus one half convention.925#[wasm_bindgen]926pub fn series_bernoulli(count: usize) -> Result<JsValue, JsValue> {927    let value = mrlyrs::num::series::bernoulli(count).map_err(hand::throw)?;928    hand::list_to_js(&value, |x1| Ok(hand::tuple_to_js(&[JsValue::from_str(&x1.0.to_string()), JsValue::from_str(&x1.1.to_string())])))929}930931/// Returns the Dirichlet beta value, the alternating odd-denominator sum averaged over its last two partial sums.932#[wasm_bindgen]933pub fn series_beta(s: f64, terms: usize) -> Result<f64, JsValue> {934    let value = mrlyrs::num::series::beta(s, terms);935    Ok(value)936}937938/// Returns the powers of two up to the limit.939#[wasm_bindgen]940pub fn series_binary(limit: usize) -> Result<Vec<usize>, JsValue> {941    let value = mrlyrs::num::series::binary(limit);942    Ok(value)943}944945/// Returns the distinct Catalan numbers up to the limit.946#[wasm_bindgen]947pub fn series_catalan(limit: usize) -> Result<Vec<usize>, JsValue> {948    let value = mrlyrs::num::series::catalan(limit);949    Ok(value)950}951952/// Returns the mod-three rhythm of the number: zero, one, minus one.953#[wasm_bindgen]954pub fn series_chi3(number: usize) -> Result<i8, JsValue> {955    let value = mrlyrs::num::series::chi3(number);956    Ok(value)957}958959/// Returns the mod-four rhythm of the number: zero, one, zero, minus one.960#[wasm_bindgen]961pub fn series_chi4(number: usize) -> Result<i8, JsValue> {962    let value = mrlyrs::num::series::chi4(number);963    Ok(value)964}965966/// Returns the mod-eight rhythm of the number, the discriminant minus-eight character: one on one and three, minus one on five and seven, zero on the evens.967#[wasm_bindgen]968pub fn series_chi8(number: usize) -> Result<i8, JsValue> {969    let value = mrlyrs::num::series::chi8(number);970    Ok(value)971}972973/// Returns the L-series partial sum with a periodic rhythm painted on the terms.974#[wasm_bindgen]975pub fn series_dirichlet(s: f64, rhythm: &[i8], terms: usize) -> Result<f64, JsValue> {976    let value = mrlyrs::num::series::dirichlet(s, rhythm, terms);977    Ok(value)978}979980/// Returns one plus one over n raised to the n, walking to the natural base.981#[wasm_bindgen]982pub fn series_e_partial(n: usize) -> Result<f64, JsValue> {983    let value = mrlyrs::num::series::e_partial(n);984    Ok(value)985}986987/// Returns the harmonic sum of n terms less the logarithm of n, walking to the Euler-Mascheroni constant.988#[wasm_bindgen]989pub fn series_euler_gamma_partial(n: usize) -> Result<f64, JsValue> {990    let value = mrlyrs::num::series::euler_gamma_partial(n);991    Ok(value)992}993994/// Returns the Euler product of zeta, one over one minus p to the minus s over the primes up to the limit.995#[wasm_bindgen]996pub fn series_euler_product(s: f64, limit: usize) -> Result<f64, JsValue> {997    let value = mrlyrs::num::series::euler_product(s, limit);998    Ok(value)999}10001001/// Returns the even numbers up to the limit.1002#[wasm_bindgen]1003pub fn series_evens(limit: usize) -> Result<Vec<usize>, JsValue> {1004    let value = mrlyrs::num::series::evens(limit);1005    Ok(value)1006}10071008/// Returns the distinct Fibonacci numbers up to the limit.1009#[wasm_bindgen]1010pub fn series_fibonacci(limit: usize) -> Result<Vec<usize>, JsValue> {1011    let value = mrlyrs::num::series::fibonacci(limit);1012    Ok(value)1013}10141015/// Returns the partial harmonic sum, the reciprocals of one through the term count.1016#[wasm_bindgen]1017pub fn series_harmonic(terms: usize) -> Result<f64, JsValue> {1018    let value = mrlyrs::num::series::harmonic(terms);1019    Ok(value)1020}10211022/// Returns the Dirichlet lambda value, one minus two to the minus s times zeta.1023#[wasm_bindgen]1024pub fn series_lambda(s: f64, terms: usize) -> Result<f64, JsValue> {1025    let value = mrlyrs::num::series::lambda(s, terms).map_err(hand::throw)?;1026    Ok(value)1027}10281029/// Returns the Leibniz alternating sum of the odd reciprocals over n terms, walking to pi over four.1030#[wasm_bindgen]1031pub fn series_leibniz(n: usize) -> Result<f64, JsValue> {1032    let value = mrlyrs::num::series::leibniz(n);1033    Ok(value)1034}10351036/// Returns the logarithmic integral of a positive x by the Ramanujan series, the smooth count of the primes below x.1037#[wasm_bindgen]1038pub fn series_li(x: f64) -> Result<f64, JsValue> {1039    let value = mrlyrs::num::series::li(x);1040    Ok(value)1041}10421043/// Returns the Mertens function at n, the Mobius values of one through n summed.1044#[wasm_bindgen]1045pub fn series_mertens(n: usize) -> Result<i64, JsValue> {1046    let value = mrlyrs::num::series::mertens(n);1047    Ok(value)1048}10491050/// Returns the odd numbers up to the limit.1051#[wasm_bindgen]1052pub fn series_odds(limit: usize) -> Result<Vec<usize>, JsValue> {1053    let value = mrlyrs::num::series::odds(limit);1054    Ok(value)1055}10561057/// Counts the lattice points of the dimension-cube of the limit whose coordinates share no divisor, by Mobius inversion.1058#[wasm_bindgen]1059pub fn series_visible(limit: usize, dimension: u32) -> Result<JsValue, JsValue> {1060    let value = mrlyrs::num::series::visible(limit, dimension).map_err(hand::throw)?;1061    Ok(JsValue::from_str(&value.to_string()))1062}10631064/// Returns the Wallis product taken to n paired factors, four k squared over four k squared less one, walking to pi over two.1065#[wasm_bindgen]1066pub fn series_wallis_half_pi(n: usize) -> Result<f64, JsValue> {1067    let value = mrlyrs::num::series::wallis_half_pi(n);1068    Ok(value)1069}10701071/// Returns the Wallis product of one minus one over the odd squares taken to n factors, walking to pi over four.1072#[wasm_bindgen]1073pub fn series_wallis_quarter_pi(factors: usize) -> Result<f64, JsValue> {1074    let value = mrlyrs::num::series::wallis_quarter_pi(factors);1075    Ok(value)1076}10771078/// Returns the zeta value above one, the partial sum closed by its Euler-Maclaurin tail.1079#[wasm_bindgen]1080pub fn series_zeta(s: f64, terms: usize) -> Result<f64, JsValue> {1081    let value = mrlyrs::num::series::zeta(s, terms).map_err(hand::throw)?;1082    Ok(value)1083}10841085/// Returns the cells the word leaves, the product of its letters' fills, one punctured tile a letter.1086#[wasm_bindgen]1087pub fn sieve_cells(word: JsValue, dimension: u32) -> Result<JsValue, JsValue> {1088    let word = hand::list_from_js(&word, hand::u64_from_js)?;1089    let value = mrlyrs::num::sieve::cells(&word, dimension).map_err(hand::throw)?;1090    Ok(JsValue::from_str(&value.to_string()))1091}10921093/// Returns the box exponent the word reads at its own scale, the logarithm of its cells over the logarithm of its side, which walks up to the dimension on a schedule of distinct growing letters and stands still on any schedule that reuses its letters.1094#[wasm_bindgen]1095pub fn sieve_exponent(word: JsValue, dimension: u32) -> Result<f64, JsValue> {1096    let word = hand::list_from_js(&word, hand::u64_from_js)?;1097    let value = mrlyrs::num::sieve::exponent(&word, dimension).map_err(hand::throw)?;1098    Ok(value)1099}11001101/// Returns the constant schedule, one odd side repeated to the count of levels, whose limit set is the fixed-ratio carpet.1102#[wasm_bindgen]1103pub fn sieve_flat_word(side: JsValue, levels: usize) -> Result<Vec<u64>, JsValue> {1104    let side = hand::u64_from_js(&side)?;1105    let value = mrlyrs::num::sieve::flat_word(side, levels);1106    Ok(value)1107}11081109/// Returns the punctures the word makes, one per surviving cell at every level.1110#[wasm_bindgen]1111pub fn sieve_holes(word: JsValue, dimension: u32) -> Result<JsValue, JsValue> {1112    let word = hand::list_from_js(&word, hand::u64_from_js)?;1113    let value = mrlyrs::num::sieve::holes(&word, dimension).map_err(hand::throw)?;1114    Ok(JsValue::from_str(&value.to_string()))1115}11161117/// Returns the limit the word's schedule walks to in the given dimension, when the word names a schedule at all.1118#[wasm_bindgen]1119pub fn sieve_limit(word: JsValue, dimension: u32) -> Result<JsValue, JsValue> {1120    let word = hand::list_from_js(&word, hand::u64_from_js)?;1121    let value = mrlyrs::num::sieve::limit(&word, dimension).map_err(hand::throw)?;1122    hand::to_js(&value)1123}11241125/// Returns the classical Wallis schedule, the odd sides three, five, seven and on, to the count of levels.1126#[wasm_bindgen]1127pub fn sieve_odd_word(levels: usize) -> Result<Vec<u64>, JsValue> {1128    let value = mrlyrs::num::sieve::odd_word(levels);1129    Ok(value)1130}11311132/// Lists every puncture the word makes in the given dimension: its corner along each axis and then its side, all in units of the word's finest cell, so a level-one hole is the widest block in the list.1133#[wasm_bindgen]1134pub fn sieve_punctures(word: JsValue, dimension: u32) -> Result<Vec<u64>, JsValue> {1135    let word = hand::list_from_js(&word, hand::u64_from_js)?;1136    let value = mrlyrs::num::sieve::punctures(&word, dimension).map_err(hand::throw)?;1137    Ok(value)1138}11391140/// Builds the plane sieve the word spells as a raster: its side, then one byte a site, row by row, one where the site survives and zero where a level punched it out.1141#[wasm_bindgen]1142pub fn sieve_raster(word: JsValue) -> Result<JsValue, JsValue> {1143    let word = hand::list_from_js(&word, hand::u64_from_js)?;1144    let value = mrlyrs::num::sieve::raster(&word).map_err(hand::throw)?;1145    Ok(hand::tuple_to_js(&[hand::to_js(&value.0)?, hand::typed(&(value.1)[..])]))1146}11471148/// Returns the share of the whole the word leaves, the product of one minus the inverse of each letter's site count, exact as a product of the letters' fills.1149#[wasm_bindgen]1150pub fn sieve_ratio(word: JsValue, dimension: u32) -> Result<f64, JsValue> {1151    let word = hand::list_from_js(&word, hand::u64_from_js)?;1152    let value = mrlyrs::num::sieve::ratio(&word, dimension).map_err(hand::throw)?;1153    Ok(value)1154}11551156/// Returns the side of the word, the product of its letters' sides.1157#[wasm_bindgen]1158pub fn sieve_side(word: JsValue) -> Result<JsValue, JsValue> {1159    let word = hand::list_from_js(&word, hand::u64_from_js)?;1160    let value = mrlyrs::num::sieve::side(&word).map_err(hand::throw)?;1161    Ok(JsValue::from_str(&value.to_string()))1162}11631164/// Returns the limit of the solid Wallis sieve's surviving volume, the product of one minus n to the minus three over the odd n from three, in closed form.1165#[wasm_bindgen]1166pub fn sieve_solid_limit() -> Result<f64, JsValue> {1167    let value = mrlyrs::num::sieve::solid_limit();1168    Ok(value)1169}11701171/// Reads the quadratic a k^2 + b k + c, a at least one, over the sheet the odd side wide: every value from one through the top, its cell, the prime hits and the opening streak.1172#[wasm_bindgen]1173pub fn spiral_diagonal(lattice: JsValue, side: usize, a: JsValue, b: JsValue, c: JsValue) -> Result<JsValue, JsValue> {1174    let lattice = hand::from_js::<mrlyrs::num::spiral::Lattice>(&lattice)?;1175    let a = hand::i64_from_js(&a)?;1176    let b = hand::i64_from_js(&b)?;1177    let c = hand::i64_from_js(&c)?;1178    let value = mrlyrs::num::spiral::diagonal(lattice, side, a, b, c);1179    hand::to_js(&value)1180}11811182/// Returns the level of a number in a base, the count of its digits less one, so zero below the base and one at the base itself.1183#[wasm_bindgen]1184pub fn spiral_level_of(n: JsValue, base: JsValue) -> Result<u32, JsValue> {1185    let n = hand::u64_from_js(&n)?;1186    let base = hand::u64_from_js(&base)?;1187    let value = mrlyrs::num::spiral::level_of(n, base);1188    Ok(value)1189}11901191/// Marks every number from zero through the limit: one when marked, minus one for a Mobius value of minus one, else zero.1192#[wasm_bindgen]1193pub fn spiral_marks(mark: JsValue, limit: usize) -> Result<Vec<i8>, JsValue> {1194    let mark = hand::from_js::<mrlyrs::num::spiral::Mark>(&mark)?;1195    let value = mrlyrs::num::spiral::marks(mark, limit);1196    Ok(value)1197}11981199/// Winds one to the top on the square spiral and lays a square tile on every cell, the snail.1200#[wasm_bindgen]1201pub fn spiral_snail(base: JsValue, top: JsValue, growth: JsValue) -> Result<JsValue, JsValue> {1202    let base = hand::u64_from_js(&base)?;1203    let top = hand::u64_from_js(&top)?;1204    let growth = hand::from_js::<mrlyrs::num::spiral::Growth>(&growth)?;1205    let value = mrlyrs::num::spiral::snail(base, top, growth);1206    hand::to_js(&value)1207}12081209/// The smooth window on [1, 2]: exp(4 - 1/((u - 1)(2 - u))) inside, zero outside, every derivative vanishing at the ends and a peak of one at u = 3/2.1210#[wasm_bindgen]1211pub fn zeta_bump(u: f64) -> Result<f64, JsValue> {1212    let value = mrlyrs::num::zeta::bump(u);1213    Ok(value)1214}12151216/// Returns the first four Riemann-Siegel corrections at the fractional part p: the kernel and its derivatives by central differences with one Richardson step.1217#[wasm_bindgen]1218pub fn zeta_corrections(p: f64) -> Result<Vec<f64>, JsValue> {1219    let value = mrlyrs::num::zeta::corrections(p);1220    Ok(value.to_vec())1221}12221223/// Returns the Riemann-Siegel kernel, the cosine ratio that leads the remainder, in the form that stays finite at its removable points.1224#[wasm_bindgen]1225pub fn zeta_kernel(p: f64) -> Result<f64, JsValue> {1226    let value = mrlyrs::num::zeta::kernel(p);1227    Ok(value)1228}12291230/// Returns the Mellin transform of the bump at a complex s, the integral of bump(u) u^(s - 1) over [1, 2], by a 4096-node midpoint rule.1231#[wasm_bindgen]1232pub fn zeta_mellin(s: &zeta_Complex) -> Result<zeta_Complex, JsValue> {1233    let value = mrlyrs::num::zeta::mellin(s.inner);1234    Ok(zeta_Complex { inner: value })1235}12361237/// Returns the main term of the smoothed novelty: six over pi squared times the bump's transform at two.1238#[wasm_bindgen]1239pub fn zeta_novelty_main() -> Result<f64, JsValue> {1240    let value = mrlyrs::num::zeta::novelty_main();1241    Ok(value)1242}12431244/// Sums the waves of the zeros at log y: twice the real part of the coefficients times y to the minus i gamma, the smoothed error over y to the three halves that the zeros predict.1245#[wasm_bindgen]1246pub fn zeta_novelty_wave(gammas: &[f64], coef: JsValue, log_y: f64) -> Result<f64, JsValue> {1247    let coef = hand::list_from_js(&coef, |x1| hand::from_js::<mrlyrs::num::zeta::Complex>(&hand::plain(x1)?))?;1248    let value = mrlyrs::num::zeta::novelty_wave(gammas, &coef, log_y);1249    Ok(value)1250}12511252/// Returns the von Mangoldt explicit formula at x over the zeros at the given ordinates and their mirrors: x less the sum of x to the rho over rho, less ln two pi, less half the ln of one minus x to the minus two.1253#[wasm_bindgen]1254pub fn zeta_psi_formula(x: f64, gammas: &[f64]) -> Result<f64, JsValue> {1255    let value = mrlyrs::num::zeta::psi_formula(x, gammas);1256    Ok(value)1257}12581259/// Returns the Chebyshev staircase at every whole number from one to x: the sum of ln p over the prime powers up to each.1260#[wasm_bindgen]1261pub fn zeta_psi_stair(x: usize) -> Result<Vec<f64>, JsValue> {1262    let value = mrlyrs::num::zeta::psi_stair(x);1263    Ok(value)1264}12651266/// Returns a positive real base raised to a complex exponent.1267#[wasm_bindgen]1268pub fn zeta_raise(base: f64, exponent: &zeta_Complex) -> Result<zeta_Complex, JsValue> {1269    let value = mrlyrs::num::zeta::raise(base, exponent.inner);1270    Ok(zeta_Complex { inner: value })1271}12721273/// Returns the sharp novelty error at y: y squared times the totient sum over the scales from 1 over y to 2 over y, both ends in, less nine over pi squared, from the prefix sums of the totients, which must reach 2 over y.1274#[wasm_bindgen]1275pub fn zeta_sharp_novelty(prefix: JsValue, y: f64) -> Result<f64, JsValue> {1276    let prefix = hand::list_from_js(&prefix, hand::u64_from_js)?;1277    let value = mrlyrs::num::zeta::sharp_novelty(&prefix, y);1278    Ok(value)1279}12801281/// Returns the smoothed novelty error at y: y squared times the totients weighed by the bump at n y, less the main term given; the totients must reach 2 over y.1282#[wasm_bindgen]1283pub fn zeta_smoothed_novelty(phi: JsValue, y: f64, main: f64) -> Result<f64, JsValue> {1284    let phi = hand::list_from_js(&phi, hand::u64_from_js)?;1285    let value = mrlyrs::num::zeta::smoothed_novelty(&phi, y, main);1286    Ok(value)1287}12881289/// The most circles one growth makes before it gives up.1290#[wasm_bindgen]1291pub fn apollonian_CIRCLE_CAP() -> Result<usize, JsValue> {1292    let value = mrlyrs::num::apollonian::CIRCLE_CAP;1293    Ok(value)1294}12951296/// The largest curvature a packing is grown to.1297#[wasm_bindgen]1298pub fn apollonian_CURVATURE_CAP() -> Result<i64, JsValue> {1299    let value = mrlyrs::num::apollonian::CURVATURE_CAP;1300    Ok(value)1301}13021303/// The deepest the Farey stack is read against a packing.1304#[wasm_bindgen]1305pub fn apollonian_ORDER_CAP() -> Result<usize, JsValue> {1306    let value = mrlyrs::num::apollonian::ORDER_CAP;1307    Ok(value)1308}13091310/// The root quadruples on offer: the strip first, then the bounded packings named by their curvatures.1311#[wasm_bindgen]1312pub fn apollonian_ROOTS() -> Result<JsValue, JsValue> {1313    let value = mrlyrs::num::apollonian::ROOTS;1314    hand::to_js(&value)1315}13161317/// The relative rounding allowance the double-precision matrix ladder charges against the scale it carries.1318#[wasm_bindgen]1319pub fn automaton_ROUNDING() -> Result<f64, JsValue> {1320    let value = mrlyrs::num::automaton::ROUNDING;1321    Ok(value)1322}13231324/// The ordinates of the first fourteen nontrivial zeros of the Riemann zeta function, the imaginary parts of the zeros on the critical line in ascending order.1325#[wasm_bindgen]1326pub fn design_ZETA_ORDINATES() -> Result<Vec<f64>, JsValue> {1327    let value = mrlyrs::num::design::ZETA_ORDINATES;1328    Ok(value.to_vec())1329}13301331/// The relative rounding allowance the double-precision ladder charges against the scale it carries.1332#[wasm_bindgen]1333pub fn ladder_ROUNDING() -> Result<f64, JsValue> {1334    let value = mrlyrs::num::ladder::ROUNDING;1335    Ok(value)1336}13371338/// The largest digit span a rule may read, so its code fits a `u64`.1339#[wasm_bindgen]1340pub fn memory_SPAN() -> Result<usize, JsValue> {1341    let value = mrlyrs::num::memory::SPAN;1342    Ok(value)1343}13441345/// The sweep cap of the power iteration.1346#[wasm_bindgen]1347pub fn memory_SWEEPS() -> Result<usize, JsValue> {1348    let value = mrlyrs::num::memory::SWEEPS;1349    Ok(value)1350}13511352/// The absolute `l^1` move of the normalised iterate that stops the power iteration, counted only when it holds over three consecutive sweeps.1353#[wasm_bindgen]1354pub fn memory_TOLERANCE() -> Result<f64, JsValue> {1355    let value = mrlyrs::num::memory::TOLERANCE;1356    Ok(value)1357}13581359/// Lists the lifts in the order the gallery draws them.1360#[wasm_bindgen]1361pub fn morse_LIFTS() -> Result<JsValue, JsValue> {1362    let value = mrlyrs::num::morse::LIFTS;1363    hand::to_js(&value)1364}13651366/// The Apery constant, the value zeta takes at three.1367#[wasm_bindgen]1368pub fn series_APERY() -> Result<f64, JsValue> {1369    let value = mrlyrs::num::series::APERY;1370    Ok(value)1371}13721373/// The Basel constant, pi squared over six, the value zeta takes at two.1374#[wasm_bindgen]1375pub fn series_BASEL() -> Result<f64, JsValue> {1376    let value = mrlyrs::num::series::BASEL;1377    Ok(value)1378}13791380/// The Catalan constant, the value the Dirichlet beta function takes at two.1381#[wasm_bindgen]1382pub fn series_CATALAN() -> Result<f64, JsValue> {1383    let value = mrlyrs::num::series::CATALAN;1384    Ok(value)1385}13861387/// The Euler constant, the limit of the harmonic sum less the logarithm.1388#[wasm_bindgen]1389pub fn series_EULER() -> Result<f64, JsValue> {1390    let value = mrlyrs::num::series::EULER;1391    Ok(value)1392}13931394/// The visible density, six over pi squared, the share of lattice pairs that are coprime.1395#[wasm_bindgen]1396pub fn series_VISIBLE() -> Result<f64, JsValue> {1397    let value = mrlyrs::num::series::VISIBLE;1398    Ok(value)1399}14001401/// The limit of the plane Wallis sieve's surviving area, pi over four.1402#[wasm_bindgen]1403pub fn sieve_PLANE_LIMIT() -> Result<f64, JsValue> {1404    let value = mrlyrs::num::sieve::PLANE_LIMIT;1405    Ok(value)1406}14071408/// The t where the walk hands over from Euler-Maclaurin to Riemann-Siegel.1409#[wasm_bindgen]1410pub fn zeta_JOIN() -> Result<f64, JsValue> {1411    let value = mrlyrs::num::zeta::JOIN;1412    Ok(value)1413}14141415/// A circle in the integer coordinates `(k, k x, k y)`: a line is `k = 0` with `(k x, k y)` its outward unit normal, and the curvature is negative on the circle that contains a bounded packing.1416#[wasm_bindgen]1417pub struct apollonian_Circle {1418    inner: mrlyrs::num::apollonian::Circle,1419}14201421#[wasm_bindgen]1422impl apollonian_Circle {1423    /// Reads the Circle from its plain data.1424    #[wasm_bindgen(js_name = "from")]1425    pub fn from_plain(data: JsValue) -> Result<apollonian_Circle, JsValue> {1426        Ok(apollonian_Circle { inner: hand::from_js(&data)? })1427    }1428    /// Writes the Circle as plain data.1429    #[wasm_bindgen(js_name = "toJSON")]1430    pub fn to_plain(&self) -> Result<JsValue, JsValue> {1431        hand::to_js(&self.inner)1432    }1433    /// The curvature.1434    #[wasm_bindgen(getter)]1435    pub fn k(&self) -> Result<i64, JsValue> {1436        let value = self.inner.k;1437        Ok(value)1438    }1439    #[wasm_bindgen(setter)]1440    pub fn set_k(&mut self, value: JsValue) -> Result<(), JsValue> {1441        let value = hand::i64_from_js(&value)?;1442        self.inner.k = value;1443        Ok(())1444    }1445    /// The curvature times the centre's abscissa.1446    #[wasm_bindgen(getter)]1447    pub fn x(&self) -> Result<i64, JsValue> {1448        let value = self.inner.x;1449        Ok(value)1450    }1451    #[wasm_bindgen(setter)]1452    pub fn set_x(&mut self, value: JsValue) -> Result<(), JsValue> {1453        let value = hand::i64_from_js(&value)?;1454        self.inner.x = value;1455        Ok(())1456    }1457    /// The curvature times the centre's ordinate.1458    #[wasm_bindgen(getter)]1459    pub fn y(&self) -> Result<i64, JsValue> {1460        let value = self.inner.y;1461        Ok(value)1462    }1463    #[wasm_bindgen(setter)]1464    pub fn set_y(&mut self, value: JsValue) -> Result<(), JsValue> {1465        let value = hand::i64_from_js(&value)?;1466        self.inner.y = value;1467        Ok(())1468    }1469    /// The centre, none on a line.1470    pub fn centre(&self) -> Result<JsValue, JsValue> {1471        let value = self.inner.centre();1472        hand::to_js(&value)1473    }1474    /// Whether the circle is a line.1475    pub fn is_line(&self) -> Result<bool, JsValue> {1476        let value = self.inner.is_line();1477        Ok(value)1478    }1479    /// The radius, none on a line.1480    pub fn radius(&self) -> Result<JsValue, JsValue> {1481        let value = self.inner.radius();1482        hand::to_js(&value)1483    }1484}14851486/// A memory design read as a matrix ladder: the rule, the transfer matrix on its `(k-1)`-window states, and the peel depth its Dirichlet series is continued from.1487#[wasm_bindgen]1488pub struct automaton_Automaton {1489    inner: mrlyrs::num::automaton::Automaton,1490}14911492#[wasm_bindgen]1493impl automaton_Automaton {1494    /// Reads the Automaton from its plain data.1495    #[wasm_bindgen(js_name = "from")]1496    pub fn from_plain(data: JsValue) -> Result<automaton_Automaton, JsValue> {1497        Ok(automaton_Automaton { inner: hand::from_js(&data)? })1498    }1499    /// Writes the Automaton as plain data.1500    #[wasm_bindgen(js_name = "toJSON")]1501    pub fn to_plain(&self) -> Result<JsValue, JsValue> {1502        hand::to_js(&self.inner)1503    }1504    /// Returns the abscissa `alpha = log_q rho`, with `rho` the exact Perron root of [`crate::num::memory::perron`].1505    pub fn abscissa(&self) -> Result<f64, JsValue> {1506        let value = self.inner.abscissa();1507        Ok(value)1508    }1509    /// Returns the base `q = 2^D`.1510    pub fn base(&self) -> Result<u64, JsValue> {1511        let value = self.inner.base();1512        Ok(value)1513    }1514    /// Returns the matrix Lyndon cofactor `Z_W(s) = det(I - q^(-s) T) zeta_W(s)` and the bound it is known to.1515    pub fn cofactor(&self, s: &zeta_Complex, tolerance: f64) -> Result<JsValue, JsValue> {1516        let value = self.inner.cofactor(s.inner, tolerance).map_err(hand::throw)?;1517        Ok(hand::tuple_to_js(&[JsValue::from(zeta_Complex { inner: value.0 }), hand::to_js(&value.1)?]))1518    }1519    /// Returns the coefficients `c_0 .. c_n` of `det(I - x T) = sum c_i x^i`, the ladder denominator read as a polynomial in `x = q^(-s)`.1520    pub fn denominator(&self) -> Result<Vec<f64>, JsValue> {1521        let value = self.inner.denominator();1522        Ok(value)1523    }1524    /// Returns the transfer matrix `T = Gamma_0` the ladder runs on, the transpose of [`crate::num::memory::transfer`], entry `(u', u)` counting the letters carrying `u` to `u'`.1525    pub fn matrix(&self) -> Result<JsValue, JsValue> {1526        let value = self.inner.matrix();1527        hand::list_to_js(&value, |x1| Ok(hand::typed(&(*x1)[..])))1528    }1529    /// Builds the ladder of a rule, choosing the peel depth.1530    #[wasm_bindgen(constructor)]1531    pub fn new(rule: &memory_Rule) -> Result<automaton_Automaton, JsValue> {1532        let value = mrlyrs::num::automaton::Automaton::new(&rule.inner).map_err(hand::throw)?;1533        Ok(automaton_Automaton { inner: value })1534    }1535    /// Returns the peel depth `P`.1536    pub fn peel(&self) -> Result<usize, JsValue> {1537        let value = self.inner.peel();1538        Ok(value)1539    }1540    /// Returns the pole spacing `2 pi / log q`.1541    pub fn period(&self) -> Result<f64, JsValue> {1542        let value = self.inner.period();1543        Ok(value)1544    }1545    /// Returns the Collatz-Wielandt bracket `(low, high)` of the Perron root of the transfer matrix, the ratios the ladder divides with.1546    pub fn perron(&self) -> Result<JsValue, JsValue> {1547        let value = self.inner.perron();1548        hand::to_js(&value)1549    }1550    /// Returns the residue of `zeta_W` at a simple pole `w0` of the resolvent and the bound it is known to.1551    pub fn residue(&self, w0: &zeta_Complex, tolerance: f64) -> Result<JsValue, JsValue> {1552        let value = self.inner.residue(w0.inner, tolerance).map_err(hand::throw)?;1553        Ok(hand::tuple_to_js(&[JsValue::from(zeta_Complex { inner: value.0 }), hand::to_js(&value.1)?]))1554    }1555    /// Returns the rule.1556    pub fn rule(&self) -> Result<memory_Rule, JsValue> {1557        let value = self.inner.rule();1558        Ok(memory_Rule { inner: value })1559    }1560    /// Returns the state count `q^(k-1)`.1561    pub fn states(&self) -> Result<usize, JsValue> {1562        let value = self.inner.states();1563        Ok(value)1564    }1565    /// Builds the ladder at an explicit peel depth, at least the rule width and at least two.1566    pub fn with_peel(rule: &memory_Rule, peel: usize) -> Result<automaton_Automaton, JsValue> {1567        let value = mrlyrs::num::automaton::Automaton::with_peel(&rule.inner, peel).map_err(hand::throw)?;1568        Ok(automaton_Automaton { inner: value })1569    }1570    /// Returns `zeta_W(s)` and the bound it is known to.1571    pub fn zeta(&self, s: &zeta_Complex, tolerance: f64) -> Result<JsValue, JsValue> {1572        let value = self.inner.zeta(s.inner, tolerance).map_err(hand::throw)?;1573        Ok(hand::tuple_to_js(&[JsValue::from(zeta_Complex { inner: value.0 }), hand::to_js(&value.1)?]))1574    }1575}15761577/// The symmetric window of one ring: every point within a reach, with the norms sieved once.1578#[wasm_bindgen]1579pub struct gauss_Window {1580    inner: mrlyrs::num::gauss::Window,1581}15821583#[wasm_bindgen]1584impl gauss_Window {1585    /// Reads the Window from its plain data.1586    #[wasm_bindgen(js_name = "from")]1587    pub fn from_plain(data: JsValue) -> Result<gauss_Window, JsValue> {1588        Ok(gauss_Window { inner: hand::from_js(&data)? })1589    }1590    /// Writes the Window as plain data.1591    #[wasm_bindgen(js_name = "toJSON")]1592    pub fn to_plain(&self) -> Result<JsValue, JsValue> {1593        hand::to_js(&self.inner)1594    }1595    /// Counts every class inside.1596    pub fn census(&self) -> Result<JsValue, JsValue> {1597        let value = self.inner.census();1598        hand::to_js(&value)1599    }1600    /// Classifies a point: prime when its norm is a rational prime, or when it is a unit times a rational prime that stays prime.1601    pub fn class(&self, a: JsValue, b: JsValue) -> Result<JsValue, JsValue> {1602        let a = hand::i64_from_js(&a)?;1603        let b = hand::i64_from_js(&b)?;1604        let value = self.inner.class(a, b);1605        hand::to_js(&value)1606    }1607    /// Returns whether a point lies inside.1608    pub fn holds(&self, a: JsValue, b: JsValue) -> Result<bool, JsValue> {1609        let a = hand::i64_from_js(&a)?;1610        let b = hand::i64_from_js(&b)?;1611        let value = self.inner.holds(a, b);1612        Ok(value)1613    }1614    /// Opens the window of a ring out to a reach, sieving every norm inside it.1615    #[wasm_bindgen(constructor)]1616    pub fn new(ring: JsValue, radius: JsValue) -> Result<gauss_Window, JsValue> {1617        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;1618        let radius = hand::u64_from_js(&radius)?;1619        let value = mrlyrs::num::gauss::Window::new(ring, radius);1620        Ok(gauss_Window { inner: value })1621    }1622    /// Lists every point inside, row by row from the bottom left of the bounding square.1623    pub fn points(&self) -> Result<JsValue, JsValue> {1624        let value = self.inner.points();1625        hand::list_to_js(&value, |x1| Ok(hand::tuple_to_js(&[JsValue::from(x1.0), JsValue::from(x1.1)])))1626    }1627    /// Returns the reach.1628    pub fn radius(&self) -> Result<u64, JsValue> {1629        let value = self.inner.radius();1630        Ok(value)1631    }1632    /// Returns the ring.1633    pub fn ring(&self) -> Result<JsValue, JsValue> {1634        let value = self.inner.ring();1635        hand::to_js(&value)1636    }1637}16381639/// A digit design: the base `q`, the digit set `F` its elements are written with, and the peel depth `P` its ladder starts at.1640#[wasm_bindgen]1641pub struct ladder_Design {1642    inner: mrlyrs::num::ladder::Design,1643}16441645#[wasm_bindgen]1646impl ladder_Design {1647    /// Reads the Design from its plain data.1648    #[wasm_bindgen(js_name = "from")]1649    pub fn from_plain(data: JsValue) -> Result<ladder_Design, JsValue> {1650        Ok(ladder_Design { inner: hand::from_js(&data)? })1651    }1652    /// Writes the Design as plain data.1653    #[wasm_bindgen(js_name = "toJSON")]1654    pub fn to_plain(&self) -> Result<JsValue, JsValue> {1655        hand::to_js(&self.inner)1656    }1657    /// Returns the abscissa `alpha = log_q k`.1658    pub fn abscissa(&self) -> Result<f64, JsValue> {1659        let value = self.inner.abscissa();1660        Ok(value)1661    }1662    /// Returns the base.1663    pub fn base(&self) -> Result<u64, JsValue> {1664        let value = self.inner.base();1665        Ok(value)1666    }1667    /// Returns the digit set, ascending.1668    pub fn digits(&self) -> Result<Vec<u64>, JsValue> {1669        let value = self.inner.digits();1670        Ok(value.to_vec())1671    }1672    /// Builds a design on the base and the digit set, choosing the peel depth.1673    #[wasm_bindgen(constructor)]1674    pub fn new(base: JsValue, digits: JsValue) -> Result<ladder_Design, JsValue> {1675        let base = hand::u64_from_js(&base)?;1676        let digits = hand::list_from_js(&digits, hand::u64_from_js)?;1677        let value = mrlyrs::num::ladder::Design::new(base, &digits).map_err(hand::throw)?;1678        Ok(ladder_Design { inner: value })1679    }1680    /// Returns the peel depth.1681    pub fn peel(&self) -> Result<usize, JsValue> {1682        let value = self.inner.peel();1683        Ok(value)1684    }1685    /// Returns the pole spacing `2 pi / log q`.1686    pub fn period(&self) -> Result<f64, JsValue> {1687        let value = self.inner.period();1688        Ok(value)1689    }1690    /// Returns the pole `s_(m,j) = alpha - m + 2 pi i j / log q`.1691    pub fn pole(&self, m: usize, j: JsValue) -> Result<zeta_Complex, JsValue> {1692        let j = hand::i64_from_js(&j)?;1693        let value = self.inner.pole(m, j);1694        Ok(zeta_Complex { inner: value })1695    }1696    /// Builds a design at an explicit peel depth, at least two.1697    pub fn with_peel(base: JsValue, digits: JsValue, peel: usize) -> Result<ladder_Design, JsValue> {1698        let base = hand::u64_from_js(&base)?;1699        let digits = hand::list_from_js(&digits, hand::u64_from_js)?;1700        let value = mrlyrs::num::ladder::Design::with_peel(base, &digits, peel).map_err(hand::throw)?;1701        Ok(ladder_Design { inner: value })1702    }1703}17041705/// A rule on `k` consecutive digits of a design word.1706#[wasm_bindgen]1707pub struct memory_Rule {1708    inner: mrlyrs::num::memory::Rule,1709}17101711#[wasm_bindgen]1712impl memory_Rule {1713    /// Reads the Rule from its plain data.1714    #[wasm_bindgen(js_name = "from")]1715    pub fn from_plain(data: JsValue) -> Result<memory_Rule, JsValue> {1716        Ok(memory_Rule { inner: hand::from_js(&data)? })1717    }1718    /// Writes the Rule as plain data.1719    #[wasm_bindgen(js_name = "toJSON")]1720    pub fn to_plain(&self) -> Result<JsValue, JsValue> {1721        hand::to_js(&self.inner)1722    }1723    /// The dimension `D`, one to three.1724    #[wasm_bindgen(getter)]1725    pub fn dimension(&self) -> Result<usize, JsValue> {1726        let value = self.inner.dimension;1727        Ok(value)1728    }1729    #[wasm_bindgen(setter)]1730    pub fn set_dimension(&mut self, value: usize) -> Result<(), JsValue> {1731        self.inner.dimension = value;1732        Ok(())1733    }1734    /// The window width `k`, at least one.1735    #[wasm_bindgen(getter)]1736    pub fn width(&self) -> Result<usize, JsValue> {1737        let value = self.inner.width;1738        Ok(value)1739    }1740    #[wasm_bindgen(setter)]1741    pub fn set_width(&mut self, value: usize) -> Result<(), JsValue> {1742        self.inner.width = value;1743        Ok(())1744    }1745    /// The window code, bit `w` set when window `w` is allowed.1746    #[wasm_bindgen(getter)]1747    pub fn code(&self) -> Result<u64, JsValue> {1748        let value = self.inner.code;1749        Ok(value)1750    }1751    #[wasm_bindgen(setter)]1752    pub fn set_code(&mut self, value: JsValue) -> Result<(), JsValue> {1753        let value = hand::u64_from_js(&value)?;1754        self.inner.code = value;1755        Ok(())1756    }1757    /// Returns whether a word, coarsest digit first, is accepted.1758    pub fn accepts(&self, word: &[usize]) -> Result<bool, JsValue> {1759        let value = self.inner.accepts(word);1760        Ok(value)1761    }1762    /// Returns whether the window is allowed, and false for any window out of range.1763    pub fn allowed(&self, window: usize) -> Result<bool, JsValue> {1764        let value = self.inner.allowed(window);1765        Ok(value)1766    }1767    /// Returns the letters that stand in at least one allowed window.1768    pub fn alphabet(&self) -> Result<Vec<usize>, JsValue> {1769        let value = self.inner.alphabet();1770        Ok(value)1771    }1772    /// Returns the count of rules of this shape, `2^(2^(k D))`.1773    pub fn codes(&self) -> Result<JsValue, JsValue> {1774        let value = self.inner.codes();1775        Ok(JsValue::from_str(&value.to_string()))1776    }1777    /// Returns the rule that allows every window.1778    pub fn full(dimension: usize, width: usize) -> Result<memory_Rule, JsValue> {1779        let value = mrlyrs::num::memory::Rule::full(dimension, width).map_err(hand::throw)?;1780        Ok(memory_Rule { inner: value })1781    }1782    /// Returns the letter count `2^D`, the digit vectors of the cube's corners.1783    pub fn letters(&self) -> Result<usize, JsValue> {1784        let value = self.inner.letters();1785        Ok(value)1786    }1787    /// Builds a rule from its dimension, its width and its code.1788    #[wasm_bindgen(constructor)]1789    pub fn new(dimension: usize, width: usize, code: JsValue) -> Result<memory_Rule, JsValue> {1790        let code = hand::u64_from_js(&code)?;1791        let value = mrlyrs::num::memory::Rule::new(dimension, width, code).map_err(hand::throw)?;1792        Ok(memory_Rule { inner: value })1793    }1794    /// Returns the state count `2^((k - 1) D)`, the windows of one digit less that the transfer matrix runs on.1795    pub fn states(&self) -> Result<usize, JsValue> {1796        let value = self.inner.states();1797        Ok(value)1798    }1799    /// Returns the window count `2^(k D)`.1800    pub fn windows(&self) -> Result<usize, JsValue> {1801        let value = self.inner.windows();1802        Ok(value)1803    }1804}18051806/// The sieve of Eratosthenes taken one prime at a time, each number remembering which prime struck it.1807#[wasm_bindgen]1808pub struct prime_Sieve {1809    inner: mrlyrs::num::prime::Sieve,1810}18111812#[wasm_bindgen]1813impl prime_Sieve {1814    /// Reads the Sieve from its plain data.1815    #[wasm_bindgen(js_name = "from")]1816    pub fn from_plain(data: JsValue) -> Result<prime_Sieve, JsValue> {1817        Ok(prime_Sieve { inner: hand::from_js(&data)? })1818    }1819    /// Writes the Sieve as plain data.1820    #[wasm_bindgen(js_name = "toJSON")]1821    pub fn to_plain(&self) -> Result<JsValue, JsValue> {1822        hand::to_js(&self.inner)1823    }1824    /// Returns the count of numbers marked prime so far.1825    pub fn count(&self) -> Result<usize, JsValue> {1826        let value = self.inner.count();1827        Ok(value)1828    }1829    /// Returns whether every number is settled.1830    pub fn done(&self) -> Result<bool, JsValue> {1831        let value = self.inner.done();1832        Ok(value)1833    }1834    /// Runs the sieve to the end.1835    pub fn finish(&mut self) -> Result<(), JsValue> {1836        self.inner.finish();1837        Ok(())1838    }1839    /// Starts a sieve over zero through the limit with every number untouched; it is done at once when no prime has its square inside.1840    #[wasm_bindgen(constructor)]1841    pub fn new(limit: usize) -> Result<prime_Sieve, JsValue> {1842        let value = mrlyrs::num::prime::Sieve::new(limit);1843        Ok(prime_Sieve { inner: value })1844    }1845    /// Returns the count of primes used so far.1846    pub fn rank(&self) -> Result<usize, JsValue> {1847        let value = self.inner.rank();1848        Ok(value)1849    }1850    /// Uses the next prime: marks it prime, strikes its untouched multiples from its square with its rank plus one, and returns it; zero once done.1851    pub fn step(&mut self) -> Result<usize, JsValue> {1852        let value = self.inner.step();1853        Ok(value)1854    }1855    /// Returns the count of numbers the last step struck.1856    pub fn struck(&self) -> Result<usize, JsValue> {1857        let value = self.inner.struck();1858        Ok(value)1859    }1860    /// Returns the type of every number from zero: zero untouched, one prime, and one past the rank of the prime that struck it.1861    pub fn types(&self) -> Result<Vec<u8>, JsValue> {1862        let value = self.inner.types();1863        Ok(value.to_vec())1864    }1865}18661867/// The base of a radix design: a ring and an element of norm at least two, the scale every word is read against.1868#[wasm_bindgen]1869pub struct radix_Base {1870    inner: mrlyrs::num::radix::Base,1871}18721873#[wasm_bindgen]1874impl radix_Base {1875    /// Reads the Base from its plain data.1876    #[wasm_bindgen(js_name = "from")]1877    pub fn from_plain(data: JsValue) -> Result<radix_Base, JsValue> {1878        Ok(radix_Base { inner: hand::from_js(&data)? })1879    }1880    /// Writes the Base as plain data.1881    #[wasm_bindgen(js_name = "toJSON")]1882    pub fn to_plain(&self) -> Result<JsValue, JsValue> {1883        hand::to_js(&self.inner)1884    }1885    /// Returns the index in the canonical residue system of the class of a point.1886    pub fn class(&self, z: JsValue) -> Result<usize, JsValue> {1887        let z = (hand::i64_from_js(&hand::item(&z, 0)?)?, hand::i64_from_js(&hand::item(&z, 1)?)?);1888        let value = self.inner.class(z).map_err(hand::throw)?;1889        Ok(value)1890    }1891    /// Returns whether two points are congruent modulo the base.1892    pub fn congruent(&self, z: JsValue, w: JsValue) -> Result<bool, JsValue> {1893        let z = (hand::i64_from_js(&hand::item(&z, 0)?)?, hand::i64_from_js(&hand::item(&z, 1)?)?);1894        let w = (hand::i64_from_js(&hand::item(&w, 0)?)?, hand::i64_from_js(&hand::item(&w, 1)?)?);1895        let value = self.inner.congruent(z, w);1896        Ok(value)1897    }1898    /// Returns the symmetry group of the base as permutations of the canonical residue indices: every unit multiplication, and every unit times conjugation when the conjugate of the base is an associate of the base.1899    pub fn group(&self) -> Result<JsValue, JsValue> {1900        let value = self.inner.group().map_err(hand::throw)?;1901        hand::list_to_js(&value, |x1| Ok(hand::typed(&(*x1)[..])))1902    }1903    /// Returns whether the conjugate of the base is an associate of the base, which is when the mirror joins the symmetry group.1904    pub fn mirrored(&self) -> Result<bool, JsValue> {1905        let value = self.inner.mirrored();1906        Ok(value)1907    }1908    /// Fixes a base in a ring.1909    #[wasm_bindgen(constructor)]1910    pub fn new(ring: JsValue, value: JsValue) -> Result<radix_Base, JsValue> {1911        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;1912        let value = (hand::i64_from_js(&hand::item(&value, 0)?)?, hand::i64_from_js(&hand::item(&value, 1)?)?);1913        let value = mrlyrs::num::radix::Base::new(ring, value).map_err(hand::throw)?;1914        Ok(radix_Base { inner: value })1915    }1916    /// Returns the norm `q` of the base: the count of residue classes and the square of the scale.1917    pub fn norm(&self) -> Result<u64, JsValue> {1918        let value = self.inner.norm();1919        Ok(value)1920    }1921    /// Returns the base raised to a level.1922    pub fn power(&self, level: usize) -> Result<JsValue, JsValue> {1923        let value = self.inner.power(level);1924        Ok(hand::tuple_to_js(&[JsValue::from(value.0), JsValue::from(value.1)]))1925    }1926    /// Returns the canonical complete residue system modulo the base: the `q` representatives of least norm, ties broken by argument in `[0, 2 pi)`.1927    pub fn residues(&self) -> Result<JsValue, JsValue> {1928        let value = self.inner.residues().map_err(hand::throw)?;1929        hand::list_to_js(&value, |x1| Ok(hand::tuple_to_js(&[JsValue::from(x1.0), JsValue::from(x1.1)])))1930    }1931    /// Returns the ring.1932    pub fn ring(&self) -> Result<JsValue, JsValue> {1933        let value = self.inner.ring();1934        hand::to_js(&value)1935    }1936    /// Returns the base element.1937    pub fn value(&self) -> Result<JsValue, JsValue> {1938        let value = self.inner.value();1939        Ok(hand::tuple_to_js(&[JsValue::from(value.0), JsValue::from(value.1)]))1940    }1941}19421943/// A radix design: a digit set inside one ring, placed by a base with a unit twist per digit.1944#[wasm_bindgen]1945pub struct radix_Radix {1946    inner: mrlyrs::num::radix::Radix,1947}19481949#[wasm_bindgen]1950impl radix_Radix {1951    /// Reads the Radix from its plain data.1952    #[wasm_bindgen(js_name = "from")]1953    pub fn from_plain(data: JsValue) -> Result<radix_Radix, JsValue> {1954        Ok(radix_Radix { inner: hand::from_js(&data)? })1955    }1956    /// Writes the Radix as plain data.1957    #[wasm_bindgen(js_name = "toJSON")]1958    pub fn to_plain(&self) -> Result<JsValue, JsValue> {1959        hand::to_js(&self.inner)1960    }1961    /// Returns the base.1962    pub fn base(&self) -> Result<radix_Base, JsValue> {1963        let value = self.inner.base();1964        Ok(radix_Base { inner: value })1965    }1966    /// Returns whether every digit is the canonical representative of its class.1967    pub fn canonical(&self) -> Result<bool, JsValue> {1968        let value = self.inner.canonical().map_err(hand::throw)?;1969        Ok(value)1970    }1971    /// Returns the code of the classes the digits occupy, which names the design only when the digits are the canonical representatives.1972    pub fn code(&self) -> Result<JsValue, JsValue> {1973        let value = self.inner.code().map_err(hand::throw)?;1974        Ok(JsValue::from_str(&value.to_string()))1975    }1976    /// Returns the digits.1977    pub fn digits(&self) -> Result<JsValue, JsValue> {1978        let value = self.inner.digits();1979        hand::list_to_js(value, |x1| Ok(hand::tuple_to_js(&[JsValue::from(x1.0), JsValue::from(x1.1)])))1980    }1981    /// Returns the similarity dimension `log |F| / log sqrt(q)`, the ratio of the digit count to the scale of the base.1982    pub fn dimension(&self) -> Result<f64, JsValue> {1983        let value = self.inner.dimension();1984        Ok(value)1985    }1986    /// Returns the count of distinct level-`L` points: the glue count, which is the fill exactly when no two words name one point.1987    pub fn distinct(&self, level: usize) -> Result<usize, JsValue> {1988        let value = self.inner.distinct(level);1989        Ok(value)1990    }1991    /// Returns the count of words of a level, `|F|^L`.1992    pub fn fill(&self, level: usize) -> Result<JsValue, JsValue> {1993        let value = self.inner.fill(level);1994        Ok(JsValue::from_str(&value.to_string()))1995    }1996    /// Builds an untwisted design from a code over the canonical residue system, bit `i` of the code selecting residue `i`.1997    pub fn from_code(base: &radix_Base, code: JsValue) -> Result<radix_Radix, JsValue> {1998        let code = hand::u128_from_js(&code)?;1999        let value = mrlyrs::num::radix::Radix::from_code(base.inner, code).map_err(hand::throw)?;2000        Ok(radix_Radix { inner: value })2001    }2002    /// Builds a design from a base, a digit list and a unit twist per digit.2003    #[wasm_bindgen(constructor)]2004    pub fn new(base: &radix_Base, digits: JsValue, twists: JsValue) -> Result<radix_Radix, JsValue> {2005        let digits = hand::list_from_js(&digits, |x1| Ok((hand::i64_from_js(&hand::item(x1, 0)?)?, hand::i64_from_js(&hand::item(x1, 1)?)?)))?;2006        let twists = hand::list_from_js(&twists, |x1| Ok((hand::i64_from_js(&hand::item(x1, 0)?)?, hand::i64_from_js(&hand::item(x1, 1)?)?)))?;2007        let value = mrlyrs::num::radix::Radix::new(base.inner, digits, twists).map_err(hand::throw)?;2008        Ok(radix_Radix { inner: value })2009    }2010    /// Returns the level-`L` points in the plane, the scaled words divided by `b^L`.2011    pub fn plane(&self, level: usize) -> Result<JsValue, JsValue> {2012        let value = self.inner.plane(level);2013        hand::to_js(&value)2014    }2015    /// Returns the ring.2016    pub fn ring(&self) -> Result<JsValue, JsValue> {2017        let value = self.inner.ring();2018        hand::to_js(&value)2019    }2020    /// Returns the digit count `|F|`.2021    pub fn size(&self) -> Result<usize, JsValue> {2022        let value = self.inner.size();2023        Ok(value)2024    }2025    /// Returns the twists.2026    pub fn twists(&self) -> Result<JsValue, JsValue> {2027        let value = self.inner.twists();2028        hand::list_to_js(value, |x1| Ok(hand::tuple_to_js(&[JsValue::from(x1.0), JsValue::from(x1.1)])))2029    }2030    /// Returns the design with the twists named by their index in the unit list, the units in turning order from one.2031    pub fn with_twists(&self, units: &[usize]) -> Result<radix_Radix, JsValue> {2032        let value = self.inner.clone().with_twists(units).map_err(hand::throw)?;2033        Ok(radix_Radix { inner: value })2034    }2035    /// Returns the level-`L` points in exact ring coordinates scaled by `b^L`.2036    pub fn words(&self, level: usize) -> Result<JsValue, JsValue> {2037        let value = self.inner.words(level);2038        hand::list_to_js(&value, |x1| Ok(hand::tuple_to_js(&[JsValue::from(x1.0), JsValue::from(x1.1)])))2039    }2040}20412042/// A complex number: a real and an imaginary part.2043#[wasm_bindgen]2044pub struct zeta_Complex {2045    inner: mrlyrs::num::zeta::Complex,2046}20472048#[wasm_bindgen]2049impl zeta_Complex {2050    /// Reads the Complex from its plain data.2051    #[wasm_bindgen(js_name = "from")]2052    pub fn from_plain(data: JsValue) -> Result<zeta_Complex, JsValue> {2053        Ok(zeta_Complex { inner: hand::from_js(&data)? })2054    }2055    /// Writes the Complex as plain data.2056    #[wasm_bindgen(js_name = "toJSON")]2057    pub fn to_plain(&self) -> Result<JsValue, JsValue> {2058        hand::to_js(&self.inner)2059    }2060    /// The real part.2061    #[wasm_bindgen(getter)]2062    pub fn re(&self) -> Result<f64, JsValue> {2063        let value = self.inner.re;2064        Ok(value)2065    }2066    #[wasm_bindgen(setter)]2067    pub fn set_re(&mut self, value: f64) -> Result<(), JsValue> {2068        self.inner.re = value;2069        Ok(())2070    }2071    /// The imaginary part.2072    #[wasm_bindgen(getter)]2073    pub fn im(&self) -> Result<f64, JsValue> {2074        let value = self.inner.im;2075        Ok(value)2076    }2077    #[wasm_bindgen(setter)]2078    pub fn set_im(&mut self, value: f64) -> Result<(), JsValue> {2079        self.inner.im = value;2080        Ok(())2081    }2082    /// Returns the modulus.2083    pub fn abs(&self) -> Result<f64, JsValue> {2084        let value = self.inner.abs();2085        Ok(value)2086    }2087    /// Returns the principal argument.2088    pub fn arg(&self) -> Result<f64, JsValue> {2089        let value = self.inner.arg();2090        Ok(value)2091    }2092    /// Returns the default Complex.2093    #[wasm_bindgen(js_name = "default")]2094    pub fn default_() -> Result<zeta_Complex, JsValue> {2095        let value = mrlyrs::num::zeta::Complex::default();2096        Ok(zeta_Complex { inner: value })2097    }2098    /// Returns the exponential.2099    pub fn exp(&self) -> Result<zeta_Complex, JsValue> {2100        let value = self.inner.exp();2101        Ok(zeta_Complex { inner: value })2102    }2103    /// Returns the principal logarithm.2104    pub fn ln(&self) -> Result<zeta_Complex, JsValue> {2105        let value = self.inner.ln();2106        Ok(zeta_Complex { inner: value })2107    }2108    /// Builds a complex number from its parts.2109    #[wasm_bindgen(constructor)]2110    pub fn new(re: f64, im: f64) -> Result<zeta_Complex, JsValue> {2111        let value = mrlyrs::num::zeta::Complex::new(re, im);2112        Ok(zeta_Complex { inner: value })2113    }2114    /// Returns a unit complex number at the given angle.2115    pub fn turn(angle: f64) -> Result<zeta_Complex, JsValue> {2116        let value = mrlyrs::num::zeta::Complex::turn(angle);2117        Ok(zeta_Complex { inner: value })2118    }2119}21202121/// The critical line: the Bernoulli numbers and the Euler-Maclaurin weights the two engines share, built once.2122#[wasm_bindgen]2123pub struct zeta_Line {2124    inner: mrlyrs::num::zeta::Line,2125}21262127#[wasm_bindgen]2128impl zeta_Line {2129    /// Reads the Line from its plain data.2130    #[wasm_bindgen(js_name = "from")]2131    pub fn from_plain(data: JsValue) -> Result<zeta_Line, JsValue> {2132        Ok(zeta_Line { inner: hand::from_js(&data)? })2133    }2134    /// Writes the Line as plain data.2135    #[wasm_bindgen(js_name = "toJSON")]2136    pub fn to_plain(&self) -> Result<JsValue, JsValue> {2137        hand::to_js(&self.inner)2138    }2139    /// Counts the zeros on the line below t.2140    pub fn count(&self, t: f64) -> Result<usize, JsValue> {2141        let value = self.inner.count(t);2142        Ok(value)2143    }2144    /// Returns the default Line.2145    #[wasm_bindgen(js_name = "default")]2146    pub fn default_() -> Result<zeta_Line, JsValue> {2147        let value = mrlyrs::num::zeta::Line::default();2148        Ok(zeta_Line { inner: value })2149    }2150    /// Returns Z(t) from the Euler-Maclaurin value turned onto the real axis.2151    pub fn exact(&self, t: f64) -> Result<f64, JsValue> {2152        let value = self.inner.exact(t);2153        Ok(value)2154    }2155    /// Returns the n-th Gram point, where theta is n pi, by Newton from the right.2156    pub fn gram(&self, n: JsValue) -> Result<f64, JsValue> {2157        let n = hand::i64_from_js(&n)?;2158        let value = self.inner.gram(n);2159        Ok(value)2160    }2161    /// Returns zeta at one half plus i t by the complex Euler-Maclaurin sum: t plus ten terms and seven Bernoulli corrections.2162    pub fn maclaurin(&self, t: f64) -> Result<zeta_Complex, JsValue> {2163        let value = self.inner.maclaurin(t);2164        Ok(zeta_Complex { inner: value })2165    }2166    /// Builds the line: the even Bernoulli numbers through the fourteenth and their Euler-Maclaurin weights.2167    #[wasm_bindgen(constructor)]2168    pub fn new() -> Result<zeta_Line, JsValue> {2169        let value = mrlyrs::num::zeta::Line::new();2170        Ok(zeta_Line { inner: value })2171    }2172    /// Returns the wave coefficient of every zero at the given ordinates: F(rho) zeta(rho - 1) over zeta'(rho) at rho one half plus i gamma, F the Mellin transform of the bump.2173    pub fn novelty_coefficients(&self, gammas: &[f64]) -> Result<JsValue, JsValue> {2174        let value = self.inner.novelty_coefficients(gammas);2175        hand::list_to_js(&value, |x1| Ok(JsValue::from(zeta_Complex { inner: *x1 })))2176    }2177    /// Returns zeta and its derivative together at any complex s but one, by the same Euler-Maclaurin sum: the modulus of t plus ten terms and seven Bernoulli corrections, each term differentiated in s.2178    pub fn pair(&self, s: &zeta_Complex) -> Result<JsValue, JsValue> {2179        let value = self.inner.pair(s.inner);2180        Ok(hand::tuple_to_js(&[JsValue::from(zeta_Complex { inner: value.0 }), JsValue::from(zeta_Complex { inner: value.1 })]))2181    }2182    /// Returns zeta on the line and Z(t) together, from the engine that serves the t.2183    pub fn point(&self, t: f64) -> Result<JsValue, JsValue> {2184        let value = self.inner.point(t);2185        Ok(hand::tuple_to_js(&[JsValue::from(zeta_Complex { inner: value.0 }), hand::to_js(&value.1)?]))2186    }2187    /// Returns the largest gap between the two engines over the t range on a grid.2188    pub fn seam(&self, t0: f64, t1: f64, steps: usize) -> Result<f64, JsValue> {2189        let value = self.inner.seam(t0, t1, steps);2190        Ok(value)2191    }2192    /// Returns Z(t) by the Riemann-Siegel formula: the main sum and the first four corrections.2193    pub fn siegel(&self, t: f64) -> Result<f64, JsValue> {2194        let value = self.inner.siegel(t);2195        Ok(value)2196    }2197    /// Returns the Riemann-Siegel theta: the argument of gamma at one quarter plus i t over two, less t ln pi over two, by Stirling's series after a shift of ten.2198    pub fn theta(&self, t: f64) -> Result<f64, JsValue> {2199        let value = self.inner.theta(t);2200        Ok(value)2201    }2202    /// Returns Z(t): Euler-Maclaurin below the join, Riemann-Siegel above.2203    pub fn z(&self, t: f64) -> Result<f64, JsValue> {2204        let value = self.inner.z(t);2205        Ok(value)2206    }2207    /// Returns the first zeros on the line: sign changes of Z between Gram points, refined by bisection on Euler-Maclaurin to a billionth.2208    pub fn zeros(&self, count: usize) -> Result<Vec<f64>, JsValue> {2209        let value = self.inner.zeros(count);2210        Ok(value)2211    }2212}22132214/// What a point of the ring is.2215#[wasm_bindgen]2216pub struct gauss_Class {}22172218#[wasm_bindgen]2219impl gauss_Class {2220    /// Returns whether the class is prime.2221    pub fn prime(class_: JsValue) -> Result<bool, JsValue> {2222        let class_ = hand::from_js::<mrlyrs::num::gauss::Class>(&class_)?;2223        let value = class_.prime();2224        Ok(value)2225    }2226    /// Returns the class as a word.2227    pub fn word(class_: JsValue) -> Result<String, JsValue> {2228        let class_ = hand::from_js::<mrlyrs::num::gauss::Class>(&class_)?;2229        let value = class_.word();2230        Ok(value)2231    }2232}22332234/// The two rings of whole numbers in the plane, each a pair (a, b) on its own lattice.2235#[wasm_bindgen]2236pub struct gauss_Ring {}22372238#[wasm_bindgen]2239impl gauss_Ring {2240    /// Returns the unit multiples of a point, the point first, turning anticlockwise.2241    pub fn associates(ring: JsValue, a: JsValue, b: JsValue) -> Result<JsValue, JsValue> {2242        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2243        let a = hand::i64_from_js(&a)?;2244        let b = hand::i64_from_js(&b)?;2245        let value = ring.associates(a, b);2246        hand::list_to_js(&value, |x1| Ok(hand::tuple_to_js(&[JsValue::from(x1.0), JsValue::from(x1.1)])))2247    }2248    /// Returns the canonical associate of a point: the one with `a > 0` and `b >= 0` on the square lattice, the one with `a > 0` and `0 <= b < a` on the hexagonal, the origin for the origin.2249    pub fn canon(ring: JsValue, a: JsValue, b: JsValue) -> Result<JsValue, JsValue> {2250        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2251        let a = hand::i64_from_js(&a)?;2252        let b = hand::i64_from_js(&b)?;2253        let value = ring.canon(a, b);2254        Ok(hand::tuple_to_js(&[JsValue::from(value.0), JsValue::from(value.1)]))2255    }2256    /// Returns the conjugate: the mirror image in the real axis.2257    pub fn conjugate(ring: JsValue, a: JsValue, b: JsValue) -> Result<JsValue, JsValue> {2258        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2259        let a = hand::i64_from_js(&a)?;2260        let b = hand::i64_from_js(&b)?;2261        let value = ring.conjugate(a, b);2262        Ok(hand::tuple_to_js(&[JsValue::from(value.0), JsValue::from(value.1)]))2263    }2264    /// Returns the count of points within the reach: the square or the hexagon.2265    pub fn count(ring: JsValue, radius: JsValue) -> Result<usize, JsValue> {2266        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2267        let radius = hand::u64_from_js(&radius)?;2268        let value = ring.count(radius);2269        Ok(value)2270    }2271    /// Returns the quotient and the remainder of a point by a nonzero point: `z = q w + r` with the norm of `r` below the norm of `w`.2272    pub fn div_rem(ring: JsValue, z: JsValue, w: JsValue) -> Result<JsValue, JsValue> {2273        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2274        let z = (hand::i64_from_js(&hand::item(&z, 0)?)?, hand::i64_from_js(&hand::item(&z, 1)?)?);2275        let w = (hand::i64_from_js(&hand::item(&w, 0)?)?, hand::i64_from_js(&hand::item(&w, 1)?)?);2276        let value = ring.div_rem(z, w);2277        Ok(hand::tuple_to_js(&[hand::tuple_to_js(&[JsValue::from(value.0.0), JsValue::from(value.0.1)]), hand::tuple_to_js(&[JsValue::from(value.1.0), JsValue::from(value.1.1)])]))2278    }2279    /// Returns the fate of a whole number as a prime of the ring: split, inert or ramified, unit for one, zero for zero, composite otherwise.2280    pub fn fate(ring: JsValue, n: JsValue) -> Result<JsValue, JsValue> {2281        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2282        let n = hand::u64_from_js(&n)?;2283        let value = ring.fate(n);2284        hand::to_js(&value)2285    }2286    /// Returns the greatest common divisor of two points as its canonical associate, by the nearest-point Euclidean algorithm, the origin for two origins.2287    pub fn gaussian_gcd(ring: JsValue, z: JsValue, w: JsValue) -> Result<JsValue, JsValue> {2288        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2289        let z = (hand::i64_from_js(&hand::item(&z, 0)?)?, hand::i64_from_js(&hand::item(&z, 1)?)?);2290        let w = (hand::i64_from_js(&hand::item(&w, 0)?)?, hand::i64_from_js(&hand::item(&w, 1)?)?);2291        let value = ring.gaussian_gcd(z, w);2292        Ok(hand::tuple_to_js(&[JsValue::from(value.0), JsValue::from(value.1)]))2293    }2294    /// Returns whether a rational prime stays prime in the ring: 3 mod 4, or 2 mod 3.2295    pub fn inert(ring: JsValue, p: JsValue) -> Result<bool, JsValue> {2296        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2297        let p = hand::u64_from_js(&p)?;2298        let value = ring.inert(p);2299        Ok(value)2300    }2301    /// Returns the product of two points.2302    pub fn mul(ring: JsValue, arg1: JsValue, arg2: JsValue) -> Result<JsValue, JsValue> {2303        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2304        let arg1 = (hand::i64_from_js(&hand::item(&arg1, 0)?)?, hand::i64_from_js(&hand::item(&arg1, 1)?)?);2305        let arg2 = (hand::i64_from_js(&hand::item(&arg2, 0)?)?, hand::i64_from_js(&hand::item(&arg2, 1)?)?);2306        let value = ring.mul(arg1, arg2);2307        Ok(hand::tuple_to_js(&[JsValue::from(value.0), JsValue::from(value.1)]))2308    }2309    /// Reads a ring from its name.2310    pub fn named(name: &str) -> Result<JsValue, JsValue> {2311        let value = mrlyrs::num::gauss::Ring::named(name);2312        hand::to_js(&value)2313    }2314    /// Returns the point nearest a place in the plane.2315    pub fn nearest(ring: JsValue, x: f64, y: f64) -> Result<JsValue, JsValue> {2316        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2317        let value = ring.nearest(x, y);2318        Ok(hand::tuple_to_js(&[JsValue::from(value.0), JsValue::from(value.1)]))2319    }2320    /// Returns the norm of a point: its squared length.2321    pub fn norm(ring: JsValue, a: JsValue, b: JsValue) -> Result<u64, JsValue> {2322        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2323        let a = hand::i64_from_js(&a)?;2324        let b = hand::i64_from_js(&b)?;2325        let value = ring.norm(a, b);2326        Ok(value)2327    }2328    /// Returns the place of a point in the plane, x right and y up, one unit between neighbours.2329    pub fn place(ring: JsValue, a: JsValue, b: JsValue) -> Result<JsValue, JsValue> {2330        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2331        let a = hand::i64_from_js(&a)?;2332        let b = hand::i64_from_js(&b)?;2333        let value = ring.place(a, b);2334        hand::to_js(&value)2335    }2336    /// Returns the one rational prime that ramifies: 2 or 3.2337    pub fn ramified(ring: JsValue) -> Result<u64, JsValue> {2338        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2339        let value = ring.ramified();2340        Ok(value)2341    }2342    /// Returns the reach of a point: the ring of the window it sits on, the Chebyshev distance or the hex distance.2343    pub fn reach(ring: JsValue, a: JsValue, b: JsValue) -> Result<u64, JsValue> {2344        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2345        let a = hand::i64_from_js(&a)?;2346        let b = hand::i64_from_js(&b)?;2347        let value = ring.reach(a, b);2348        Ok(value)2349    }2350    /// Returns the order of the symmetry of the picture, the units and the mirror: 8 or 12.2351    pub fn symmetry(ring: JsValue) -> Result<usize, JsValue> {2352        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2353        let value = ring.symmetry();2354        Ok(value)2355    }2356    /// Returns the largest norm within the reach: 2 r^2 at the square's corner, r^2 at the hexagon's.2357    pub fn top(ring: JsValue, radius: JsValue) -> Result<u64, JsValue> {2358        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2359        let radius = hand::u64_from_js(&radius)?;2360        let value = ring.top(radius);2361        Ok(value)2362    }2363    /// Returns the point turned anticlockwise by one unit: a quarter turn or a sixth.2364    pub fn turn(ring: JsValue, a: JsValue, b: JsValue) -> Result<JsValue, JsValue> {2365        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2366        let a = hand::i64_from_js(&a)?;2367        let b = hand::i64_from_js(&b)?;2368        let value = ring.turn(a, b);2369        Ok(hand::tuple_to_js(&[JsValue::from(value.0), JsValue::from(value.1)]))2370    }2371    /// Returns the count of units: 4 or 6.2372    pub fn units(ring: JsValue) -> Result<usize, JsValue> {2373        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2374        let value = ring.units();2375        Ok(value)2376    }2377    /// Returns the whole number an associate of the point lies on, when one lies on the positive real axis.2378    pub fn whole(ring: JsValue, a: JsValue, b: JsValue) -> Result<JsValue, JsValue> {2379        let ring = hand::from_js::<mrlyrs::num::gauss::Ring>(&ring)?;2380        let a = hand::i64_from_js(&a)?;2381        let b = hand::i64_from_js(&b)?;2382        let value = ring.whole(a, b);2383        hand::option_to_js(value.as_ref(), |x1| Ok(JsValue::from(*x1)))2384    }2385}23862387/// The four ways the word lifts from a line to the plane, one sign at every site.2388#[wasm_bindgen]2389pub struct morse_Lift {}23902391#[wasm_bindgen]2392impl morse_Lift {2393    /// Returns every Lift in canonical order.2394    pub fn all() -> Result<JsValue, JsValue> {2395        let value = mrlyrs::num::morse::Lift::all();2396        hand::to_js(&value)2397    }2398    /// Returns the sign at a site, zero for plus one and one for minus one.2399    pub fn at(lift: JsValue, i: JsValue, j: JsValue) -> Result<u8, JsValue> {2400        let lift = hand::from_js::<mrlyrs::num::morse::Lift>(&lift)?;2401        let i = hand::u64_from_js(&i)?;2402        let j = hand::u64_from_js(&j)?;2403        let value = lift.at(i, j);2404        Ok(value)2405    }2406    /// Returns the lift's formula, written the way the page prints it.2407    pub fn formula(lift: JsValue) -> Result<String, JsValue> {2408        let lift = hand::from_js::<mrlyrs::num::morse::Lift>(&lift)?;2409        let value = lift.formula();2410        Ok(value)2411    }2412}24132414/// Which cells of the square winding grow into a tile.2415#[wasm_bindgen]2416pub struct spiral_Growth {}24172418#[wasm_bindgen]2419impl spiral_Growth {2420    /// Returns every Growth in canonical order.2421    pub fn all() -> Result<JsValue, JsValue> {2422        let value = mrlyrs::num::spiral::Growth::all();2423        hand::to_js(&value)2424    }2425}24262427/// The two lattices a spiral of the whole numbers is wound on, one at the centre and two to its right.2428#[wasm_bindgen]2429pub struct spiral_Lattice {}24302431#[wasm_bindgen]2432impl spiral_Lattice {2433    /// Returns every Lattice in canonical order.2434    pub fn all() -> Result<JsValue, JsValue> {2435        let value = mrlyrs::num::spiral::Lattice::all();2436        hand::to_js(&value)2437    }2438    /// Returns the count of numbers a sheet the odd side wide holds: the side squared, or the hexagon of that many cells across.2439    pub fn count(lattice: JsValue, side: usize) -> Result<usize, JsValue> {2440        let lattice = hand::from_js::<mrlyrs::num::spiral::Lattice>(&lattice)?;2441        let value = lattice.count(side);2442        Ok(value)2443    }2444    /// Returns the number at a cell, one at the origin.2445    pub fn n(lattice: JsValue, x: JsValue, y: JsValue) -> Result<u64, JsValue> {2446        let lattice = hand::from_js::<mrlyrs::num::spiral::Lattice>(&lattice)?;2447        let x = hand::i64_from_js(&x)?;2448        let y = hand::i64_from_js(&y)?;2449        let value = lattice.n(x, y);2450        Ok(value)2451    }2452    /// Returns the outermost ring of a sheet the odd side wide, half the side rounded down.2453    pub fn radius(lattice: JsValue, side: usize) -> Result<usize, JsValue> {2454        let lattice = hand::from_js::<mrlyrs::num::spiral::Lattice>(&lattice)?;2455        let value = lattice.radius(side);2456        Ok(value)2457    }2458    /// Returns the ring a number sits on, zero for one.2459    pub fn ring(lattice: JsValue, n: JsValue) -> Result<u64, JsValue> {2460        let lattice = hand::from_js::<mrlyrs::num::spiral::Lattice>(&lattice)?;2461        let n = hand::u64_from_js(&n)?;2462        let value = lattice.ring(n);2463        Ok(value)2464    }2465    /// Returns the ring of a cell: the larger of the coordinates on the square, the hex distance on the hexagon.2466    pub fn ring_of(lattice: JsValue, x: JsValue, y: JsValue) -> Result<u64, JsValue> {2467        let lattice = hand::from_js::<mrlyrs::num::spiral::Lattice>(&lattice)?;2468        let x = hand::i64_from_js(&x)?;2469        let y = hand::i64_from_js(&y)?;2470        let value = lattice.ring_of(x, y);2471        Ok(value)2472    }2473    /// Returns the cell of a number: x right and y up on the square, axial q and r on the hexagon.2474    pub fn xy(lattice: JsValue, n: JsValue) -> Result<JsValue, JsValue> {2475        let lattice = hand::from_js::<mrlyrs::num::spiral::Lattice>(&lattice)?;2476        let n = hand::u64_from_js(&n)?;2477        let value = lattice.xy(n);2478        Ok(hand::tuple_to_js(&[JsValue::from(value.0), JsValue::from(value.1)]))2479    }2480}24812482/// What a cell is painted for.2483#[wasm_bindgen]2484pub struct spiral_Mark {}24852486#[wasm_bindgen]2487impl spiral_Mark {2488    /// Returns every Mark in canonical order.2489    pub fn all() -> Result<JsValue, JsValue> {2490        let value = mrlyrs::num::spiral::Mark::all();2491        hand::to_js(&value)2492    }2493}