Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow color computations in MathFormula and use to allow computed Turtle colors #530

Draft
wants to merge 27 commits into
base: ui2
Choose a base branch
from

Conversation

gwhitney
Copy link
Collaborator

By submitting this PR, I am indicating to the Numberscope maintainers that I have read and understood the contributing guidelines and that this PR follows those guidelines to the best of my knowledge. I have also read the pull request checklist and followed the instructions therein.


This is a reconstituted version of #528. It incorporates the color computations of chroma.js into mathjs and allows them to be used in MathFormulas to compute colors. It then uses this facility to allow the stroke color (and all other segment parameters of Turtle) to be computed by formula.

With the more complicated options for the Turtle parameters, it also adopts the changes to ParamField and ParamEditor layout from the first three commits of #522.

@gwhitney gwhitney changed the base branch from main to ui2 January 20, 2025 02:34
@gwhitney gwhitney marked this pull request as draft January 20, 2025 02:34
@gwhitney
Copy link
Collaborator Author

OK, this now picks up where #528 left off. You can now switch back and forth to the formula display of Turtle parameters, but the formula parameters do not yet have any effect. I will continue the implementation and mark as ready for review when I think all is well, but welcome feedback now or at any point.

@gwhitney
Copy link
Collaborator Author

OK, added a colorChooser that will insert into whichever color parameter is currently in effect. The formula parameters are still not implemented.

@gwhitney
Copy link
Collaborator Author

Now the list rules convert themselves into formulas whenever they are entered, but Turtle still only draws using the list rules. Also, all of the checks should now pass (at least when run locally). This way, I can switch over to always using the formulas for drawing and make sure that I get exactly the same images.

@gwhitney gwhitney marked this pull request as ready for review January 22, 2025 03:49
@gwhitney
Copy link
Collaborator Author

OK, Turtle is computing with formulas for all the attributes of each segment: turn, step, width, and color. When you are in List mode and you change the list parameters, it updates all of the formulas to be ones that implement the list rules. I suspect I need to update the Github snapshots, but this can be reviewed in the meantime. And it could really use a Turtle example that actually uses one or more of the formulas in a meaningful way, so Kate if you have or can cook up one or more such example(s), please push a commit that adds it/them

Note that the translated formulas for the list rules are pretty klunky; they are done in a way to hopefully work in all circumstances. If you just want the turn angle to be 30 degrees times the sequence value mod 5, for example, you can write 30*(a%5). If you want the step lengths to be some table lookup covering all of the residues of the sequence value mod 3, you can write for example [2.5, 1.5, 3][1 + a%3] (sadly mathjs expression array indexing is one-based not zero-based).

@gwhitney
Copy link
Collaborator Author

OK, snapshots updated. All differences were just font/text layout. So the new Turtle is reproducing the old one, while extending it to allow formulas. As far as I am concerned, this just needs a commit with a Featured specimen (or more) that uses formulas, with at least one color formula involved, and the usual review of the PR itself.

@gwhitney
Copy link
Collaborator Author

gwhitney commented Jan 24, 2025

We had a sort of "group review" in meeting today, and it generated the following TODO items; I will mark this PR as draft until they have been implemented:

  • The color chooser in List mode should insert a space before the new color if the current value is nonempty.
  • The color input should have a description "A color or list of colors, in order corresponding to the sequence values listed in Domain".
  • Allow descriptions to have links and make the word "color" in the above description be a link to our documentation page/section on color specifications. Deferred, added to user interface design ideas discussion
  • Why is chroma(255) blue? That does not seem right/intended. Because 255 = 0x0000FF, of course ;-/...
  • Allow chroma() expressions in the color list in List mode (in order to be consistent with documentation)
  • The Color chooser should fire on select action, not change action.
  • When you switch back to List, the formulas need to go back to respecting the list.
  • Formulas also need to change when the Domain changes!
  • Add a rainbow() constructor (using the oklch color space) for colors.
  • Conform the variable names to n - sequence index; a - sequence value; s - step serial number starting from 1; f,l - first and last sequence index; x, y -- coordinates; b - bearing. [AS ADJUSTED in comment below]
  • Add some featured specimens that @katestange and @Vectornaut will suggest that use formulas. (Progress update: we have settled on "Vertigo of Divergence" from below, and will have a variant of the zeta convergence when Kate has had a chance to play around more, and maybe the candidate Glen suggested recently based on Kate's clockwork one, which I am copying to the interesting specimens in discussions.)
  • Import all of the color brewer palettes directly into the mathjs namespace under their chromajs names, so that e.g. the bare symbol RdBu in a formula will evaluate to an array of 9 colors.
  • Get skipped tests to pass Deferred because of mathjs function application.
  • Investigate the anomalous behaviors posted below.
  • Decide on a way to handle mathjs formulas returning types that the surrounding code is not equipped to deal with
  • Implement a "preferred type" scheme for Formula parameters, where the infrastructure does the conversion for you and warns in the UI if not possible. Also deferred until or after the mathjs upgrade. See Implement a "preferred type" scheme for Formula parameters, where the infrastructure does the conversion for you and warns in the UI if not possible. #534.
  • "Preimplement" chroma.scale()(0.5,) to unambiguously mean that the function chroma.scale() should be called on 0.5 to avoid the implicit multiplication trap for trying to use this color formula. Deferred, decided to wait for this to come around through mathjs itself.
  • Document all the color math in the right place(s).
  • Investigate "TouchEvent is not defined" warning box from the new color picker -- see if glen can reproduce... Update: glen supplied a patch to the vue-color-picker package below, which needs testing by Kate or Aaron, then if it works Glen will submit that as a PR to vue-color-picker.
  • Add angle control toggles: Degree/radian and Turn/Absolute bearing modes.

I am not planning to make any other comments as/when I simply push a commit that implements one or more of the above, but I will check the items off as I do, and mark this again as ready for review when they are all done.

@gwhitney gwhitney marked this pull request as draft January 24, 2025 01:28
@katestange
Copy link
Member

This produces a disconnected path. This is perhaps a malformed URL in some sense, as it includes both List and Formula mode parameters. To reproduce from first principles, open Wait For It, then go to Formula mode. Change the formula entries to a, a, 1, white; then change the sequence formula to xgcd(3,n)[2]. The resulting path is disconnected, but as far as I can tell from the choices "a,a,1,white" it shouldn't be possible?

http://localhost:5173/?name=Formula%3A+n&viz=Turtle&domain=-1+1&turns=30+120&steps=30+30&widths=2&strokeColor=%237a9f6f&bgColor=5d509f&ruleMode=1&turnFormula=a&stepFormula=a&colorFormula=white&seq=Formula&formula=xgcd%283%2Cn%29%5B2%5D

Screenshot from 2025-01-24 18-56-37

@katestange
Copy link
Member

I'm trying to do things like 'chroma.scale()(0.5)' in the colour formula but it doesn't work.

@katestange
Copy link
Member

@gwhitney
Copy link
Collaborator Author

I'm guessing it's the turn formula that is a problem, combined with the xgcd and array call in math.js. But these errors aren't getting caught, they are breaking through to pop-up.

Indeed, it appears that the issue is that the sequence has a negative value, and then the turn formula is raising that to a a fractional power, and so getting a complex number. Then Turtle is trying to interpret that complex number as a turn angle, which it is unable to do. It is producing a popup rather than a formula warning on the parameter because the error is not occurring in the formula computation -- that is working perfectly well to produce a complex number -- but rather in the implementation code itself when it tries to convert the complex number to the JavaScript number type, which is impossible.

It's not clear what the best solution here is. The name of the function (that we added to mathjs) "safeNumber" seems to imply that it is always safe to call it. But what is it supposed to do when it is called with something like a matrix or a complex number that mathjs might return, for which there is simply no sensible way to convert the result to a number? I don't see what else it could do but throw an error. So then we would still have to catch errors any time we call safeNumber, which is a pain.

So one possibility would be that for formula parameters we could supply a list of allowed return types (as a list of the names that mathjs uses for types) so that the parameter would go into an error state when it returned a disallowed type (and the code would get some value that would forestall further throws). This list could default to [bigint] or possibly [number, bigint], so that you would have to explicitly bless any other type of return value that you might want to allow (like Chroma). What do you think of that option? Other thoughts on how to proceed here?

@gwhitney
Copy link
Collaborator Author

gwhitney commented Feb 1, 2025

OK all of the new tests now pass, except for the one that needs code to realize that foo()(x,) is a function call of the result of foo() on x. Note this has been done by just making OrRd etc valid pre-defined constants.

@gwhitney
Copy link
Collaborator Author

gwhitney commented Feb 1, 2025

So one possibility would be that for formula parameters we could supply a list of allowed return types (as a list of the names that mathjs uses for types) so that the parameter would go into an error state when it returned a disallowed type (and the code would get some value that would forestall further throws). This list could default to [bigint] or possibly [number, bigint], so that you would have to explicitly bless any other type of return value that you might want to allow (like Chroma). What do you think of that option? Other thoughts on how to proceed here?

OK, this has percolated and I now have a concrete proposal. MathFormula objects should have a preferred return type, defaulting to bigint (because that's what a Formula Sequence wants), but it can be any type supported by mathjs. The compute infrastructure will attempt to convert to your preferred type for you, so that if the conversion fails, it can return a dummy value and post an error to the status for that formula parameter.

How's that sound? I think it provides ease for the visualizer writer while being comprehensible for the sequence explorer -- if the latter puts in a formula that produces an unusable value like a complex number, they will get a message to that effect in the parameter box and can adjust their formula.

@gwhitney
Copy link
Collaborator Author

gwhitney commented Feb 1, 2025

This produces a disconnected path.

Right, there was a bug that prevented steps of negative length, which are perfectly sensible, from actually being drawn. Fixed now.

  THe difficulty with the built-in color picker is that it operates
  differently from browser to browser, and there is no reliable way
  to tell when the explorer closes the color picker. Therefore,
  this commit switches to using a 3rd-party color picker. The new
  package already supported a list of colors, so we use that to
  support a new COLOR_ARRAY param type. The new param type is perfect
  for Turtle Stroke color(s) parameter in List mode.
@gwhitney
Copy link
Collaborator Author

gwhitney commented Feb 4, 2025

OK, it turned out there was literally no way to get an event to reliably fire across browsers when you close the built-in color picker, if the color picked hasn't changed, which mean that with the built-in picker, there was no way to fulfill our goal of re-selecting the same color in the chooser inserting it into the stroke color parameter.

So in the latest commit I switched to a 3rd party color picker. That one, it turns out, has a built-in method for selecting a sequence of colors, so I enabled that for the Stroke color(s) parameter. So now there is no need to mess with text representations of colors in the Turtle List mode at all. And therefore the color chooser only appears, right below the Color formula, in formula mode. (The background color button is always active.) Moreover, the chosen color replaces whatever part of the formula you had selected prior to making the choice, making it easy to replace one color in your formula with another.

Hopefully this is pleasant and easy to use. I will continue to plow through the many points here.

@gwhitney
Copy link
Collaborator Author

gwhitney commented Feb 4, 2025

  • Allow descriptions to have links and make the word "color" in the above description be a link to our documentation page/section on color specifications.

Now that the color list is not using text color notations, I recommend we postpone this and not do it as part of this PR. Links in descriptions basically means switching to supporting Markdown descriptions (don't clearly see any other way, since arbitrary HTML is not allowed in the text of fields for security reasons), and that is a larger effort, seems beyond the scope of this PR. If you're comfortable turning on Formula mode, I think we can assume that you are a Numberscope guru or at least know how to find the doc pages...

@gwhitney
Copy link
Collaborator Author

gwhitney commented Feb 5, 2025

  • Conform the variable names to n - sequence index; a - sequence value; s - step serial number starting from 1; f,l - first and last sequence index; x, y -- coordinates; b - bearing.

Oops, unfortunately this list overlooked that f needs to be used for the frame number. So I am going to implement:

  • n: sequence index
  • a: sequence value
  • s: step serial number
  • m: minimum sequence index (so n = m + s - 1)
  • M: Maximum sequence index
  • f: frame number
  • x,y: coordinates of current position
  • b: bearing

Any objections/better suggestions, let me know.

@gwhitney
Copy link
Collaborator Author

gwhitney commented Feb 5, 2025

  • "Preimplement" chroma.scale()(0.5,) to unambiguously mean that the function chroma.scale() should be called on 0.5 to avoid the implicit multiplication trap for trying to use this color formula.
  • Get skipped tests to pass

I have filed josdejong/mathjs#3378 to support this notation in mathjs. The "preimplementation" idea looks pretty tricky: it's a small change inside of mathjs's parser, but the parser is open to customization from outside the package only in very specific ways. So it seems as though we would need to basically have a copy of the mathjs parsing code within frontscope in order to "preimplement" this, and it would be temporary until mathjs adopts this or some other notation for allowing function-returning expressions to be called. So my recommendation is to wait on these items: not make them part of this PR, and once a mathjs update is merged that has this function-calling feature, revisit the skipped tests (which now only deal with this point).

@gwhitney
Copy link
Collaborator Author

gwhitney commented Feb 6, 2025

I like the Vertigo of Divergence and am in the process of adding it as a featured specimen.

On the other hand, I don't see how your second example reflects the convergence of the first nontrivial zeta zero. If we let $s_1 = \frac12 + \rho_1i \approx \frac12 + 14.135i$, and ignoring the radian -> degree conversion (for which in the future I recommend 360/tau as the clearest factor), you have the turn formula $\rho_1 \log n$ and the step formula $200/\sqrt n$. As these expressions are the argument and constant-scaled radius of $n^{-s_1}$, I think you are attempting to do direct summation of the original defining sum of the zeta function by having each turtle move represent the addition of the next complex number. But to do that summation, we want the bearing of each turtle move to be the argument of the corresponding term in the zeta-summation, not the turn angle (= bearing difference) to be that argument.

Fortunately, that's easy to do: subtracting b, the current bearing, from any expression EXPR to create a turn angle formula will make EXPR become the new bearing. But now changing the turn formula to log(n)*14.135*360/tau - b produces a not-very-interesting picture: it jumps around for the first half-dozen steps haphazardly, and then settles into a steady outward spiral. But that shouldn't be surprising, in two ways:
(a) the original defining summation diverges for Re z ≤ 1.
(b) this turn angle could just as well be written (ignoring unit conversion) as log(n)*14.135 - log(n-1)*14.135 , i.e. $\rho_1\log(1 - 1/n)$, which is getting smaller and smaller. So the turtle is turning less and less, and so of course it is spiraling outwards.

So what I think is interesting -- definitely something I didn't know before -- is that for larger imaginary parts, at least near roots of zeta, the direct summation of the terms in the series, before it starts its final "death spiral to infinity", comes very near to crossing right over the actual value of its analytic continuation. Moreover, one can easily compute the exact pair of terms such that the midpoint of the line segment between them comes closest to the value of zeta. And you get a pretty picture of what's going on. These statements are the gist of https://math.stackexchange.com/questions/805396/simpler-zeta-zeros that you referenced.

So for example http://localhost:5173/?name=Convergence+of+Riemann+Zero+%2310143&viz=Turtle&speed=10&ruleMode=1&turnFormula=log%28n%29*10000.065345417*360%2Ftau+-b&stepFormula=200%2Fsqrt%28n%29&colorFormula=rainbow%282b%29&seq=Formula&first=1&last=3183&length=3183 reproduces exactly the diagram of that math stackexchange article (prettier, though, I think ;-). So we could include that as a featured visualization.

There are lots of things to notice here. A few are:

  • The path beautifully comes back to visually precisely where it starts, precisely because this $\rho_{10143}$ is the imaginary part of a root of zeta. In fact, if you increase the scale factor to 200,000 from 200, the very last stroke still goes through exactly the starting pixel! (That's how good this cutoff of the summation is at estimating the true zeta function.) So we could instead have a featured specimen in which we animate that scale factor, zooming in on the beautiful structure at the origin. A step formula of 200*1.03^f/sqrt(n) works well for this.
  • Alternatively, if you swap in the previous root $\rho_{10142}\approx 9998.850397090$ in the turn formula, you get a trajectory which shares the qualitative features that it consists of a bunch of whorls connected by s-curves and lands back at 0, but which takes a completely different path in detail to get there. So we could animate the imaginary part of s starting from this root, and you get a compelling picture of the enormous numerical coincidences that must occur for zeta to have a root (in fact it makes it seem unfathomable that zeta in fact has any nontrivial roots). And that could be the featured specimen. A turn formula of log(n)*(9998.850397090+0.007f)*360/tau - b works well for this.
  • One could instead animate the real part of s with something like 200/n^(0.35+0.001f) but that's less visually interesting because it mostly looks like scaling. While it makes it seem clear that there will only be one root as the real part changes, because the center of the final whorl is moving close to linearly, I wouldn't recommend this animation as a featured specimen.

Looking forward to your thoughts/recommendations. One other thing to note is that the alternating sum of inverse s-th powers of n, with the proper scaling factor, does converge in the usual sense to $\zeta(s)$. However, this produces a less interesting picture because it is a sum that in fact converges very well. So you just get a sort of star-shaped spiral that homes in very quickly on the origin, even for the first root. I haven't tried animating the imaginary part of this summation, though -- that might be interesting in terms of seeing the trajectory of zeta, starting from a smallish imaginary part and reaching the first few roots. Let me know if you think that's worth looking at.

Oh and as far as the third example it was indeed cute but I don't think it's quite "featured specimen" caliber. But I did find the following related specimen that I think could be a candidate:
http://localhost:5173/?name=PEMDASymmetry&viz=Turtle&bgColor=22274e&speed=10&ruleMode=1&turnFormula=30%2B15a&stepFormula=4&colorFormula=rainbow(abs(y-160))&seq=Formula&formula=(n%2F10)^2+-+n%2F10^2&last=8191&length=8192

@gwhitney
Copy link
Collaborator Author

gwhitney commented Feb 6, 2025

If we put an exception into the Turtle code that treats infinite turn angles as 0, then we could instead write the turn formula for the zeta summation at $\rho_{10143}$ as log1p(1/n) * 10000.065345417 * 360/tau which is very elegant as well, especially insofar it does not use the bearing variable b but is just in terms of n, and as per the stackexchange article, perhaps shows even more clearly what is going on.

But I am not sure such an exception makes mathematical or logical sense. On the other hand, what else should the poor turtle do with an infinite (or NaN) turn angle?

Other tweaks we might make:

  • Should Turtle (or frontscope in general?) have a degree/radian mode toggle somewhere? That way we could get rid of the 360/tau term (which in point of fact is canceling a pi/180 term that we have in the Turtle code to interpret the angles as degrees!).
  • Should Turtle have a "Bearing/Turn" toggle to tell you whether the angle formula gives you the absolute or relative bearing? Or is the ability to tack on a - b at the end of the formula to basically morph the rest of the formula into an absolute bearing formula enough? I worry just slightly about the possibility of cancellation numerical errors when we calculate x - b + b, in effect, to get the new bearing to be x. In particular, if b happens to be very large and x very small (i.e. in a case where the heading fluctuates rapidly) then this calculation will in effect discard the value of x. But perhaps such cases are not too likely to come up in practice?

@Vectornaut
Copy link
Collaborator

Vectornaut commented Feb 6, 2025

Should Turtle have a "Bearing/Turn" toggle to tell you whether the angle formula gives you the absolute or relative bearing?

Yeah, I think that would be useful, because the OEIS includes at least one sequence that lists the turtle bearings for a curve. Sequence A229214 gives the bearings for the flowsnake. It would also be great for drawing cutting sequences on the torus (also known as Sturmian sequences)!

@gwhitney
Copy link
Collaborator Author

gwhitney commented Feb 7, 2025

Yeah, I think that would be useful, because the OEIS includes at least one sequence that lists the turtle bearings for a curve. Sequence A229214 gives the bearings for the flowsnake. It would also be great for drawing cutting sequences on the torus (also known as Sturmian sequences)!

OK, in progress. When a commit for it is pushed here, I will also post a link for the flowsnake specimen in the interesting specimens discussion.

@gwhitney
Copy link
Collaborator Author

gwhitney commented Feb 7, 2025

@katestange @Vectornaut I am stumped by "TouchEvent is not defined". I cannot reproduce on any browser. So I definitely need more info. I am using Firefox 134.0.2, what version do you have? There are definitely reports of this error online, always associated with either Firefox or Safari, but mostly years old. There is one software package I found (grafana/grafana#78431) that had an issue with this fixed only a year ago, so it could be a thing still. But the funny thing ist neither vue-pick-colors (the component I added) or its sole dependency @popperjs/core even contain the strings 'Touch' or 'touch' in their entire package contents. So I guess we should start with your Firefox version(s), an exact reproducing sequence of actions, and the backtrace it is presumably producing in the console either just before or just after popping up that error window, and then take it from there. Thanks so much for lending a hand with this.

@Vectornaut
Copy link
Collaborator

Vectornaut commented Feb 7, 2025

So I guess we should start with your Firefox version(s), an exact reproducing sequence of actions, and the backtrace it is presumably producing in the console either just before or just after popping up that error window, and then take it from there.

Browser

Firefox 135.0

Reproduction steps

  1. Launch Numberscope (commit 23c1c4a) with npm run dev
  2. Go to http://localhost:5173/?name=OEIS+A000045&viz=ModFill&seq=OEIS+A000045
  3. Click the black swatch next to the Mod Fill visualizer's Fill color control
    • A color picker appears
  4. Click any point on the constant-hue slice in the color picker
    • The error dialog appears

Console messages

When I trigger the error, the following log messages appear.
Numberscope encountered error: ReferenceError: TouchEvent is not defined
    onSelect index.esm.js:1
    G.render/t[0]< index.esm.js:1
    cacheKey runtime-dom.esm-bundler.js:1705
    callWithErrorHandling runtime-core.esm-bundler.js:199
    callWithAsyncErrorHandling runtime-core.esm-bundler.js:206
    invoker runtime-dom.esm-bundler.js:729
    addEventListener runtime-dom.esm-bundler.js:680
    patchEvent runtime-dom.esm-bundler.js:698
    patchProp runtime-dom.esm-bundler.js:775
    mountElement runtime-core.esm-bundler.js:4873
    processElement runtime-core.esm-bundler.js:4820
    patch runtime-core.esm-bundler.js:4688
    componentUpdateFn runtime-core.esm-bundler.js:5326
    run reactivity.esm-bundler.js:225
    setupRenderEffect runtime-core.esm-bundler.js:5454
    mountComponent runtime-core.esm-bundler.js:5229
    processComponent runtime-core.esm-bundler.js:5182
    patch runtime-core.esm-bundler.js:4700
    mountChildren runtime-core.esm-bundler.js:4932
    mountElement runtime-core.esm-bundler.js:4855
    processElement runtime-core.esm-bundler.js:4820
    patch runtime-core.esm-bundler.js:4688
    mountChildren runtime-core.esm-bundler.js:4932
    mountElement runtime-core.esm-bundler.js:4855
    processElement runtime-core.esm-bundler.js:4820
    patch runtime-core.esm-bundler.js:4688
    mountChildren runtime-core.esm-bundler.js:4932
    mountElement runtime-core.esm-bundler.js:4855
    processElement runtime-core.esm-bundler.js:4820
    patch runtime-core.esm-bundler.js:4688
    componentUpdateFn runtime-core.esm-bundler.js:5326
    run reactivity.esm-bundler.js:225
    setupRenderEffect runtime-core.esm-bundler.js:5454
    mountComponent runtime-core.esm-bundler.js:5229
    processComponent runtime-core.esm-bundler.js:5182
    patch runtime-core.esm-bundler.js:4700
    componentUpdateFn runtime-core.esm-bundler.js:5406
    run reactivity.esm-bundler.js:225
    runIfDirty reactivity.esm-bundler.js:263
    callWithErrorHandling runtime-core.esm-bundler.js:199
    flushJobs runtime-core.esm-bundler.js:408
    promise callback*queueFlush runtime-core.esm-bundler.js:322
    queueJob runtime-core.esm-bundler.js:317
    scheduler runtime-core.esm-bundler.js:5448
    trigger reactivity.esm-bundler.js:253
    endBatch reactivity.esm-bundler.js:311
    notify reactivity.esm-bundler.js:597
    trigger reactivity.esm-bundler.js:571
    set value reactivity.esm-bundler.js:1448
    togglePicker ParamField.vue:177
    maybeTogglePicker ParamField.vue:172
    patchStopImmediatePropagation runtime-dom.esm-bundler.js:758
    callWithErrorHandling runtime-core.esm-bundler.js:199
    callWithAsyncErrorHandling runtime-core.esm-bundler.js:206
    callWithAsyncErrorHandling runtime-core.esm-bundler.js:217
    invoker runtime-dom.esm-bundler.js:729
main.ts:11:12
    errorHandler main.ts:11
    callWithErrorHandling runtime-core.esm-bundler.js:199
    handleError runtime-core.esm-bundler.js:246
    callWithErrorHandling runtime-core.esm-bundler.js:201
    callWithAsyncErrorHandling runtime-core.esm-bundler.js:206
    invoker runtime-dom.esm-bundler.js:729
    (Async: EventListener.handleEvent)
    addEventListener runtime-dom.esm-bundler.js:680
    patchEvent runtime-dom.esm-bundler.js:698
    patchProp runtime-dom.esm-bundler.js:775
    mountElement runtime-core.esm-bundler.js:4873
    processElement runtime-core.esm-bundler.js:4820
    patch runtime-core.esm-bundler.js:4688
    componentUpdateFn runtime-core.esm-bundler.js:5326
    run reactivity.esm-bundler.js:225
    setupRenderEffect runtime-core.esm-bundler.js:5454
    mountComponent runtime-core.esm-bundler.js:5229
    processComponent runtime-core.esm-bundler.js:5182
    patch runtime-core.esm-bundler.js:4700
    mountChildren runtime-core.esm-bundler.js:4932
    mountElement runtime-core.esm-bundler.js:4855
    processElement runtime-core.esm-bundler.js:4820
    patch runtime-core.esm-bundler.js:4688
    mountChildren runtime-core.esm-bundler.js:4932
    mountElement runtime-core.esm-bundler.js:4855
    processElement runtime-core.esm-bundler.js:4820
    patch runtime-core.esm-bundler.js:4688
    mountChildren runtime-core.esm-bundler.js:4932
    mountElement runtime-core.esm-bundler.js:4855
    processElement runtime-core.esm-bundler.js:4820
    patch runtime-core.esm-bundler.js:4688
    componentUpdateFn runtime-core.esm-bundler.js:5326
    run reactivity.esm-bundler.js:225
    setupRenderEffect runtime-core.esm-bundler.js:5454
    mountComponent runtime-core.esm-bundler.js:5229
    processComponent runtime-core.esm-bundler.js:5182
    patch runtime-core.esm-bundler.js:4700
    componentUpdateFn runtime-core.esm-bundler.js:5406
    run reactivity.esm-bundler.js:225
    runIfDirty reactivity.esm-bundler.js:263
    callWithErrorHandling runtime-core.esm-bundler.js:199
    flushJobs runtime-core.esm-bundler.js:408
    (Async: promise callback)
    queueFlush runtime-core.esm-bundler.js:322
    queueJob runtime-core.esm-bundler.js:317
    scheduler runtime-core.esm-bundler.js:5448
    trigger reactivity.esm-bundler.js:253
    endBatch reactivity.esm-bundler.js:311
    notify reactivity.esm-bundler.js:597
    trigger reactivity.esm-bundler.js:571
    set value reactivity.esm-bundler.js:1448
    togglePicker ParamField.vue:177
    maybeTogglePicker ParamField.vue:172
    patchStopImmediatePropagation runtime-dom.esm-bundler.js:758
    callWithErrorHandling runtime-core.esm-bundler.js:199
    callWithAsyncErrorHandling runtime-core.esm-bundler.js:206
    callWithAsyncErrorHandling runtime-core.esm-bundler.js:217
    invoker runtime-dom.esm-bundler.js:729
In component: 
Proxy { <target>: {…}, <handler>: {…} }
main.ts:12:12
Additional information: native event handler main.ts:13:12

@gwhitney
Copy link
Collaborator Author

gwhitney commented Feb 7, 2025

Aha! That was really helpful. vue-pick-colors does explicitly mention TouchEvent, it just wasn't showing up in rg -i touch node_modules/vue-pick-colors I think due to some automatic filtering of minified javascript files in ripgrep. I will investigate further.

@gwhitney
Copy link
Collaborator Author

gwhitney commented Feb 7, 2025

OK, @katestange or @Vectornaut, could one of you try the following in this branch:

  1. Do npm run preview and visit the URL that produces and verify the problem is present.
  2. Replace node_modules/vue-pick-colors/dist/index.esm.js with the version attached to this comment. (After all this, you can rm -r node_modules/vue-pick-colors and then npm install again to revert to the standard vue-pick-colors, but the differences are tiny so it shouldn't really make any difference whether you do or not.)
  3. Run npm run build:clean
  4. Run npm run preview and verify that the problem is no longer occurring.

Sorry about the slightly circuitous route via preview, but I am not clear on how to be certain that npm run dev will pick up a hot-patched dependency, whereas a clean build is obliged to go and get whatever is there in your node_modules to package up a self-contained distro.

Thanks! If this works I will submit a PR with the tiny fixes (that just check if TouchEvent support is enabled before trying to use it; turns out many desktop Firefox distros don't turn on the support and that's what's biting us).

@gwhitney
Copy link
Collaborator Author

gwhitney commented Feb 8, 2025

  • Implement a "preferred type" scheme for Formula parameters, where the infrastructure does the conversion for you and warns in the UI if not possible.

OK, this isn't really feasible before updating to the new mathjs. It also isn't really germane to this PR; it's just that Kate happened to run into some complex numbers being generated from a negative input to a fractional power while messing around with this PR. So I am going to file this as a separate issue for alpha, so it can be done within or after the mathjs update PR, and take it off the list for this one.

@gwhitney
Copy link
Collaborator Author

gwhitney commented Feb 8, 2025

  • Degree/radian

Oh! It occurs to me that mathjs already has angle units: deg and rad and even the obscure grad (400 grad = τ radians). So I recommend that in formula mode, angles are angles and they should either have a unit, or if they are left unitless, are interpreted as radians. So I think there is no need for a unit toggle (and I prefer not to include one to keep the interface simpler, but I will put a mention in the docs of the units). On the other hand, in List mode, to keep things accessible to newcomers, I suggest we continue to interpret the typed-in numbers as degrees.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants