diff --git a/cicd/jsweet-legacy-code.bash b/cicd/jsweet-legacy-code.bash
index a41a7e56b..67547a078 100755
--- a/cicd/jsweet-legacy-code.bash
+++ b/cicd/jsweet-legacy-code.bash
@@ -46,7 +46,6 @@ banner 'Patching up the core bundle as an ES6 module' ##########################
OUTJS=$LEGACY/core-java.js
echo 'import { java, javaemul } from "./candies/j4ts-2.1.0-SNAPSHOT/bundle.js"' > $OUTJS
-# echo 'import { javax } from "./candies/j4ts-awt-swing-0.0.2-SNAPSHOT/bundle.js"' >> $OUTJS
cat 'online/jsweetOut/core/js/bundle.js' | \
sed \
@@ -55,3 +54,9 @@ cat 'online/jsweetOut/core/js/bundle.js' | \
-e 's/(java || (java = {}));/(java);/' \
>> $OUTJS
+
+banner 'You should regenerate the un-bundled Typescript!'
+
+echo '/* THIS FILE IS CURRENTLY IGNORED! We are using the generated core-java.js instead, for now. */' > $LEGACY/ts/core-java.ts
+cat online/jsweetOut/core/ts/bundle.ts >> $LEGACY/ts/core-java.ts
+
diff --git a/core/src/main/java/com/vzome/core/exporters/POVRayExporter.java b/core/src/main/java/com/vzome/core/exporters/POVRayExporter.java
index ad8e80f75..1f0bb682c 100644
--- a/core/src/main/java/com/vzome/core/exporters/POVRayExporter.java
+++ b/core/src/main/java/com/vzome/core/exporters/POVRayExporter.java
@@ -23,6 +23,7 @@
import com.vzome.core.math.symmetry.Embedding;
import com.vzome.core.render.RenderedManifestation;
import com.vzome.core.viewing.CameraIntf;
+import com.vzome.xml.ResourceLoader;
/**
* Renders out to POV-Ray using #declare statements to reuse geometry.
@@ -67,18 +68,8 @@ public void doExport( File povFile, Writer writer, int height, int width ) throw
output .println( "#declare parallel_proj = " + (mScene .isPerspective()?0:1) + ";" );
output .println();
- InputStream input = getClass() .getClassLoader()
- .getResourceAsStream( PREAMBLE_FILE );
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- byte[] buf = new byte[1024];
- int num;
- try {
- while ( ( num = input .read( buf, 0, 1024 )) > 0 )
- out .write( buf, 0, num );
- } catch (IOException e) {
- e.printStackTrace();
- }
- output .println( new String( out .toByteArray() ) );
+ String preamble = ResourceLoader.loadStringResource( PREAMBLE_FILE );
+ output .println( preamble );
output .println();
for ( int i = 0; i<3; i++ ) {
diff --git a/online/build.gradle b/online/build.gradle
index 64cbf4721..b3f7233e2 100644
--- a/online/build.gradle
+++ b/online/build.gradle
@@ -91,7 +91,7 @@ core.config {
encoding = 'UTF-8'
sourceMap = false // I can't set breakpoints if the browser cannot find the Java file, so disabling for now.
- bundle = true
+ bundle = true // I set this to false to generate the unbundled Typescript sources
workingDir = project.file( '.jsweet/core' )
tsOut = project.file( 'jsweetOut/core/ts' )
@@ -241,15 +241,12 @@ core.config {
'com/vzome/core/commands/CommandExecutePythonScript.java',
+ // These have already been reimplemented
'com/vzome/core/edits/ImportSimpleMeshJson.java',
'com/vzome/core/edits/ImportColoredMeshJson.java',
- 'com/vzome/core/edits/DodecagonSymmetry.java',
- 'com/vzome/core/edits/GhostSymmetry24Cell.java',
- 'com/vzome/core/edits/Symmetry4d.java',
+
'com/vzome/core/edits/RunZomodScript.java',
'com/vzome/core/edits/RunPythonScript.java',
- 'com/vzome/core/edits/RealizeMetaParts.java',
- // 'com/vzome/core/edits/ReplaceWithShape.java',
// These have already been reimplemented
'com/vzome/core/exporters/ColoredMeshJsonExporter.java',
diff --git a/online/src/app/classic/menus/filemenu.jsx b/online/src/app/classic/menus/filemenu.jsx
index 67ca6ff52..ef7f83f74 100644
--- a/online/src/app/classic/menus/filemenu.jsx
+++ b/online/src/app/classic/menus/filemenu.jsx
@@ -9,7 +9,7 @@ import { saveFileAs, openFile, saveTextFileAs, saveTextFile } from "../../../vie
import { CommandAction, Divider, Menu, MenuAction, MenuItem, SubMenu } from "../../framework/menus.jsx";
import { UrlDialog } from '../dialogs/webloader.jsx'
import { SvgPreviewDialog } from "../dialogs/svgpreview.jsx";
-import { useCamera } from "../../../viewer/context/camera.jsx";
+import { INITIAL_DISTANCE, useCamera } from "../../../viewer/context/camera.jsx";
import { useImageCapture } from "../../../viewer/context/export.jsx";
const queryParams = new URLSearchParams( window.location.search );
@@ -33,7 +33,7 @@ export const FileMenu = () =>
{
const { rootController, state, setState,
createDesign, openDesignFile, fetchDesignUrl, importMeshFile, guard, edited } = useEditor();
- const { state: cameraState } = useCamera();
+ const { state: cameraState, mapViewToWorld } = useCamera();
const [ showDialog, setShowDialog ] = createSignal( false );
const fields = () => controllerProperty( rootController(), 'fields', 'fields', true );
@@ -98,7 +98,11 @@ export const FileMenu = () =>
const exportAs = ( extension, mimeType, format=extension, params={} ) => evt =>
{
const camera = unwrap( cameraState.camera );
+ camera .magnification = Math.log( camera.distance / INITIAL_DISTANCE );
+
const lighting = unwrap( cameraState.lighting );
+ lighting .directionalLights .forEach( light => light .worldDirection = mapViewToWorld( light.direction ) );
+
controllerExportAction( rootController(), format, { camera, lighting, ...params } )
.then( text => {
const name = (state.designName || 'untitled') .concat( "." + extension );
@@ -163,7 +167,7 @@ export const FileMenu = () =>
-
+
diff --git a/online/src/viewer/context/camera.jsx b/online/src/viewer/context/camera.jsx
index 6feb4c231..553cf6c25 100644
--- a/online/src/viewer/context/camera.jsx
+++ b/online/src/viewer/context/camera.jsx
@@ -1,6 +1,6 @@
import { createContext, createEffect, useContext } from 'solid-js';
-import { PerspectiveCamera } from "three";
+import { PerspectiveCamera, Vector3 } from "three";
import { createStore } from 'solid-js/store';
@@ -154,6 +154,13 @@ const CameraProvider = ( props ) =>
}
const trackballProps = { camera: trackballCamera, sync }; // no need (or desire) for reactivity here
+ const mapViewToWorld = ( [ x, y, z ] ) =>
+ {
+ const vec = new Vector3( x, y, z );
+ vec .transformDirection( trackballCamera.matrixWorldInverse );
+ return [ vec.x, vec.y, vec.z ];
+ }
+
const setCamera = loadedCamera =>
{
setState( 'camera', loadedCamera );
@@ -179,7 +186,7 @@ const CameraProvider = ( props ) =>
const providerValue = {
name: props.name,
perspectiveProps, trackballProps, state,
- resetCamera, setCamera, setLighting, togglePerspective, toggleOutlines, setDistance,
+ resetCamera, setCamera, setLighting, togglePerspective, toggleOutlines, setDistance, mapViewToWorld,
};
// The perspectiveProps is used to initialize PerspectiveCamera in clients.
diff --git a/online/src/worker/java/java/util/UUID.java b/online/src/worker/java/java/util/UUID.java
index 578367f58..62cabc952 100644
--- a/online/src/worker/java/java/util/UUID.java
+++ b/online/src/worker/java/java/util/UUID.java
@@ -13,7 +13,7 @@ private UUID( String s )
public static UUID randomUUID()
{
- return new UUID( Double.toString( Math.random() ) );
+ return new UUID( Double.toString( Math.random() ) .substring( 2 ) );
}
public String toString()
diff --git a/online/src/worker/legacy/core-java.js b/online/src/worker/legacy/core-java.js
index e2d867d23..e8211f115 100644
--- a/online/src/worker/legacy/core-java.js
+++ b/online/src/worker/legacy/core-java.js
@@ -11,7 +11,7 @@ import { java, javaemul } from "./candies/j4ts-2.1.0-SNAPSHOT/bundle.js"
this.value = s;
}
static randomUUID() {
- return new UUID(/* toString */ ('' + (Math.random())));
+ return new UUID(/* toString */ ('' + (Math.random())).substring(2));
}
toString() {
return this.value;
@@ -3952,6 +3952,10 @@ export var com;
this.orbits = new com.vzome.core.math.symmetry.OrbitSet(symmetry);
}
/* Default method injected from com.vzome.core.editor.api.OrbitSource */
+ getZone(orbit, orientation) {
+ return this.getSymmetry().getDirection(orbit).getAxis(com.vzome.core.math.symmetry.Symmetry.PLUS, orientation);
+ }
+ /* Default method injected from com.vzome.core.editor.api.OrbitSource */
getEmbedding() {
const symmetry = this.getSymmetry();
const field = symmetry.getField();
@@ -3979,10 +3983,6 @@ export var com;
return this.getOrientations(false);
}
/* Default method injected from com.vzome.core.editor.api.OrbitSource */
- getZone(orbit, orientation) {
- return this.getSymmetry().getDirection(orbit).getAxis(com.vzome.core.math.symmetry.Symmetry.PLUS, orientation);
- }
- /* Default method injected from com.vzome.core.editor.api.OrbitSource */
getOrientations(rowMajor) {
if (((typeof rowMajor === 'boolean') || rowMajor === null)) {
let __args = arguments;
@@ -16761,6 +16761,10 @@ export var com;
this.setStyle(styleName);
}
/* Default method injected from com.vzome.core.editor.api.OrbitSource */
+ getZone(orbit, orientation) {
+ return this.getSymmetry().getDirection(orbit).getAxis(com.vzome.core.math.symmetry.Symmetry.PLUS, orientation);
+ }
+ /* Default method injected from com.vzome.core.editor.api.OrbitSource */
getEmbedding() {
const symmetry = this.getSymmetry();
const field = symmetry.getField();
@@ -16788,10 +16792,6 @@ export var com;
return this.getOrientations(false);
}
/* Default method injected from com.vzome.core.editor.api.OrbitSource */
- getZone(orbit, orientation) {
- return this.getSymmetry().getDirection(orbit).getAxis(com.vzome.core.math.symmetry.Symmetry.PLUS, orientation);
- }
- /* Default method injected from com.vzome.core.editor.api.OrbitSource */
getOrientations(rowMajor) {
if (((typeof rowMajor === 'boolean') || rowMajor === null)) {
let __args = arguments;
@@ -36960,21 +36960,8 @@ export var com;
this.output.println$();
this.output.println$java_lang_Object("#declare parallel_proj = " + (this.mScene.isPerspective() ? 0 : 1) + ";");
this.output.println$();
- const input = this.constructor.getClassLoader().getResourceAsStream(POVRayExporter.PREAMBLE_FILE);
- const out = new java.io.ByteArrayOutputStream();
- const buf = (s => { let a = []; while (s-- > 0)
- a.push(0); return a; })(1024);
- let num;
- try {
- while (((num = input.read(buf, 0, 1024)) > 0)) {
- out.write(buf, 0, num);
- }
- ;
- }
- catch (e) {
- console.error(e.message, e);
- }
- this.output.println$java_lang_Object(new String(out.toByteArray()));
+ const preamble = com.vzome.xml.ResourceLoader.loadStringResource(POVRayExporter.PREAMBLE_FILE);
+ this.output.println$java_lang_Object(preamble);
this.output.println$();
for (let i = 0; i < 3; i++) {
{
@@ -45563,6 +45550,103 @@ export var com;
})(core = vzome.core || (vzome.core = {}));
})(vzome = com.vzome || (com.vzome = {}));
})(com || (com = {}));
+(function (com) {
+ var vzome;
+ (function (vzome) {
+ var core;
+ (function (core) {
+ var edits;
+ (function (edits) {
+ class GhostSymmetry24Cell extends com.vzome.core.editor.api.ChangeManifestations {
+ constructor(editor) {
+ super(editor);
+ if (this.field === undefined) {
+ this.field = null;
+ }
+ if (this.proj === undefined) {
+ this.proj = null;
+ }
+ if (this.symmAxis === undefined) {
+ this.symmAxis = null;
+ }
+ if (this.symm === undefined) {
+ this.symm = null;
+ }
+ this.symm = editor['getSymmetrySystem$']().getSymmetry();
+ this.field = this.symm.getField();
+ this.symmAxis = editor.getSymmetrySegment();
+ }
+ /**
+ *
+ * @return {string}
+ */
+ getXmlElementName() {
+ return "GhostSymmetry24Cell";
+ }
+ /**
+ *
+ * @param {*} result
+ */
+ getXmlAttributes(result) {
+ if (this.symmAxis != null)
+ com.vzome.core.commands.XmlSaveFormat.serializeSegment(result, "start", "end", this.symmAxis);
+ }
+ /**
+ *
+ * @param {*} xml
+ * @param {com.vzome.core.commands.XmlSaveFormat} format
+ */
+ setXmlAttributes(xml, format) {
+ this.symmAxis = format.parseSegment$org_w3c_dom_Element$java_lang_String$java_lang_String(xml, "start", "end");
+ }
+ /**
+ *
+ */
+ perform() {
+ if (this.symmAxis == null)
+ this.proj = new com.vzome.core.math.Projection.Default(this.field);
+ else
+ this.proj = new com.vzome.core.math.QuaternionProjection(this.field, null, this.symmAxis.getOffset().scale(this.field['createPower$int'](-5)));
+ const blue = this.symm.getDirection("blue");
+ const green = this.symm.getDirection("green");
+ for (let k = 0; k < 12; k++) {
+ {
+ const A1 = blue.getAxis$int$int(com.vzome.core.math.symmetry.Symmetry.PLUS, (k + 2) % 12).normal();
+ const A2 = green.getAxis$int$int(com.vzome.core.math.symmetry.Symmetry.PLUS, (5 * k + 2) % 12).normal();
+ const B1 = green.getAxis$int$int(com.vzome.core.math.symmetry.Symmetry.PLUS, (k + 2) % 12).normal();
+ const B2 = blue.getAxis$int$int(com.vzome.core.math.symmetry.Symmetry.PLUS, (5 * k + 5) % 12).normal();
+ let projected = this.symm.getField().origin(4);
+ projected.setComponent(0, A2.getComponent(0));
+ projected.setComponent(1, A2.getComponent(1));
+ projected.setComponent(2, A1.getComponent(0));
+ projected.setComponent(3, A1.getComponent(1));
+ if (this.proj != null)
+ projected = this.proj.projectImage(projected, true);
+ let p = new com.vzome.core.construction.FreePoint(projected.scale(this.field['createPower$int'](5)));
+ p.setIndex(k);
+ this.manifestConstruction(p);
+ projected = this.symm.getField().origin(4);
+ projected.setComponent(0, B2.getComponent(0));
+ projected.setComponent(1, B2.getComponent(1));
+ projected.setComponent(2, B1.getComponent(0));
+ projected.setComponent(3, B1.getComponent(1));
+ if (this.proj != null)
+ projected = this.proj.projectImage(projected, true);
+ p = new com.vzome.core.construction.FreePoint(projected.scale(this.field['createPower$int'](5)));
+ p.setIndex(12 + k);
+ this.manifestConstruction(p);
+ }
+ ;
+ }
+ this.redo();
+ }
+ }
+ edits.GhostSymmetry24Cell = GhostSymmetry24Cell;
+ GhostSymmetry24Cell["__class"] = "com.vzome.core.edits.GhostSymmetry24Cell";
+ })(edits = core.edits || (core.edits = {}));
+ })(core = vzome.core || (vzome.core = {}));
+ })(vzome = com.vzome || (com.vzome = {}));
+})(com || (com = {}));
(function (com) {
var vzome;
(function (vzome) {
@@ -46644,6 +46728,178 @@ export var com;
})(core = vzome.core || (vzome.core = {}));
})(vzome = com.vzome || (com.vzome = {}));
})(com || (com = {}));
+(function (com) {
+ var vzome;
+ (function (vzome) {
+ var core;
+ (function (core) {
+ var edits;
+ (function (edits) {
+ /**
+ * This is a modern replacement for CommandQuaternionSymmetry, which is a legacy command.
+ * It duplicates the math from that command, but one key change: only parameter objects that lie
+ * in the W=0 plane are transformed. This makes it safe and predictable to use
+ * on objects produced by Polytope4d, which retain their 4D coordinates.
+ *
+ * As with CommandQuaternionSymmetry, all transformed vertices are projected to the W=0 plane
+ * before being added to the model.
+ *
+ * @author vorth
+ * @param {*} editor
+ * @param {com.vzome.core.math.symmetry.QuaternionicSymmetry} left
+ * @param {com.vzome.core.math.symmetry.QuaternionicSymmetry} right
+ * @class
+ * @extends com.vzome.core.editor.api.ChangeManifestations
+ */
+ class Symmetry4d extends com.vzome.core.editor.api.ChangeManifestations {
+ constructor(editor, left, right) {
+ if (((editor != null && (editor.constructor != null && editor.constructor["__interfaces"] != null && editor.constructor["__interfaces"].indexOf("com.vzome.core.editor.api.EditorModel") >= 0)) || editor === null) && ((left != null && left instanceof com.vzome.core.math.symmetry.QuaternionicSymmetry) || left === null) && ((right != null && right instanceof com.vzome.core.math.symmetry.QuaternionicSymmetry) || right === null)) {
+ let __args = arguments;
+ super(editor);
+ if (this.left === undefined) {
+ this.left = null;
+ }
+ if (this.right === undefined) {
+ this.right = null;
+ }
+ this.left = left;
+ this.right = right;
+ }
+ else if (((editor != null && (editor.constructor != null && editor.constructor["__interfaces"] != null && editor.constructor["__interfaces"].indexOf("com.vzome.core.editor.api.EditorModel") >= 0)) || editor === null) && left === undefined && right === undefined) {
+ let __args = arguments;
+ super(editor);
+ if (this.left === undefined) {
+ this.left = null;
+ }
+ if (this.right === undefined) {
+ this.right = null;
+ }
+ this.left = editor.get4dSymmetries().getQuaternionSymmetry("H_4");
+ this.right = this.left;
+ }
+ else
+ throw new Error('invalid overload');
+ }
+ /**
+ *
+ * @param {*} parameters
+ */
+ configure(parameters) {
+ this.left = parameters.get("left");
+ this.right = parameters.get("right");
+ }
+ /**
+ *
+ * @return {string}
+ */
+ getXmlElementName() {
+ return "Symmetry4d";
+ }
+ /*private*/ static inW0hyperplane(v) {
+ if (v.dimension() > 3)
+ return v.getComponent(com.vzome.core.algebra.AlgebraicVector.W4).isZero();
+ else
+ return true;
+ }
+ /**
+ *
+ */
+ perform() {
+ const params = (new java.util.ArrayList());
+ for (let index = this.mSelection.iterator(); index.hasNext();) {
+ let man = index.next();
+ {
+ this.unselect$com_vzome_core_model_Manifestation(man);
+ const cs = man.getConstructions();
+ let useThis = null;
+ if (!cs.hasNext())
+ throw new com.vzome.core.commands.Command.Failure("No construction for this manifestation");
+ for (const iterator = man.getConstructions(); iterator.hasNext();) {
+ {
+ const construction = iterator.next();
+ if (construction != null && construction instanceof com.vzome.core.construction.Point) {
+ const p = construction;
+ if (!Symmetry4d.inW0hyperplane(p.getLocation()))
+ throw new com.vzome.core.commands.Command.Failure("Some ball is not in the W=0 hyperplane.");
+ }
+ else if (construction != null && construction instanceof com.vzome.core.construction.Segment) {
+ const s = construction;
+ if (!Symmetry4d.inW0hyperplane(s.getStart()))
+ throw new com.vzome.core.commands.Command.Failure("Some strut end is not in the W=0 hyperplane.");
+ if (!Symmetry4d.inW0hyperplane(s.getEnd()))
+ throw new com.vzome.core.commands.Command.Failure("Some strut end is not in the W=0 hyperplane.");
+ }
+ else if (construction != null && construction instanceof com.vzome.core.construction.Polygon) {
+ const p = construction;
+ for (let i = 0; i < p.getVertexCount(); i++) {
+ {
+ if (!Symmetry4d.inW0hyperplane(p.getVertex(i))) {
+ throw new com.vzome.core.commands.Command.Failure("Some panel vertex is not in the W=0 hyperplane.");
+ }
+ }
+ ;
+ }
+ }
+ else {
+ throw new com.vzome.core.commands.Command.Failure("Unknown construction type.");
+ }
+ useThis = construction;
+ }
+ ;
+ }
+ if (useThis != null)
+ params.add(useThis);
+ }
+ }
+ this.redo();
+ const leftRoots = this.left.getRoots();
+ const rightRoots = this.right.getRoots();
+ for (let index = 0; index < leftRoots.length; index++) {
+ let leftRoot = leftRoots[index];
+ {
+ for (let index1 = 0; index1 < rightRoots.length; index1++) {
+ let rightRoot = rightRoots[index1];
+ {
+ for (let index2 = params.iterator(); index2.hasNext();) {
+ let construction = index2.next();
+ {
+ let result = null;
+ if (construction != null && construction instanceof com.vzome.core.construction.Point) {
+ result = new com.vzome.core.construction.PointRotated4D(leftRoot, rightRoot, construction);
+ }
+ else if (construction != null && construction instanceof com.vzome.core.construction.Segment) {
+ result = new com.vzome.core.construction.SegmentRotated4D(leftRoot, rightRoot, construction);
+ }
+ else if (construction != null && construction instanceof com.vzome.core.construction.Polygon) {
+ result = new com.vzome.core.construction.PolygonRotated4D(leftRoot, rightRoot, construction);
+ }
+ else {
+ }
+ if (result == null)
+ continue;
+ this.manifestConstruction(result);
+ }
+ }
+ }
+ }
+ }
+ }
+ this.redo();
+ }
+ rotateAndProject(loc3d, leftQuaternion, rightQuaternion) {
+ let loc = loc3d.inflateTo4d$boolean(true);
+ loc = rightQuaternion.leftMultiply(loc);
+ loc = leftQuaternion.rightMultiply(loc);
+ loc = loc.projectTo3d(true);
+ return new com.vzome.core.construction.FreePoint(loc);
+ }
+ }
+ edits.Symmetry4d = Symmetry4d;
+ Symmetry4d["__class"] = "com.vzome.core.edits.Symmetry4d";
+ })(edits = core.edits || (core.edits = {}));
+ })(core = vzome.core || (vzome.core = {}));
+ })(vzome = com.vzome || (com.vzome = {}));
+})(com || (com = {}));
(function (com) {
var vzome;
(function (vzome) {
@@ -47367,6 +47623,86 @@ export var com;
})(core = vzome.core || (vzome.core = {}));
})(vzome = com.vzome || (com.vzome = {}));
})(com || (com = {}));
+(function (com) {
+ var vzome;
+ (function (vzome) {
+ var core;
+ (function (core) {
+ var edits;
+ (function (edits) {
+ class RealizeMetaParts extends com.vzome.core.editor.api.ChangeManifestations {
+ constructor(editor) {
+ super(editor);
+ }
+ /**
+ *
+ */
+ perform() {
+ let scale = null;
+ for (let index = this.mSelection.iterator(); index.hasNext();) {
+ let man = index.next();
+ {
+ this.unselect$com_vzome_core_model_Manifestation(man);
+ const rm = man.getRenderedObject();
+ if (rm != null) {
+ const shape = rm.getShape();
+ if (scale == null) {
+ const field = shape.getField();
+ scale = field['createPower$int'](5);
+ }
+ const orientation = rm.getOrientation();
+ const vertexList = shape.getVertexList();
+ for (let index = shape.getVertexList().iterator(); index.hasNext();) {
+ let vertex = index.next();
+ {
+ const vertexPt = this.transformVertex(vertex, man.getLocation(), scale, orientation);
+ this.select$com_vzome_core_model_Manifestation(this.manifestConstruction(vertexPt));
+ }
+ }
+ for (let index = shape.getFaceSet().iterator(); index.hasNext();) {
+ let face = index.next();
+ {
+ const vertices = (s => { let a = []; while (s-- > 0)
+ a.push(null); return a; })(face.size());
+ for (let i = 0; i < vertices.length; i++) {
+ {
+ const vertexIndex = face.getVertex(i);
+ const vertex = vertexList.get(vertexIndex);
+ vertices[i] = this.transformVertex(vertex, man.getLocation(), scale, orientation);
+ }
+ ;
+ }
+ const polygon = new com.vzome.core.construction.PolygonFromVertices(vertices);
+ this.select$com_vzome_core_model_Manifestation(this.manifestConstruction(polygon));
+ }
+ }
+ }
+ }
+ }
+ this.redo();
+ }
+ /*private*/ transformVertex(vertex, offset, scale, orientation) {
+ if (orientation != null)
+ vertex = orientation.timesColumn(vertex);
+ if (offset != null)
+ vertex = vertex.plus(offset);
+ return new com.vzome.core.construction.FreePoint(vertex.scale(scale));
+ }
+ /**
+ *
+ * @return {string}
+ */
+ getXmlElementName() {
+ return RealizeMetaParts.NAME;
+ }
+ }
+ RealizeMetaParts.NAME = "realizeMetaParts";
+ edits.RealizeMetaParts = RealizeMetaParts;
+ RealizeMetaParts["__class"] = "com.vzome.core.edits.RealizeMetaParts";
+ })(edits = core.edits || (core.edits = {}));
+ })(core = vzome.core || (vzome.core = {}));
+ })(vzome = com.vzome || (com.vzome = {}));
+})(com || (com = {}));
(function (com) {
var vzome;
(function (vzome) {
@@ -47702,6 +48038,10 @@ export var com;
this.__parent = __parent;
}
/* Default method injected from com.vzome.core.editor.api.OrbitSource */
+ getZone(orbit, orientation) {
+ return this.getSymmetry().getDirection(orbit).getAxis(com.vzome.core.math.symmetry.Symmetry.PLUS, orientation);
+ }
+ /* Default method injected from com.vzome.core.editor.api.OrbitSource */
getEmbedding() {
const symmetry = this.getSymmetry();
const field = symmetry.getField();
@@ -47729,10 +48069,6 @@ export var com;
return this.getOrientations(false);
}
/* Default method injected from com.vzome.core.editor.api.OrbitSource */
- getZone(orbit, orientation) {
- return this.getSymmetry().getDirection(orbit).getAxis(com.vzome.core.math.symmetry.Symmetry.PLUS, orientation);
- }
- /* Default method injected from com.vzome.core.editor.api.OrbitSource */
getOrientations(rowMajor) {
if (((typeof rowMajor === 'boolean') || rowMajor === null)) {
let __args = arguments;
@@ -48358,6 +48694,61 @@ export var com;
})(core = vzome.core || (vzome.core = {}));
})(vzome = com.vzome || (com.vzome = {}));
})(com || (com = {}));
+(function (com) {
+ var vzome;
+ (function (vzome) {
+ var core;
+ (function (core) {
+ var edits;
+ (function (edits) {
+ class DodecagonSymmetry extends com.vzome.core.editor.api.ChangeManifestations {
+ constructor(editor) {
+ super(editor);
+ if (this.center === undefined) {
+ this.center = null;
+ }
+ if (this.symmetry === undefined) {
+ this.symmetry = null;
+ }
+ this.center = editor.getCenterPoint();
+ this.symmetry = editor['getSymmetrySystem$']().getSymmetry();
+ }
+ /**
+ *
+ */
+ perform() {
+ const transform = new com.vzome.core.construction.SymmetryTransformation(this.symmetry, 1, this.center);
+ for (let index = this.mSelection.iterator(); index.hasNext();) {
+ let man = index.next();
+ {
+ let c = man.getFirstConstruction();
+ for (let i = 0; i < 11; i++) {
+ {
+ c = transform.transform$com_vzome_core_construction_Construction(c);
+ if (c == null)
+ continue;
+ this.select$com_vzome_core_model_Manifestation(this.manifestConstruction(c));
+ }
+ ;
+ }
+ }
+ }
+ this.redo();
+ }
+ /**
+ *
+ * @return {string}
+ */
+ getXmlElementName() {
+ return "DodecagonSymmetry";
+ }
+ }
+ edits.DodecagonSymmetry = DodecagonSymmetry;
+ DodecagonSymmetry["__class"] = "com.vzome.core.edits.DodecagonSymmetry";
+ })(edits = core.edits || (core.edits = {}));
+ })(core = vzome.core || (vzome.core = {}));
+ })(vzome = com.vzome || (com.vzome = {}));
+})(com || (com = {}));
(function (com) {
var vzome;
(function (vzome) {
diff --git a/online/src/worker/legacy/exporters.js b/online/src/worker/legacy/exporters.js
index aeec13234..e7d158997 100644
--- a/online/src/worker/legacy/exporters.js
+++ b/online/src/worker/legacy/exporters.js
@@ -10,7 +10,7 @@ const exporterClasses = {
'off' : 'OffExporter',
'ply' : 'PlyExporter',
'vrml' : 'VRMLExporter',
- 'pov' : 'PovRayExporter',
+ 'pov' : 'POVRayExporter',
'partgeom' : 'PartGeometryExporter',
'openscad' : 'OpenScadExporter',
'math' : 'MathTableExporter',
@@ -29,44 +29,6 @@ const exporterClasses = {
// 'FORMAT' : 'VefModelExporter',
}
-export const export3d = ( scene, configuration ) =>
-{
- const { format, height, width } = configuration;
- const { renderedModel } = scene;
- const exporter = new com.vzome.core.exporters[ exporterClasses[ format ] ]();
- const out = new java.io.StringWriter();
- exporter .exportGeometry( renderedModel, null, out, height, width );
- return out.toString();
-}
-
-const createDocument = ( legacyDesign, camera, lighting ) =>
-{
- // TODO
- return {
- // CameraIntf getCameraModel();
-
- // Lights getSceneLighting();
-
- // RenderedModel getRenderedModel();
-
- // ToolsModel getToolsModel();
-
- // Element getDetailsXml( Document dom, boolean b );
-
- // EditorModel getEditorModel();
- }
-}
-
-export const export3dDocument = ( legacyDesign, camera, lighting, configuration ) =>
-{
- const { format, height, width } = configuration;
- const exporter = new com.vzome.core.exporters[ exporterClasses[ format ] ]();
- const out = new java.io.StringWriter();
- const document = createDocument( legacyDesign, camera, lighting );
- exporter .exportDocument( document, null, out, height, width );
- return out.toString();
-}
-
const parseColor = input =>
{
const m = input .match( /^#([0-9a-f]{6})$/i )[1];
@@ -86,7 +48,9 @@ const createLights = lighting =>
const lights = new com.vzome.core.viewing.Lights();
lights .setBackgroundColor( parseColor( backgroundColor ) );
lights .setAmbientColor( parseColor( ambientColor ) );
- for ( const { direction: [x,y,z], color } of directionalLights ) {
+ for ( const { worldDirection: [x,y,z], color } of directionalLights ) {
+ // Because we are using worldDirection rather than direction, these vectors are in world coordinates already.
+ // Apparently, POVRayExporter is the only exporter that uses directional lights.
lights .addDirectionLight( parseColor( color ), new com.vzome.core.math.RealVector( x, y, z ) );
}
return lights;
@@ -110,6 +74,49 @@ const createProjectionMatrix = ( camera, aspectRatio ) =>
return com.vzome.core.math.RealMatrix4.perspective( fovX, aspectRatio, near, far );
}
+const createCamera = ( camera ) =>
+{
+ const { distance, width, perspective, lookAt, up, lookDir, magnification } = camera; // This camera always comes from the client context
+ const halfX = width / 2;
+ const fov = 2 * Math.atan( halfX / distance );
+ let [ x, y, z ] = lookAt;
+ const lookAtRV = new com.vzome.core.math.RealVector( x, y, z );
+ [ x, y, z ] = up;
+ const upRV = new com.vzome.core.math.RealVector( x, y, z );
+ [ x, y, z ] = lookDir;
+ const lookDirRV = new com.vzome.core.math.RealVector( x, y, z );
+ return {
+ isPerspective: () => perspective,
+ getFieldOfView: () => fov,
+ getViewDistance: () => distance,
+ getMagnification: () => magnification,
+ getLookAtPointRV: () => lookAtRV,
+ getLookDirectionRV: () => lookDirRV,
+ getUpDirectionRV: () => upRV,
+
+ // POVRayExporter will call this to map light directions to world coordinates, in the Java code,
+ // but here in Javascript our light directions are *already* in world coordinates.
+ mapViewToWorld: rv => rv,
+ }
+}
+
+const createDocument = ( legacyDesign, camera, lighting ) =>
+ {
+ const { renderedModel, editor, toolsModel } = legacyDesign;
+ const lights = createLights( lighting );
+ const cameraModel = createCamera( camera );
+ return {
+ getCameraModel: () => cameraModel,
+ getSceneLighting: () => lights,
+ getRenderedModel: () => renderedModel,
+ getToolsModel: () => toolsModel,
+ getEditorModel: () => editor,
+ getDetailsXml: ( dom, deep ) => null, // TODO: implement this so more exporters work
+ }
+ }
+
+////////////////////////////////////////////// main entry points:
+
export const export2d = ( scene, configuration ) =>
{
const { format, height, width, useShapes, drawOutlines, monochrome, showBackground, useLighting } = configuration;
@@ -123,4 +130,26 @@ export const export2d = ( scene, configuration ) =>
const out = new java.io.StringWriter();
exporter .export( snapshot, out, drawOutlines, monochrome, showBackground );
return out.toString();
-}
\ No newline at end of file
+}
+
+export const export3d = ( scene, configuration ) =>
+ {
+ const { format, height, width } = configuration;
+ const { renderedModel } = scene;
+ const exporter = new com.vzome.core.exporters[ exporterClasses[ format ] ]();
+ const out = new java.io.StringWriter();
+ exporter .exportGeometry( renderedModel, null, out, height, width );
+ return out.toString();
+ }
+
+export const export3dDocument = ( legacyDesign, camera, lighting, configuration ) =>
+ {
+ const { format, height, width } = configuration;
+ const exporter = new com.vzome.core.exporters[ exporterClasses[ format ] ]();
+ const out = new java.io.StringWriter();
+ // Satisfy the DocumentIntf contract required by DocumentExporter
+ const document = createDocument( legacyDesign, camera, lighting );
+ exporter .exportDocument( document, null, out, height, width );
+ return out.toString();
+ }
+
\ No newline at end of file
diff --git a/online/src/worker/legacy/ts/.tsc-rootfile.ts b/online/src/worker/legacy/ts/.tsc-rootfile.ts
new file mode 100644
index 000000000..066587b5e
--- /dev/null
+++ b/online/src/worker/legacy/ts/.tsc-rootfile.ts
@@ -0,0 +1,2 @@
+// Root empty file generated by JSweet to avoid tsc behavior, which
+// does not preserve the entire file hierarchy for empty directories.
\ No newline at end of file
diff --git a/online/src/worker/legacy/ts/com/vzome/api/Tool.ts b/online/src/worker/legacy/ts/com/vzome/api/Tool.ts
new file mode 100644
index 000000000..3a005677f
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/api/Tool.ts
@@ -0,0 +1,59 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.api {
+ export interface Tool {
+ apply(selectInputs: boolean, deleteInputs: boolean, createOutputs: boolean, selectOutputs: boolean, copyColors: boolean);
+
+ selectParameters();
+
+ isPredefined(): boolean;
+
+ getId(): string;
+
+ getCategory(): string;
+
+ getLabel(): string;
+
+ setLabel(label: string);
+
+ isSelectInputs(): boolean;
+
+ isDeleteInputs(): boolean;
+
+ isCopyColors(): boolean;
+
+ setInputBehaviors(selectInputs: boolean, deleteInputs: boolean);
+
+ setCopyColors(value: boolean);
+
+ isHidden(): boolean;
+
+ setHidden(hidden: boolean);
+ }
+
+ export namespace Tool {
+
+ export enum Kind {
+ SYMMETRY, TRANSFORM, LINEAR_MAP
+ }
+
+ export interface Factory {
+ addListener(listener: java.beans.PropertyChangeListener);
+
+ createTool(): com.vzome.api.Tool;
+
+ isEnabled(): boolean;
+
+ getToolTip(): string;
+
+ getLabel(): string;
+
+ getId(): string;
+ }
+
+ export interface Source {
+ getPredefinedTool(id: string): com.vzome.api.Tool;
+ }
+ }
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/AbstractAlgebraicField.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/AbstractAlgebraicField.ts
new file mode 100644
index 000000000..40b7c912d
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/AbstractAlgebraicField.ts
@@ -0,0 +1,886 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export abstract class AbstractAlgebraicField implements com.vzome.core.algebra.AlgebraicField {
+ /* Default method injected from com.vzome.core.algebra.AlgebraicField */
+ supportsSubfield(fieldName: string): boolean {
+ if (fieldName === this.getName())return true;
+ return (fieldName === ("golden")) && this.getGoldenRatio() != null;
+ }
+ abstract multiply(v1: com.vzome.core.algebra.BigRational[], v2: com.vzome.core.algebra.BigRational[]): com.vzome.core.algebra.BigRational[];
+
+ abstract evaluateNumber(factors: com.vzome.core.algebra.BigRational[]): number;
+
+ abstract scaleBy(factors: com.vzome.core.algebra.BigRational[], whichIrrational: number): com.vzome.core.algebra.BigRational[];
+
+ public abstract getCoefficients(): number[];
+
+ /**
+ * The integers should be the same indices used by getUnitTerm().
+ * Subclasses must override to usefully participate in the generation
+ * of AlgebraicSeries.
+ * @param {*} input
+ * @return
+ * @return {*}
+ */
+ public recurrence(input: java.util.List): java.util.List {
+ return input;
+ }
+
+ normalize(factors: com.vzome.core.algebra.BigRational[]) {
+ }
+
+ /**
+ *
+ * @return {number}
+ */
+ public getOrder(): number {
+ return this.order;
+ }
+
+ /**
+ *
+ * @return {number}
+ */
+ public getNumIrrationals(): number {
+ return this.order - 1;
+ }
+
+ /**
+ *
+ * @return {boolean}
+ */
+ public scale4dRoots(): boolean {
+ return false;
+ }
+
+ /**
+ *
+ * @return {boolean}
+ */
+ public doubleFrameVectors(): boolean {
+ return false;
+ }
+
+ /**
+ *
+ * @param {string} name
+ * @return {*}
+ */
+ public getNumberByName(name: string): com.vzome.core.algebra.AlgebraicNumber {
+ switch((name)) {
+ case "zero":
+ return this.zero();
+ case "one":
+ return this.one();
+ case "phi":
+ case "\u03c6":
+ return this.getGoldenRatio();
+ case "\u221a5":
+ case "root5":
+ case "sqrt5":
+ {
+ const n: com.vzome.core.algebra.AlgebraicNumber = this.getGoldenRatio();
+ return n == null ? null : n['plus$com_vzome_core_algebra_AlgebraicNumber'](n)['minus$com_vzome_core_algebra_AlgebraicNumber'](this.one());
+ };
+ case "\u221a8":
+ case "root8":
+ case "sqrt8":
+ {
+ const n: com.vzome.core.algebra.AlgebraicNumber = this.getNumberByName("sqrt2");
+ return n == null ? null : n['times$com_vzome_core_algebra_AlgebraicNumber'](this.createRational$long(2));
+ };
+ default:
+ for(let format: number = AbstractAlgebraicField.DEFAULT_FORMAT; format <= AbstractAlgebraicField.EXPRESSION_FORMAT; format++) {{
+ for(let i: number = 1; i < this.getOrder(); i++) {{
+ if (this['getIrrational$int$int'](i, format) === name){
+ return this.getUnitTerm(i);
+ }
+ };}
+ };}
+ }
+ return null;
+ }
+
+ public getIrrational$int(i: number): string {
+ return this['getIrrational$int$int'](i, AbstractAlgebraicField.DEFAULT_FORMAT);
+ }
+
+ name: string;
+
+ /*private*/ order: number;
+
+ /*private*/ __hashCode: number;
+
+ __one: com.vzome.core.algebra.AlgebraicNumber;
+
+ __zero: com.vzome.core.algebra.AlgebraicNumber;
+
+ /**
+ * Positive powers of the irrationals.
+ */
+ /*private*/ positivePowers: java.util.ArrayList[];
+
+ /**
+ * Negative powers of the irrationals.
+ */
+ /*private*/ negativePowers: java.util.ArrayList[];
+
+ static SMALL_SERIES_THRESHOLD: number = 30.0;
+
+ /*private*/ smallSeries: com.vzome.core.algebra.AlgebraicSeries;
+
+ numberFactory: com.vzome.core.algebra.AlgebraicNumberFactory;
+
+ public constructor(name: string, order: number, factory: com.vzome.core.algebra.AlgebraicNumberFactory) {
+ if (this.name === undefined) { this.name = null; }
+ if (this.order === undefined) { this.order = 0; }
+ if (this.__hashCode === undefined) { this.__hashCode = null; }
+ if (this.__one === undefined) { this.__one = null; }
+ if (this.__zero === undefined) { this.__zero = null; }
+ if (this.positivePowers === undefined) { this.positivePowers = null; }
+ if (this.negativePowers === undefined) { this.negativePowers = null; }
+ if (this.smallSeries === undefined) { this.smallSeries = null; }
+ if (this.numberFactory === undefined) { this.numberFactory = null; }
+ this.name = name;
+ this.order = order;
+ this.numberFactory = factory;
+ this.__zero = this.numberFactory.createRational(this, 0, 1);
+ this.__one = this.numberFactory.createRational(this, 1, 1);
+ this.positivePowers = (s => { let a=[]; while(s-->0) a.push(null); return a; })(order - 1);
+ this.negativePowers = (s => { let a=[]; while(s-->0) a.push(null); return a; })(order - 1);
+ }
+
+ /*private*/ initSmallSeries() {
+ if (this.smallSeries == null){
+ this.smallSeries = this.generateSeries(AbstractAlgebraicField.SMALL_SERIES_THRESHOLD);
+ }
+ }
+
+ public nearestAlgebraicNumber(target: number): com.vzome.core.algebra.AlgebraicNumber {
+ this.initSmallSeries();
+ return this.smallSeries.nearestAlgebraicNumber(target);
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.math.RealVector} target
+ * @return {com.vzome.core.algebra.AlgebraicVector}
+ */
+ public nearestAlgebraicVector(target: com.vzome.core.math.RealVector): com.vzome.core.algebra.AlgebraicVector {
+ this.initSmallSeries();
+ return new com.vzome.core.algebra.AlgebraicVector(this.smallSeries.nearestAlgebraicNumber(target.x), this.smallSeries.nearestAlgebraicNumber(target.y), this.smallSeries.nearestAlgebraicNumber(target.z));
+ }
+
+ /**
+ *
+ * @return {string}
+ */
+ public getName(): string {
+ return this.name;
+ }
+
+ /**
+ *
+ * @return {string}
+ */
+ public toString(): string {
+ return this.getName();
+ }
+
+ /**
+ *
+ * @return {number}
+ */
+ public hashCode(): number {
+ if (this.__hashCode == null){
+ const prime: number = 43;
+ this.__hashCode = 7;
+ const coefficients: number[] = this.getCoefficients();
+ for(let i: number = 0; i < coefficients.length; i++) {{
+ const coefficient: number = coefficients[i];
+ this.__hashCode = prime * this.__hashCode + /* hashCode */(((o: any) => { if (o.hashCode) { return o.hashCode(); } else { return o.toString().split('').reduce((prevHash, currVal) => (((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0); }})(coefficient));
+ };}
+ }
+ return this.__hashCode;
+ }
+
+ /**
+ * With the use of parameterized fields, it's possible for two fields
+ * of different classes to be equal
+ * or for two fields of the same class to not be equal.
+ * For example RootTwoField equals SqrtField(2)
+ * but SqrtField(2) does not equal SqrtField(3).
+ * Similarly, PolygonField(4) equals SqrtField(2)
+ * and PolygonField(6) equals SqrtField(3).
+ *
+ * @param {*} obj
+ * @return {boolean}
+ */
+ public equals(obj: any): boolean {
+ if (this === obj){
+ return true;
+ }
+ if (obj == null){
+ return false;
+ }
+ if (!(obj != null && obj instanceof com.vzome.core.algebra.AbstractAlgebraicField)){
+ return false;
+ }
+ const that: AbstractAlgebraicField = obj;
+ if (this.getName() === that.getName()){
+ return true;
+ }
+ if (this.getOrder() !== that.getOrder()){
+ return false;
+ }
+ const thisCoefficients: number[] = this.getCoefficients();
+ const thatCoefficients: number[] = that.getCoefficients();
+ for(let i: number = 0; i < thisCoefficients.length; i++) {{
+ if (thisCoefficients[i] - thatCoefficients[i] !== 0.0){
+ return false;
+ }
+ };}
+ return true;
+ }
+
+ /**
+ * This method is intended to allow subclasses to intercept a 4 element int array
+ * representing the numerators and denominators of a pair of terms (units and phis)
+ * from the golden field and remap them as needed for that field.
+ * Otherwise, the terms are returned unchanged.
+ * @param terms
+ * @return
+ * @param {long[]} pairs
+ * @return {long[]}
+ */
+ convertGoldenNumberPairs(pairs: number[]): number[] {
+ if (pairs.length === 2 * this.order)return pairs; else {
+ const newPairs: number[] = (s => { let a=[]; while(s-->0) a.push(0); return a; })(2 * this.order);
+ for(let i: number = 0; i < this.order; i++) {{
+ newPairs[2 * i + 0] = (i >= 2) ? 0 : pairs[2 * i + 0];
+ newPairs[2 * i + 1] = (i >= 2) ? 1 : pairs[2 * i + 1];
+ };}
+ return newPairs;
+ }
+ }
+
+ public createAlgebraicNumber$int_A(terms: number[]): com.vzome.core.algebra.AlgebraicNumber {
+ return this.numberFactory.createAlgebraicNumber(this, terms, 1);
+ }
+
+ /**
+ * Generates an AlgebraicNumber from a "trailing divisor" int array representation.
+ * @param {int[]} trailingDivisorForm numerators trailed by a common denominator for all numerators
+ * @return
+ * @return {*}
+ */
+ public createAlgebraicNumberFromTD(trailingDivisorForm: number[]): com.vzome.core.algebra.AlgebraicNumber {
+ let terms: number = trailingDivisorForm.length - 1;
+ if (terms === 2 && this.getOrder() > 2){
+ let pairs: number[] = (s => { let a=[]; while(s-->0) a.push(0); return a; })(2 * terms);
+ const divisor: number = trailingDivisorForm[terms];
+ for(let i: number = 0; i < terms; i++) {{
+ pairs[2 * i + 0] = trailingDivisorForm[i];
+ pairs[2 * i + 1] = divisor;
+ };}
+ pairs = this.convertGoldenNumberPairs(pairs);
+ terms = (pairs.length / 2|0);
+ trailingDivisorForm = (s => { let a=[]; while(s-->0) a.push(0); return a; })(terms + 1);
+ trailingDivisorForm[terms] = (pairs[1]|0);
+ for(let i: number = 0; i < (pairs.length / 2|0); i++) {{
+ trailingDivisorForm[i] = (pairs[2 * i]|0);
+ };}
+ }
+ return this.numberFactory.createAlgebraicNumberFromTD(this, trailingDivisorForm);
+ }
+
+ public createAlgebraicNumber$int_A$int(numerators: number[], denominator: number): com.vzome.core.algebra.AlgebraicNumber {
+ return this.numberFactory.createAlgebraicNumber(this, numerators, denominator);
+ }
+
+ public createAlgebraicNumber$int$int$int$int(ones: number, irrat: number, denominator: number, scalePower: number): com.vzome.core.algebra.AlgebraicNumber {
+ const factors: number[] = (s => { let a=[]; while(s-->0) a.push(0); return a; })(this.order + 1);
+ factors[0] = ones;
+ factors[1] = irrat;
+ for(let i: number = 2; i < this.order; i++) {{
+ factors[i] = 0;
+ };}
+ factors[this.order] = denominator;
+ const result: com.vzome.core.algebra.AlgebraicNumber = this.numberFactory.createAlgebraicNumberFromTD(this, factors);
+ if (scalePower !== 0){
+ const multiplier: com.vzome.core.algebra.AlgebraicNumber = this.createPower$int(scalePower);
+ return result['times$com_vzome_core_algebra_AlgebraicNumber'](multiplier);
+ } else return result;
+ }
+
+ /**
+ *
+ * @param {number} ones
+ * @param {number} irrat
+ * @param {number} denominator
+ * @param {number} scalePower
+ * @return {*}
+ */
+ public createAlgebraicNumber(ones?: any, irrat?: any, denominator?: any, scalePower?: any): com.vzome.core.algebra.AlgebraicNumber {
+ if (((typeof ones === 'number') || ones === null) && ((typeof irrat === 'number') || irrat === null) && ((typeof denominator === 'number') || denominator === null) && ((typeof scalePower === 'number') || scalePower === null)) {
+ return this.createAlgebraicNumber$int$int$int$int(ones, irrat, denominator, scalePower);
+ } else if (((ones != null && ones instanceof Array && (ones.length == 0 || ones[0] == null ||(typeof ones[0] === 'number'))) || ones === null) && ((typeof irrat === 'number') || irrat === null) && denominator === undefined && scalePower === undefined) {
+ return this.createAlgebraicNumber$int_A$int(ones, irrat);
+ } else if (((ones != null && ones instanceof Array && (ones.length == 0 || ones[0] == null ||(typeof ones[0] === 'number'))) || ones === null) && irrat === undefined && denominator === undefined && scalePower === undefined) {
+ return this.createAlgebraicNumber$int_A(ones);
+ } else throw new Error('invalid overload');
+ }
+
+ /**
+ * The golden ratio (and thus icosahedral symmetry and related tools)
+ * can be generated by some fields even though it's not one of their irrational coefficients.
+ * For example, SqrtField(5) and PolygonField(10) can both generate the golden ratio
+ * so they can support icosa symmetry and related tools.
+ * In some such cases, the resulting AlgebraicNumber
+ * may have multiple terms and/or factors other than one.
+ *
+ * @return {*} An AlgebraicNumber which evaluates to the golden ratio, or null if not possible in this field.
+ */
+ public getGoldenRatio(): com.vzome.core.algebra.AlgebraicNumber {
+ return null;
+ }
+
+ public createPower$int(power: number): com.vzome.core.algebra.AlgebraicNumber {
+ return this.createPower$int$int(power, 1);
+ }
+
+ public createPower$int$int(power: number, irr: number): com.vzome.core.algebra.AlgebraicNumber {
+ const one: com.vzome.core.algebra.AlgebraicNumber = this.one();
+ if (power === 0 || irr === 0)return one;
+ irr -= 1;
+ if (power > 0){
+ if (this.positivePowers[irr] == null)this.positivePowers[irr] = (new java.util.ArrayList(8));
+ if (power >= this.positivePowers[irr].size()){
+ if (this.positivePowers[irr].isEmpty()){
+ this.positivePowers[irr].add(one);
+ this.positivePowers[irr].add(this.getUnitTerm(irr + 1));
+ }
+ const size: number = this.positivePowers[irr].size();
+ const irrat: com.vzome.core.algebra.AlgebraicNumber = this.positivePowers[irr].get(1);
+ let last: com.vzome.core.algebra.AlgebraicNumber = this.positivePowers[irr].get(size - 1);
+ for(let i: number = size; i <= power; i++) {{
+ const next: com.vzome.core.algebra.AlgebraicNumber = last['times$com_vzome_core_algebra_AlgebraicNumber'](irrat);
+ this.positivePowers[irr].add(next);
+ last = next;
+ };}
+ }
+ return this.positivePowers[irr].get(power);
+ } else {
+ power = -power;
+ if (this.negativePowers[irr] == null)this.negativePowers[irr] = (new java.util.ArrayList(8));
+ if (power >= this.negativePowers[irr].size()){
+ if (this.negativePowers[irr].isEmpty()){
+ this.negativePowers[irr].add(one);
+ this.negativePowers[irr].add(this.getUnitTerm(irr + 1).reciprocal());
+ }
+ const size: number = this.negativePowers[irr].size();
+ const irrat: com.vzome.core.algebra.AlgebraicNumber = this.negativePowers[irr].get(1);
+ let last: com.vzome.core.algebra.AlgebraicNumber = this.negativePowers[irr].get(size - 1);
+ for(let i: number = size; i <= power; i++) {{
+ const next: com.vzome.core.algebra.AlgebraicNumber = last['times$com_vzome_core_algebra_AlgebraicNumber'](irrat);
+ this.negativePowers[irr].add(next);
+ last = next;
+ };}
+ }
+ return this.negativePowers[irr].get(power);
+ }
+ }
+
+ /**
+ *
+ * @param {number} power
+ * @param {number} irr
+ * @return {*}
+ */
+ public createPower(power?: any, irr?: any): com.vzome.core.algebra.AlgebraicNumber {
+ if (((typeof power === 'number') || power === null) && ((typeof irr === 'number') || irr === null)) {
+ return this.createPower$int$int(power, irr);
+ } else if (((typeof power === 'number') || power === null) && irr === undefined) {
+ return this.createPower$int(power);
+ } else throw new Error('invalid overload');
+ }
+
+ public createRational$long(wholeNumber: number): com.vzome.core.algebra.AlgebraicNumber {
+ return this.numberFactory.createRational(this, wholeNumber, 1);
+ }
+
+ public createRational$long$long(numerator: number, denominator: number): com.vzome.core.algebra.AlgebraicNumber {
+ return this.numberFactory.createRational(this, numerator, denominator);
+ }
+
+ /**
+ * @param {number} numerator
+ * @param {number} denominator
+ * @return {*} AlgebraicNumber
+ */
+ public createRational(numerator?: any, denominator?: any): com.vzome.core.algebra.AlgebraicNumber {
+ if (((typeof numerator === 'number') || numerator === null) && ((typeof denominator === 'number') || denominator === null)) {
+ return this.createRational$long$long(numerator, denominator);
+ } else if (((typeof numerator === 'number') || numerator === null) && denominator === undefined) {
+ return this.createRational$long(numerator);
+ } else throw new Error('invalid overload');
+ }
+
+ /**
+ * @return {*} The AlgebraicNumber to be use for the Chord Ratio construction in the given field.
+ * This method can be used to generalize an AffinePolygon tool and a PolygonalAntiprismSymmetry.
+ * This base class returns one, which is the scalar for an affine square and works in any field.
+ * Derived classes should override this method if they can be used to generate any other affine polygon.
+ */
+ public getAffineScalar(): com.vzome.core.algebra.AlgebraicNumber {
+ return this.__one;
+ }
+
+ /**
+ * @param {number} n specifies the ordinal of the term in the AlgebraicNumber which will be set to one.
+ * When {@code n == 0}, the result is the same as {@code createRational(1)}.
+ * When {@code n == 1}, the result is the same as {@code createPower(1)}.
+ * When {@code n < 0}, the result will be {@code zero()}.
+ * When {@code n >= getOrder()}, an IndexOutOfBoundsException will be thrown.
+ * @return {*} an AlgebraicNumber with the factor specified by {@code n} set to one.
+ */
+ public getUnitTerm(n: number): com.vzome.core.algebra.AlgebraicNumber {
+ if (n < 0){
+ return this.zero();
+ }
+ const factors: number[] = this.zero().toTrailingDivisor();
+ factors[n] = factors[factors.length - 1];
+ return this.numberFactory.createAlgebraicNumberFromTD(this, factors);
+ }
+
+ /**
+ * Drop one coordinate from the 4D vector. If wFirst (the usual), then drop
+ * the first coordinate, taking the "imaginary part" of the vector. If
+ * !wFirst (for old VEF import, etc.), drop the last coordinate.
+ *
+ * @param {com.vzome.core.algebra.AlgebraicVector} source
+ * @param {boolean} wFirst
+ * @return
+ * @return {com.vzome.core.algebra.AlgebraicVector}
+ */
+ public projectTo3d(source: com.vzome.core.algebra.AlgebraicVector, wFirst: boolean): com.vzome.core.algebra.AlgebraicVector {
+ if (source.dimension() === 3)return source; else {
+ const result: com.vzome.core.algebra.AlgebraicVector = this.origin(3);
+ for(let i: number = 0; i < 3; i++) {result.setComponent(i, source.getComponent(wFirst ? i + 1 : i));}
+ return result;
+ }
+ }
+
+ /**
+ *
+ * @param {number} dims
+ * @return {com.vzome.core.algebra.AlgebraicVector}
+ */
+ public origin(dims: number): com.vzome.core.algebra.AlgebraicVector {
+ return new com.vzome.core.algebra.AlgebraicVector(this, dims);
+ }
+
+ /**
+ *
+ * @param {number} dims
+ * @param {number} axis
+ * @return {com.vzome.core.algebra.AlgebraicVector}
+ */
+ public basisVector(dims: number, axis: number): com.vzome.core.algebra.AlgebraicVector {
+ const result: com.vzome.core.algebra.AlgebraicVector = this.origin(dims);
+ return result.setComponent(axis, this.one());
+ }
+
+ reciprocal(fieldElement: com.vzome.core.algebra.BigRational[]): com.vzome.core.algebra.BigRational[] {
+ const length: number = fieldElement.length;
+ const representation: com.vzome.core.algebra.BigRational[][] = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return null; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([length, length]);
+ let isZero: boolean = true;
+ for(let i: number = 0; i < length; i++) {{
+ isZero = isZero && fieldElement[i].isZero();
+ representation[0][i] = fieldElement[i];
+ };}
+ if (isZero)throw new java.lang.RuntimeException("Denominator is zero");
+ for(let j: number = 1; j < length; j++) {{
+ const column: com.vzome.core.algebra.BigRational[] = this.scaleBy(fieldElement, j);
+ java.lang.System.arraycopy(column, 0, representation[j], 0, length);
+ };}
+ const reciprocal: com.vzome.core.algebra.BigRational[][] = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return null; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([length, length]);
+ for(let j: number = 0; j < length; j++) {{
+ for(let i: number = 0; i < length; i++) {{
+ reciprocal[j][i] = (i === j) ? this.numberFactory.one() : this.numberFactory.zero();
+ };}
+ };}
+ const rank: number = com.vzome.core.algebra.Fields.gaussJordanReduction$com_vzome_core_algebra_Fields_Element_A_A$com_vzome_core_algebra_Fields_Element_A_A(representation, reciprocal);
+ const reciprocalFactors: com.vzome.core.algebra.BigRational[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(length);
+ java.lang.System.arraycopy(reciprocal[0], 0, reciprocalFactors, 0, length);
+ return (rank === length) ? reciprocalFactors : this.onReciprocalRankDeficient(rank, reciprocal, reciprocalFactors);
+ }
+
+ /**
+ * Subclasses can overloading this method to handle special cases. (e.g. SqrtField of a perfect square)
+ * @param {number} rank
+ * @param {com.vzome.core.algebra.BigRational[][]} reciprocal
+ * @param {com.vzome.core.algebra.BigRational[]} reciprocalFactors
+ * @throws IllegalStateException
+ * @return {com.vzome.core.algebra.BigRational[]}
+ */
+ onReciprocalRankDeficient(rank: number, reciprocal: com.vzome.core.algebra.BigRational[][], reciprocalFactors: com.vzome.core.algebra.BigRational[]): com.vzome.core.algebra.BigRational[] {
+ const msg: string = this.getName() + " expects reciprocal matrix to be full rank (" + reciprocal.length + "), but it is " + rank + ".";
+ console.error(msg);
+ throw new java.lang.IllegalStateException(msg);
+ }
+
+ public static DEFAULT_FORMAT: number = 0;
+
+ public static EXPRESSION_FORMAT: number = 1;
+
+ public static ZOMIC_FORMAT: number = 2;
+
+ public static VEF_FORMAT: number = 3;
+
+ /**
+ *
+ * @return {*}
+ */
+ public zero(): com.vzome.core.algebra.AlgebraicNumber {
+ return this.__zero;
+ }
+
+ /**
+ *
+ * @return {*}
+ */
+ public one(): com.vzome.core.algebra.AlgebraicNumber {
+ return this.__one;
+ }
+
+ /**
+ *
+ * @param {int[][]} nums is an array of integer arrays: One array of coordinate terms per dimension.
+ * Initially, this is designed to simplify migration of order 2 golden directions
+ * to new fields of higher order having golden subfields as their first two factors.
+ * {@code
+ * field.createVector( new int[] { 0,1,2,3, 4,5,6,7, 8,9,0,1 } ); // older code like this...
+ * field.createVector( new int[][]{ {0,1,2,3}, {4,5,6,7}, {8,9,0,1} } ); // should be replaced by this.
+ * }
+ * The older code shown in the first example requires an order 2 field.
+ * The second example will work with any field of order 2 or greater.
+ * This new overload has the advantage that the internal arrays representing the individual dimensions are more clearly delineated and controlled.
+ * Inner arrays require an even number of elements since they represent a sequence of numerator/denominator pairs.
+ *
+ * createVector is currently limited to int valued vectors, not long, and definitely not BigInteger
+ * In most cases, this is adequate, but in the case where it's called by XmlSaveFormat.parseAlgebraicObject(),
+ * it seems possible that a value larger than Integer.MAX_VALUE could be saved to the XML which could not subsequently be parsed.
+ * TODO: Consider refactoring createVector to use long[][] instead of int[][] if this becomes an issue.
+ *
+ * @return {com.vzome.core.algebra.AlgebraicVector} an AlgebraicVector
+ */
+ public createVector(nums: number[][]): com.vzome.core.algebra.AlgebraicVector {
+ const dims: number = nums.length;
+ const coords: com.vzome.core.algebra.AlgebraicNumber[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(dims);
+ for(let c: number = 0; c < coords.length; c++) {{
+ const coordLength: number = nums[c].length;
+ if (coordLength % 2 !== 0){
+ throw new java.lang.IllegalStateException("Vector dimension " + c + " has " + coordLength + " components. An even number is required.");
+ }
+ const nTerms: number = (coordLength / 2|0);
+ if (nTerms > this.getOrder()){
+ throw new java.lang.IllegalStateException("Vector dimension " + c + " has " + ((coordLength / 2|0)) + " terms. Each dimension of the " + this.getName() + " field is limited to " + this.getOrder() + " terms. Each term consists of a numerator and a denominator.");
+ }
+ let pairs: number[] = (s => { let a=[]; while(s-->0) a.push(0); return a; })(nums[c].length);
+ for(let i: number = 0; i < pairs.length; i++) {{
+ pairs[i] = nums[c][i];
+ };}
+ if (pairs.length === 4 && this.getOrder() > 2){
+ pairs = this.convertGoldenNumberPairs(pairs);
+ }
+ coords[c] = this.numberFactory.createAlgebraicNumberFromPairs(this, pairs);
+ };}
+ return new com.vzome.core.algebra.AlgebraicVector(coords);
+ }
+
+ /**
+ *
+ * @param {int[][]} nums
+ * @return {com.vzome.core.algebra.AlgebraicVector}
+ */
+ public createVectorFromTDs(nums: number[][]): com.vzome.core.algebra.AlgebraicVector {
+ const x: com.vzome.core.algebra.AlgebraicNumber = this.createAlgebraicNumberFromTD(nums[0]);
+ const y: com.vzome.core.algebra.AlgebraicNumber = this.createAlgebraicNumberFromTD(nums[1]);
+ const z: com.vzome.core.algebra.AlgebraicNumber = this.createAlgebraicNumberFromTD(nums[2]);
+ return new com.vzome.core.algebra.AlgebraicVector(x, y, z);
+ }
+
+ /**
+ * Generates an AlgebraicVector with all AlgebraicNumber terms being integers (having unit denominators).
+ * Contrast this with {@code createVector(int[][] nums)} which requires all denominators to be specified.
+ * @param {int[][]} nums is a 2 dimensional integer array. The length of nums becomes the number of dimensions in the resulting AlgebraicVector.
+ * For example, {@code (new PentagonField()).createIntegerVector( new int[][]{ {0,-1}, {2,3}, {4,5} } ); }
+ * generates the 3 dimensional vector (-φ, 2 +3φ, 4 +5φ) having all integer terms.
+ * @return {com.vzome.core.algebra.AlgebraicVector} an AlgebraicVector
+ */
+ public createIntegerVector(nums: number[][]): com.vzome.core.algebra.AlgebraicVector {
+ const dims: number = nums.length;
+ const result: com.vzome.core.algebra.AlgebraicVector = this.origin(dims);
+ for(let dim: number = 0; dim < dims; dim++) {{
+ result.setComponent(dim, this.createAlgebraicNumber$int_A(nums[dim]));
+ };}
+ return result;
+ }
+
+ /**
+ * Create a 3x3 square matrix from integer data.
+ * TODO: Generalize this method to create a matrix with dimensions matching the dimensions of the data array
+ * Sample input data for an order-4 field:
+ * {{{7,5,0,1,-4,5,0,1},{-2,5,0,1,4,5,0,1},{0,1,-8,5,0,1,6,5}},
+ * {{-2,5,0,1,4,5,0,1},{7,5,0,1,-4,5,0,1},{0,1,8,5,0,1,-6,5}},
+ * {{0,1,-8,5,0,1,6,5},{0,1,8,5,0,1,-6,5},{-9,5,0,1,8,5,0,1}}}
+ * @param field
+ * @param {int[][][]} data integer coordinates, in row-major order, complete with denominators.
+ * @return
+ * @return {com.vzome.core.algebra.AlgebraicMatrix}
+ */
+ public createMatrix(data: number[][][]): com.vzome.core.algebra.AlgebraicMatrix {
+ const col1: com.vzome.core.algebra.AlgebraicVector = this.createVector([data[0][0], data[1][0], data[2][0]]);
+ const col2: com.vzome.core.algebra.AlgebraicVector = this.createVector([data[0][1], data[1][1], data[2][1]]);
+ const col3: com.vzome.core.algebra.AlgebraicVector = this.createVector([data[0][2], data[1][2], data[2][2]]);
+ return new com.vzome.core.algebra.AlgebraicMatrix(col1, col2, col3);
+ }
+
+ /**
+ *
+ * @param {java.lang.StringBuffer} buf
+ * @param {com.vzome.core.algebra.BigRational[]} factors
+ * @param {number} format must be one of the following values.
+ * The result is formatted as follows:
+ *
+ * {@code DEFAULT_FORMAT // 4 + 3φ}
+ * {@code EXPRESSION_FORMAT // 4 +3*phi}
+ * {@code ZOMIC_FORMAT // 4 3}
+ * {@code VEF_FORMAT // (3,4)}
+ */
+ getNumberExpression(buf: java.lang.StringBuffer, factors: com.vzome.core.algebra.BigRational[], format: number) {
+ switch((format)) {
+ case 2 /* ZOMIC_FORMAT */:
+ for(let i: number = 0; i < factors.length; i++) {{
+ if (i > 0)buf.append(" ");
+ buf.append(factors[i].toString());
+ };}
+ break;
+ case 3 /* VEF_FORMAT */:
+ buf.append("(");
+ for(let i: number = factors.length; i > 0; i--) {{
+ buf.append(factors[i - 1].toString());
+ if (i > 1)buf.append(",");
+ };}
+ buf.append(")");
+ break;
+ default:
+ let first: number = 0;
+ for(let i: number = 0; i < factors.length; i++) {{
+ let factor: com.vzome.core.algebra.BigRational = factors[i];
+ if (factor.isZero()){
+ ++first;
+ continue;
+ }
+ if (i > first){
+ buf.append(" ");
+ }
+ if (factor.isNegative()){
+ factor = factor.negate();
+ buf.append("-");
+ } else if (i > first){
+ buf.append("+");
+ }
+ if (i === 0)buf.append(factor.toString()); else {
+ if (!factor.isOne()){
+ buf.append(factor.toString());
+ if (format === AbstractAlgebraicField.EXPRESSION_FORMAT)buf.append("*");
+ }
+ const multiplier: string = this['getIrrational$int$int'](i, format);
+ buf.append(multiplier);
+ }
+ };}
+ if (first === factors.length)buf.append("0");
+ break;
+ }
+ }
+
+ /**
+ *
+ * @param {string} val
+ * @return {*}
+ */
+ public parseLegacyNumber(val: string): com.vzome.core.algebra.AlgebraicNumber {
+ throw new java.lang.IllegalStateException("This field does not support vZome 2.x files.");
+ }
+
+ /**
+ *
+ * @param {string} string
+ * @param {boolean} isRational
+ * @return {*}
+ */
+ public parseVefNumber(string: string, isRational: boolean): com.vzome.core.algebra.AlgebraicNumber {
+ let pairs: number[] = (s => { let a=[]; while(s-->0) a.push(0); return a; })(this.getOrder() * 2);
+ for(let i: number = 1; i < pairs.length; i += 2) {{
+ pairs[i] = 1;
+ };}
+ if ((!isRational) && /* startsWith */((str, searchString, position = 0) => str.substr(position, searchString.length) === searchString)(string, "(") && /* endsWith */((str, searchString) => { let pos = str.length - searchString.length; let lastIndex = str.indexOf(searchString, pos); return lastIndex !== -1 && lastIndex === pos; })(string, ")")){
+ const tokens: java.util.StringTokenizer = new java.util.StringTokenizer(string.substring(1, string.length - 1), ",");
+ const numStack: java.util.Stack = (new java.util.Stack());
+ const denomStack: java.util.Stack = (new java.util.Stack());
+ while((tokens.hasMoreTokens())) {{
+ if (numStack.size() >= this.getOrder()){
+ throw new java.lang.RuntimeException("VEF format error: \"" + string + "\" has too many factors for " + this.getName() + " field");
+ }
+ const parts: string[] = tokens.nextToken().split("/");
+ numStack.push(javaemul.internal.IntegerHelper.parseInt(parts[0]));
+ denomStack.push((parts.length > 1) ? javaemul.internal.IntegerHelper.parseInt(parts[1]) : 1);
+ }};
+ let i: number = 0;
+ while((!numStack.empty())) {{
+ pairs[i++] = numStack.pop();
+ pairs[i++] = denomStack.pop();
+ }};
+ if (i === 4 && this.getOrder() > 2){
+ pairs = this.convertGoldenNumberPairs([pairs[0], pairs[1], pairs[2], pairs[3]]);
+ }
+ } else {
+ const parts: string[] = string.split("/");
+ pairs[0] = javaemul.internal.IntegerHelper.parseInt(parts[0]);
+ pairs[1] = (parts.length > 1) ? javaemul.internal.IntegerHelper.parseInt(parts[1]) : 1;
+ }
+ return this.numberFactory.createAlgebraicNumberFromPairs(this, pairs);
+ }
+
+ public parseNumber$java_lang_String(nums: string): com.vzome.core.algebra.AlgebraicNumber {
+ const tokens: java.util.StringTokenizer = new java.util.StringTokenizer(nums, " ");
+ return this.parseNumber$java_util_StringTokenizer(tokens);
+ }
+
+ /**
+ *
+ * @param {string} nums
+ * @return {*}
+ */
+ public parseNumber(nums?: any): com.vzome.core.algebra.AlgebraicNumber {
+ if (((typeof nums === 'string') || nums === null)) {
+ return this.parseNumber$java_lang_String(nums);
+ } else if (((nums != null && nums instanceof java.util.StringTokenizer) || nums === null)) {
+ return this.parseNumber$java_util_StringTokenizer(nums);
+ } else throw new Error('invalid overload');
+ }
+
+ /*private*/ parseNumber$java_util_StringTokenizer(tokens: java.util.StringTokenizer): com.vzome.core.algebra.AlgebraicNumber {
+ const order: number = this.getOrder();
+ const pairs: number[] = (s => { let a=[]; while(s-->0) a.push(0); return a; })(order * 2);
+ for(let i: number = 0; i < order; i++) {{
+ const digit: string = tokens.nextToken();
+ const parts: string[] = digit.split("/");
+ pairs[i * 2] = javaemul.internal.LongHelper.parseLong(parts[0]);
+ if (parts.length > 1)pairs[i * 2 + 1] = javaemul.internal.LongHelper.parseLong(parts[1]); else pairs[i * 2 + 1] = 1;
+ };}
+ return this.numberFactory.createAlgebraicNumberFromPairs(this, pairs);
+ }
+
+ /**
+ *
+ * @param {string} nums
+ * @return {com.vzome.core.algebra.AlgebraicVector}
+ */
+ public parseVector(nums: string): com.vzome.core.algebra.AlgebraicVector {
+ const tokens: java.util.StringTokenizer = new java.util.StringTokenizer(nums, " ");
+ const numToks: number = tokens.countTokens();
+ if (numToks % this.getOrder() !== 0)throw new java.lang.IllegalStateException("Field order (" + this.getOrder() + ") does not divide token count: " + numToks + ", for \'" + nums + "\'");
+ const dims: number = (numToks / this.getOrder()|0);
+ const coords: com.vzome.core.algebra.AlgebraicNumber[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(dims);
+ for(let i: number = 0; i < dims; i++) {{
+ coords[i] = this.parseNumber$java_util_StringTokenizer(tokens);
+ };}
+ return new com.vzome.core.algebra.AlgebraicVector(coords);
+ }
+
+ /**
+ *
+ * @param {number} dims
+ * @return {com.vzome.core.algebra.AlgebraicMatrix}
+ */
+ public identityMatrix(dims: number): com.vzome.core.algebra.AlgebraicMatrix {
+ const columns: com.vzome.core.algebra.AlgebraicVector[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(dims);
+ for(let i: number = 0; i < columns.length; i++) {{
+ columns[i] = this.basisVector(dims, i);
+ };}
+ return new com.vzome.core.algebra.AlgebraicMatrix(columns);
+ }
+
+ /**
+ * @return {number} the number of independent multipliers in this field.
+ * These are the primitive elements of the field.
+ * The value should be less than or equal to getNumIrrationals.
+ * It will be less whenever the irrationals are dependent.
+ * For example, in the field for sqrt(phi), there is only one
+ * multiplier, since the other irrational is just the square of that one.
+ */
+ public getNumMultipliers(): number {
+ return this.getNumIrrationals();
+ }
+
+ public generateSeries(threshold: number): com.vzome.core.algebra.AlgebraicSeries {
+ const multiplier: com.vzome.core.algebra.AlgebraicNumber = this.createPower$int$int(1, this.getNumIrrationals());
+ let cover: com.vzome.core.algebra.AlgebraicNumber = this.one();
+ let power: number = 0;
+ while((cover.evaluate() < threshold)) {{
+ cover = cover['times$com_vzome_core_algebra_AlgebraicNumber'](multiplier);
+ ++power;
+ }};
+ return new com.vzome.core.algebra.AlgebraicSeries(this, power);
+ }
+
+ public getMathML(factors: com.vzome.core.algebra.BigRational[]): string {
+ const buf: java.lang.StringBuffer = new java.lang.StringBuffer();
+ let first: number = 0;
+ for(let i: number = 0; i < factors.length; i++) {{
+ let factor: com.vzome.core.algebra.BigRational = factors[i];
+ if (factor.isZero()){
+ ++first;
+ continue;
+ }
+ if (factor.isNegative()){
+ factor = factor.negate();
+ buf.append("-");
+ } else if (i > first){
+ buf.append("+");
+ }
+ if (i === 0)buf.append(factor.getMathML()); else {
+ if (!factor.isOne()){
+ buf.append(factor.getMathML());
+ }
+ const multiplier: string = this['getIrrational$int$int'](i, AbstractAlgebraicField.DEFAULT_FORMAT);
+ buf.append("");
+ buf.append(multiplier);
+ buf.append("");
+ }
+ };}
+ if (first === factors.length)return "0"; else if (factors.length - first > 1)return "" + buf.toString() + ""; else return buf.toString();
+ }
+
+ /**
+ *
+ * @param {string} script
+ * @param {string} language
+ * @param {com.vzome.core.construction.Point} offset
+ * @param {*} symmetry
+ * @param {*} effects
+ */
+ public interpretScript(script: string, language: string, offset: com.vzome.core.construction.Point, symmetry: com.vzome.core.math.symmetry.Symmetry, effects: com.vzome.core.construction.ConstructionChanges) {
+ throw new Error("Scripts are only supported in the golden field.");
+ }
+
+ public abstract getIrrational(i?: any, format?: any): any; }
+ AbstractAlgebraicField["__class"] = "com.vzome.core.algebra.AbstractAlgebraicField";
+ AbstractAlgebraicField["__interfaces"] = ["com.vzome.core.algebra.AlgebraicField"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicField.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicField.ts
new file mode 100644
index 000000000..40d02f75a
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicField.ts
@@ -0,0 +1,230 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export interface AlgebraicField {
+ getOrder(): number;
+
+ getNumIrrationals(): number;
+
+ /**
+ * Returns the label using the specified format for the irrational term with ordinal i.
+ * i=0 refers to the rational term.
+ * @param {number} i
+ * @param {number} format must be either {@code DEFAULT_FORMAT = 0} or
+ * {@code EXPRESSION_FORMAT = 1}
+ * @return
+ * @return {string}
+ */
+ getIrrational(i?: any, format?: any): string;
+
+ nearestAlgebraicVector(target: com.vzome.core.math.RealVector): com.vzome.core.algebra.AlgebraicVector;
+
+ getName(): string;
+
+ /**
+ * Generates an AlgebraicNumber from a "trailing divisor" int array representation.
+ * @param {int[]} trailingDivisorForm numerators trailed by a common denominator for all numerators
+ * @return
+ * @return {*}
+ */
+ createAlgebraicNumberFromTD(trailingDivisorForm: number[]): com.vzome.core.algebra.AlgebraicNumber;
+
+ createAlgebraicNumber(ones?: any, irrat?: any, denominator?: any, scalePower?: any): com.vzome.core.algebra.AlgebraicNumber;
+
+ /**
+ * The golden ratio (and thus icosahedral symmetry and related tools)
+ * can be generated by some fields even though it's not one of their irrational coefficients.
+ * For example, SqrtField(5) and PolygonField(10) can both generate the golden ratio
+ * so they can support icosa symmetry and related tools.
+ * In some such cases, the resulting AlgebraicNumber
+ * may have multiple terms and/or factors other than one.
+ *
+ * @return {*} An AlgebraicNumber which evaluates to the golden ratio, or null if not possible in this field.
+ */
+ getGoldenRatio(): com.vzome.core.algebra.AlgebraicNumber;
+
+ createPower(power?: any, irr?: any): com.vzome.core.algebra.AlgebraicNumber;
+
+ /**
+ * @param {number} numerator
+ * @param {number} denominator
+ * @return {*} AlgebraicNumber
+ */
+ createRational(numerator?: any, denominator?: any): com.vzome.core.algebra.AlgebraicNumber;
+
+ /**
+ * @return {*} The AlgebraicNumber to be use for the Chord Ratio construction in the given field.
+ * This method can be used to generalize an AffinePolygon tool and a PolygonalAntiprismSymmetry.
+ * This base class returns one, which is the scalar for an affine square and works in any field.
+ * Derived classes should override this method if they can be used to generate any other affine polygon.
+ */
+ getAffineScalar(): com.vzome.core.algebra.AlgebraicNumber;
+
+ /**
+ * @param {number} n specifies the ordinal of the term in the AlgebraicNumber which will be set to one.
+ * When {@code n == 0}, the result is the same as {@code createRational(1)}.
+ * When {@code n == 1}, the result is the same as {@code createPower(1)}.
+ * When {@code n < 0}, the result will be {@code zero()}.
+ * When {@code n >= getOrder()}, an IndexOutOfBoundsException will be thrown.
+ * @return {*} an AlgebraicNumber with the factor specified by {@code n} set to one.
+ */
+ getUnitTerm(n: number): com.vzome.core.algebra.AlgebraicNumber;
+
+ /**
+ * Drop one coordinate from the 4D vector. If wFirst (the usual), then drop
+ * the first coordinate, taking the "imaginary part" of the vector. If
+ * !wFirst (for old VEF import, etc.), drop the last coordinate.
+ *
+ * @param {com.vzome.core.algebra.AlgebraicVector} source
+ * @param {boolean} wFirst
+ * @return
+ * @return {com.vzome.core.algebra.AlgebraicVector}
+ */
+ projectTo3d(source: com.vzome.core.algebra.AlgebraicVector, wFirst: boolean): com.vzome.core.algebra.AlgebraicVector;
+
+ origin(dims: number): com.vzome.core.algebra.AlgebraicVector;
+
+ basisVector(dims: number, axis: number): com.vzome.core.algebra.AlgebraicVector;
+
+ zero(): com.vzome.core.algebra.AlgebraicNumber;
+
+ one(): com.vzome.core.algebra.AlgebraicNumber;
+
+ /**
+ *
+ * @param {int[][]} nums is an array of integer arrays: One array of coordinate terms per dimension.
+ * Initially, this is designed to simplify migration of order 2 golden directions
+ * to new fields of higher order having golden subfields as their first two factors.
+ * {@code
+ * field.createVector( new int[] { 0,1,2,3, 4,5,6,7, 8,9,0,1 } ); // older code like this...
+ * field.createVector( new int[][]{ {0,1,2,3}, {4,5,6,7}, {8,9,0,1} } ); // should be replaced by this...
+ * field.createVector( new int[][]{ {0,1,2,3}, {4,5,6,7}, {8,9 } } ); // ... or even this.
+ * }
+ * The older code shown in the first example requires an order 2 field.
+ * The second example will work with any field of order 2 or greater.
+ * This new overload has the advantage that the internal arrays representing the individual dimensions are more clearly delineated and controlled.
+ * As shown in the third example, the internal arrays need not be all the same length. Trailing zero terms can be omitted as shown.
+ * Inner arrays require an even number of elements since they represent a sequence of numerator/denominator pairs.
+ *
+ * createVector is currently limited to int valued vectors, not long, and definitely not BigInteger
+ * In most cases, this is adequate, but in the case where it's called by XmlSaveFormat.parseAlgebraicObject(),
+ * it seems possible that a value larger than Integer.MAX_VALUE could be saved to the XML which could not subsequently be parsed.
+ * TODO: Consider refactoring createVector to use long[][] instead of int[][] if this becomes an issue.
+ *
+ * @return {com.vzome.core.algebra.AlgebraicVector} an AlgebraicVector
+ */
+ createVector(nums: number[][]): com.vzome.core.algebra.AlgebraicVector;
+
+ /**
+ *
+ * @param {int[][]} nums nums is an array of integer arrays: One array of coordinate terms per dimension.
+ * Each inner array is in "trailing divisor" form, to represent a rational AlgebraicNumber.
+ * If the order of the field is N, each inner array will be of length N+1, with the last
+ * element being the divisor.
+ * @return
+ * @return {com.vzome.core.algebra.AlgebraicVector}
+ */
+ createVectorFromTDs(nums: number[][]): com.vzome.core.algebra.AlgebraicVector;
+
+ /**
+ * Generates an AlgebraicVector with all AlgebraicNumber terms being integers (having unit denominators).
+ * Contrast this with {@code createVector(int[][] nums)} which requires all denominators to be specified.
+ * @param {int[][]} nums is a 2 dimensional integer array. The length of nums becomes the number of dimensions in the resulting AlgebraicVector.
+ * For example, {@code (new PentagonField()).createIntegerVector( new int[][]{ {0,-1}, {2,3}, {4,5} } ); }
+ * generates the 3 dimensional vector (-φ, 2 +3φ, 4 +5φ) having all integer terms.
+ * @return {com.vzome.core.algebra.AlgebraicVector} an AlgebraicVector
+ */
+ createIntegerVector(nums: number[][]): com.vzome.core.algebra.AlgebraicVector;
+
+ /**
+ * Create a 3x3 square matrix from integer data.
+ * TODO: Generalize this method to create a matrix with dimensions matching the dimensions of the data array
+ * Sample input data for an order-4 field:
+ * {{{7,5,0,1,-4,5,0,1},{-2,5,0,1,4,5,0,1},{0,1,-8,5,0,1,6,5}},
+ * {{-2,5,0,1,4,5,0,1},{7,5,0,1,-4,5,0,1},{0,1,8,5,0,1,-6,5}},
+ * {{0,1,-8,5,0,1,6,5},{0,1,8,5,0,1,-6,5},{-9,5,0,1,8,5,0,1}}}
+ * @param field
+ * @param {int[][][]} data integer coordinates, in row-major order, complete with denominators.
+ * @return
+ * @return {com.vzome.core.algebra.AlgebraicMatrix}
+ */
+ createMatrix(data: number[][][]): com.vzome.core.algebra.AlgebraicMatrix;
+
+ parseLegacyNumber(val: string): com.vzome.core.algebra.AlgebraicNumber;
+
+ parseNumber(nums: string): com.vzome.core.algebra.AlgebraicNumber;
+
+ parseVector(nums: string): com.vzome.core.algebra.AlgebraicVector;
+
+ identityMatrix(dims: number): com.vzome.core.algebra.AlgebraicMatrix;
+
+ /**
+ * @return {number} the number of independent multipliers in this field.
+ * These are the primitive elements of the field.
+ * The value should be less than or equal to getNumIrrationals.
+ * It will be less whenever the irrationals are dependent.
+ * For example, in the field for sqrt(phi), there is only one
+ * multiplier, since the other irrational is just the square of that one.
+ */
+ getNumMultipliers(): number;
+
+ parseVefNumber(string: string, isRational: boolean): com.vzome.core.algebra.AlgebraicNumber;
+
+ scale4dRoots(): boolean;
+
+ doubleFrameVectors(): boolean;
+
+ /**
+ * If the field supports the value having the common name specified,
+ * this method returns an AlgebraicNumber having that value.
+ * Note that the value may not correspond to a unique term in the AlgebraicField (e.g. {"phi" for @code PolygonField(10)}).
+ * For example, {@code getNumberByName("phi")}
+ * should return the same value as {@code getGoldenRatio()}
+ * @param {string} name
+ * @return {*} An AlgebraicNumber which evaluates to the specified name, or null if not possible in this field.
+ */
+ getNumberByName(name: string): com.vzome.core.algebra.AlgebraicNumber;
+
+ supportsSubfield(fieldName: string): boolean;
+
+ interpretScript(script: string, language: string, offset: com.vzome.core.construction.Point, symmetry: com.vzome.core.math.symmetry.Symmetry, effects: com.vzome.core.construction.ConstructionChanges);
+ }
+
+ export namespace AlgebraicField {
+
+ export const DEFAULT_FORMAT: number = 0;
+
+ export const EXPRESSION_FORMAT: number = 1;
+
+ export const ZOMIC_FORMAT: number = 2;
+
+ export const VEF_FORMAT: number = 3;
+
+ export function getIrrationals(field: AlgebraicField): string[] {
+ const len: number = field.getNumIrrationals();
+ const result: string[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(len);
+ for(let i: number = 0; i < result.length; i++) {{
+ result[i] = field['getIrrational$int'](i + 1);
+ };}
+ return result;
+ }
+
+ export function getMultipliers(field: AlgebraicField): string[] {
+ const len: number = field.getNumMultipliers();
+ const result: string[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(len);
+ for(let i: number = 0; i < result.length; i++) {{
+ result[i] = field['getIrrational$int'](i + 1);
+ };}
+ return result;
+ }
+ }
+
+
+ export namespace AlgebraicField {
+
+ export interface Registry {
+ getField(name: string): com.vzome.core.algebra.AlgebraicField;
+ }
+ }
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicMatrix.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicMatrix.ts
new file mode 100644
index 000000000..d79d30757
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicMatrix.ts
@@ -0,0 +1,307 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export class AlgebraicMatrix {
+ /**
+ *
+ * @return {number}
+ */
+ public hashCode(): number {
+ const prime: number = 31;
+ let result: number = 1;
+ for(let index = 0; index < this.matrix.length; index++) {
+ let m = this.matrix[index];
+ {
+ result = prime * result + java.util.Arrays.hashCode(m);
+ }
+ }
+ return result;
+ }
+
+ /**
+ *
+ * @param {*} obj
+ * @return {boolean}
+ */
+ public equals(obj: any): boolean {
+ if (this === obj)return true;
+ if (obj == null)return false;
+ if ((this.constructor) !== (obj.constructor))return false;
+ const other: AlgebraicMatrix = obj;
+ return java.util.Arrays.deepEquals(this.matrix, other.matrix);
+ }
+
+ matrix: com.vzome.core.algebra.AlgebraicNumber[][];
+
+ public getMatrix(): com.vzome.core.algebra.AlgebraicNumber[][] {
+ return this.matrix;
+ }
+
+ public getRowMajorRealElements(): number[] {
+ const result: number[] = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
+ for(let i: number = 0; i < 3; i++) {{
+ for(let j: number = 0; j < 3; j++) {{
+ result[i * 4 + j] = (Math).fround(this.getElement(i, j).evaluate());
+ };}
+ };}
+ return result;
+ }
+
+ public constructor(x?: any, y?: any, z?: any, w?: any) {
+ if (((x != null && x instanceof com.vzome.core.algebra.AlgebraicVector) || x === null) && ((y != null && y instanceof com.vzome.core.algebra.AlgebraicVector) || y === null) && ((z != null && z instanceof com.vzome.core.algebra.AlgebraicVector) || z === null) && ((w != null && w instanceof com.vzome.core.algebra.AlgebraicVector) || w === null)) {
+ let __args = arguments;
+ {
+ let __args = arguments;
+ let columns: any = [x, y, z, w];
+ if (this.matrix === undefined) { this.matrix = null; }
+ const rows: number = columns[0].dimension();
+ const cols: number = columns.length;
+ this.matrix = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return null; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([rows, cols]);
+ for(let i: number = 0; i < rows; i++) {{
+ for(let j: number = 0; j < cols; j++) {{
+ this.matrix[i][j] = columns[j].getComponent(i);
+ };}
+ };}
+ }
+ } else if (((x != null && x instanceof com.vzome.core.algebra.AlgebraicVector) || x === null) && ((y != null && y instanceof com.vzome.core.algebra.AlgebraicVector) || y === null) && ((z != null && z instanceof com.vzome.core.algebra.AlgebraicVector) || z === null) && w === undefined) {
+ let __args = arguments;
+ {
+ let __args = arguments;
+ let columns: any = [x, y, z];
+ if (this.matrix === undefined) { this.matrix = null; }
+ const rows: number = columns[0].dimension();
+ const cols: number = columns.length;
+ this.matrix = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return null; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([rows, cols]);
+ for(let i: number = 0; i < rows; i++) {{
+ for(let j: number = 0; j < cols; j++) {{
+ this.matrix[i][j] = columns[j].getComponent(i);
+ };}
+ };}
+ }
+ } else if (((x != null && (x.constructor != null && x.constructor["__interfaces"] != null && x.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicField") >= 0)) || x === null) && ((typeof y === 'number') || y === null) && ((typeof z === 'number') || z === null) && w === undefined) {
+ let __args = arguments;
+ let field: any = __args[0];
+ let rows: any = __args[1];
+ let cols: any = __args[2];
+ if (this.matrix === undefined) { this.matrix = null; }
+ this.matrix = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return null; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([rows, cols]);
+ for(let i: number = 0; i < rows; i++) {{
+ for(let j: number = 0; j < cols; j++) {{
+ this.matrix[i][j] = field.zero();
+ };}
+ };}
+ } else if (((x != null && x instanceof com.vzome.core.algebra.AlgebraicVector) || x === null) && ((y != null && y instanceof com.vzome.core.algebra.AlgebraicVector) || y === null) && z === undefined && w === undefined) {
+ let __args = arguments;
+ {
+ let __args = arguments;
+ let columns: any = [x, y];
+ if (this.matrix === undefined) { this.matrix = null; }
+ const rows: number = columns[0].dimension();
+ const cols: number = columns.length;
+ this.matrix = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return null; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([rows, cols]);
+ for(let i: number = 0; i < rows; i++) {{
+ for(let j: number = 0; j < cols; j++) {{
+ this.matrix[i][j] = columns[j].getComponent(i);
+ };}
+ };}
+ }
+ } else if (((x != null && (x.constructor != null && x.constructor["__interfaces"] != null && x.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicField") >= 0)) || x === null) && ((typeof y === 'number') || y === null) && z === undefined && w === undefined) {
+ let __args = arguments;
+ let field: any = __args[0];
+ let dim: any = __args[1];
+ if (this.matrix === undefined) { this.matrix = null; }
+ this.matrix = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return null; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([dim, dim]);
+ for(let i: number = 0; i < dim; i++) {{
+ for(let j: number = 0; j < dim; j++) {{
+ if (i === j)this.matrix[i][j] = field.one(); else this.matrix[i][j] = field.zero();
+ };}
+ };}
+ } else if (((x != null && x instanceof Array && (x.length == 0 || x[0] == null ||(x[0] != null && x[0] instanceof com.vzome.core.algebra.AlgebraicVector))) || x === null) && y === undefined && z === undefined && w === undefined) {
+ let __args = arguments;
+ let columns: any = __args[0];
+ if (this.matrix === undefined) { this.matrix = null; }
+ const rows: number = columns[0].dimension();
+ const cols: number = columns.length;
+ this.matrix = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return null; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([rows, cols]);
+ for(let i: number = 0; i < rows; i++) {{
+ for(let j: number = 0; j < cols; j++) {{
+ this.matrix[i][j] = columns[j].getComponent(i);
+ };}
+ };}
+ } else throw new Error('invalid overload');
+ }
+
+ /**
+ *
+ * @return {string}
+ */
+ public toString(): string {
+ const buf: java.lang.StringBuilder = new java.lang.StringBuilder();
+ for(let index = 0; index < this.matrix.length; index++) {
+ let m = this.matrix[index];
+ {
+ buf.append(java.util.Arrays.toString(m));
+ buf.append(", ");
+ }
+ }
+ return "[ " + buf.toString() + " ]";
+ }
+
+ public negate(): AlgebraicMatrix {
+ const field: com.vzome.core.algebra.AlgebraicField = this.matrix[0][0].getField();
+ const result: AlgebraicMatrix = new AlgebraicMatrix(field, this.matrix.length);
+ for(let i: number = 0; i < this.matrix.length; i++) {{
+ for(let j: number = 0; j < this.matrix[i].length; j++) {{
+ result.matrix[i][j] = this.matrix[i][j].negate();
+ };}
+ };}
+ return result;
+ }
+
+ public inverse(): AlgebraicMatrix {
+ if (!this.isSquare()){
+ throw new java.lang.IllegalArgumentException("matrix is not square");
+ }
+ const field: com.vzome.core.algebra.AlgebraicField = this.matrix[0][0].getField();
+ const result: AlgebraicMatrix = new AlgebraicMatrix(field, this.matrix.length);
+ const rank: number = com.vzome.core.algebra.Fields.gaussJordanReduction$com_vzome_core_algebra_Fields_Element_A_A$com_vzome_core_algebra_Fields_Element_A_A(this.matrix, result.matrix);
+ if (rank !== this.matrix.length){
+ const message: string = "AlgebraicMatrix inverse expects matrix rank to be " + this.matrix.length + ", but it is " + rank + ".";
+ console.error(message);
+ }
+ return result;
+ }
+
+ public transpose(): AlgebraicMatrix {
+ const field: com.vzome.core.algebra.AlgebraicField = this.matrix[0][0].getField();
+ const result: AlgebraicMatrix = new AlgebraicMatrix(field, this.matrix[0].length, this.matrix.length);
+ for(let i: number = 0; i < result.matrix.length; i++) {{
+ for(let j: number = 0; j < this.matrix.length; j++) {{
+ result.matrix[i][j] = this.matrix[j][i];
+ };}
+ };}
+ return result;
+ }
+
+ public times(that: AlgebraicMatrix): AlgebraicMatrix {
+ const field: com.vzome.core.algebra.AlgebraicField = this.matrix[0][0].getField();
+ const result: AlgebraicMatrix = new AlgebraicMatrix(field, this.matrix.length, that.matrix[0].length);
+ com.vzome.core.algebra.Fields.matrixMultiplication(this.matrix, that.matrix, result.matrix);
+ return result;
+ }
+
+ public timesRow(rowVector: com.vzome.core.algebra.AlgebraicVector): com.vzome.core.algebra.AlgebraicVector {
+ const colLength: number = rowVector.dimension();
+ if (this.matrix.length !== colLength)throw new java.lang.IllegalArgumentException("vector length incorrect for this matrix: " + rowVector);
+ const rowLength: number = this.matrix[0].length;
+ const resultComponents: com.vzome.core.algebra.AlgebraicNumber[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(rowLength);
+ const field: com.vzome.core.algebra.AlgebraicField = this.matrix[0][0].getField();
+ for(let j: number = 0; j < rowLength; j++) {{
+ resultComponents[j] = field.zero();
+ for(let i: number = 0; i < colLength; i++) {{
+ const product: com.vzome.core.algebra.AlgebraicNumber = rowVector.getComponent(i)['times$com_vzome_core_algebra_AlgebraicNumber'](this.matrix[i][j]);
+ resultComponents[j] = resultComponents[j]['plus$com_vzome_core_algebra_AlgebraicNumber'](product);
+ };}
+ };}
+ return new com.vzome.core.algebra.AlgebraicVector(resultComponents);
+ }
+
+ public timesColumn(columnVector: com.vzome.core.algebra.AlgebraicVector): com.vzome.core.algebra.AlgebraicVector {
+ const rowLength: number = columnVector.dimension();
+ if (this.matrix[0].length !== rowLength)throw new java.lang.IllegalArgumentException("vector length incorrect for this matrix: " + columnVector);
+ const colLength: number = this.matrix.length;
+ const resultComponents: com.vzome.core.algebra.AlgebraicNumber[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(colLength);
+ const field: com.vzome.core.algebra.AlgebraicField = this.matrix[0][0].getField();
+ for(let i: number = 0; i < colLength; i++) {{
+ resultComponents[i] = field.zero();
+ for(let j: number = 0; j < rowLength; j++) {{
+ const product: com.vzome.core.algebra.AlgebraicNumber = columnVector.getComponent(j)['times$com_vzome_core_algebra_AlgebraicNumber'](this.matrix[i][j]);
+ resultComponents[i] = resultComponents[i]['plus$com_vzome_core_algebra_AlgebraicNumber'](product);
+ };}
+ };}
+ return new com.vzome.core.algebra.AlgebraicVector(resultComponents);
+ }
+
+ public timesScalar(scalar: com.vzome.core.algebra.AlgebraicNumber): AlgebraicMatrix {
+ const result: AlgebraicMatrix = new AlgebraicMatrix(scalar.getField(), this.matrix.length);
+ for(let i: number = 0; i < this.matrix.length; i++) {{
+ for(let j: number = 0; j < this.matrix[i].length; j++) {{
+ result.matrix[i][j] = this.matrix[i][j]['times$com_vzome_core_algebra_AlgebraicNumber'](scalar);
+ };}
+ };}
+ return result;
+ }
+
+ public isSquare(): boolean {
+ return this.matrix.length === this.matrix[0].length;
+ }
+
+ public trace(): com.vzome.core.algebra.AlgebraicNumber {
+ if (!this.isSquare()){
+ throw new java.lang.IllegalArgumentException("matrix is not square");
+ }
+ let trace: com.vzome.core.algebra.AlgebraicNumber = this.matrix[0][0].getField().zero();
+ for(let i: number = 0; i < this.matrix.length; i++) {{
+ trace = trace['plus$com_vzome_core_algebra_AlgebraicNumber'](this.matrix[i][i]);
+ };}
+ return trace;
+ }
+
+ public determinant(): com.vzome.core.algebra.AlgebraicNumber {
+ return AlgebraicMatrix.laplaceDeterminant(this.matrix);
+ }
+
+ public static laplaceDeterminant(matrix: com.vzome.core.algebra.AlgebraicNumber[][]): com.vzome.core.algebra.AlgebraicNumber {
+ if (matrix.length !== matrix[0].length){
+ throw new java.lang.IllegalArgumentException("matrix is not square");
+ }
+ let determinant: com.vzome.core.algebra.AlgebraicNumber = null;
+ switch((matrix.length)) {
+ case 3:
+ determinant = (matrix[0][0]['times$com_vzome_core_algebra_AlgebraicNumber'](matrix[1][1])['times$com_vzome_core_algebra_AlgebraicNumber'](matrix[2][2]))['plus$com_vzome_core_algebra_AlgebraicNumber'](matrix[0][1]['times$com_vzome_core_algebra_AlgebraicNumber'](matrix[1][2])['times$com_vzome_core_algebra_AlgebraicNumber'](matrix[2][0]))['plus$com_vzome_core_algebra_AlgebraicNumber'](matrix[0][2]['times$com_vzome_core_algebra_AlgebraicNumber'](matrix[1][0])['times$com_vzome_core_algebra_AlgebraicNumber'](matrix[2][1]))['minus$com_vzome_core_algebra_AlgebraicNumber'](matrix[0][2]['times$com_vzome_core_algebra_AlgebraicNumber'](matrix[1][1])['times$com_vzome_core_algebra_AlgebraicNumber'](matrix[2][0]))['minus$com_vzome_core_algebra_AlgebraicNumber'](matrix[0][0]['times$com_vzome_core_algebra_AlgebraicNumber'](matrix[1][2])['times$com_vzome_core_algebra_AlgebraicNumber'](matrix[2][1]))['minus$com_vzome_core_algebra_AlgebraicNumber'](matrix[0][1]['times$com_vzome_core_algebra_AlgebraicNumber'](matrix[1][0])['times$com_vzome_core_algebra_AlgebraicNumber'](matrix[2][2]));
+ break;
+ case 2:
+ determinant = (matrix[0][0]['times$com_vzome_core_algebra_AlgebraicNumber'](matrix[1][1]))['minus$com_vzome_core_algebra_AlgebraicNumber'](matrix[0][1]['times$com_vzome_core_algebra_AlgebraicNumber'](matrix[1][0]));
+ break;
+ case 1:
+ determinant = matrix[0][0];
+ break;
+ default:
+ determinant = matrix[0][0].getField().zero();
+ const auxLength: number = matrix.length - 1;
+ let sign: com.vzome.core.algebra.AlgebraicNumber = matrix[0][0].getField().one();
+ for(let i: number = 0; i < matrix.length; i++) {{
+ if (!matrix[0][i].isZero()){
+ const aux: com.vzome.core.algebra.AlgebraicNumber[][] = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return null; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([auxLength, auxLength]);
+ let iAux: number = 0;
+ let jAux: number = 0;
+ for(let row: number = 1; row < matrix.length; row++) {{
+ for(let col: number = 0; col < matrix.length; col++) {{
+ if (col !== i){
+ aux[iAux][jAux] = matrix[row][col];
+ jAux++;
+ }
+ };}
+ iAux++;
+ jAux = 0;
+ };}
+ determinant = determinant['plus$com_vzome_core_algebra_AlgebraicNumber'](sign['times$com_vzome_core_algebra_AlgebraicNumber'](matrix[0][i])['times$com_vzome_core_algebra_AlgebraicNumber'](AlgebraicMatrix.laplaceDeterminant(aux)));
+ }
+ sign = sign.negate();
+ };}
+ }
+ return determinant;
+ }
+
+ public setElement(i: number, j: number, value: com.vzome.core.algebra.AlgebraicNumber): AlgebraicMatrix {
+ this.matrix[i][j] = value;
+ return this;
+ }
+
+ public getElement(i: number, j: number): com.vzome.core.algebra.AlgebraicNumber {
+ return this.matrix[i][j];
+ }
+ }
+ AlgebraicMatrix["__class"] = "com.vzome.core.algebra.AlgebraicMatrix";
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicNumber.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicNumber.ts
new file mode 100644
index 000000000..96208d538
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicNumber.ts
@@ -0,0 +1,182 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ /**
+ *
+ * Immutable representation of an Algebraic Number
+ * @class
+ */
+ export interface AlgebraicNumber extends com.vzome.core.algebra.Fields.Element, java.lang.Comparable {
+ greaterThan(other: AlgebraicNumber): boolean;
+
+ lessThan(other: AlgebraicNumber): boolean;
+
+ greaterThanOrEqualTo(other: AlgebraicNumber): boolean;
+
+ lessThanOrEqualTo(other: AlgebraicNumber): boolean;
+
+ getField(): com.vzome.core.algebra.AlgebraicField;
+
+ /**
+ *
+ * @param {number} n is the value to be added
+ * @return {*} this + n
+ */
+ plusInt(n: number): AlgebraicNumber;
+
+ /**
+ *
+ * @param {number} num is the numerator of the rational value to be added
+ * @param {number} den is the denominator of the rational value to be added
+ * @return {*} this + (num / den)
+ */
+ plusRational(num: number, den: number): AlgebraicNumber;
+
+ /**
+ *
+ * @param {*} that is the value to be added
+ * @return {*} this + n
+ */
+ plus(that?: any): any;
+
+ /**
+ *
+ * @param {number} n is the value to be multiplied
+ * @return {*} this * n
+ */
+ timesInt(n: number): AlgebraicNumber;
+
+ /**
+ *
+ * @param {number} num is the numerator of the rational value to be multiplied
+ * @param {number} den is the denominator of the rational value to be multiplied
+ * @return {*} this * (num / den)
+ */
+ timesRational(num: number, den: number): AlgebraicNumber;
+
+ /**
+ *
+ * @param {*} that
+ * @return {*}
+ */
+ times(that?: any): any;
+
+ /**
+ *
+ * @param {number} n is the value to be subtracted
+ * @return {*} this - n
+ */
+ minusInt(n: number): AlgebraicNumber;
+
+ /**
+ *
+ * @param {number} num is the numerator of the rational value to be subtracted
+ * @param {number} den is the denominator of the rational value to be subtracted
+ * @return {*} this - (num / den)
+ */
+ minusRational(num: number, den: number): AlgebraicNumber;
+
+ /**
+ *
+ * @param {*} that is the value to be subtracted
+ * @return {*} this - n
+ */
+ minus(that?: any): any;
+
+ /**
+ *
+ * @param {number} divisor
+ * @return {*} this / divisor
+ */
+ dividedByInt(divisor: number): AlgebraicNumber;
+
+ /**
+ *
+ * @param {number} num is the numerator of the divisor
+ * @param {number} den is the denominator of the divisor
+ * @return {*} this / (num / den)
+ */
+ dividedByRational(num: number, den: number): AlgebraicNumber;
+
+ dividedBy(that: AlgebraicNumber): AlgebraicNumber;
+
+ evaluate(): number;
+
+ isRational(): boolean;
+
+ /**
+ *
+ * @return {boolean}
+ */
+ isZero(): boolean;
+
+ /**
+ *
+ * @return {boolean}
+ */
+ isOne(): boolean;
+
+ signum(): number;
+
+ /**
+ *
+ * @return {*}
+ */
+ negate(): AlgebraicNumber;
+
+ /**
+ *
+ * @return {*}
+ */
+ reciprocal(): AlgebraicNumber;
+
+ /**
+ *
+ * @param {java.lang.StringBuffer} buf
+ * @param {number} format must be one of the following values.
+ * The result is formatted as follows:
+ *
+ * {@code DEFAULT_FORMAT // 4 + 3φ}
+ * {@code EXPRESSION_FORMAT // 4 +3*phi}
+ * {@code ZOMIC_FORMAT // 4 3}
+ * {@code VEF_FORMAT // (3,4)}
+ */
+ getNumberExpression(buf: java.lang.StringBuffer, format: number);
+
+ /**
+ *
+ * @param {number} format must be one of the following values.
+ * The result is formatted as follows:
+ *
+ * {@code DEFAULT_FORMAT // 4 + 3φ}
+ * {@code EXPRESSION_FORMAT // 4 +3*phi}
+ * {@code ZOMIC_FORMAT // 4 3}
+ * {@code VEF_FORMAT // (3,4)}
+ * @return {string}
+ */
+ toString(format: number): string;
+
+ toTrailingDivisor(): number[];
+ }
+
+ export namespace AlgebraicNumber {
+
+ export class Views {
+ constructor() {
+ }
+ }
+ Views["__class"] = "com.vzome.core.algebra.AlgebraicNumber.Views";
+
+
+ export namespace Views {
+
+ export interface TrailingDivisor { }
+
+ export interface Rational { }
+
+ export interface Real { }
+ }
+
+ }
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicNumberFactory.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicNumberFactory.ts
new file mode 100644
index 000000000..0588342d5
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicNumberFactory.ts
@@ -0,0 +1,23 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export interface AlgebraicNumberFactory {
+ zero(): com.vzome.core.algebra.BigRational;
+
+ one(): com.vzome.core.algebra.BigRational;
+
+ createBigRational(numerator: number, denominator: number): com.vzome.core.algebra.BigRational;
+
+ createAlgebraicNumber(field: com.vzome.core.algebra.AlgebraicField, numerators: number[], divisor: number): com.vzome.core.algebra.AlgebraicNumber;
+
+ createAlgebraicNumberFromTD(field: com.vzome.core.algebra.AlgebraicField, trailingDivisorForm: number[]): com.vzome.core.algebra.AlgebraicNumber;
+
+ createAlgebraicNumberFromPairs(field: com.vzome.core.algebra.AlgebraicField, pairs: number[]): com.vzome.core.algebra.AlgebraicNumber;
+
+ createRational(field: com.vzome.core.algebra.AlgebraicField, numerator: number, denominator: number): com.vzome.core.algebra.AlgebraicNumber;
+
+ isPrime(n: number): boolean;
+
+ nextPrime(n: number): number;
+ }
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicSeries.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicSeries.ts
new file mode 100644
index 000000000..d79c3dae6
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicSeries.ts
@@ -0,0 +1,66 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export class AlgebraicSeries {
+ public series: com.vzome.core.algebra.AlgebraicNumber[];
+
+ public constructor(field: com.vzome.core.algebra.AbstractAlgebraicField, power: number) {
+ if (this.series === undefined) { this.series = null; }
+ let sequence: java.util.List = (new java.util.ArrayList());
+ sequence.add(0);
+ let divisor: com.vzome.core.algebra.AlgebraicNumber = field.getUnitTerm(1);
+ divisor = divisor['times$com_vzome_core_algebra_AlgebraicNumber'](divisor);
+ for(let i: number = 0; i < power + 2; i++) {{
+ sequence = field.recurrence(sequence);
+ };}
+ this.series = (s => { let a=[]; while(s-->0) a.push(null); return a; })(sequence.size() + 1);
+ this.series[0] = field.zero();
+ let prevIndex: number = 0;
+ for(let index=sequence.iterator();index.hasNext();) {
+ let integer = index.next();
+ {
+ const prev: com.vzome.core.algebra.AlgebraicNumber = this.series[prevIndex++];
+ const step: com.vzome.core.algebra.AlgebraicNumber = field.getUnitTerm(integer).dividedBy(divisor);
+ this.series[prevIndex] = prev['plus$com_vzome_core_algebra_AlgebraicNumber'](step);
+ }
+ }
+ }
+
+ public nearestAlgebraicNumber(target: number): com.vzome.core.algebra.AlgebraicNumber {
+ const negative: boolean = target < 0.0;
+ if (negative)target = -target;
+ const positive: com.vzome.core.algebra.AlgebraicNumber = this.checkRange(0, this.series.length - 1, target);
+ if (negative)return positive.negate(); else return positive;
+ }
+
+ /*private*/ checkRange(minIndex: number, maxIndex: number, target: number): com.vzome.core.algebra.AlgebraicNumber {
+ if (minIndex >= maxIndex)return this.series[maxIndex]; else {
+ const lowDiff: number = target - this.series[minIndex].evaluate();
+ const highDiff: number = this.series[maxIndex].evaluate() - target;
+ if (maxIndex === minIndex + 1){
+ return (highDiff < lowDiff) ? this.series[maxIndex] : this.series[minIndex];
+ } else {
+ const midIndex: number = (Math.floor(((maxIndex + minIndex) / 2|0))|0);
+ return (highDiff < lowDiff) ? this.checkRange(midIndex, maxIndex, target) : this.checkRange(minIndex, midIndex, target);
+ }
+ }
+ }
+
+ /**
+ *
+ * @return {string}
+ */
+ public toString(): string {
+ let result: string = "";
+ for(let index = 0; index < this.series.length; index++) {
+ let algebraicNumber = this.series[index];
+ {
+ result += algebraicNumber.toString() + ", ";
+ }
+ }
+ return result;
+ }
+ }
+ AlgebraicSeries["__class"] = "com.vzome.core.algebra.AlgebraicSeries";
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicVector.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicVector.ts
new file mode 100644
index 000000000..ddc7ea2c4
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicVector.ts
@@ -0,0 +1,384 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ /**
+ * @author vorth
+ * @param {*} n1
+ * @param {*} n2
+ * @param {*} n3
+ * @param {*} n4
+ * @param {*} n5
+ * @class
+ */
+ export class AlgebraicVector implements java.lang.Comparable {
+ public static X: number = 0;
+
+ public static Y: number = 1;
+
+ public static Z: number = 2;
+
+ public static W4: number = 0;
+
+ public static X4: number = 1;
+
+ public static Y4: number = 2;
+
+ public static Z4: number = 3;
+
+ /*private*/ coordinates: com.vzome.core.algebra.AlgebraicNumber[];
+
+ /*private*/ field: com.vzome.core.algebra.AlgebraicField;
+
+ public constructor(n1?: any, n2?: any, n3?: any, n4?: any, n5?: any) {
+ if (((n1 != null && (n1.constructor != null && n1.constructor["__interfaces"] != null && n1.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || n1 === null) && ((n2 != null && (n2.constructor != null && n2.constructor["__interfaces"] != null && n2.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || n2 === null) && ((n3 != null && (n3.constructor != null && n3.constructor["__interfaces"] != null && n3.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || n3 === null) && ((n4 != null && (n4.constructor != null && n4.constructor["__interfaces"] != null && n4.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || n4 === null) && ((n5 != null && (n5.constructor != null && n5.constructor["__interfaces"] != null && n5.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || n5 === null)) {
+ let __args = arguments;
+ {
+ let __args = arguments;
+ let field: any = n1.getField();
+ let dims: any = 5;
+ if (this.coordinates === undefined) { this.coordinates = null; }
+ if (this.field === undefined) { this.field = null; }
+ this.coordinates = (s => { let a=[]; while(s-->0) a.push(null); return a; })(dims);
+ for(let i: number = 0; i < dims; i++) {{
+ this.coordinates[i] = field.zero();
+ };}
+ this.field = field;
+ }
+ (() => {
+ this.coordinates[0] = n1;
+ this.coordinates[1] = n2;
+ this.coordinates[2] = n3;
+ this.coordinates[3] = n4;
+ this.coordinates[4] = n5;
+ })();
+ } else if (((n1 != null && (n1.constructor != null && n1.constructor["__interfaces"] != null && n1.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || n1 === null) && ((n2 != null && (n2.constructor != null && n2.constructor["__interfaces"] != null && n2.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || n2 === null) && ((n3 != null && (n3.constructor != null && n3.constructor["__interfaces"] != null && n3.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || n3 === null) && ((n4 != null && (n4.constructor != null && n4.constructor["__interfaces"] != null && n4.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || n4 === null) && n5 === undefined) {
+ let __args = arguments;
+ {
+ let __args = arguments;
+ let field: any = n1.getField();
+ let dims: any = 4;
+ if (this.coordinates === undefined) { this.coordinates = null; }
+ if (this.field === undefined) { this.field = null; }
+ this.coordinates = (s => { let a=[]; while(s-->0) a.push(null); return a; })(dims);
+ for(let i: number = 0; i < dims; i++) {{
+ this.coordinates[i] = field.zero();
+ };}
+ this.field = field;
+ }
+ (() => {
+ this.coordinates[0] = n1;
+ this.coordinates[1] = n2;
+ this.coordinates[2] = n3;
+ this.coordinates[3] = n4;
+ })();
+ } else if (((n1 != null && (n1.constructor != null && n1.constructor["__interfaces"] != null && n1.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || n1 === null) && ((n2 != null && (n2.constructor != null && n2.constructor["__interfaces"] != null && n2.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || n2 === null) && ((n3 != null && (n3.constructor != null && n3.constructor["__interfaces"] != null && n3.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || n3 === null) && n4 === undefined && n5 === undefined) {
+ let __args = arguments;
+ {
+ let __args = arguments;
+ let field: any = n1.getField();
+ let dims: any = 3;
+ if (this.coordinates === undefined) { this.coordinates = null; }
+ if (this.field === undefined) { this.field = null; }
+ this.coordinates = (s => { let a=[]; while(s-->0) a.push(null); return a; })(dims);
+ for(let i: number = 0; i < dims; i++) {{
+ this.coordinates[i] = field.zero();
+ };}
+ this.field = field;
+ }
+ (() => {
+ this.coordinates[0] = n1;
+ this.coordinates[1] = n2;
+ this.coordinates[2] = n3;
+ })();
+ } else if (((n1 != null && (n1.constructor != null && n1.constructor["__interfaces"] != null && n1.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || n1 === null) && ((n2 != null && (n2.constructor != null && n2.constructor["__interfaces"] != null && n2.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || n2 === null) && n3 === undefined && n4 === undefined && n5 === undefined) {
+ let __args = arguments;
+ {
+ let __args = arguments;
+ let field: any = n1.getField();
+ let dims: any = 2;
+ if (this.coordinates === undefined) { this.coordinates = null; }
+ if (this.field === undefined) { this.field = null; }
+ this.coordinates = (s => { let a=[]; while(s-->0) a.push(null); return a; })(dims);
+ for(let i: number = 0; i < dims; i++) {{
+ this.coordinates[i] = field.zero();
+ };}
+ this.field = field;
+ }
+ (() => {
+ this.coordinates[0] = n1;
+ this.coordinates[1] = n2;
+ })();
+ } else if (((n1 != null && (n1.constructor != null && n1.constructor["__interfaces"] != null && n1.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicField") >= 0)) || n1 === null) && ((typeof n2 === 'number') || n2 === null) && n3 === undefined && n4 === undefined && n5 === undefined) {
+ let __args = arguments;
+ let field: any = __args[0];
+ let dims: any = __args[1];
+ if (this.coordinates === undefined) { this.coordinates = null; }
+ if (this.field === undefined) { this.field = null; }
+ this.coordinates = (s => { let a=[]; while(s-->0) a.push(null); return a; })(dims);
+ for(let i: number = 0; i < dims; i++) {{
+ this.coordinates[i] = field.zero();
+ };}
+ this.field = field;
+ } else if (((n1 != null && n1 instanceof Array && (n1.length == 0 || n1[0] == null ||(n1[0] != null && (n1[0].constructor != null && n1[0].constructor["__interfaces"] != null && n1[0].constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)))) || n1 === null) && n2 === undefined && n3 === undefined && n4 === undefined && n5 === undefined) {
+ let __args = arguments;
+ let n: any = __args[0];
+ if (this.coordinates === undefined) { this.coordinates = null; }
+ if (this.field === undefined) { this.field = null; }
+ this.coordinates = (s => { let a=[]; while(s-->0) a.push(null); return a; })(n.length);
+ java.lang.System.arraycopy(n, 0, this.coordinates, 0, n.length);
+ this.field = n[0].getField();
+ } else if (((n1 != null && (n1.constructor != null && n1.constructor["__interfaces"] != null && n1.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || n1 === null) && n2 === undefined && n3 === undefined && n4 === undefined && n5 === undefined) {
+ let __args = arguments;
+ {
+ let __args = arguments;
+ let field: any = n1.getField();
+ let dims: any = 1;
+ if (this.coordinates === undefined) { this.coordinates = null; }
+ if (this.field === undefined) { this.field = null; }
+ this.coordinates = (s => { let a=[]; while(s-->0) a.push(null); return a; })(dims);
+ for(let i: number = 0; i < dims; i++) {{
+ this.coordinates[i] = field.zero();
+ };}
+ this.field = field;
+ }
+ (() => {
+ this.coordinates[0] = n1;
+ })();
+ } else throw new Error('invalid overload');
+ }
+
+ /**
+ *
+ * @return {number}
+ */
+ public hashCode(): number {
+ const prime: number = 31;
+ let result: number = 1;
+ result = prime * result + java.util.Arrays.hashCode(this.coordinates);
+ return result;
+ }
+
+ /**
+ *
+ * @param {*} obj
+ * @return {boolean}
+ */
+ public equals(obj: any): boolean {
+ if (this === obj)return true;
+ if (obj == null)return false;
+ if ((this.constructor) !== (obj.constructor))return false;
+ const other: AlgebraicVector = obj;
+ if (!/* equals */(((o1: any, o2: any) => { if (o1 && o1.equals) { return o1.equals(o2); } else { return o1 === o2; } })(this.field,other.field))){
+ const reason: string = "Invalid comparison of " + /* getSimpleName */(c => typeof c === 'string' ? (c).substring((c).lastIndexOf('.')+1) : c["__class"] ? c["__class"].substring(c["__class"].lastIndexOf('.')+1) : c["name"].substring(c["name"].lastIndexOf('.')+1))((this.constructor)) + "swith different fields: " + this.field.getName() + " and " + other.field.getName();
+ throw new java.lang.IllegalStateException(reason);
+ }
+ return java.util.Arrays.equals(this.coordinates, other.coordinates);
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.algebra.AlgebraicVector} other
+ * @return {number}
+ */
+ public compareTo(other: AlgebraicVector): number {
+ if (this === other){
+ return 0;
+ }
+ if (other.equals(this)){
+ return 0;
+ }
+ let comparison: number = /* compare */(this.coordinates.length - other.coordinates.length);
+ if (comparison !== 0){
+ return comparison;
+ }
+ for(let i: number = 0; i < this.coordinates.length; i++) {{
+ const n1: com.vzome.core.algebra.AlgebraicNumber = this.coordinates[i];
+ const n2: com.vzome.core.algebra.AlgebraicNumber = other.coordinates[i];
+ comparison = n1.compareTo(n2);
+ if (comparison !== 0){
+ return comparison;
+ }
+ };}
+ return comparison;
+ }
+
+ public toRealVector(): com.vzome.core.math.RealVector {
+ return new com.vzome.core.math.RealVector(this.coordinates[0].evaluate(), this.coordinates[1].evaluate(), this.coordinates[2].evaluate());
+ }
+
+ public to3dDoubleVector(): number[] {
+ return [this.coordinates[0].evaluate(), this.coordinates[1].evaluate(), this.coordinates[2].evaluate()];
+ }
+
+ /**
+ * @return {string} A String with no extended characters so it's suitable for writing
+ * to an 8 bit stream such as System.out or an ASCII text log file in Windows.
+ * Contrast this with {@link toString()} which contains extended characters (e.g. φ (phi))
+ */
+ public toASCIIString(): string {
+ return this.getVectorExpression$int(com.vzome.core.algebra.AlgebraicField.EXPRESSION_FORMAT);
+ }
+
+ /**
+ * @return {string} A String representation that can be persisted to XML and parsed by XmlSaveFormat.parseRationalVector().
+ */
+ public toParsableString(): string {
+ return this.getVectorExpression$int(com.vzome.core.algebra.AlgebraicField.ZOMIC_FORMAT);
+ }
+
+ public toString(format: number = com.vzome.core.algebra.AlgebraicField.DEFAULT_FORMAT): string {
+ return this.getVectorExpression$int(format);
+ }
+
+ public getComponent(i: number): com.vzome.core.algebra.AlgebraicNumber {
+ return this.coordinates[i];
+ }
+
+ public getComponents(): com.vzome.core.algebra.AlgebraicNumber[] {
+ return this.coordinates;
+ }
+
+ public setComponent(component: number, coord: com.vzome.core.algebra.AlgebraicNumber): AlgebraicVector {
+ this.coordinates[component] = coord;
+ return this;
+ }
+
+ public negate(): AlgebraicVector {
+ const result: com.vzome.core.algebra.AlgebraicNumber[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(this.coordinates.length);
+ for(let i: number = 0; i < result.length; i++) {{
+ result[i] = this.coordinates[i].negate();
+ };}
+ return new AlgebraicVector(result);
+ }
+
+ public scale(scale: com.vzome.core.algebra.AlgebraicNumber): AlgebraicVector {
+ const result: com.vzome.core.algebra.AlgebraicNumber[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(this.coordinates.length);
+ for(let i: number = 0; i < result.length; i++) {{
+ result[i] = this.coordinates[i]['times$com_vzome_core_algebra_AlgebraicNumber'](scale);
+ };}
+ return new AlgebraicVector(result);
+ }
+
+ public isOrigin(): boolean {
+ for(let index = 0; index < this.coordinates.length; index++) {
+ let coordinate = this.coordinates[index];
+ {
+ if (!coordinate.isZero()){
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public plus(that: AlgebraicVector): AlgebraicVector {
+ const result: com.vzome.core.algebra.AlgebraicNumber[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(this.coordinates.length);
+ for(let i: number = 0; i < result.length; i++) {{
+ result[i] = this.coordinates[i]['plus$com_vzome_core_algebra_AlgebraicNumber'](that.coordinates[i]);
+ };}
+ return new AlgebraicVector(result);
+ }
+
+ public minus(that: AlgebraicVector): AlgebraicVector {
+ const result: com.vzome.core.algebra.AlgebraicNumber[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(this.coordinates.length);
+ for(let i: number = 0; i < result.length; i++) {{
+ result[i] = this.coordinates[i]['minus$com_vzome_core_algebra_AlgebraicNumber'](that.coordinates[i]);
+ };}
+ return new AlgebraicVector(result);
+ }
+
+ public dimension(): number {
+ return this.coordinates.length;
+ }
+
+ public cross(that: AlgebraicVector): AlgebraicVector {
+ const result: com.vzome.core.algebra.AlgebraicNumber[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(this.coordinates.length);
+ for(let i: number = 0; i < result.length; i++) {{
+ const j: number = (i + 1) % 3;
+ const k: number = (i + 2) % 3;
+ result[i] = this.coordinates[j]['times$com_vzome_core_algebra_AlgebraicNumber'](that.coordinates[k])['minus$com_vzome_core_algebra_AlgebraicNumber'](this.coordinates[k]['times$com_vzome_core_algebra_AlgebraicNumber'](that.coordinates[j]));
+ };}
+ return new AlgebraicVector(result);
+ }
+
+ public inflateTo4d$(): AlgebraicVector {
+ return this.inflateTo4d$boolean(true);
+ }
+
+ public inflateTo4d$boolean(wFirst: boolean): AlgebraicVector {
+ if (this.coordinates.length === 4){
+ if (wFirst)return this; else return new AlgebraicVector([this.coordinates[1], this.coordinates[2], this.coordinates[3], this.coordinates[0]]);
+ }
+ if (wFirst)return new AlgebraicVector([this.field.zero(), this.coordinates[0], this.coordinates[1], this.coordinates[2]]); else return new AlgebraicVector([this.coordinates[0], this.coordinates[1], this.coordinates[2], this.field.zero()]);
+ }
+
+ public inflateTo4d(wFirst?: any): AlgebraicVector {
+ if (((typeof wFirst === 'boolean') || wFirst === null)) {
+ return this.inflateTo4d$boolean(wFirst);
+ } else if (wFirst === undefined) {
+ return this.inflateTo4d$();
+ } else throw new Error('invalid overload');
+ }
+
+ public projectTo3d(wFirst: boolean): AlgebraicVector {
+ if (this.dimension() === 3)return this;
+ if (wFirst)return new AlgebraicVector([this.coordinates[1], this.coordinates[2], this.coordinates[3]]); else return new AlgebraicVector([this.coordinates[0], this.coordinates[1], this.coordinates[2]]);
+ }
+
+ public getVectorExpression$java_lang_StringBuffer$int(buf: java.lang.StringBuffer, format: number) {
+ if (format === com.vzome.core.algebra.AlgebraicField.DEFAULT_FORMAT)buf.append("(");
+ for(let i: number = 0; i < this.coordinates.length; i++) {{
+ if (i > 0)if (format === com.vzome.core.algebra.AlgebraicField.VEF_FORMAT || format === com.vzome.core.algebra.AlgebraicField.ZOMIC_FORMAT)buf.append(" "); else buf.append(", ");
+ this.coordinates[i].getNumberExpression(buf, format);
+ };}
+ if (format === com.vzome.core.algebra.AlgebraicField.DEFAULT_FORMAT)buf.append(")");
+ }
+
+ /**
+ *
+ * @param {java.lang.StringBuffer} buf a StringBuffer to which the formatted vector will be appended.
+ * @param {number} format may be any of the following:
+ * {@code AlgebraicField.DEFAULT_FORMAT = 0; // 4 + 3φ}
+ * {@code AlgebraicField.EXPRESSION_FORMAT = 1; // 4 +3*phi}
+ * {@code AlgebraicField.ZOMIC_FORMAT = 2; // 4 3}
+ * {@code AlgebraicField.VEF_FORMAT = 3; // (3,4)}
+ */
+ public getVectorExpression(buf?: any, format?: any) {
+ if (((buf != null && buf instanceof java.lang.StringBuffer) || buf === null) && ((typeof format === 'number') || format === null)) {
+ return this.getVectorExpression$java_lang_StringBuffer$int(buf, format);
+ } else if (((typeof buf === 'number') || buf === null) && format === undefined) {
+ return this.getVectorExpression$int(buf);
+ } else throw new Error('invalid overload');
+ }
+
+ public getVectorExpression$int(format: number): string {
+ const buf: java.lang.StringBuffer = new java.lang.StringBuffer();
+ this.getVectorExpression$java_lang_StringBuffer$int(buf, format);
+ return buf.toString();
+ }
+
+ public dot(that: AlgebraicVector): com.vzome.core.algebra.AlgebraicNumber {
+ let result: com.vzome.core.algebra.AlgebraicNumber = this.field.zero();
+ for(let i: number = 0; i < that.dimension(); i++) {{
+ result = result['plus$com_vzome_core_algebra_AlgebraicNumber'](this.coordinates[i]['times$com_vzome_core_algebra_AlgebraicNumber'](that.coordinates[i]));
+ };}
+ return result;
+ }
+
+ public getLength(unit: AlgebraicVector): com.vzome.core.algebra.AlgebraicNumber {
+ for(let i: number = 0; i < this.coordinates.length; i++) {{
+ if (this.coordinates[i].isZero())continue;
+ return this.coordinates[i].dividedBy(unit.coordinates[i]);
+ };}
+ throw new java.lang.IllegalStateException("vector is the origin!");
+ }
+
+ public getField(): com.vzome.core.algebra.AlgebraicField {
+ return this.field;
+ }
+ }
+ AlgebraicVector["__class"] = "com.vzome.core.algebra.AlgebraicVector";
+ AlgebraicVector["__interfaces"] = ["java.lang.Comparable"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicVectors.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicVectors.ts
new file mode 100644
index 000000000..4737c06ec
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/AlgebraicVectors.ts
@@ -0,0 +1,218 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ /**
+ * A collection of static helper methods for the AlgebraicVector class
+ * @class
+ */
+ export class AlgebraicVectors {
+ constructor() {
+ }
+
+ public static getNormal$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector(v1: com.vzome.core.algebra.AlgebraicVector, v2: com.vzome.core.algebra.AlgebraicVector): com.vzome.core.algebra.AlgebraicVector {
+ return v1.cross(v2);
+ }
+
+ public static getNormal$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector(v0: com.vzome.core.algebra.AlgebraicVector, v1: com.vzome.core.algebra.AlgebraicVector, v2: com.vzome.core.algebra.AlgebraicVector): com.vzome.core.algebra.AlgebraicVector {
+ return AlgebraicVectors.getNormal$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector(v1.minus(v0), v2.minus(v0));
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.algebra.AlgebraicVector} v0
+ * @param {com.vzome.core.algebra.AlgebraicVector} v1
+ * @param {com.vzome.core.algebra.AlgebraicVector} v2
+ * @return {com.vzome.core.algebra.AlgebraicVector} normal to vectors v1 and v2,
+ * with both v1 and v2 positioned at v0
+ * using the righthand rule.
+ */
+ public static getNormal(v0?: any, v1?: any, v2?: any): com.vzome.core.algebra.AlgebraicVector {
+ if (((v0 != null && v0 instanceof com.vzome.core.algebra.AlgebraicVector) || v0 === null) && ((v1 != null && v1 instanceof com.vzome.core.algebra.AlgebraicVector) || v1 === null) && ((v2 != null && v2 instanceof com.vzome.core.algebra.AlgebraicVector) || v2 === null)) {
+ return com.vzome.core.algebra.AlgebraicVectors.getNormal$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector(v0, v1, v2);
+ } else if (((v0 != null && v0 instanceof com.vzome.core.algebra.AlgebraicVector) || v0 === null) && ((v1 != null && v1 instanceof com.vzome.core.algebra.AlgebraicVector) || v1 === null) && v2 === undefined) {
+ return com.vzome.core.algebra.AlgebraicVectors.getNormal$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector(v0, v1);
+ } else if (((v0 != null && (v0.constructor != null && v0.constructor["__interfaces"] != null && v0.constructor["__interfaces"].indexOf("java.util.Collection") >= 0)) || v0 === null) && v1 === undefined && v2 === undefined) {
+ return com.vzome.core.algebra.AlgebraicVectors.getNormal$java_util_Collection(v0);
+ } else throw new Error('invalid overload');
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.algebra.AlgebraicVector} v1
+ * @param {com.vzome.core.algebra.AlgebraicVector} v2
+ * @return {boolean} true if vectors v1 and v2 are parallel, otherwise false.
+ * Considered as position vectors, this is the same as testing if they are collinear with the origin.
+ */
+ public static areParallel(v1: com.vzome.core.algebra.AlgebraicVector, v2: com.vzome.core.algebra.AlgebraicVector): boolean {
+ return AlgebraicVectors.getNormal$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector(v1, v2).isOrigin();
+ }
+
+ public static getNormal$java_util_Collection(vectors: java.util.Collection): com.vzome.core.algebra.AlgebraicVector {
+ if (vectors.size() < 3){
+ throw new java.lang.IllegalArgumentException("Three vertices are required to calculate a normal. Found " + vectors.size());
+ }
+ let v0: com.vzome.core.algebra.AlgebraicVector = null;
+ let v1: com.vzome.core.algebra.AlgebraicVector = null;
+ let normal: com.vzome.core.algebra.AlgebraicVector = null;
+ for(let index=vectors.iterator();index.hasNext();) {
+ let vector = index.next();
+ {
+ if (v0 == null){
+ v0 = vector;
+ } else if (v1 == null){
+ if (vector !== v0){
+ v1 = vector;
+ }
+ } else {
+ normal = AlgebraicVectors.getNormal$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector(v0, v1, vector);
+ if (!normal.isOrigin()){
+ return normal;
+ }
+ }
+ }
+ }
+ return normal;
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.algebra.AlgebraicVector} vector
+ * @return {number} index of the vector component having the greatest absolute value.
+ * If more than one component has the same absolute value,
+ * the greatest index will be returned.
+ */
+ public static getMaxComponentIndex(vector: com.vzome.core.algebra.AlgebraicVector): number {
+ let maxIndex: number = 0;
+ let maxSq: com.vzome.core.algebra.AlgebraicNumber = vector.getField().zero();
+ for(let i: number = 0; i < vector.dimension(); i++) {{
+ const n: com.vzome.core.algebra.AlgebraicNumber = vector.getComponent(i);
+ const sq: com.vzome.core.algebra.AlgebraicNumber = n['times$com_vzome_core_algebra_AlgebraicNumber'](n);
+ if (!sq.lessThan(maxSq)){
+ maxIndex = i;
+ maxSq = sq;
+ }
+ };}
+ return maxIndex;
+ }
+
+ public static areCoplanar(vectors: java.util.Collection): boolean {
+ if (vectors.size() < 4){
+ return true;
+ }
+ const normal: com.vzome.core.algebra.AlgebraicVector = AlgebraicVectors.getNormal$java_util_Collection(vectors);
+ if (normal.isOrigin() || normal.dimension() < 3){
+ return true;
+ }
+ return AlgebraicVectors.areOrthogonalTo(normal, vectors);
+ }
+
+ public static areOrthogonalTo(normal: com.vzome.core.algebra.AlgebraicVector, vectors: java.util.Collection): boolean {
+ if (normal.isOrigin()){
+ throw new java.lang.IllegalArgumentException("Normal vector cannot be the origin");
+ }
+ let v0: com.vzome.core.algebra.AlgebraicVector = null;
+ for(let index=vectors.iterator();index.hasNext();) {
+ let vector = index.next();
+ {
+ if (v0 == null){
+ v0 = vector;
+ } else if (!vector.minus(v0).dot(normal).isZero()){
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public static areCollinear$java_util_Collection(vectors: java.util.Collection): boolean {
+ return (vectors.size() < 3) ? true : AlgebraicVectors.getNormal$java_util_Collection(vectors).isOrigin();
+ }
+
+ public static areCollinear$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector(v0: com.vzome.core.algebra.AlgebraicVector, v1: com.vzome.core.algebra.AlgebraicVector, v2: com.vzome.core.algebra.AlgebraicVector): boolean {
+ return AlgebraicVectors.getNormal$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector(v0, v1, v2).isOrigin();
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.algebra.AlgebraicVector} v0
+ * @param {com.vzome.core.algebra.AlgebraicVector} v1
+ * @param {com.vzome.core.algebra.AlgebraicVector} v2
+ * @return {boolean} true if position vectors v0, v1 and v2 are collinear, otherwise false.
+ */
+ public static areCollinear(v0?: any, v1?: any, v2?: any): boolean {
+ if (((v0 != null && v0 instanceof com.vzome.core.algebra.AlgebraicVector) || v0 === null) && ((v1 != null && v1 instanceof com.vzome.core.algebra.AlgebraicVector) || v1 === null) && ((v2 != null && v2 instanceof com.vzome.core.algebra.AlgebraicVector) || v2 === null)) {
+ return com.vzome.core.algebra.AlgebraicVectors.areCollinear$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector$com_vzome_core_algebra_AlgebraicVector(v0, v1, v2);
+ } else if (((v0 != null && (v0.constructor != null && v0.constructor["__interfaces"] != null && v0.constructor["__interfaces"].indexOf("java.util.Collection") >= 0)) || v0 === null) && v1 === undefined && v2 === undefined) {
+ return com.vzome.core.algebra.AlgebraicVectors.areCollinear$java_util_Collection(v0);
+ } else throw new Error('invalid overload');
+ }
+
+ public static getLinePlaneIntersection(lineStart: com.vzome.core.algebra.AlgebraicVector, lineDirection: com.vzome.core.algebra.AlgebraicVector, planeCenter: com.vzome.core.algebra.AlgebraicVector, planeNormal: com.vzome.core.algebra.AlgebraicVector): com.vzome.core.algebra.AlgebraicVector {
+ const denom: com.vzome.core.algebra.AlgebraicNumber = planeNormal.dot(lineDirection);
+ if (denom.isZero())return null;
+ const p1p3: com.vzome.core.algebra.AlgebraicVector = planeCenter.minus(lineStart);
+ const numerator: com.vzome.core.algebra.AlgebraicNumber = planeNormal.dot(p1p3);
+ const u: com.vzome.core.algebra.AlgebraicNumber = numerator.dividedBy(denom);
+ return lineStart.plus(lineDirection.scale(u));
+ }
+
+ public static calculateCentroid(vectors: java.util.Collection): com.vzome.core.algebra.AlgebraicVector {
+ return AlgebraicVectors.getCentroid(vectors.toArray((s => { let a=[]; while(s-->0) a.push(null); return a; })(vectors.size())));
+ }
+
+ public static getCentroid(vectors: com.vzome.core.algebra.AlgebraicVector[]): com.vzome.core.algebra.AlgebraicVector {
+ const field: com.vzome.core.algebra.AlgebraicField = vectors[0].getField();
+ let sum: com.vzome.core.algebra.AlgebraicVector = new com.vzome.core.algebra.AlgebraicVector(field, vectors[0].dimension());
+ for(let index = 0; index < vectors.length; index++) {
+ let vector = vectors[index];
+ {
+ sum = sum.plus(vector);
+ }
+ }
+ return sum.scale(field['createRational$long$long'](1, vectors.length));
+ }
+
+ public static getMagnitudeSquared(v: com.vzome.core.algebra.AlgebraicVector): com.vzome.core.algebra.AlgebraicNumber {
+ return v.dot(v);
+ }
+
+ /**
+ * @param {com.vzome.core.algebra.AlgebraicVector} vector
+ * @return {com.vzome.core.algebra.AlgebraicVector} the greater of {@code vector} and its inverse.
+ * The comparison is based on a canonical (not mathematical) comparison as implemented in {@code AlgebraicVector.compareTo()}.
+ * There is no reasonable mathematical sense of ordering vectors,
+ * but this provides a way to map a vector and its inverse to a common vector for such purposes as sorting and color mapping.
+ */
+ public static getCanonicalOrientation(vector: com.vzome.core.algebra.AlgebraicVector): com.vzome.core.algebra.AlgebraicVector {
+ const negate: com.vzome.core.algebra.AlgebraicVector = vector.negate();
+ return vector.compareTo(negate) > 0 ? vector : negate;
+ }
+
+ /**
+ * getMostDistantFromOrigin() is is used by a few ColorMapper classes, but I think it can eventually be useful elsewhere as well, for example, a zoom-to-fit command or in deriving a convex hull. I've made it a static method of the AlgebraicVector class to encourage such reuse.
+ *
+ * @param {*} vectors A collection of vectors to be evaluated.
+ * @return {java.util.TreeSet} A canonically sorted subset (maybe all) of the {@code vectors} collection. All of the returned vectors will be the same distance from the origin. That distance will be the maximum distance from the origin of any of the vectors in the original collection. If the original collection contains only the origin then so will the result.
+ */
+ public static getMostDistantFromOrigin(vectors: java.util.Collection): java.util.TreeSet {
+ const mostDistant: java.util.TreeSet = (new java.util.TreeSet());
+ let maxDistanceSquared: number = 0.0;
+ for(let index=vectors.iterator();index.hasNext();) {
+ let vector = index.next();
+ {
+ const magnitudeSquared: number = AlgebraicVectors.getMagnitudeSquared(vector).evaluate();
+ if (magnitudeSquared >= maxDistanceSquared){
+ if (magnitudeSquared > maxDistanceSquared){
+ mostDistant.clear();
+ }
+ maxDistanceSquared = magnitudeSquared;
+ mostDistant.add(vector);
+ }
+ }
+ }
+ return mostDistant;
+ }
+ }
+ AlgebraicVectors["__class"] = "com.vzome.core.algebra.AlgebraicVectors";
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/BigRational.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/BigRational.ts
new file mode 100644
index 000000000..47f853962
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/BigRational.ts
@@ -0,0 +1,11 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ /**
+ * Immutable Abstract Data Type for arbitrarily large rational numbers.
+ * @class
+ */
+ export interface BigRational extends com.vzome.core.algebra.Fields.Element {
+ isNegative(): boolean;
+ }
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/Bivector3d.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/Bivector3d.ts
new file mode 100644
index 000000000..bca6922a1
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/Bivector3d.ts
@@ -0,0 +1,88 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export class Bivector3d {
+ /*private*/ a: com.vzome.core.algebra.AlgebraicNumber;
+
+ /*private*/ b: com.vzome.core.algebra.AlgebraicNumber;
+
+ /*private*/ c: com.vzome.core.algebra.AlgebraicNumber;
+
+ public constructor(a: com.vzome.core.algebra.AlgebraicNumber, b: com.vzome.core.algebra.AlgebraicNumber, c: com.vzome.core.algebra.AlgebraicNumber) {
+ if (this.a === undefined) { this.a = null; }
+ if (this.b === undefined) { this.b = null; }
+ if (this.c === undefined) { this.c = null; }
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ }
+
+ /**
+ *
+ * @return {number}
+ */
+ public hashCode(): number {
+ const prime: number = 31;
+ let result: number = 1;
+ result = prime * result + ((this.a == null) ? 0 : /* hashCode */(((o: any) => { if (o.hashCode) { return o.hashCode(); } else { return o.toString().split('').reduce((prevHash, currVal) => (((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0); }})(this.a)));
+ result = prime * result + ((this.b == null) ? 0 : /* hashCode */(((o: any) => { if (o.hashCode) { return o.hashCode(); } else { return o.toString().split('').reduce((prevHash, currVal) => (((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0); }})(this.b)));
+ result = prime * result + ((this.c == null) ? 0 : /* hashCode */(((o: any) => { if (o.hashCode) { return o.hashCode(); } else { return o.toString().split('').reduce((prevHash, currVal) => (((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0); }})(this.c)));
+ return result;
+ }
+
+ /**
+ *
+ * @param {*} obj
+ * @return {boolean}
+ */
+ public equals(obj: any): boolean {
+ if (this === obj){
+ return true;
+ }
+ if (obj == null){
+ return false;
+ }
+ if ((this.constructor) !== (obj.constructor)){
+ return false;
+ }
+ const other: Bivector3d = obj;
+ if (this.a == null){
+ if (other.a != null){
+ return false;
+ }
+ } else if (!/* equals */(((o1: any, o2: any) => { if (o1 && o1.equals) { return o1.equals(o2); } else { return o1 === o2; } })(this.a,other.a))){
+ return false;
+ }
+ if (this.b == null){
+ if (other.b != null){
+ return false;
+ }
+ } else if (!/* equals */(((o1: any, o2: any) => { if (o1 && o1.equals) { return o1.equals(o2); } else { return o1 === o2; } })(this.b,other.b))){
+ return false;
+ }
+ if (this.c == null){
+ if (other.c != null){
+ return false;
+ }
+ } else if (!/* equals */(((o1: any, o2: any) => { if (o1 && o1.equals) { return o1.equals(o2); } else { return o1 === o2; } })(this.c,other.c))){
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * The pseudoscalar is implied in the result.
+ * @param {com.vzome.core.algebra.Vector3d} v
+ * @return
+ * @return {*}
+ */
+ public outer(v: com.vzome.core.algebra.Vector3d): com.vzome.core.algebra.AlgebraicNumber {
+ const a: com.vzome.core.algebra.AlgebraicNumber = this.a['times$com_vzome_core_algebra_AlgebraicNumber'](v.c);
+ const b: com.vzome.core.algebra.AlgebraicNumber = this.b['times$com_vzome_core_algebra_AlgebraicNumber'](v.a);
+ const c: com.vzome.core.algebra.AlgebraicNumber = this.c['times$com_vzome_core_algebra_AlgebraicNumber'](v.b);
+ return a['plus$com_vzome_core_algebra_AlgebraicNumber'](b)['plus$com_vzome_core_algebra_AlgebraicNumber'](c);
+ }
+ }
+ Bivector3d["__class"] = "com.vzome.core.algebra.Bivector3d";
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/Bivector3dHomogeneous.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/Bivector3dHomogeneous.ts
new file mode 100644
index 000000000..706e4f264
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/Bivector3dHomogeneous.ts
@@ -0,0 +1,46 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export class Bivector3dHomogeneous {
+ e12: com.vzome.core.algebra.AlgebraicNumber;
+
+ e23: com.vzome.core.algebra.AlgebraicNumber;
+
+ e31: com.vzome.core.algebra.AlgebraicNumber;
+
+ e10: com.vzome.core.algebra.AlgebraicNumber;
+
+ e20: com.vzome.core.algebra.AlgebraicNumber;
+
+ e30: com.vzome.core.algebra.AlgebraicNumber;
+
+ /*private*/ field: com.vzome.core.algebra.AlgebraicField;
+
+ public constructor(e12: com.vzome.core.algebra.AlgebraicNumber, e23: com.vzome.core.algebra.AlgebraicNumber, e31: com.vzome.core.algebra.AlgebraicNumber, e10: com.vzome.core.algebra.AlgebraicNumber, e20: com.vzome.core.algebra.AlgebraicNumber, e30: com.vzome.core.algebra.AlgebraicNumber, field: com.vzome.core.algebra.AlgebraicField) {
+ if (this.e12 === undefined) { this.e12 = null; }
+ if (this.e23 === undefined) { this.e23 = null; }
+ if (this.e31 === undefined) { this.e31 = null; }
+ if (this.e10 === undefined) { this.e10 = null; }
+ if (this.e20 === undefined) { this.e20 = null; }
+ if (this.e30 === undefined) { this.e30 = null; }
+ if (this.field === undefined) { this.field = null; }
+ this.e12 = e12;
+ this.e23 = e23;
+ this.e31 = e31;
+ this.e10 = e10;
+ this.e20 = e20;
+ this.e30 = e30;
+ this.field = field;
+ }
+
+ public outer(that: com.vzome.core.algebra.Vector3dHomogeneous): com.vzome.core.algebra.Trivector3dHomogeneous {
+ const e123: com.vzome.core.algebra.AlgebraicNumber = this.e12['times$com_vzome_core_algebra_AlgebraicNumber'](that.e3)['plus$com_vzome_core_algebra_AlgebraicNumber'](this.e23['times$com_vzome_core_algebra_AlgebraicNumber'](that.e1))['plus$com_vzome_core_algebra_AlgebraicNumber'](this.e31['times$com_vzome_core_algebra_AlgebraicNumber'](that.e2));
+ const e310: com.vzome.core.algebra.AlgebraicNumber = this.e10['times$com_vzome_core_algebra_AlgebraicNumber'](that.e3)['plus$com_vzome_core_algebra_AlgebraicNumber'](this.e31['times$com_vzome_core_algebra_AlgebraicNumber'](that.e0))['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e30['times$com_vzome_core_algebra_AlgebraicNumber'](that.e1));
+ const e320: com.vzome.core.algebra.AlgebraicNumber = this.e20['times$com_vzome_core_algebra_AlgebraicNumber'](that.e3)['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e30['times$com_vzome_core_algebra_AlgebraicNumber'](that.e2))['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e23['times$com_vzome_core_algebra_AlgebraicNumber'](that.e0));
+ const e120: com.vzome.core.algebra.AlgebraicNumber = this.e12['times$com_vzome_core_algebra_AlgebraicNumber'](that.e0)['plus$com_vzome_core_algebra_AlgebraicNumber'](this.e20['times$com_vzome_core_algebra_AlgebraicNumber'](that.e1))['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e10['times$com_vzome_core_algebra_AlgebraicNumber'](that.e2));
+ return new com.vzome.core.algebra.Trivector3dHomogeneous(e123, e310, e320, e120, this.field);
+ }
+ }
+ Bivector3dHomogeneous["__class"] = "com.vzome.core.algebra.Bivector3dHomogeneous";
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/EdPeggField.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/EdPeggField.ts
new file mode 100644
index 000000000..454d42b23
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/EdPeggField.ts
@@ -0,0 +1,73 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export class EdPeggField extends com.vzome.core.algebra.ParameterizedField {
+ public static FIELD_NAME: string = "edPegg";
+
+ /**
+ *
+ * @return {double[]} the coefficients of an EdPeggField.
+ * This can be used to determine when two fields have compatible coefficients
+ * without having to generate an instance of the class.
+ */
+ public static getFieldCoefficients(): number[] {
+ const a: number = 1.76929235423863;
+ return [1.0, a, a * a];
+ }
+
+ /**
+ *
+ * @return {number}
+ */
+ public getNumMultipliers(): number {
+ return 1;
+ }
+
+ /**
+ *
+ * @return {double[]}
+ */
+ public getCoefficients(): number[] {
+ return EdPeggField.getFieldCoefficients();
+ }
+
+ public constructor(factory: com.vzome.core.algebra.AlgebraicNumberFactory) {
+ super(EdPeggField.FIELD_NAME, 3, factory);
+ this.initialize();
+ }
+
+ /**
+ *
+ */
+ initializeCoefficients() {
+ const temp: number[] = this.getCoefficients();
+ let i: number = 0;
+ for(let index = 0; index < temp.length; index++) {
+ let coefficient = temp[index];
+ {
+ this.coefficients[i++] = coefficient;
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ initializeMultiplicationTensor() {
+ const mt: number[][][] = [[[1, 0, 0], [0, 0, 2], [0, 2, 0]], [[0, 1, 0], [1, 0, 2], [0, 2, 2]], [[0, 0, 1], [0, 1, 0], [1, 0, 2]]];
+ this.multiplicationTensor = mt;
+ }
+
+ /**
+ *
+ */
+ initializeLabels() {
+ this.irrationalLabels[1] = ["\u03b5", "epsilon"];
+ this.irrationalLabels[2] = ["\u03b5\u00b2", "epsilon^2"];
+ }
+ }
+ EdPeggField["__class"] = "com.vzome.core.algebra.EdPeggField";
+ EdPeggField["__interfaces"] = ["com.vzome.core.algebra.AlgebraicField"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/Fields.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/Fields.ts
new file mode 100644
index 000000000..deb2cf675
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/Fields.ts
@@ -0,0 +1,159 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export class Fields {
+ public static rows(matrix: any[][]): number {
+ return matrix.length;
+ }
+
+ public static columns(matrix: any[][]): number {
+ return matrix[0].length;
+ }
+
+ public static matrixMultiplication>(left: T[][], right: T[][], product: T[][]) {
+ if (Fields.rows(right) !== Fields.columns(left))throw new java.lang.IllegalArgumentException("matrices cannot be multiplied");
+ if (Fields.rows(product) !== Fields.rows(left))throw new java.lang.IllegalArgumentException("product matrix has wrong number of rows");
+ if (Fields.columns(right) !== Fields.columns(product))throw new java.lang.IllegalArgumentException("product matrix has wrong number of columns");
+ for(let i: number = 0; i < Fields.rows(product); i++) {{
+ for(let j: number = 0; j < Fields.columns(product); j++) {{
+ let sum: T = null;
+ for(let j2: number = 0; j2 < Fields.columns(left); j2++) {{
+ const prod: T = left[i][j2].times(right[j2][j]);
+ if (sum == null)sum = prod; else sum = sum.plus(prod);
+ };}
+ product[i][j] = sum;
+ };}
+ };}
+ }
+
+ public static gaussJordanReduction$com_vzome_core_algebra_Fields_Element_A_A>(matrix: T[][]): number {
+ return Fields.gaussJordanReduction$com_vzome_core_algebra_Fields_Element_A_A$com_vzome_core_algebra_Fields_Element_A_A(matrix, matrix);
+ }
+
+ public static gaussJordanReduction$com_vzome_core_algebra_Fields_Element_A_A$com_vzome_core_algebra_Fields_Element_A_A>(immutableMatrix: T[][], adjoined: T[][]): number {
+ const nRows: number = Fields.rows(immutableMatrix);
+ const matrix: any[][] = Fields.copyOf(immutableMatrix);
+ let rank: number = 0;
+ for(let col: number = 0; col < Fields.columns(matrix); col++) {{
+ let pivotRow: number = -1;
+ for(let row: number = rank; row < nRows; row++) {{
+ const element: T = matrix[row][col];
+ if (!element.isZero()){
+ pivotRow = row;
+ break;
+ }
+ };}
+ if (pivotRow >= 0){
+ if (pivotRow !== rank){
+ Fields.swap(matrix, rank, pivotRow);
+ Fields.swap(adjoined, rank, pivotRow);
+ pivotRow = rank;
+ }
+ let scalar: T = matrix[pivotRow][col];
+ if (!scalar.isOne()){
+ scalar = scalar.reciprocal();
+ Fields.scale(matrix[pivotRow], scalar);
+ Fields.scale(adjoined[pivotRow], scalar);
+ }
+ for(let row: number = 0; row < nRows; row++) {{
+ if (row !== pivotRow){
+ scalar = (matrix[row][col]);
+ if (!scalar.isZero()){
+ scalar = scalar.negate();
+ Fields.pivot(matrix, row, scalar, pivotRow);
+ Fields.pivot(adjoined, row, scalar, pivotRow);
+ }
+ }
+ };}
+ rank++;
+ }
+ };}
+ return rank;
+ }
+
+ public static gaussJordanReduction(immutableMatrix?: any, adjoined?: any): number {
+ if (((immutableMatrix != null && immutableMatrix instanceof Array && (immutableMatrix.length == 0 || immutableMatrix[0] == null ||immutableMatrix[0] instanceof Array)) || immutableMatrix === null) && ((adjoined != null && adjoined instanceof Array && (adjoined.length == 0 || adjoined[0] == null ||adjoined[0] instanceof Array)) || adjoined === null)) {
+ return com.vzome.core.algebra.Fields.gaussJordanReduction$com_vzome_core_algebra_Fields_Element_A_A$com_vzome_core_algebra_Fields_Element_A_A(immutableMatrix, adjoined);
+ } else if (((immutableMatrix != null && immutableMatrix instanceof Array && (immutableMatrix.length == 0 || immutableMatrix[0] == null ||immutableMatrix[0] instanceof Array)) || immutableMatrix === null) && adjoined === undefined) {
+ return com.vzome.core.algebra.Fields.gaussJordanReduction$com_vzome_core_algebra_Fields_Element_A_A(immutableMatrix);
+ } else throw new Error('invalid overload');
+ }
+
+ static copyOf>(matrix: T[][]): any[][] {
+ const nRows: number = Fields.rows(matrix);
+ const nCols: number = Fields.columns(matrix);
+ const copy: any[][] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(nRows);
+ for(let i: number = 0; i < nRows; i++) {{
+ copy[i] = java.util.Arrays.copyOf(matrix[i], nCols);
+ };}
+ return copy;
+ }
+
+ /**
+ *
+ * @param {java.lang.Object[]} array of elements to be swapped
+ * @param {number} r index of the first element to be swapped
+ * @param {number} s index of the second element to be swapped
+ *
+ * Note that since Java implements a multi-dimensional array as an array of arrays,
+ * the {@code array} parameter can be an {@code Object[][]} in which case
+ * entire rows are swapped rather than an element at a time.
+ * Besides being more efficient at run time, this also means
+ * that rows of multi-dimensional arrays do not necessarily have to be the same length.
+ * @private
+ */
+ static swap(array: any[], r: number, s: number) {
+ const temp: any = array[r];
+ array[r] = array[s];
+ array[s] = temp;
+ }
+
+ static scale>(array: T[], scalar: T) {
+ for(let col: number = 0; col < array.length; col++) {{
+ array[col] = scalar.times(array[col]);
+ };}
+ }
+
+ static pivot>(matrix: any[][], row: number, scalar: T, rank: number) {
+ for(let col: number = 0; col < Fields.columns(matrix); col++) {{
+ matrix[row][col] = (matrix[row][col]).plus((matrix[rank][col]).times(scalar));
+ };}
+ }
+ }
+ Fields["__class"] = "com.vzome.core.algebra.Fields";
+
+
+ export namespace Fields {
+
+ export interface RationalElement extends Fields.Element {
+ getNumerator(): R;
+
+ getDenominator(): R;
+
+ dividedBy(that: T): T;
+ }
+
+ export interface Element {
+ times(that: T): T;
+
+ timesInt(that: number): T;
+
+ plus(that: T): T;
+
+ minus(that: T): T;
+
+ reciprocal(): T;
+
+ negate(): T;
+
+ isZero(): boolean;
+
+ isOne(): boolean;
+
+ evaluate(): number;
+
+ getMathML(): string;
+ }
+ }
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/ParameterizedField.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/ParameterizedField.ts
new file mode 100644
index 000000000..6c9569b7d
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/ParameterizedField.ts
@@ -0,0 +1,168 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ /**
+ * @author David Hall
+ * @param {string} name
+ * @param {number} order
+ * @param {*} factory
+ * @class
+ * @extends com.vzome.core.algebra.AbstractAlgebraicField
+ */
+ export abstract class ParameterizedField extends com.vzome.core.algebra.AbstractAlgebraicField {
+ coefficients: number[];
+
+ multiplicationTensor: number[][][];
+
+ irrationalLabels: string[][];
+
+ public constructor(name: string, order: number, factory: com.vzome.core.algebra.AlgebraicNumberFactory) {
+ super(name, order, factory);
+ if (this.coefficients === undefined) { this.coefficients = null; }
+ if (this.multiplicationTensor === undefined) { this.multiplicationTensor = null; }
+ if (this.irrationalLabels === undefined) { this.irrationalLabels = null; }
+ this.normalizer = (field,factors) => { return ParameterizedField.doNothing(field,factors) };
+ this.coefficients = (s => { let a=[]; while(s-->0) a.push(0); return a; })(order);
+ this.multiplicationTensor = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return 0; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([order, order, order]);
+ this.irrationalLabels = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return null; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([order, 2]);
+ this.irrationalLabels[0] = [" ", " "];
+ }
+
+ /**
+ * doNothing is the default normalizer method.
+ * @param {com.vzome.core.algebra.BigRational[]} factors
+ * @param {*} field
+ */
+ static doNothing(field: com.vzome.core.algebra.AlgebraicField, factors: com.vzome.core.algebra.BigRational[]) {
+ }
+
+ /**
+ * Subclasses may need different normalization methods based on their parameters.
+ * For example, SqrtField(2) doesn't need normalization, but SqrtField(4) does since 4 is a perfect square
+ * By assigning an appropriate normalizer method once in the c'tor,
+ * the method can avoid the repeated overhead of checking isPerfectSquare() within the normalizer method itself.
+ */
+ normalizer: (p1: com.vzome.core.algebra.AlgebraicField, p2: com.vzome.core.algebra.BigRational[]) => void;
+
+ /**
+ *
+ * @param {com.vzome.core.algebra.BigRational[]} factors
+ */
+ normalize(factors: com.vzome.core.algebra.BigRational[]) {
+ (target => (typeof target === 'function') ? target(this, factors) : (target).accept(this, factors))(this.normalizer);
+ }
+
+ initialize() {
+ this.initializeNormalizer();
+ this.initializeMultiplicationTensor();
+ this.initializeCoefficients();
+ this.initializeLabels();
+ }
+
+ initializeNormalizer() {
+ this.normalizer = (field,factors) => { return ParameterizedField.doNothing(field,factors) };
+ }
+
+ abstract initializeMultiplicationTensor();
+
+ abstract initializeCoefficients();
+
+ abstract initializeLabels();
+
+ /**
+ *
+ * @param {com.vzome.core.algebra.BigRational[]} v1
+ * @param {com.vzome.core.algebra.BigRational[]} v2
+ * @return {com.vzome.core.algebra.BigRational[]}
+ */
+ multiply(v1: com.vzome.core.algebra.BigRational[], v2: com.vzome.core.algebra.BigRational[]): com.vzome.core.algebra.BigRational[] {
+ const order: number = this.getOrder();
+ const result: com.vzome.core.algebra.BigRational[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(order);
+ for(let i: number = 0; i < order; i++) {{
+ result[i] = this.numberFactory.zero();
+ for(let j: number = 0; j < order; j++) {{
+ for(let k: number = 0; k < order; k++) {{
+ const multiplier: number = this.multiplicationTensor[i][j][k];
+ if (multiplier !== 0){
+ let product: com.vzome.core.algebra.BigRational = v1[j].times(v2[k]);
+ if (multiplier !== 1){
+ product = product.timesInt(multiplier);
+ }
+ result[i] = result[i].plus(product);
+ }
+ };}
+ };}
+ };}
+ return result;
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.algebra.BigRational[]} factors
+ * @param {number} whichIrrational
+ * @return {com.vzome.core.algebra.BigRational[]}
+ */
+ scaleBy(factors: com.vzome.core.algebra.BigRational[], whichIrrational: number): com.vzome.core.algebra.BigRational[] {
+ if (whichIrrational === 0){
+ return factors;
+ }
+ const order: number = this.getOrder();
+ const result: com.vzome.core.algebra.BigRational[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(order);
+ for(let i: number = 0; i < order; i++) {{
+ result[i] = this.numberFactory.zero();
+ for(let j: number = 0; j < order; j++) {{
+ const multiplier: number = this.multiplicationTensor[i][j][whichIrrational];
+ if (multiplier !== 0){
+ if (multiplier === 1){
+ result[i] = result[i].plus(factors[j]);
+ } else {
+ result[i] = result[i].plus(factors[j].timesInt(multiplier));
+ }
+ }
+ };}
+ };}
+ this.normalize(result);
+ return result;
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.algebra.BigRational[]} factors
+ * @return {number}
+ */
+ evaluateNumber(factors: com.vzome.core.algebra.BigRational[]): number {
+ let result: number = 0.0;
+ const order: number = this.getOrder();
+ for(let i: number = 0; i < order; i++) {{
+ result += factors[i].evaluate() * this.coefficients[i];
+ };}
+ return result;
+ }
+
+ public getIrrational$int$int(i: number, format: number): string {
+ return this.irrationalLabels[i][format];
+ }
+
+ /**
+ *
+ * @param {number} i
+ * @param {number} format
+ * @return {string}
+ */
+ public getIrrational(i?: any, format?: any): string {
+ if (((typeof i === 'number') || i === null) && ((typeof format === 'number') || format === null)) {
+ return this.getIrrational$int$int(i, format);
+ } else if (((typeof i === 'number') || i === null) && format === undefined) {
+ return this.getIrrational$int(i);
+ } else throw new Error('invalid overload');
+ }
+
+ public getCoefficient(i: number): number {
+ return this.coefficients[i];
+ }
+ }
+ ParameterizedField["__class"] = "com.vzome.core.algebra.ParameterizedField";
+ ParameterizedField["__interfaces"] = ["com.vzome.core.algebra.AlgebraicField"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/PlasticNumberField.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/PlasticNumberField.ts
new file mode 100644
index 000000000..7691c5cca
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/PlasticNumberField.ts
@@ -0,0 +1,80 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ /**
+ * @author David Hall
+ * @param {*} factory
+ * @class
+ * @extends com.vzome.core.algebra.ParameterizedField
+ */
+ export class PlasticNumberField extends com.vzome.core.algebra.ParameterizedField {
+ public static FIELD_NAME: string = "plasticNumber";
+
+ /**
+ *
+ * @return {double[]} the coefficients of a PlasticNumberField.
+ * This can be used to determine when two fields have compatible coefficients
+ * without having to generate an instance of the class.
+ */
+ public static getFieldCoefficients(): number[] {
+ const plasticNumber: number = 1.32471795724475;
+ return [1.0, plasticNumber, plasticNumber * plasticNumber];
+ }
+
+ /**
+ *
+ * @return {number}
+ */
+ public getNumMultipliers(): number {
+ return 1;
+ }
+
+ /**
+ *
+ * @return {double[]}
+ */
+ public getCoefficients(): number[] {
+ return PlasticNumberField.getFieldCoefficients();
+ }
+
+ public constructor(factory: com.vzome.core.algebra.AlgebraicNumberFactory) {
+ super(PlasticNumberField.FIELD_NAME, 3, factory);
+ this.initialize();
+ }
+
+ /**
+ *
+ */
+ initializeCoefficients() {
+ const temp: number[] = this.getCoefficients();
+ let i: number = 0;
+ for(let index = 0; index < temp.length; index++) {
+ let coefficient = temp[index];
+ {
+ this.coefficients[i++] = coefficient;
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ initializeMultiplicationTensor() {
+ const tensor: number[][][] = [[[1, 0, 0], [0, 0, 1], [0, 1, 0]], [[0, 1, 0], [1, 0, 1], [0, 1, 1]], [[0, 0, 1], [0, 1, 0], [1, 0, 1]]];
+ this.multiplicationTensor = tensor;
+ }
+
+ /**
+ *
+ */
+ initializeLabels() {
+ const upperRho: string = "\u03a1";
+ this.irrationalLabels[1] = [upperRho, "P"];
+ this.irrationalLabels[2] = [upperRho + "\u00b2", "P^2"];
+ }
+ }
+ PlasticNumberField["__class"] = "com.vzome.core.algebra.PlasticNumberField";
+ PlasticNumberField["__interfaces"] = ["com.vzome.core.algebra.AlgebraicField"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/PlasticPhiField.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/PlasticPhiField.ts
new file mode 100644
index 000000000..ea93ada79
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/PlasticPhiField.ts
@@ -0,0 +1,86 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export class PlasticPhiField extends com.vzome.core.algebra.ParameterizedField {
+ public static FIELD_NAME: string = "plasticPhi";
+
+ /**
+ * @return {double[]} the coefficients of a PlasticPhiField.
+ * This can be used to determine when two fields have compatible coefficients
+ * without having to generate an instance of the class.
+ */
+ public static getFieldCoefficients(): number[] {
+ const plasticNumber: number = 1.32471795724475;
+ const phi: number = (1.0 + Math.sqrt(5)) / 2.0;
+ return [1.0, phi, plasticNumber, plasticNumber * phi, plasticNumber * plasticNumber, plasticNumber * plasticNumber * phi];
+ }
+
+ /**
+ *
+ * @return {number}
+ */
+ public getNumMultipliers(): number {
+ return 2;
+ }
+
+ /**
+ *
+ * @return {double[]}
+ */
+ public getCoefficients(): number[] {
+ return PlasticPhiField.getFieldCoefficients();
+ }
+
+ public constructor(factory: com.vzome.core.algebra.AlgebraicNumberFactory) {
+ super(PlasticPhiField.FIELD_NAME, 6, factory);
+ this.initialize();
+ }
+
+ /**
+ *
+ */
+ initializeCoefficients() {
+ const temp: number[] = this.getCoefficients();
+ let i: number = 0;
+ for(let index = 0; index < temp.length; index++) {
+ let coefficient = temp[index];
+ {
+ this.coefficients[i++] = coefficient;
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ initializeMultiplicationTensor() {
+ const tensor: number[][][] = [[[1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0]], [[0, 1, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1, 1], [0, 0, 0, 1, 0, 0], [0, 0, 1, 1, 0, 0]], [[0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 1, 0], [0, 1, 0, 0, 0, 1], [0, 0, 1, 0, 1, 0], [0, 0, 0, 1, 0, 1]], [[0, 0, 0, 1, 0, 0], [0, 0, 1, 1, 0, 0], [0, 1, 0, 0, 0, 1], [1, 1, 0, 0, 1, 1], [0, 0, 0, 1, 0, 1], [0, 0, 1, 1, 1, 1]], [[0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 1, 0], [0, 1, 0, 0, 0, 1]], [[0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1, 1], [0, 0, 0, 1, 0, 0], [0, 0, 1, 1, 0, 0], [0, 1, 0, 0, 0, 1], [1, 1, 0, 0, 1, 1]]];
+ this.multiplicationTensor = tensor;
+ }
+
+ /**
+ *
+ */
+ initializeLabels() {
+ const upperRho: string = "\u03a1";
+ const lowerPhi: string = "\u03c6";
+ this.irrationalLabels[1] = [lowerPhi, "phi"];
+ this.irrationalLabels[2] = [upperRho, "P"];
+ this.irrationalLabels[3] = [upperRho + "\u03c6", "Pphi"];
+ this.irrationalLabels[4] = [upperRho + "\u00b2", "P^2"];
+ this.irrationalLabels[5] = [upperRho + "\u00b2\u03c6", "P^2phi"];
+ }
+
+ /**
+ *
+ * @return {*}
+ */
+ public getGoldenRatio(): com.vzome.core.algebra.AlgebraicNumber {
+ return this.getUnitTerm(1);
+ }
+ }
+ PlasticPhiField["__class"] = "com.vzome.core.algebra.PlasticPhiField";
+ PlasticPhiField["__interfaces"] = ["com.vzome.core.algebra.AlgebraicField"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/PolygonField.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/PolygonField.ts
new file mode 100644
index 000000000..76b46f33e
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/PolygonField.ts
@@ -0,0 +1,660 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ /**
+ * @author David Hall
+ * @param {number} polygonSides
+ * @param {*} factory
+ * @class
+ * @extends com.vzome.core.algebra.ParameterizedField
+ */
+ export class PolygonField extends com.vzome.core.algebra.ParameterizedField {
+ static PI: number = 3.141592653589793;
+
+ /**
+ *
+ * @param {number} nSides
+ * @return {double[]} the coefficients of a PolygonField given the same parameter.
+ * This can be used to determine when two fields have compatible coefficients
+ * without having to generate an instance of the class.
+ */
+ public static getFieldCoefficients(nSides: number): number[] {
+ const order: number = PolygonField.getOrder(nSides);
+ const coefficients: number[] = (s => { let a=[]; while(s-->0) a.push(0); return a; })(order);
+ const diagLengths: number[] = PolygonField.getDiagonalLengths(nSides);
+ for(let i: number = 0; i < order; i++) {{
+ coefficients[i] = diagLengths[i];
+ };}
+ return coefficients;
+ }
+
+ /**
+ *
+ * @param {number} nSides
+ * @return {double[]} an array with the unique lengths in increasing order
+ * of the diagonals of a regular N-gon having a unit edge length.
+ */
+ public static getDiagonalLengths(nSides: number): number[] {
+ const count: number = PolygonField.diagonalCount(nSides);
+ const diagLengths: number[] = (s => { let a=[]; while(s-->0) a.push(0); return a; })(count);
+ const unitLength: number = Math.sin(PolygonField.PI / nSides);
+ diagLengths[0] = 1.0;
+ for(let i: number = 1; i < count; i++) {{
+ diagLengths[i] = Math.sin((i + 1) * PolygonField.PI / nSides) / unitLength;
+ };}
+ switch((nSides)) {
+ case 6:
+ diagLengths[2] = 2.0;
+ diagLengths[1] = Math.sqrt(3);
+ break;
+ case 5:
+ diagLengths[1] = (1.0 + Math.sqrt(5.0)) / 2.0;
+ break;
+ }
+ return diagLengths;
+ }
+
+ public static FIELD_PREFIX: string = "polygon";
+
+ public static getOrder(nSides: number): number {
+ return PolygonField.primaryDiagonalCount(nSides);
+ }
+
+ public static diagonalCount(nSides: number): number {
+ return (nSides / 2|0);
+ }
+
+ public static primaryDiagonalCount(nSides: number): number {
+ return (((n => n<0?Math.ceil(n):Math.floor(n))(PolygonField.eulerTotient(2 * nSides) / 2))|0);
+ }
+
+ public static secondaryDiagonalCount(nSides: number): number {
+ return PolygonField.diagonalCount(nSides) - PolygonField.primaryDiagonalCount(nSides);
+ }
+
+ public static eulerTotient(n: number): number {
+ let result: number = n;
+ for(let i: number = 2; i * i <= n; i++) {{
+ if (n % i === 0)result -= (n => n<0?Math.ceil(n):Math.floor(n))(result / i);
+ while((n % i === 0)) {{
+ n = (n => n<0?Math.ceil(n):Math.floor(n))(n / i);
+ }};
+ };}
+ if (n > 1){
+ result -= (n => n<0?Math.ceil(n):Math.floor(n))(result / n);
+ }
+ return result;
+ }
+
+ public static isPowerOfTwo(n: number): boolean {
+ return (n !== 0) && ((n & -n) === n);
+ }
+
+ public isPrime(n: number): boolean {
+ return this.numberFactory.isPrime(n);
+ }
+
+ /*private*/ distinctPrimeFactors(n: number): java.util.List {
+ const factors: java.util.List = (new java.util.ArrayList());
+ for(let prime: number = 2; prime <= n; prime = this.numberFactory.nextPrime(prime)) {{
+ if (n % prime === 0){
+ factors.add(prime);
+ }
+ while((n % prime === 0)) {{
+ n = (n => n<0?Math.ceil(n):Math.floor(n))(n / prime);
+ }};
+ };}
+ return factors;
+ }
+
+ public getNormalizedMultiplicationTensor(nSides: number): number[][][] {
+ const tensor: number[][][] = PolygonField.getExtendedMultiplicationTensor(nSides);
+ if (this.isPrime(nSides) || PolygonField.isPowerOfTwo(nSides)){
+ return tensor;
+ }
+ const length: number = PolygonField.primaryDiagonalCount(nSides);
+ const result: number[][][] = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return 0; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([length, length, length]);
+ for(let i: number = 0; i < length; i++) {{
+ for(let j: number = 0; j < length; j++) {{
+ for(let k: number = 0; k < length; k++) {{
+ result[i][j][k] = tensor[i][j][k];
+ };}
+ };}
+ };}
+ const normalizerMatrix: number[][] = this.getNormalizerMatrix(nSides);
+ let n: number = 0;
+ for(let term: number = length; term < PolygonField.diagonalCount(nSides); term++) {{
+ for(let r: number = 0; r < length; r++) {{
+ for(let c: number = 0; c < length; c++) {{
+ const omit: number = tensor[term][r][c];
+ if (omit !== 0){
+ for(let t: number = 0; t < length; t++) {{
+ const alt: number = normalizerMatrix[n][t];
+ if (alt !== 0){
+ const adjust: number = omit * alt;
+ result[t][r][c] = ((result[t][r][c] + adjust)|0);
+ }
+ };}
+ }
+ };}
+ };}
+ n++;
+ };}
+ return result;
+ }
+
+ public getNormalizerMatrix(nSides: number): number[][] {
+ if (nSides < PolygonField.MIN_SIDES){
+ throw new java.lang.IllegalArgumentException("nSides = " + nSides + " but must be greater than or equal to " + PolygonField.MIN_SIDES);
+ }
+ const nSecondaryDiags: number = PolygonField.secondaryDiagonalCount(nSides);
+ if (nSecondaryDiags === 0){
+ return null;
+ }
+ const nPrimaryDiags: number = PolygonField.primaryDiagonalCount(nSides);
+ const nDiags: number = nPrimaryDiags + nSecondaryDiags;
+ const primeFactors: java.util.List = this.distinctPrimeFactors(nSides);
+ if (primeFactors.get(0) === 2){
+ primeFactors.remove(0);
+ }
+ let nEquations: number = 0;
+ for(let index=primeFactors.iterator();index.hasNext();) {
+ let prime = index.next();
+ {
+ nEquations += (nDiags / /* intValue */(prime|0)|0);
+ }
+ }
+ const primaryDiags: com.vzome.core.algebra.BigRational[][] = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return null; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([nEquations, nPrimaryDiags]);
+ const secondaryDiags: com.vzome.core.algebra.BigRational[][] = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return null; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([nEquations, nSecondaryDiags]);
+ let equationRow: number = 0;
+ for(let index=primeFactors.iterator();index.hasNext();) {
+ let factor = index.next();
+ {
+ const period: number = (nSides / factor|0);
+ const steps: number = (period / 2|0);
+ const parity: number = period % 2;
+ for(let step: number = 0; step < steps; step++) {{
+ let n: number = (step === 0 && parity === 0) ? 2 : 1;
+ if (nSides % 2 === parity){
+ n *= -1;
+ }
+ const terms: number[] = (s => { let a=[]; while(s-->0) a.push(0); return a; })(nDiags);
+ terms[step] = 1;
+ for(let mid: number = period - parity; mid < nDiags; mid += period) {{
+ terms[mid + step + parity] = terms[mid - step] = n;
+ n *= -1;
+ };}
+ primaryDiags[equationRow] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(nPrimaryDiags);
+ secondaryDiags[equationRow] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(nSecondaryDiags);
+ for(let t: number = 0; t < terms.length; t++) {{
+ let term: number = terms[t];
+ if (t < nSecondaryDiags){
+ secondaryDiags[equationRow][t] = this.numberFactory.createBigRational(term, 1);
+ } else {
+ term *= -1;
+ primaryDiags[equationRow][t - nSecondaryDiags] = this.numberFactory.createBigRational(term, 1);
+ }
+ };}
+ equationRow++;
+ };}
+ }
+ }
+ const rank: number = com.vzome.core.algebra.Fields.gaussJordanReduction$com_vzome_core_algebra_Fields_Element_A_A$com_vzome_core_algebra_Fields_Element_A_A(secondaryDiags, primaryDiags);
+ if (rank !== nSecondaryDiags){
+ throw new java.lang.IllegalStateException("System of equations has unexpected rank: " + rank);
+ }
+ for(let r: number = rank; r < primaryDiags.length; r++) {{
+ for(let c: number = 0; c < primaryDiags[0].length; c++) {{
+ if (!primaryDiags[r][c].isZero()){
+ throw new java.lang.IllegalStateException("System of equations is inconsistent. Rank = " + rank);
+ }
+ };}
+ };}
+ const results: number[][] = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return 0; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([rank, nPrimaryDiags]);
+ for(let r: number = 0; r < rank; r++) {{
+ for(let c: number = nPrimaryDiags - 1; c >= 0; c--) {{
+ const bigTerm: com.vzome.core.algebra.BigRational = primaryDiags[rank - 1 - r][nPrimaryDiags - 1 - c];
+ results[r][c] = /* shortValue */(javaemul.internal.DoubleHelper.valueOf(bigTerm.evaluate())|0);
+ };}
+ };}
+ return results;
+ }
+
+ public static getExtendedMultiplicationTensor(nSides: number): number[][][] {
+ const nDiags: number = PolygonField.diagonalCount(nSides);
+ const tensor: number[][][] = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return 0; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([nDiags, nDiags, nDiags]);
+ for(let i: number = 0; i < nDiags; i++) {{
+ for(let j: number = 0; j < nDiags; j++) {{
+ for(let k: number = 0; k < nDiags; k++) {{
+ tensor[i][j][k] = 0;
+ };}
+ };}
+ };}
+ for(let layer: number = 0; layer < nDiags; layer++) {{
+ const midWay: number = (layer / 2|0);
+ for(let bx: number = layer, by: number = 0; bx > midWay || bx === by; bx--, by++) {{
+ for(let x: number = bx, y: number = by; x < nDiags && y < nDiags; x++, y++) {{
+ tensor[layer][y][x] += 1;
+ if (x !== y){
+ tensor[layer][x][y] += 1;
+ }
+ };}
+ };}
+ };}
+ const box: number = nSides - 2;
+ const parity: number = (nSides + 1) % 2;
+ for(let layer: number = 0; layer < nDiags - parity; layer++) {{
+ const base: number = box - layer;
+ for(let xb: number = base, yb: number = 0; xb >= 0; xb--, yb++) {{
+ let x: number = xb;
+ let y: number = yb;
+ while((x < nDiags && y < nDiags)) {{
+ tensor[layer][y][x] += 1;
+ x++;
+ y++;
+ }};
+ };}
+ };}
+ return tensor;
+ }
+
+ public static subscriptString(i: number): string {
+ return /* replace *//* replace *//* replace *//* replace *//* replace *//* replace *//* replace *//* replace *//* replace *//* replace *//* replace *//* replace *//* toString */(''+(i)).split("0").join("\u2080").split("1").join("\u2081").split("2").join("\u2082").split("3").join("\u2083").split("4").join("\u2084").split("5").join("\u2085").split("6").join("\u2086").split("7").join("\u2087").split("8").join("\u2088").split("9").join("\u2089").split("+").join("\u208a").split("-").join("\u208b");
+ }
+
+ public static MIN_SIDES: number = 4;
+
+ /*private*/ __isEven: boolean;
+
+ /*private*/ goldenRatio: com.vzome.core.algebra.AlgebraicNumber;
+
+ /*private*/ __polygonSides: number;
+
+ public constructor(name?: any, polygonSides?: any, factory?: any) {
+ if (((typeof name === 'string') || name === null) && ((typeof polygonSides === 'number') || polygonSides === null) && ((factory != null && (factory.constructor != null && factory.constructor["__interfaces"] != null && factory.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumberFactory") >= 0)) || factory === null)) {
+ let __args = arguments;
+ super(name, PolygonField.getOrder(polygonSides), factory);
+ if (this.__isEven === undefined) { this.__isEven = false; }
+ if (this.goldenRatio === undefined) { this.goldenRatio = null; }
+ if (this.__polygonSides === undefined) { this.__polygonSides = 0; }
+ if (this.normalizerMatrix === undefined) { this.normalizerMatrix = null; }
+ this.__polygonSides = polygonSides;
+ this.validate();
+ this.initialize();
+ this.__isEven = polygonSides % 2 === 0;
+ this.goldenRatio = this.getDiagonalRatio$int(5);
+ } else if (((typeof name === 'number') || name === null) && ((polygonSides != null && (polygonSides.constructor != null && polygonSides.constructor["__interfaces"] != null && polygonSides.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumberFactory") >= 0)) || polygonSides === null) && factory === undefined) {
+ let __args = arguments;
+ let polygonSides: any = __args[0];
+ let factory: any = __args[1];
+ {
+ let __args = arguments;
+ let name: any = PolygonField.FIELD_PREFIX + __args[1];
+ super(name, PolygonField.getOrder(polygonSides), factory);
+ if (this.__isEven === undefined) { this.__isEven = false; }
+ if (this.goldenRatio === undefined) { this.goldenRatio = null; }
+ if (this.__polygonSides === undefined) { this.__polygonSides = 0; }
+ if (this.normalizerMatrix === undefined) { this.normalizerMatrix = null; }
+ this.__polygonSides = polygonSides;
+ this.validate();
+ this.initialize();
+ this.__isEven = polygonSides % 2 === 0;
+ this.goldenRatio = this.getDiagonalRatio$int(5);
+ }
+ } else throw new Error('invalid overload');
+ }
+
+ /**
+ *
+ * u = units numerator
+ * U = units denominator
+ * p = phis numerator
+ * P = phis denominator
+ * ____ = 0,1
+ * COMBO ... see comments inline below
+ * Remapping the 4 element pairs array [u,U, p,P]
+ * looks like this based on polygonSides:
+ * 5 [ u, U, p, P] // unchanged
+ * 10 [ COMBO, ____, p, P ... // the two units elements combine all of the input pairs
+ * 15 [ u, U, -p,-P, ____, p, P ...
+ * 20 [ u, U, ____, -p,-P, ____, p, P ...
+ * 25 [ u, U, ____, ____, -p,-P, ____, p, P ...
+ * 30 [ u, U, ____, ____, ____, -p,-P, ____, p, P ...
+ * 35 [ u, U, ____, ____, ____, ____, -p,-P, ____, p, P ...
+ * 40 [ u, U, ____, ____, ____, ____, ____, -p,-P, ____, p, P ...
+ * 45 [ u, U, ____, ____, ____, ____, ____, ____, -p,-P, ____, p, P ...
+ * index 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
+ * @param {long[]} pairs
+ * @return {long[]}
+ */
+ convertGoldenNumberPairs(pairs: number[]): number[] {
+ if (this.__polygonSides % 5 === 0 && pairs.length === 4 && this.getOrder() > 2){
+ const u: number = pairs[0];
+ const U: number = pairs[1];
+ const p: number = pairs[2];
+ const P: number = pairs[3];
+ const remapped: number[] = (s => { let a=[]; while(s-->0) a.push(0); return a; })(2 * this.getOrder());
+ for(let den: number = 1; den < remapped.length; den += 2) {{
+ remapped[den] = 1;
+ };}
+ const i: number = ((this.__polygonSides / 5|0)) * 2;
+ remapped[i - 4] = -p;
+ remapped[i - 3] = P;
+ remapped[i + 0] = p;
+ remapped[i + 1] = P;
+ if (this.__polygonSides === 10){
+ remapped[0] = PolygonField.safeSubtract((u * P), (U * p));
+ remapped[1] = U * P;
+ } else {
+ remapped[0] = u;
+ remapped[1] = U;
+ }
+ return remapped;
+ }
+ return pairs;
+ }
+
+ /**
+ * @param {number} j
+ * @param {number} k
+ * @return {number} a long that equals j - k
+ * @throws ArithmeticException if the subtraction causes an integer overflow
+ */
+ static safeSubtract(j: number, k: number): number {
+ const result: number = j - k;
+ if ((k > 0 && result >= j) || (k < 0 && result <= j)){
+ throw new java.lang.ArithmeticException("Arithmetic Overflow: " + j + " - " + k + " = " + result + ". Result exceeds the size of a long.");
+ }
+ return result;
+ }
+
+ public diagonalCount(): number {
+ return PolygonField.diagonalCount(this.polygonSides());
+ }
+
+ /**
+ *
+ * @return {double[]}
+ */
+ public getCoefficients(): number[] {
+ return PolygonField.getFieldCoefficients(this.polygonSides());
+ }
+
+ /**
+ *
+ * @return {*}
+ */
+ public getAffineScalar(): com.vzome.core.algebra.AlgebraicNumber {
+ return this.getUnitDiagonal(2);
+ }
+
+ validate() {
+ if (this.polygonSides() < PolygonField.MIN_SIDES){
+ const msg: string = "polygon sides = " + this.polygonSides() + ". It must be at least " + PolygonField.MIN_SIDES + ".";
+ throw new java.lang.IllegalArgumentException(msg);
+ }
+ }
+
+ /**
+ *
+ */
+ initializeLabels() {
+ const nSides: number = this.polygonSides();
+ if (this.irrationalLabels.length !== PolygonField.diagonalCount(nSides)){
+ const unitLabels: string[] = this.irrationalLabels[0];
+ this.irrationalLabels = (function(dims) { let allocate = function(dims) { if (dims.length === 0) { return null; } else { let array = []; for(let i = 0; i < dims[0]; i++) { array.push(allocate(dims.slice(1))); } return array; }}; return allocate(dims);})([PolygonField.diagonalCount(nSides), unitLabels.length]);
+ this.irrationalLabels[0] = unitLabels;
+ }
+ switch((this.polygonSides())) {
+ case 4:
+ this.irrationalLabels[1] = ["\u221a2", "sqrtTwo"];
+ break;
+ case 5:
+ this.irrationalLabels[1] = ["\u03c6", "phi"];
+ break;
+ case 6:
+ this.irrationalLabels[1] = ["\u221a3", "sqrtThree"];
+ this.irrationalLabels[2] = ["\u03b2", "beta"];
+ break;
+ case 7:
+ this.irrationalLabels[1] = ["\u03c1", "rho"];
+ this.irrationalLabels[2] = ["\u03c3", "sigma"];
+ break;
+ case 9:
+ this.irrationalLabels[1] = ["\u03b1", "alpha"];
+ this.irrationalLabels[2] = ["\u03b2", "beta"];
+ this.irrationalLabels[3] = ["\u03b3", "gamma"];
+ break;
+ case 11:
+ this.irrationalLabels[1] = ["\u03b8", "theta"];
+ this.irrationalLabels[2] = ["\u03ba", "kappa"];
+ this.irrationalLabels[3] = ["\u03bb", "lambda"];
+ this.irrationalLabels[4] = ["\u03bc", "mu"];
+ break;
+ case 13:
+ this.irrationalLabels[1] = ["\u03b1", "alpha"];
+ this.irrationalLabels[2] = ["\u03b2", "beta"];
+ this.irrationalLabels[3] = ["\u03b3", "gamma"];
+ this.irrationalLabels[4] = ["\u03b4", "delta"];
+ this.irrationalLabels[5] = ["\u03b5", "epsilon"];
+ break;
+ default:
+ const alphabet: string = "abcdefghijklmnopqrstuvwxyz";
+ const length: number = this.irrationalLabels.length;
+ if (length - 1 <= alphabet.length){
+ for(let i: number = 1; i < length; i++) {{
+ const name: string = alphabet.substring(i - 1, i);
+ this.irrationalLabels[i] = [name, "d[" + i + "]"];
+ };}
+ } else {
+ for(let i: number = 1; i < this.irrationalLabels.length; i++) {{
+ this.irrationalLabels[i] = ["d" + PolygonField.subscriptString(i), "d[" + i + "]"];
+ };}
+ }
+ break;
+ }
+ }
+
+ /**
+ * getUnitTerm(n) expects n < getOrder().
+ * This method handles normalized diagonal lengths
+ * where getOrder() <= n < diagonalCount()
+ * In these cases, the resulting AlgebraicNumber will not have just the nth term set to 1,
+ * but rather, will have the normalized equivalent.
+ * For example, since a normalized PolygonField(6) is of order 2, but diagonalCount() == 3,
+ * PolygonField(6).getUnitTerm(2) would return an AlgebraicNumber with terms of {2,0} rather than {0,0,1}.
+ * @param {number} n
+ * @return {*}
+ */
+ public getUnitDiagonal(n: number): com.vzome.core.algebra.AlgebraicNumber {
+ if (n >= this.getOrder() && n < this.diagonalCount()){
+ const terms: number[] = this.zero().toTrailingDivisor();
+ const row: number = n - this.getOrder();
+ for(let i: number = 0; i < this.getOrder(); i++) {{
+ const term: number = this.normalizerMatrix[row][i];
+ if (term !== 0){
+ terms[i] = term;
+ }
+ };}
+ return this.createAlgebraicNumberFromTD(terms);
+ }
+ return super.getUnitTerm(n);
+ }
+
+ /**
+ *
+ * @return {*}
+ */
+ public getGoldenRatio(): com.vzome.core.algebra.AlgebraicNumber {
+ return this.goldenRatio;
+ }
+
+ /**
+ *
+ * @param {string} name
+ * @return {*}
+ */
+ public getNumberByName(name: string): com.vzome.core.algebra.AlgebraicNumber {
+ switch((name)) {
+ case "\u221a2":
+ case "root2":
+ case "sqrt2":
+ return this.getRoot2();
+ case "\u221a3":
+ case "root3":
+ case "sqrt3":
+ return this.getRoot3();
+ case "\u221a5":
+ case "root5":
+ case "sqrt5":
+ return super.getNumberByName("root5");
+ case "\u221a6":
+ case "root6":
+ case "sqrt6":
+ return this.getRoot6();
+ case "\u221a7":
+ case "root7":
+ case "sqrt7":
+ return this.getRoot7();
+ case "\u221a8":
+ case "root8":
+ case "sqrt8":
+ return super.getNumberByName("root8");
+ case "\u221a10":
+ case "root10":
+ case "sqrt10":
+ return this.getRoot10();
+ case "rho":
+ return this.getDiagonalRatio$int(7);
+ case "sigma":
+ return this.getDiagonalRatio$int$int(7, 3);
+ case "alpha":
+ return this.getDiagonalRatio$int$int((this.__polygonSides % 9 === 0 ? 9 : 13), 2);
+ case "beta":
+ return this.getDiagonalRatio$int$int((this.__polygonSides % 9 === 0 ? 9 : 13), 3);
+ case "gamma":
+ return this.getDiagonalRatio$int$int((this.__polygonSides % 9 === 0 ? 9 : 13), 4);
+ case "delta":
+ return this.getDiagonalRatio$int$int(13, 5);
+ case "epsilon":
+ return this.getDiagonalRatio$int$int(13, 6);
+ case "theta":
+ return this.getDiagonalRatio$int$int(11, 2);
+ case "kappa":
+ return this.getDiagonalRatio$int$int(11, 3);
+ case "lambda":
+ return this.getDiagonalRatio$int$int(11, 4);
+ case "mu":
+ return this.getDiagonalRatio$int$int(11, 5);
+ }
+ return super.getNumberByName(name);
+ }
+
+ /*private*/ getRoot2(): com.vzome.core.algebra.AlgebraicNumber {
+ return this.getDiagonalRatio$int(4);
+ }
+
+ /*private*/ getRoot3(): com.vzome.core.algebra.AlgebraicNumber {
+ return this.getDiagonalRatio$int(6);
+ }
+
+ /*private*/ getRoot6(): com.vzome.core.algebra.AlgebraicNumber {
+ const r3: com.vzome.core.algebra.AlgebraicNumber = this.getNumberByName("root3");
+ if (r3 != null){
+ const r2: com.vzome.core.algebra.AlgebraicNumber = this.getNumberByName("root2");
+ return r2 == null ? null : r2['times$com_vzome_core_algebra_AlgebraicNumber'](r3);
+ }
+ return null;
+ }
+
+ /*private*/ getRoot7(): com.vzome.core.algebra.AlgebraicNumber {
+ if (this.__polygonSides % 14 === 0){
+ const n: number = (this.__polygonSides / 14|0);
+ const d0: com.vzome.core.algebra.AlgebraicNumber = this.getUnitDiagonal((1 * n) - 1).negate();
+ const d1: com.vzome.core.algebra.AlgebraicNumber = this.getUnitDiagonal((2 * n) - 1);
+ const d2: com.vzome.core.algebra.AlgebraicNumber = this.getUnitDiagonal((3 * n) - 1);
+ const d3: com.vzome.core.algebra.AlgebraicNumber = this.getUnitDiagonal((4 * n) - 1);
+ const d4: com.vzome.core.algebra.AlgebraicNumber = this.getUnitDiagonal((5 * n) - 1);
+ const d5: com.vzome.core.algebra.AlgebraicNumber = this.getUnitDiagonal((6 * n) - 1);
+ const cotA: com.vzome.core.algebra.AlgebraicNumber = d4.dividedBy(d1);
+ const cotB: com.vzome.core.algebra.AlgebraicNumber = d2.dividedBy(d3);
+ const cotC: com.vzome.core.algebra.AlgebraicNumber = d0.dividedBy(d5);
+ return cotA['plus$com_vzome_core_algebra_AlgebraicNumber'](cotB)['plus$com_vzome_core_algebra_AlgebraicNumber'](cotC);
+ }
+ return null;
+ }
+
+ /*private*/ getRoot10(): com.vzome.core.algebra.AlgebraicNumber {
+ const r5: com.vzome.core.algebra.AlgebraicNumber = this.getNumberByName("root5");
+ if (r5 != null){
+ const r2: com.vzome.core.algebra.AlgebraicNumber = this.getNumberByName("root2");
+ return r2 == null ? null : r2['times$com_vzome_core_algebra_AlgebraicNumber'](r5);
+ }
+ return null;
+ }
+
+ /*private*/ getDiagonalRatio$int(divisor: number): com.vzome.core.algebra.AlgebraicNumber {
+ return this.getDiagonalRatio$int$int(divisor, 2);
+ }
+
+ public getDiagonalRatio$int$int(divisor: number, step: number): com.vzome.core.algebra.AlgebraicNumber {
+ if (this.__polygonSides % divisor === 0 && step > 1 && step * 2 <= this.__polygonSides){
+ const n: number = (this.__polygonSides / divisor|0);
+ const denominator: com.vzome.core.algebra.AlgebraicNumber = this.getUnitDiagonal(n - 1);
+ const numerator: com.vzome.core.algebra.AlgebraicNumber = this.getUnitDiagonal((step * n) - 1);
+ return numerator.dividedBy(denominator);
+ }
+ return null;
+ }
+
+ public getDiagonalRatio(divisor?: any, step?: any): com.vzome.core.algebra.AlgebraicNumber {
+ if (((typeof divisor === 'number') || divisor === null) && ((typeof step === 'number') || step === null)) {
+ return this.getDiagonalRatio$int$int(divisor, step);
+ } else if (((typeof divisor === 'number') || divisor === null) && step === undefined) {
+ return this.getDiagonalRatio$int(divisor);
+ } else throw new Error('invalid overload');
+ }
+
+ /**
+ *
+ */
+ initializeCoefficients() {
+ const temp: number[] = this.getCoefficients();
+ for(let i: number = 0; i < this.coefficients.length; i++) {{
+ this.coefficients[i] = temp[i];
+ };}
+ }
+
+ /**
+ *
+ */
+ initializeMultiplicationTensor() {
+ this.multiplicationTensor = this.getNormalizedMultiplicationTensor(this.polygonSides());
+ }
+
+ normalizerMatrix: number[][];
+
+ /**
+ *
+ */
+ initializeNormalizer() {
+ this.normalizerMatrix = this.getNormalizerMatrix(this.polygonSides());
+ }
+
+ public polygonSides(): number {
+ return this.__polygonSides;
+ }
+
+ public isEven(): boolean {
+ return this.__isEven;
+ }
+
+ public isOdd(): boolean {
+ return !this.__isEven;
+ }
+ }
+ PolygonField["__class"] = "com.vzome.core.algebra.PolygonField";
+ PolygonField["__interfaces"] = ["com.vzome.core.algebra.AlgebraicField"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/Quaternion.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/Quaternion.ts
new file mode 100644
index 000000000..c8cb599ce
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/Quaternion.ts
@@ -0,0 +1,123 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export class Quaternion {
+ /**
+ *
+ * @return {string}
+ */
+ public toString(): string {
+ return "Quaternion: " + this.vector.toString();
+ }
+
+ representation: com.vzome.core.algebra.AlgebraicMatrix;
+
+ transpose: com.vzome.core.algebra.AlgebraicMatrix;
+
+ /*private*/ field: com.vzome.core.algebra.AlgebraicField;
+
+ /*private*/ vector: com.vzome.core.algebra.AlgebraicVector;
+
+ public constructor(field: com.vzome.core.algebra.AlgebraicField, vector: com.vzome.core.algebra.AlgebraicVector) {
+ if (this.representation === undefined) { this.representation = null; }
+ if (this.transpose === undefined) { this.transpose = null; }
+ if (this.field === undefined) { this.field = null; }
+ if (this.vector === undefined) { this.vector = null; }
+ this.field = field;
+ this.vector = vector;
+ let w_offset: number = 0;
+ let factor: com.vzome.core.algebra.AlgebraicNumber = field['createRational$long'](0);
+ if (vector.dimension() > 3){
+ factor = vector.getComponent(0);
+ w_offset = 1;
+ }
+ this.representation = field.identityMatrix(4).timesScalar(factor);
+ factor = vector.getComponent(0 + w_offset);
+ this.representation.setElement(1, 0, factor);
+ this.representation.setElement(3, 2, factor);
+ factor = factor.negate();
+ this.representation.setElement(0, 1, factor);
+ this.representation.setElement(2, 3, factor);
+ factor = vector.getComponent(1 + w_offset);
+ this.representation.setElement(1, 3, factor);
+ this.representation.setElement(2, 0, factor);
+ factor = factor.negate();
+ this.representation.setElement(3, 1, factor);
+ this.representation.setElement(0, 2, factor);
+ factor = vector.getComponent(2 + w_offset);
+ this.representation.setElement(3, 0, factor);
+ this.representation.setElement(2, 1, factor);
+ factor = factor.negate();
+ this.representation.setElement(1, 2, factor);
+ this.representation.setElement(0, 3, factor);
+ if (w_offset === 1)factor = vector.getComponent(0); else factor = field['createRational$long'](0);
+ this.transpose = field.identityMatrix(4).timesScalar(factor);
+ factor = vector.getComponent(0 + w_offset);
+ this.transpose.setElement(0, 1, factor);
+ this.transpose.setElement(2, 3, factor);
+ factor = factor.negate();
+ this.transpose.setElement(1, 0, factor);
+ this.transpose.setElement(3, 2, factor);
+ factor = vector.getComponent(1 + w_offset);
+ this.transpose.setElement(3, 1, factor);
+ this.transpose.setElement(0, 2, factor);
+ factor = factor.negate();
+ this.transpose.setElement(1, 3, factor);
+ this.transpose.setElement(2, 0, factor);
+ factor = vector.getComponent(2 + w_offset);
+ this.transpose.setElement(1, 2, factor);
+ this.transpose.setElement(0, 3, factor);
+ factor = factor.negate();
+ this.transpose.setElement(3, 0, factor);
+ this.transpose.setElement(2, 1, factor);
+ }
+
+ public getVector(): com.vzome.core.algebra.AlgebraicVector {
+ return this.vector;
+ }
+
+ /*private*/ conjugate(q: com.vzome.core.algebra.AlgebraicVector): com.vzome.core.algebra.AlgebraicVector {
+ const result: com.vzome.core.algebra.AlgebraicVector = this.field.origin(4);
+ result.setComponent(3, q.getComponent(3).negate());
+ result.setComponent(1, q.getComponent(1).negate());
+ result.setComponent(2, q.getComponent(2).negate());
+ result.setComponent(0, q.getComponent(0));
+ return result;
+ }
+
+ public reflect(v: com.vzome.core.algebra.AlgebraicVector): com.vzome.core.algebra.AlgebraicVector {
+ let reflection: com.vzome.core.algebra.AlgebraicVector = this.rightMultiply(this.conjugate(v));
+ reflection = this.leftMultiply(reflection);
+ return reflection.negate();
+ }
+
+ /**
+ * Compute the product this * q.
+ * @param {com.vzome.core.algebra.AlgebraicVector} q
+ * @return {com.vzome.core.algebra.AlgebraicVector}
+ */
+ public rightMultiply(q: com.vzome.core.algebra.AlgebraicVector): com.vzome.core.algebra.AlgebraicVector {
+ return this.representation.timesColumn(q);
+ }
+
+ /**
+ * Compute the product q*this.
+ * This is computed using the identities:
+ *
+ * conjugate( q*this ) == conjugate( this ) * conjugate( q )
+ *
+ * q * this == conjugate( conjugate( this ) * conjugate( q ) )
+ *
+ * @param {com.vzome.core.algebra.AlgebraicVector} q
+ * @return
+ * @return {com.vzome.core.algebra.AlgebraicVector}
+ */
+ public leftMultiply(q: com.vzome.core.algebra.AlgebraicVector): com.vzome.core.algebra.AlgebraicVector {
+ let result: com.vzome.core.algebra.AlgebraicVector = this.conjugate(q);
+ result = this.transpose.timesColumn(result);
+ return this.conjugate(result);
+ }
+ }
+ Quaternion["__class"] = "com.vzome.core.algebra.Quaternion";
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/SnubCubeField.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/SnubCubeField.ts
new file mode 100644
index 000000000..0cca84a6b
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/SnubCubeField.ts
@@ -0,0 +1,80 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ /**
+ * @author David Hall
+ * @param {*} factory
+ * @class
+ * @extends com.vzome.core.algebra.ParameterizedField
+ */
+ export class SnubCubeField extends com.vzome.core.algebra.ParameterizedField {
+ public static FIELD_NAME: string = "snubCube";
+
+ /**
+ *
+ * @param radicand
+ * @return {double[]} the coefficients of a SnubCubeField.
+ * This can be used to determine when two fields have compatible coefficients
+ * without having to generate an instance of the class.
+ */
+ public static getFieldCoefficients(): number[] {
+ const tribonacciConstant: number = (1.0 + /* cbrt */Math.pow(19.0 - (3.0 * Math.sqrt(33)), 1/3) + /* cbrt */Math.pow(19.0 + (3.0 * Math.sqrt(33)), 1/3)) / 3.0;
+ return [1.0, tribonacciConstant, tribonacciConstant * tribonacciConstant];
+ }
+
+ /**
+ *
+ * @return {double[]}
+ */
+ public getCoefficients(): number[] {
+ return SnubCubeField.getFieldCoefficients();
+ }
+
+ public constructor(factory: com.vzome.core.algebra.AlgebraicNumberFactory) {
+ super(SnubCubeField.FIELD_NAME, 3, factory);
+ this.initialize();
+ }
+
+ /**
+ *
+ */
+ initializeCoefficients() {
+ const temp: number[] = this.getCoefficients();
+ let i: number = 0;
+ for(let index = 0; index < temp.length; index++) {
+ let coefficient = temp[index];
+ {
+ this.coefficients[i++] = coefficient;
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ initializeMultiplicationTensor() {
+ const mm: number[][][] = [[[1, 0, 0], [0, 0, 1], [0, 1, 1]], [[0, 1, 0], [1, 0, 1], [0, 1, 2]], [[0, 0, 1], [0, 1, 1], [1, 1, 2]]];
+ this.multiplicationTensor = mm;
+ }
+
+ /**
+ *
+ */
+ initializeLabels() {
+ this.irrationalLabels[1] = ["\u03c8", "psi"];
+ this.irrationalLabels[2] = ["\u03c8\u00b2", "psi^2"];
+ }
+
+ /**
+ *
+ * @return {number}
+ */
+ public getNumMultipliers(): number {
+ return 1;
+ }
+ }
+ SnubCubeField["__class"] = "com.vzome.core.algebra.SnubCubeField";
+ SnubCubeField["__interfaces"] = ["com.vzome.core.algebra.AlgebraicField"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/SnubDodecField.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/SnubDodecField.ts
new file mode 100644
index 000000000..429a48ec7
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/SnubDodecField.ts
@@ -0,0 +1,235 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export class SnubDodecField extends com.vzome.core.algebra.AbstractAlgebraicField {
+ public static FIELD_NAME: string = "snubDodec";
+
+ /**
+ *
+ * @return {double[]} the coefficients of this AlgebraicField class.
+ * This can be used to determine when two fields have compatible coefficients
+ * without having to generate an instance of the class.
+ */
+ public static getFieldCoefficients(): number[] {
+ return [1.0, SnubDodecField.PHI_VALUE_$LI$(), SnubDodecField.XI_VALUE, SnubDodecField.PHI_VALUE_$LI$() * SnubDodecField.XI_VALUE, SnubDodecField.XI_VALUE * SnubDodecField.XI_VALUE, SnubDodecField.PHI_VALUE_$LI$() * SnubDodecField.XI_VALUE * SnubDodecField.XI_VALUE];
+ }
+
+ /**
+ *
+ * @return {double[]}
+ */
+ public getCoefficients(): number[] {
+ return SnubDodecField.getFieldCoefficients();
+ }
+
+ public constructor(factory: com.vzome.core.algebra.AlgebraicNumberFactory) {
+ super(SnubDodecField.FIELD_NAME, 6, factory);
+ }
+
+ public static PHI_VALUE: number; public static PHI_VALUE_$LI$(): number { if (SnubDodecField.PHI_VALUE == null) { SnubDodecField.PHI_VALUE = (1.0 + Math.sqrt(5.0)) / 2.0; } return SnubDodecField.PHI_VALUE; }
+
+ public static XI_VALUE: number = 1.7155614996973678;
+
+ static A: number = 0;
+
+ static B: number = 1;
+
+ static C: number = 2;
+
+ static D: number = 3;
+
+ static E: number = 4;
+
+ static F: number = 5;
+
+ /**
+ *
+ * @param {com.vzome.core.algebra.BigRational[]} a
+ * @param {com.vzome.core.algebra.BigRational[]} b
+ * @return {com.vzome.core.algebra.BigRational[]}
+ */
+ public multiply(a: com.vzome.core.algebra.BigRational[], b: com.vzome.core.algebra.BigRational[]): com.vzome.core.algebra.BigRational[] {
+ const result: com.vzome.core.algebra.BigRational[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(this.getOrder());
+ let factor: com.vzome.core.algebra.BigRational = a[SnubDodecField.A].times(b[SnubDodecField.A]);
+ factor = factor.plus(a[SnubDodecField.B].times(b[SnubDodecField.B]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.C]));
+ factor = factor.plus(a[SnubDodecField.E].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.C].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.F]));
+ result[SnubDodecField.A] = factor;
+ factor = a[SnubDodecField.B].times(b[SnubDodecField.A]);
+ factor = factor.plus(a[SnubDodecField.A].times(b[SnubDodecField.B]));
+ factor = factor.plus(a[SnubDodecField.B].times(b[SnubDodecField.B]));
+ factor = factor.plus(a[SnubDodecField.E].times(b[SnubDodecField.C]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.C]));
+ factor = factor.plus(a[SnubDodecField.E].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.C].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.C].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.F]));
+ result[SnubDodecField.B] = factor;
+ factor = a[SnubDodecField.C].times(b[SnubDodecField.A]);
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.B]));
+ factor = factor.plus(a[SnubDodecField.A].times(b[SnubDodecField.C]));
+ factor = factor.plus(a[SnubDodecField.E].times(b[SnubDodecField.C]));
+ factor = factor.plus(a[SnubDodecField.E].times(b[SnubDodecField.C]));
+ factor = factor.plus(a[SnubDodecField.B].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.C].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.C].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.E].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.F]));
+ result[SnubDodecField.C] = factor;
+ factor = a[SnubDodecField.D].times(b[SnubDodecField.A]);
+ factor = factor.plus(a[SnubDodecField.C].times(b[SnubDodecField.B]));
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.B]));
+ factor = factor.plus(a[SnubDodecField.B].times(b[SnubDodecField.C]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.C]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.C]));
+ factor = factor.plus(a[SnubDodecField.A].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.B].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.E].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.E].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.E].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.C].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.C].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.E].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.F]));
+ result[SnubDodecField.D] = factor;
+ factor = a[SnubDodecField.E].times(b[SnubDodecField.A]);
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.B]));
+ factor = factor.plus(a[SnubDodecField.C].times(b[SnubDodecField.C]));
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.A].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.E].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.E].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.B].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.F]));
+ result[SnubDodecField.E] = factor;
+ factor = a[SnubDodecField.F].times(b[SnubDodecField.A]);
+ factor = factor.plus(a[SnubDodecField.E].times(b[SnubDodecField.B]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.B]));
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.C]));
+ factor = factor.plus(a[SnubDodecField.C].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.D].times(b[SnubDodecField.D]));
+ factor = factor.plus(a[SnubDodecField.B].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.E]));
+ factor = factor.plus(a[SnubDodecField.A].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.B].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.E].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.E].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.F]));
+ factor = factor.plus(a[SnubDodecField.F].times(b[SnubDodecField.F]));
+ result[SnubDodecField.F] = factor;
+ return result;
+ }
+
+ /**
+ *
+ * @return {number}
+ */
+ public getNumMultipliers(): number {
+ return 2;
+ }
+
+ /**
+ * scalar for an affine pentagon
+ * @return {*}
+ */
+ public getAffineScalar(): com.vzome.core.algebra.AlgebraicNumber {
+ return this.getUnitTerm(1);
+ }
+
+ /**
+ *
+ * @return {*}
+ */
+ public getGoldenRatio(): com.vzome.core.algebra.AlgebraicNumber {
+ return this.getUnitTerm(1);
+ }
+
+ static IRRATIONAL_LABELS: string[][]; public static IRRATIONAL_LABELS_$LI$(): string[][] { if (SnubDodecField.IRRATIONAL_LABELS == null) { SnubDodecField.IRRATIONAL_LABELS = [[" ", " "], ["\u03c6", "phi"], ["\u03be", "xi"], ["\u03c6\u03be", "phi*xi"], ["\u03be\u00b2", "xi^2"], ["\u03c6\u03be\u00b2", "phi*xi^2"]]; } return SnubDodecField.IRRATIONAL_LABELS; }
+
+ public getIrrational$int$int(i: number, format: number): string {
+ return SnubDodecField.IRRATIONAL_LABELS_$LI$()[i][format];
+ }
+
+ /**
+ *
+ * @param {number} i
+ * @param {number} format
+ * @return {string}
+ */
+ public getIrrational(i?: any, format?: any): string {
+ if (((typeof i === 'number') || i === null) && ((typeof format === 'number') || format === null)) {
+ return this.getIrrational$int$int(i, format);
+ } else if (((typeof i === 'number') || i === null) && format === undefined) {
+ return this.getIrrational$int(i);
+ } else throw new Error('invalid overload');
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.algebra.BigRational[]} factors
+ * @return {number}
+ */
+ evaluateNumber(factors: com.vzome.core.algebra.BigRational[]): number {
+ let result: number = 0.0;
+ result += factors[SnubDodecField.A].evaluate();
+ result += SnubDodecField.PHI_VALUE_$LI$() * factors[SnubDodecField.B].evaluate();
+ result += SnubDodecField.XI_VALUE * factors[SnubDodecField.C].evaluate();
+ result += SnubDodecField.PHI_VALUE_$LI$() * SnubDodecField.XI_VALUE * factors[SnubDodecField.D].evaluate();
+ result += SnubDodecField.XI_VALUE * SnubDodecField.XI_VALUE * factors[SnubDodecField.E].evaluate();
+ result += SnubDodecField.XI_VALUE * SnubDodecField.XI_VALUE * SnubDodecField.PHI_VALUE_$LI$() * factors[SnubDodecField.F].evaluate();
+ return result;
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.algebra.BigRational[]} factors
+ * @param {number} whichIrrational
+ * @return {com.vzome.core.algebra.BigRational[]}
+ */
+ scaleBy(factors: com.vzome.core.algebra.BigRational[], whichIrrational: number): com.vzome.core.algebra.BigRational[] {
+ switch((whichIrrational)) {
+ case 0 /* A */:
+ return factors;
+ case 1 /* B */:
+ return [factors[SnubDodecField.B], factors[SnubDodecField.A].plus(factors[SnubDodecField.B]), factors[SnubDodecField.D], factors[SnubDodecField.C].plus(factors[SnubDodecField.D]), factors[SnubDodecField.F], factors[SnubDodecField.E].plus(factors[SnubDodecField.F])];
+ case 2 /* C */:
+ return [factors[SnubDodecField.F], factors[SnubDodecField.E].plus(factors[SnubDodecField.F]), factors[SnubDodecField.A].plus(factors[SnubDodecField.E]).plus(factors[SnubDodecField.E]), factors[SnubDodecField.B].plus(factors[SnubDodecField.F]).plus(factors[SnubDodecField.F]), factors[SnubDodecField.C], factors[SnubDodecField.D]];
+ case 3 /* D */:
+ return this.scaleBy(this.scaleBy(factors, SnubDodecField.B), SnubDodecField.C);
+ case 4 /* E */:
+ return this.scaleBy(this.scaleBy(factors, SnubDodecField.C), SnubDodecField.C);
+ case 5 /* F */:
+ return this.scaleBy(this.scaleBy(factors, SnubDodecField.D), SnubDodecField.C);
+ default:
+ throw new java.lang.IllegalArgumentException(whichIrrational + " is not a valid irrational in this field");
+ }
+ }
+ }
+ SnubDodecField["__class"] = "com.vzome.core.algebra.SnubDodecField";
+ SnubDodecField["__interfaces"] = ["com.vzome.core.algebra.AlgebraicField"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/SnubDodecahedronField.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/SnubDodecahedronField.ts
new file mode 100644
index 000000000..5476cd0da
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/SnubDodecahedronField.ts
@@ -0,0 +1,99 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ /**
+ * @author David Hall
+ * @param {*} factory
+ * @class
+ * @extends com.vzome.core.algebra.ParameterizedField
+ */
+ export class SnubDodecahedronField extends com.vzome.core.algebra.ParameterizedField {
+ public static FIELD_NAME: string = "snubDodecahedron";
+
+ /**
+ *
+ * @return {double[]} the coefficients of this AlgebraicField class.
+ * This can be used to determine when two fields have compatible coefficients
+ * without having to generate an instance of the class.
+ */
+ public static getFieldCoefficients(): number[] {
+ const PHI_VALUE: number = (1.0 + Math.sqrt(5.0)) / 2.0;
+ const XI_VALUE: number = 1.7155614996973678;
+ return [1.0, PHI_VALUE, XI_VALUE, PHI_VALUE * XI_VALUE, XI_VALUE * XI_VALUE, PHI_VALUE * XI_VALUE * XI_VALUE];
+ }
+
+ /**
+ *
+ * @return {double[]}
+ */
+ public getCoefficients(): number[] {
+ return SnubDodecahedronField.getFieldCoefficients();
+ }
+
+ public constructor(factory: com.vzome.core.algebra.AlgebraicNumberFactory) {
+ super(SnubDodecahedronField.FIELD_NAME, 6, factory);
+ this.initialize();
+ }
+
+ /**
+ *
+ */
+ initializeCoefficients() {
+ const temp: number[] = this.getCoefficients();
+ let i: number = 0;
+ for(let index = 0; index < temp.length; index++) {
+ let coefficient = temp[index];
+ {
+ this.coefficients[i++] = coefficient;
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ initializeMultiplicationTensor() {
+ const mm: number[][][] = [[[1, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1, 1], [0, 0, 0, 1, 0, 0], [0, 0, 1, 1, 0, 0]], [[0, 1, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1], [0, 0, 0, 0, 1, 2], [0, 0, 1, 1, 0, 0], [0, 0, 1, 2, 0, 0]], [[0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 2, 0], [0, 1, 0, 0, 0, 2], [0, 0, 2, 0, 0, 1], [0, 0, 0, 2, 1, 1]], [[0, 0, 0, 1, 0, 0], [0, 0, 1, 1, 0, 0], [0, 1, 0, 0, 0, 2], [1, 1, 0, 0, 2, 2], [0, 0, 0, 2, 1, 1], [0, 0, 2, 2, 1, 2]], [[0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 0, 1], [0, 0, 1, 0, 0, 0], [0, 0, 0, 1, 0, 0], [1, 0, 0, 0, 2, 0], [0, 1, 0, 0, 0, 2]], [[0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 1, 1], [0, 0, 0, 1, 0, 0], [0, 0, 1, 1, 0, 0], [0, 1, 0, 0, 0, 2], [1, 1, 0, 0, 2, 2]]];
+ this.multiplicationTensor = mm;
+ }
+
+ /**
+ *
+ */
+ initializeLabels() {
+ this.irrationalLabels[1] = ["\u03c6", "phi"];
+ this.irrationalLabels[2] = ["\u03be", "xi"];
+ this.irrationalLabels[3] = ["\u03c6\u03be", "phi*xi"];
+ this.irrationalLabels[4] = ["\u03be\u00b2", "xi^2"];
+ this.irrationalLabels[5] = ["\u03c6\u03be\u00b2", "phi*xi^2"];
+ }
+
+ /**
+ *
+ * @return {number}
+ */
+ public getNumMultipliers(): number {
+ return 2;
+ }
+
+ /**
+ * scalar for an affine pentagon
+ * @return {*}
+ */
+ public getAffineScalar(): com.vzome.core.algebra.AlgebraicNumber {
+ return this.getGoldenRatio();
+ }
+
+ /**
+ *
+ * @return {*}
+ */
+ public getGoldenRatio(): com.vzome.core.algebra.AlgebraicNumber {
+ return this.getUnitTerm(1);
+ }
+ }
+ SnubDodecahedronField["__class"] = "com.vzome.core.algebra.SnubDodecahedronField";
+ SnubDodecahedronField["__interfaces"] = ["com.vzome.core.algebra.AlgebraicField"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/SuperGoldenField.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/SuperGoldenField.ts
new file mode 100644
index 000000000..0f02d91e7
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/SuperGoldenField.ts
@@ -0,0 +1,73 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export class SuperGoldenField extends com.vzome.core.algebra.ParameterizedField {
+ public static FIELD_NAME: string = "superGolden";
+
+ /**
+ *
+ * @return {double[]} the coefficients of a SuperGoldenField.
+ * This can be used to determine when two fields have compatible coefficients
+ * without having to generate an instance of the class.
+ */
+ public static getFieldCoefficients(): number[] {
+ const narayanaCowNumber: number = 1.465571231876768;
+ return [1.0, narayanaCowNumber, narayanaCowNumber * narayanaCowNumber];
+ }
+
+ /**
+ *
+ * @return {number}
+ */
+ public getNumMultipliers(): number {
+ return 1;
+ }
+
+ /**
+ *
+ * @return {double[]}
+ */
+ public getCoefficients(): number[] {
+ return SuperGoldenField.getFieldCoefficients();
+ }
+
+ public constructor(factory: com.vzome.core.algebra.AlgebraicNumberFactory) {
+ super(SuperGoldenField.FIELD_NAME, 3, factory);
+ this.initialize();
+ }
+
+ /**
+ *
+ */
+ initializeCoefficients() {
+ const temp: number[] = this.getCoefficients();
+ let i: number = 0;
+ for(let index = 0; index < temp.length; index++) {
+ let coefficient = temp[index];
+ {
+ this.coefficients[i++] = coefficient;
+ }
+ }
+ }
+
+ /**
+ *
+ */
+ initializeMultiplicationTensor() {
+ const mt: number[][][] = [[[1, 0, 0], [0, 0, 1], [0, 1, 1]], [[0, 1, 0], [1, 0, 0], [0, 0, 1]], [[0, 0, 1], [0, 1, 1], [1, 1, 1]]];
+ this.multiplicationTensor = mt;
+ }
+
+ /**
+ *
+ */
+ initializeLabels() {
+ this.irrationalLabels[1] = ["\u03c8", "psi"];
+ this.irrationalLabels[2] = ["\u03c8\u00b2", "psi^2"];
+ }
+ }
+ SuperGoldenField["__class"] = "com.vzome.core.algebra.SuperGoldenField";
+ SuperGoldenField["__interfaces"] = ["com.vzome.core.algebra.AlgebraicField"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/Trivector3dHomogeneous.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/Trivector3dHomogeneous.ts
new file mode 100644
index 000000000..7892e7f6e
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/Trivector3dHomogeneous.ts
@@ -0,0 +1,34 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export class Trivector3dHomogeneous {
+ e123: com.vzome.core.algebra.AlgebraicNumber;
+
+ e310: com.vzome.core.algebra.AlgebraicNumber;
+
+ e320: com.vzome.core.algebra.AlgebraicNumber;
+
+ e120: com.vzome.core.algebra.AlgebraicNumber;
+
+ /*private*/ field: com.vzome.core.algebra.AlgebraicField;
+
+ public constructor(e123: com.vzome.core.algebra.AlgebraicNumber, e310: com.vzome.core.algebra.AlgebraicNumber, e320: com.vzome.core.algebra.AlgebraicNumber, e120: com.vzome.core.algebra.AlgebraicNumber, field: com.vzome.core.algebra.AlgebraicField) {
+ if (this.e123 === undefined) { this.e123 = null; }
+ if (this.e310 === undefined) { this.e310 = null; }
+ if (this.e320 === undefined) { this.e320 = null; }
+ if (this.e120 === undefined) { this.e120 = null; }
+ if (this.field === undefined) { this.field = null; }
+ this.e123 = e123;
+ this.e310 = e310;
+ this.e320 = e320;
+ this.e120 = e120;
+ this.field = field;
+ }
+
+ public dual(): com.vzome.core.algebra.Vector3dHomogeneous {
+ return new com.vzome.core.algebra.Vector3dHomogeneous(this.e320.negate(), this.e310, this.e120, this.e123.negate(), this.field);
+ }
+ }
+ Trivector3dHomogeneous["__class"] = "com.vzome.core.algebra.Trivector3dHomogeneous";
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/Vector3d.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/Vector3d.ts
new file mode 100644
index 000000000..aea8cfe2a
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/Vector3d.ts
@@ -0,0 +1,41 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export class Vector3d {
+ a: com.vzome.core.algebra.AlgebraicNumber;
+
+ b: com.vzome.core.algebra.AlgebraicNumber;
+
+ c: com.vzome.core.algebra.AlgebraicNumber;
+
+ public constructor(a?: any, b?: any, c?: any) {
+ if (((a != null && (a.constructor != null && a.constructor["__interfaces"] != null && a.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || a === null) && ((b != null && (b.constructor != null && b.constructor["__interfaces"] != null && b.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || b === null) && ((c != null && (c.constructor != null && c.constructor["__interfaces"] != null && c.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || c === null)) {
+ let __args = arguments;
+ if (this.a === undefined) { this.a = null; }
+ if (this.b === undefined) { this.b = null; }
+ if (this.c === undefined) { this.c = null; }
+ this.a = a;
+ this.b = b;
+ this.c = c;
+ } else if (((a != null && a instanceof com.vzome.core.algebra.AlgebraicVector) || a === null) && b === undefined && c === undefined) {
+ let __args = arguments;
+ let v: any = __args[0];
+ if (this.a === undefined) { this.a = null; }
+ if (this.b === undefined) { this.b = null; }
+ if (this.c === undefined) { this.c = null; }
+ this.a = v.getComponent(0);
+ this.b = v.getComponent(1);
+ this.c = v.getComponent(2);
+ } else throw new Error('invalid overload');
+ }
+
+ public outer(that: Vector3d): com.vzome.core.algebra.Bivector3d {
+ const a: com.vzome.core.algebra.AlgebraicNumber = this.a['times$com_vzome_core_algebra_AlgebraicNumber'](that.b)['minus$com_vzome_core_algebra_AlgebraicNumber'](this.b['times$com_vzome_core_algebra_AlgebraicNumber'](that.a));
+ const b: com.vzome.core.algebra.AlgebraicNumber = this.b['times$com_vzome_core_algebra_AlgebraicNumber'](that.c)['minus$com_vzome_core_algebra_AlgebraicNumber'](this.c['times$com_vzome_core_algebra_AlgebraicNumber'](that.b));
+ const c: com.vzome.core.algebra.AlgebraicNumber = this.c['times$com_vzome_core_algebra_AlgebraicNumber'](that.a)['minus$com_vzome_core_algebra_AlgebraicNumber'](this.a['times$com_vzome_core_algebra_AlgebraicNumber'](that.c));
+ return new com.vzome.core.algebra.Bivector3d(a, b, c);
+ }
+ }
+ Vector3d["__class"] = "com.vzome.core.algebra.Vector3d";
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/Vector3dHomogeneous.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/Vector3dHomogeneous.ts
new file mode 100644
index 000000000..6b061e541
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/Vector3dHomogeneous.ts
@@ -0,0 +1,104 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export class Vector3dHomogeneous {
+ e1: com.vzome.core.algebra.AlgebraicNumber;
+
+ e2: com.vzome.core.algebra.AlgebraicNumber;
+
+ e3: com.vzome.core.algebra.AlgebraicNumber;
+
+ e0: com.vzome.core.algebra.AlgebraicNumber;
+
+ /*private*/ field: com.vzome.core.algebra.AlgebraicField;
+
+ public constructor(e1?: any, e2?: any, e3?: any, e0?: any, field?: any) {
+ if (((e1 != null && (e1.constructor != null && e1.constructor["__interfaces"] != null && e1.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || e1 === null) && ((e2 != null && (e2.constructor != null && e2.constructor["__interfaces"] != null && e2.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || e2 === null) && ((e3 != null && (e3.constructor != null && e3.constructor["__interfaces"] != null && e3.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || e3 === null) && ((e0 != null && (e0.constructor != null && e0.constructor["__interfaces"] != null && e0.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || e0 === null) && ((field != null && (field.constructor != null && field.constructor["__interfaces"] != null && field.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicField") >= 0)) || field === null)) {
+ let __args = arguments;
+ if (this.e1 === undefined) { this.e1 = null; }
+ if (this.e2 === undefined) { this.e2 = null; }
+ if (this.e3 === undefined) { this.e3 = null; }
+ if (this.e0 === undefined) { this.e0 = null; }
+ if (this.field === undefined) { this.field = null; }
+ this.e1 = e1;
+ this.e2 = e2;
+ this.e3 = e3;
+ this.e0 = e0;
+ this.field = field;
+ } else if (((e1 != null && (e1.constructor != null && e1.constructor["__interfaces"] != null && e1.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || e1 === null) && ((e2 != null && (e2.constructor != null && e2.constructor["__interfaces"] != null && e2.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || e2 === null) && ((e3 != null && (e3.constructor != null && e3.constructor["__interfaces"] != null && e3.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || e3 === null) && ((e0 != null && (e0.constructor != null && e0.constructor["__interfaces"] != null && e0.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicField") >= 0)) || e0 === null) && field === undefined) {
+ let __args = arguments;
+ let field: any = __args[3];
+ {
+ let __args = arguments;
+ let e2: any = __args[0];
+ let e3: any = __args[0];
+ let e0: any = __args[4].one();
+ if (this.e1 === undefined) { this.e1 = null; }
+ if (this.e2 === undefined) { this.e2 = null; }
+ if (this.e3 === undefined) { this.e3 = null; }
+ if (this.e0 === undefined) { this.e0 = null; }
+ if (this.field === undefined) { this.field = null; }
+ this.e1 = e1;
+ this.e2 = e2;
+ this.e3 = e3;
+ this.e0 = e0;
+ this.field = field;
+ }
+ } else if (((e1 != null && e1 instanceof com.vzome.core.algebra.AlgebraicVector) || e1 === null) && ((e2 != null && (e2.constructor != null && e2.constructor["__interfaces"] != null && e2.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicField") >= 0)) || e2 === null) && e3 === undefined && e0 === undefined && field === undefined) {
+ let __args = arguments;
+ let v: any = __args[0];
+ let field: any = __args[1];
+ {
+ let __args = arguments;
+ let e1: any = v.getComponent(0);
+ let e2: any = v.getComponent(1);
+ let e3: any = v.getComponent(2);
+ {
+ let __args = arguments;
+ let e2: any = __args[0];
+ let e3: any = __args[0];
+ let e0: any = __args[4].one();
+ if (this.e1 === undefined) { this.e1 = null; }
+ if (this.e2 === undefined) { this.e2 = null; }
+ if (this.e3 === undefined) { this.e3 = null; }
+ if (this.e0 === undefined) { this.e0 = null; }
+ if (this.field === undefined) { this.field = null; }
+ this.e1 = e1;
+ this.e2 = e2;
+ this.e3 = e3;
+ this.e0 = e0;
+ this.field = field;
+ }
+ }
+ } else throw new Error('invalid overload');
+ }
+
+ public outer(that: Vector3dHomogeneous): com.vzome.core.algebra.Bivector3dHomogeneous {
+ const e12: com.vzome.core.algebra.AlgebraicNumber = this.e1['times$com_vzome_core_algebra_AlgebraicNumber'](that.e2)['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e2['times$com_vzome_core_algebra_AlgebraicNumber'](that.e1));
+ const e23: com.vzome.core.algebra.AlgebraicNumber = this.e2['times$com_vzome_core_algebra_AlgebraicNumber'](that.e3)['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e3['times$com_vzome_core_algebra_AlgebraicNumber'](that.e2));
+ const e31: com.vzome.core.algebra.AlgebraicNumber = this.e3['times$com_vzome_core_algebra_AlgebraicNumber'](that.e1)['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e1['times$com_vzome_core_algebra_AlgebraicNumber'](that.e3));
+ const e10: com.vzome.core.algebra.AlgebraicNumber = this.e1['times$com_vzome_core_algebra_AlgebraicNumber'](that.e0)['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e0['times$com_vzome_core_algebra_AlgebraicNumber'](that.e1));
+ const e20: com.vzome.core.algebra.AlgebraicNumber = this.e2['times$com_vzome_core_algebra_AlgebraicNumber'](that.e0)['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e0['times$com_vzome_core_algebra_AlgebraicNumber'](that.e2));
+ const e30: com.vzome.core.algebra.AlgebraicNumber = this.e3['times$com_vzome_core_algebra_AlgebraicNumber'](that.e0)['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e0['times$com_vzome_core_algebra_AlgebraicNumber'](that.e3));
+ return new com.vzome.core.algebra.Bivector3dHomogeneous(e12, e23, e31, e10, e20, e30, this.field);
+ }
+
+ public getVector(): com.vzome.core.algebra.AlgebraicVector {
+ return new com.vzome.core.algebra.AlgebraicVector(this.e1.dividedBy(this.e0), this.e2.dividedBy(this.e0), this.e3.dividedBy(this.e0));
+ }
+
+ public dot(v: com.vzome.core.algebra.Bivector3dHomogeneous): Vector3dHomogeneous {
+ const e1: com.vzome.core.algebra.AlgebraicNumber = this.e3['times$com_vzome_core_algebra_AlgebraicNumber'](v.e31)['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e2['times$com_vzome_core_algebra_AlgebraicNumber'](v.e12))['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e0['times$com_vzome_core_algebra_AlgebraicNumber'](v.e10));
+ const e2: com.vzome.core.algebra.AlgebraicNumber = this.e1['times$com_vzome_core_algebra_AlgebraicNumber'](v.e12)['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e3['times$com_vzome_core_algebra_AlgebraicNumber'](v.e23))['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e0['times$com_vzome_core_algebra_AlgebraicNumber'](v.e20));
+ const e3: com.vzome.core.algebra.AlgebraicNumber = this.e2['times$com_vzome_core_algebra_AlgebraicNumber'](v.e23)['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e1['times$com_vzome_core_algebra_AlgebraicNumber'](v.e31))['minus$com_vzome_core_algebra_AlgebraicNumber'](this.e0['times$com_vzome_core_algebra_AlgebraicNumber'](v.e30));
+ const e0: com.vzome.core.algebra.AlgebraicNumber = this.e1['times$com_vzome_core_algebra_AlgebraicNumber'](v.e10)['plus$com_vzome_core_algebra_AlgebraicNumber'](this.e2['times$com_vzome_core_algebra_AlgebraicNumber'](v.e20))['plus$com_vzome_core_algebra_AlgebraicNumber'](this.e3['times$com_vzome_core_algebra_AlgebraicNumber'](v.e30));
+ return new Vector3dHomogeneous(e1, e2, e3, e0, this.field);
+ }
+
+ public exists(): boolean {
+ return !this.e0.isZero();
+ }
+ }
+ Vector3dHomogeneous["__class"] = "com.vzome.core.algebra.Vector3dHomogeneous";
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/algebra/VefVectorExporter.ts b/online/src/worker/legacy/ts/com/vzome/core/algebra/VefVectorExporter.ts
new file mode 100644
index 000000000..b4a899375
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/algebra/VefVectorExporter.ts
@@ -0,0 +1,213 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.algebra {
+ export class VefVectorExporter {
+ output: java.io.PrintWriter;
+
+ field: com.vzome.core.algebra.AlgebraicField;
+
+ sortedVertexList: java.util.ArrayList;
+
+ /*private*/ vertices: java.util.SortedSet;
+
+ /*private*/ ballLocations: java.util.SortedSet;
+
+ strutEnds: java.util.SortedSet;
+
+ panelVertices: java.util.SortedSet;
+
+ scale: com.vzome.core.algebra.AlgebraicNumber;
+
+ includeOffset: boolean;
+
+ exportedOffset: com.vzome.core.algebra.AlgebraicVector;
+
+ strTip: string;
+
+ public constructor(writer?: any, field?: any, scale?: any, withOffset?: any) {
+ if (((writer != null && writer instanceof java.io.Writer) || writer === null) && ((field != null && (field.constructor != null && field.constructor["__interfaces"] != null && field.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicField") >= 0)) || field === null) && ((scale != null && (scale.constructor != null && scale.constructor["__interfaces"] != null && scale.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicNumber") >= 0)) || scale === null) && ((typeof withOffset === 'boolean') || withOffset === null)) {
+ let __args = arguments;
+ if (this.output === undefined) { this.output = null; }
+ if (this.field === undefined) { this.field = null; }
+ if (this.strutEnds === undefined) { this.strutEnds = null; }
+ if (this.panelVertices === undefined) { this.panelVertices = null; }
+ if (this.scale === undefined) { this.scale = null; }
+ if (this.includeOffset === undefined) { this.includeOffset = false; }
+ this.sortedVertexList = null;
+ this.vertices = (new java.util.TreeSet());
+ this.ballLocations = (new java.util.TreeSet());
+ this.exportedOffset = null;
+ this.strTip = "tip";
+ this.strMiddle = "middle";
+ this.includeOffset = withOffset;
+ this.scale = scale;
+ this.output = new java.io.PrintWriter(writer);
+ this.field = field;
+ const arrayComparator: com.vzome.core.generic.ArrayComparator = (new com.vzome.core.generic.ArrayComparator());
+ this.strutEnds = (new java.util.TreeSet((((funcInst: any) => { if (funcInst == null || typeof funcInst == 'function') { return funcInst } return (arg0, arg1) => (funcInst['compare'] ? funcInst['compare'] : funcInst) .call(funcInst, arg0, arg1)})(arrayComparator.getContentFirstArrayComparator()))));
+ this.panelVertices = (new java.util.TreeSet((((funcInst: any) => { if (funcInst == null || typeof funcInst == 'function') { return funcInst } return (arg0, arg1) => (funcInst['compare'] ? funcInst['compare'] : funcInst) .call(funcInst, arg0, arg1)})(arrayComparator.getLengthFirstArrayComparator()))));
+ } else if (((writer != null && writer instanceof java.io.Writer) || writer === null) && ((field != null && (field.constructor != null && field.constructor["__interfaces"] != null && field.constructor["__interfaces"].indexOf("com.vzome.core.algebra.AlgebraicField") >= 0)) || field === null) && scale === undefined && withOffset === undefined) {
+ let __args = arguments;
+ {
+ let __args = arguments;
+ let scale: any = null;
+ let withOffset: any = false;
+ if (this.output === undefined) { this.output = null; }
+ if (this.field === undefined) { this.field = null; }
+ if (this.strutEnds === undefined) { this.strutEnds = null; }
+ if (this.panelVertices === undefined) { this.panelVertices = null; }
+ if (this.scale === undefined) { this.scale = null; }
+ if (this.includeOffset === undefined) { this.includeOffset = false; }
+ this.sortedVertexList = null;
+ this.vertices = (new java.util.TreeSet());
+ this.ballLocations = (new java.util.TreeSet());
+ this.exportedOffset = null;
+ this.strTip = "tip";
+ this.strMiddle = "middle";
+ this.includeOffset = withOffset;
+ this.scale = scale;
+ this.output = new java.io.PrintWriter(writer);
+ this.field = field;
+ const arrayComparator: com.vzome.core.generic.ArrayComparator = (new com.vzome.core.generic.ArrayComparator());
+ this.strutEnds = (new java.util.TreeSet((((funcInst: any) => { if (funcInst == null || typeof funcInst == 'function') { return funcInst } return (arg0, arg1) => (funcInst['compare'] ? funcInst['compare'] : funcInst) .call(funcInst, arg0, arg1)})(arrayComparator.getContentFirstArrayComparator()))));
+ this.panelVertices = (new java.util.TreeSet((((funcInst: any) => { if (funcInst == null || typeof funcInst == 'function') { return funcInst } return (arg0, arg1) => (funcInst['compare'] ? funcInst['compare'] : funcInst) .call(funcInst, arg0, arg1)})(arrayComparator.getLengthFirstArrayComparator()))));
+ }
+ } else throw new Error('invalid overload');
+ }
+
+ public exportPoint(pt: com.vzome.core.algebra.AlgebraicVector) {
+ this.vertices.add(pt);
+ this.ballLocations.add(pt);
+ if (this.includeOffset){
+ this.exportedOffset = pt;
+ }
+ }
+
+ public exportSegment(start: com.vzome.core.algebra.AlgebraicVector, end: com.vzome.core.algebra.AlgebraicVector) {
+ const ends: com.vzome.core.algebra.AlgebraicVector[] = [start, end];
+ this.vertices.add(ends[0]);
+ this.vertices.add(ends[1]);
+ this.strutEnds.add(ends);
+ }
+
+ public exportPolygon(corners: java.util.List) {
+ this.vertices.addAll(corners);
+ const cornerArray: com.vzome.core.algebra.AlgebraicVector[] = (s => { let a=[]; while(s-->0) a.push(null); return a; })(corners.size());
+ corners.toArray(cornerArray);
+ this.panelVertices.add(cornerArray);
+ }
+
+ strMiddle: string;
+
+ /**
+ * @param {java.lang.StringBuffer} buffer = Don't assume that buffer starts out empty. Results will be appended.
+ * @param {com.vzome.core.algebra.AlgebraicVector} vector = Value to be converted to a zero-padded 4D String which will be
+ * prefixed and/or padded with field specific zeroes
+ * depending on the number of dimensions in vector as follows:
+ * 1D : 0 X 0 0
+ * 2D : 0 X Y 0
+ * 3D : 0 X Y Z
+ * 4D : W X Y Z
+ * @param {*} scale
+ */
+ public static appendVector(buffer: java.lang.StringBuffer, vector: com.vzome.core.algebra.AlgebraicVector, scale: com.vzome.core.algebra.AlgebraicNumber) {
+ const zeroString: string = vector.getField().zero().toString(com.vzome.core.algebra.AlgebraicField.VEF_FORMAT);
+ const dims: number = vector.dimension();
+ if (dims < 4){
+ buffer.append(zeroString);
+ buffer.append(" ");
+ }
+ if (scale != null)vector = vector.scale(scale);
+ vector.getVectorExpression$java_lang_StringBuffer$int(buffer, com.vzome.core.algebra.AlgebraicField.VEF_FORMAT);
+ for(let d: number = dims + 1; d < 4; d++) {{
+ buffer.append(" ");
+ buffer.append(zeroString);
+ };}
+ }
+
+ public static exportPolyhedron(polyhedron: com.vzome.core.math.Polyhedron): string {
+ const out: java.io.StringWriter = new java.io.StringWriter();
+ const exporter: VefVectorExporter = new VefVectorExporter(out, polyhedron.getField());
+ const vertexList: java.util.List = polyhedron.getVertexList();
+ for(let index=polyhedron.getFaceSet().iterator();index.hasNext();) {
+ let face = index.next();
+ {
+ const vertices: java.util.List = (new java.util.ArrayList(face.size()));
+ for(let i: number = 0; i < face.size(); i++) {{
+ const vertexIndex: number = face.getVertex(i);
+ vertices.add(vertexList.get(vertexIndex));
+ };}
+ exporter.exportPolygon(vertices);
+ }
+ }
+ exporter.finishExport();
+ return out.toString();
+ }
+
+ public finishExport() {
+ this.sortedVertexList = (new java.util.ArrayList(this.vertices));
+ this.vertices = null;
+ const version: number = (this.exportedOffset == null) ? com.vzome.core.math.VefParser.VERSION_EXPLICIT_BALLS : com.vzome.core.math.VefParser.VERSION_EXPLICIT_OFFSET;
+ this.output.println$java_lang_Object("vZome VEF " + version + " field " + this.field.getName());
+ if (this.exportedOffset != null){
+ const buf: java.lang.StringBuffer = new java.lang.StringBuffer();
+ buf.append("\noffset ");
+ VefVectorExporter.appendVector(buf, this.exportedOffset.negate(), null);
+ buf.append("\n");
+ this.output.println$java_lang_Object(buf.toString());
+ }
+ this.output.println$java_lang_Object("\n" + this.sortedVertexList.size());
+ {
+ const buf: java.lang.StringBuffer = new java.lang.StringBuffer();
+ for(let index=this.sortedVertexList.iterator();index.hasNext();) {
+ let vector = index.next();
+ {
+ VefVectorExporter.appendVector(buf, vector, this.scale);
+ buf.append("\n");
+ }
+ }
+ buf.append("\n");
+ this.output.println$java_lang_Object(buf.toString());
+ };
+ this.output.println$java_lang_Object("\n" + this.strutEnds.size());
+ for(let index=this.strutEnds.iterator();index.hasNext();) {
+ let ends = index.next();
+ {
+ this.output.print(this.sortedVertexList.indexOf(ends[0]) + " ");
+ this.output.println$java_lang_Object(this.sortedVertexList.indexOf(ends[1]));
+ }
+ }
+ this.output.println$java_lang_Object("\n");
+ this.output.println$java_lang_Object("\n" + this.panelVertices.size());
+ for(let index=this.panelVertices.iterator();index.hasNext();) {
+ let corners = index.next();
+ {
+ this.output.print(corners.length + " ");
+ for(let index = 0; index < corners.length; index++) {
+ let corner = corners[index];
+ {
+ this.output.print(this.sortedVertexList.indexOf(corner) + " ");
+ }
+ }
+ this.output.println$();
+ }
+ }
+ this.output.println$java_lang_Object("\n");
+ this.output.println$java_lang_Object("\n" + this.ballLocations.size());
+ let i: number = 0;
+ for(let index=this.ballLocations.iterator();index.hasNext();) {
+ let ball = index.next();
+ {
+ this.output.print(this.sortedVertexList.indexOf(ball) + " ");
+ if (++i % 10 === 0){
+ this.output.println$();
+ }
+ }
+ }
+ this.output.println$java_lang_Object("\n");
+ this.output.flush();
+ }
+ }
+ VefVectorExporter["__class"] = "com.vzome.core.algebra.VefVectorExporter";
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/commands/AbstractCommand.ts b/online/src/worker/legacy/ts/com/vzome/core/commands/AbstractCommand.ts
new file mode 100644
index 000000000..96e152a05
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/commands/AbstractCommand.ts
@@ -0,0 +1,124 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.commands {
+ export abstract class AbstractCommand implements com.vzome.core.commands.Command {
+ /**
+ * This default behavior deserializes in the old way, before XmlSaveFormat .COMPACTED_COMMAND_EDITS
+ * @param attributes
+ * @param {*} xml
+ * @param {com.vzome.core.commands.XmlSaveFormat} format
+ * @return
+ * @return {com.vzome.core.commands.AttributeMap}
+ */
+ public setXml(xml: org.w3c.dom.Element, format: com.vzome.core.commands.XmlSaveFormat): com.vzome.core.commands.AttributeMap {
+ const attrs: com.vzome.core.commands.AttributeMap = format.loadCommandAttributes$org_w3c_dom_Element(xml);
+ this.setFixedAttributes(attrs, format);
+ return attrs;
+ }
+
+ public setFixedAttributes(attributes: com.vzome.core.commands.AttributeMap, format: com.vzome.core.commands.XmlSaveFormat) {
+ attributes.put(com.vzome.core.commands.Command.FIELD_ATTR_NAME, format.getField());
+ }
+
+ /**
+ * This default behavior serializes in the old way, before XmlSaveFormat .COMPACTED_COMMAND_EDITS
+ * @param {com.vzome.core.commands.AttributeMap} attributes
+ * @return
+ * @param {*} result
+ */
+ public getXml(result: org.w3c.dom.Element, attributes: com.vzome.core.commands.AttributeMap) {
+ if (attributes == null)return;
+ for(let index=attributes.keySet().iterator();index.hasNext();) {
+ let key = index.next();
+ {
+ if (key === com.vzome.core.commands.Command.FIELD_ATTR_NAME)continue;
+ if (key === com.vzome.core.commands.CommandTransform.SYMMETRY_CENTER_ATTR_NAME)continue;
+ if (key === com.vzome.core.commands.CommandTransform.SYMMETRY_AXIS_ATTR_NAME)continue;
+ if (key === com.vzome.core.commands.CommandImportVEFData.FIELD_ATTR_NAME)continue;
+ const value: any = attributes.get(key);
+ if (value != null && value instanceof com.vzome.core.math.symmetry.IcosahedralSymmetry)continue;
+ AbstractCommand.saveCommandAttribute(result, key, value);
+ }
+ }
+ }
+
+ public static saveCommandAttribute(command: org.w3c.dom.Element, attrName: string, value: any) {
+ const doc: org.w3c.dom.Document = command.getOwnerDocument();
+ let valElem: org.w3c.dom.Element = null;
+ if (value != null && value instanceof Array && (value.length == 0 || value[0] == null ||typeof value[0] === 'number')){
+ const v: number[] = value;
+ valElem = command.getOwnerDocument().createElement("RationalVector");
+ let allOnes: boolean = true;
+ let allZeros: boolean = true;
+ for(let i: number = 0; i < (v.length / 2|0); i++) {{
+ allZeros = allZeros && (v[2 * i] === 0);
+ allOnes = allOnes && (v[2 * i + 1] === 1);
+ };}
+ if (!allZeros){
+ const numerators: java.lang.StringBuffer = new java.lang.StringBuffer();
+ for(let i: number = 0; i < (v.length / 2|0); i++) {{
+ if (i > 0)numerators.append(" ");
+ numerators.append(v[2 * i]);
+ };}
+ com.vzome.xml.DomUtils.addAttribute(valElem, "nums", numerators.toString());
+ if (!allOnes){
+ const denominators: java.lang.StringBuffer = new java.lang.StringBuffer();
+ for(let i: number = 0; i < (v.length / 2|0); i++) {{
+ if (i > 0)denominators.append(" ");
+ denominators.append(v[2 * i + 1]);
+ };}
+ com.vzome.xml.DomUtils.addAttribute(valElem, "denoms", denominators.toString());
+ }
+ }
+ } else if (value != null && value instanceof com.vzome.core.math.symmetry.Axis){
+ valElem = doc.createElement("Axis");
+ (value).getXML(valElem);
+ } else if (typeof value === 'boolean'){
+ valElem = doc.createElement("Boolean");
+ com.vzome.xml.DomUtils.addAttribute(valElem, "value", (value).toString());
+ } else if (typeof value === 'number'){
+ valElem = doc.createElement("Integer");
+ com.vzome.xml.DomUtils.addAttribute(valElem, "value", (value).toString());
+ } else if (value != null && value instanceof com.vzome.core.construction.Construction){
+ valElem = (value).getXml(command.getOwnerDocument());
+ } else if (typeof value === 'string'){
+ valElem = doc.createElement("String");
+ const str: string = com.vzome.core.commands.XmlSaveFormat.escapeNewlines(value);
+ valElem.appendChild(doc.createTextNode(str));
+ } else if (value != null && value instanceof com.vzome.core.math.symmetry.QuaternionicSymmetry){
+ valElem = doc.createElement("QuaternionicSymmetry");
+ com.vzome.xml.DomUtils.addAttribute(valElem, "name", (value).getName());
+ } else if (value != null && (value.constructor != null && value.constructor["__interfaces"] != null && value.constructor["__interfaces"].indexOf("com.vzome.core.math.symmetry.Symmetry") >= 0)){
+ valElem = doc.createElement("Symmetry");
+ com.vzome.xml.DomUtils.addAttribute(valElem, "name", (value).getName());
+ } else if (value == null){
+ valElem = doc.createElement("Null");
+ } else {
+ throw new java.lang.IllegalStateException("unable to save " + /* getName */(c => typeof c === 'string' ? c : c["__class"] ? c["__class"] : c["name"])((value.constructor)));
+ }
+ com.vzome.xml.DomUtils.addAttribute(valElem, "attrName", attrName);
+ command.appendChild(valElem);
+ }
+
+ public attributeIs3D(attrName: string): boolean {
+ return true;
+ }
+
+ public setQuaternion(offset: com.vzome.core.algebra.AlgebraicVector) {
+ }
+
+ public ordersSelection(): boolean {
+ return false;
+ }
+
+ public abstract apply(parameters?: any, attributes?: any, effects?: any): any;
+ public abstract getAttributeSignature(): any;
+ public abstract getParameterSignature(): any;
+ constructor() {
+ }
+ }
+ AbstractCommand["__class"] = "com.vzome.core.commands.AbstractCommand";
+ AbstractCommand["__interfaces"] = ["com.vzome.core.commands.Command"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/commands/AttributeMap.ts b/online/src/worker/legacy/ts/com/vzome/core/commands/AttributeMap.ts
new file mode 100644
index 000000000..d427a9c3a
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/commands/AttributeMap.ts
@@ -0,0 +1,33 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.commands {
+ /**
+ * @author David Hall
+ * This class doesn't add anything to the TreeMap,
+ * but there were so many places that were using Map,
+ * that I decided to use this class to clarify which ones were using it
+ * for managing attributes. It also avoids cluttering the code
+ * with Map which is just needed for type safety,
+ * but which does nothing for describing the intended use of the variables.
+ *
+ * Note that in XmlSaveFormat, AttributeMap replaces TreeMap<>,
+ * but in other places (such as CommandEdit), it replaces HashMap<>.
+ * XmlSaveFormat requires the Map<> to be ordered, but I assume
+ * that other places can safely use any implementation of Map<>.
+ * Therefore, I have used TreeMap<> rather than HashMap<> as the basis
+ * for AttributeMap across the board.
+ * @class
+ * @extends java.util.TreeMap
+ */
+ export class AttributeMap extends java.util.TreeMap {
+ static __com_vzome_core_commands_AttributeMap_serialVersionUID: number = 1;
+
+ constructor() {
+ super();
+ }
+ }
+ AttributeMap["__class"] = "com.vzome.core.commands.AttributeMap";
+ AttributeMap["__interfaces"] = ["java.lang.Cloneable","java.util.Map","java.util.NavigableMap","java.util.SortedMap","java.io.Serializable"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/commands/Command.ts b/online/src/worker/legacy/ts/com/vzome/core/commands/Command.ts
new file mode 100644
index 000000000..e1f7a5556
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/commands/Command.ts
@@ -0,0 +1,85 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.commands {
+ /**
+ * @author Scott Vorthmann
+ * @class
+ */
+ export interface Command {
+ /**
+ * Get the parameter signature for this command.
+ * Parameter are an ordered list of pre-existing Constructions.
+ * Each parameter has a name (for UI purposes), and an abstract Construction type
+ * (Point, Line, Segment, Plane, ...).
+ * @return {java.lang.Object[][]} an array of { String, Class } pairs, one for each parameter.
+ */
+ getParameterSignature(): any[][];
+
+ /**
+ * Get the attribute signature for this command.
+ * Attributes are an unordered set of primitive values.
+ * Each attribute has a name , and a primitive type
+ * (GoldenNumber, GoldenVector, Axis, Direction, GoldenMatrix, ...).
+ * @return {java.lang.Object[][]} an array of { String, Class } pairs, one for each attribute.
+ */
+ getAttributeSignature(): any[][];
+
+ apply(parameters: com.vzome.core.construction.ConstructionList, attributes: com.vzome.core.commands.AttributeMap, effects: com.vzome.core.construction.ConstructionChanges): com.vzome.core.construction.ConstructionList;
+ }
+
+ export namespace Command {
+
+ export const LOADING_FROM_FILE: string = "org.vorthmann.zome.editor.Command.LOADING_FROM_FILE";
+
+ export const FIELD_ATTR_NAME: string = "org.vorthmann.zome.commands.Command.ALGEBRAIC_FIELD";
+
+ export const GENERIC_PARAM_NAME: string = "org.vorthmann.zome.editor.Command.GENERIC_PARAM";
+ }
+
+
+ export namespace Command {
+
+ export interface Registry {
+ getCommand(name: string): com.vzome.core.commands.Command;
+ }
+
+ export interface FailureChannel {
+ reportFailure(f: Command.Failure);
+ }
+
+ /**
+ * @param {string} message
+ * @param {java.lang.Throwable} cause
+ * @class
+ * @extends java.lang.Exception
+ */
+ export class Failure extends Error {
+ static logger: java.util.logging.Logger; public static logger_$LI$(): java.util.logging.Logger { if (Failure.logger == null) { Failure.logger = java.util.logging.Logger.getLogger("org.vorthmann.zome.commands"); } return Failure.logger; }
+
+ public constructor(message?: any, cause?: any) {
+ if (((typeof message === 'string') || message === null) && ((cause != null && cause instanceof Error) || cause === null)) {
+ let __args = arguments;
+ super(message); this.message=message;
+ Failure.logger_$LI$().log(java.util.logging.Level.INFO, "command failure: " + message, cause);
+ } else if (((typeof message === 'string') || message === null) && cause === undefined) {
+ let __args = arguments;
+ super(message); this.message=message;
+ if (Failure.logger_$LI$().isLoggable(java.util.logging.Level.FINE))Failure.logger_$LI$().log(java.util.logging.Level.FINE, "command failure: " + message);
+ } else if (((message != null && message instanceof Error) || message === null) && cause === undefined) {
+ let __args = arguments;
+ let cause: any = __args[0];
+ super(cause); this.message=cause;
+ Failure.logger_$LI$().log(java.util.logging.Level.INFO, "command failure", cause);
+ } else if (message === undefined && cause === undefined) {
+ let __args = arguments;
+ super();
+ } else throw new Error('invalid overload');
+ }
+ }
+ Failure["__class"] = "com.vzome.core.commands.Command.Failure";
+ Failure["__interfaces"] = ["java.io.Serializable"];
+
+
+ }
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/commands/CommandAxialSymmetry.ts b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandAxialSymmetry.ts
new file mode 100644
index 000000000..af11c79ba
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandAxialSymmetry.ts
@@ -0,0 +1,60 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.commands {
+ /**
+ * @author Scott Vorthmann
+ * @param {*} symmetry
+ * @class
+ * @extends com.vzome.core.commands.CommandSymmetry
+ */
+ export class CommandAxialSymmetry extends com.vzome.core.commands.CommandSymmetry {
+ public constructor(symmetry: com.vzome.core.math.symmetry.Symmetry = null) {
+ super(symmetry);
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.construction.ConstructionList} parameters
+ * @param {com.vzome.core.commands.AttributeMap} attributes
+ * @param {*} effects
+ * @return {com.vzome.core.construction.ConstructionList}
+ */
+ public apply(parameters: com.vzome.core.construction.ConstructionList, attributes: com.vzome.core.commands.AttributeMap, effects: com.vzome.core.construction.ConstructionChanges): com.vzome.core.construction.ConstructionList {
+ this.setSymmetry(attributes);
+ const norm: com.vzome.core.construction.Segment = attributes.get(com.vzome.core.commands.CommandTransform.SYMMETRY_AXIS_ATTR_NAME);
+ if (norm == null){
+ throw new com.vzome.core.commands.Command.Failure("no symmetry axis provided");
+ }
+ const output: com.vzome.core.construction.ConstructionList = new com.vzome.core.construction.ConstructionList();
+ let vector: com.vzome.core.algebra.AlgebraicVector = norm.getOffset();
+ vector = norm.getField().projectTo3d(vector, true);
+ const axis: com.vzome.core.math.symmetry.Axis = this.mSymmetry['getAxis$com_vzome_core_algebra_AlgebraicVector'](vector);
+ const rotation: com.vzome.core.math.symmetry.Permutation = axis.getRotationPermutation();
+ if (rotation == null){
+ throw new com.vzome.core.commands.Command.Failure("symmetry axis does not support axial symmetry");
+ }
+ const order: number = rotation.getOrder();
+ const rotate: com.vzome.core.commands.CommandRotate = new com.vzome.core.commands.CommandRotate();
+ for(let i: number = 1; i < order; i++) {{
+ for(let index=parameters.iterator();index.hasNext();) {
+ let param = index.next();
+ {
+ output.addConstruction(param);
+ }
+ }
+ parameters = rotate.apply(parameters, attributes, effects);
+ };}
+ for(let index=parameters.iterator();index.hasNext();) {
+ let param = index.next();
+ {
+ output.addConstruction(param);
+ }
+ }
+ return output;
+ }
+ }
+ CommandAxialSymmetry["__class"] = "com.vzome.core.commands.CommandAxialSymmetry";
+ CommandAxialSymmetry["__interfaces"] = ["com.vzome.core.commands.Command"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/commands/CommandBuildAnchoredSegment.ts b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandBuildAnchoredSegment.ts
new file mode 100644
index 000000000..d0b25d00c
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandBuildAnchoredSegment.ts
@@ -0,0 +1,89 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.commands {
+ /**
+ * @author Scott Vorthmann
+ * @class
+ * @extends com.vzome.core.commands.AbstractCommand
+ */
+ export class CommandBuildAnchoredSegment extends com.vzome.core.commands.AbstractCommand {
+ /**
+ *
+ * @param {*} xml
+ * @param {com.vzome.core.commands.AttributeMap} attributes
+ */
+ public getXml(xml: org.w3c.dom.Element, attributes: com.vzome.core.commands.AttributeMap) {
+ com.vzome.core.commands.XmlSymmetryFormat.serializeAxis(xml, "symm", "dir", "index", "sense", attributes.get("axis"));
+ com.vzome.core.commands.XmlSaveFormat.serializeNumber(xml, "len", attributes.get("length"));
+ }
+
+ /**
+ *
+ * @param {*} xml
+ * @param {com.vzome.core.commands.XmlSaveFormat} format
+ * @return {com.vzome.core.commands.AttributeMap}
+ */
+ public setXml(xml: org.w3c.dom.Element, format: com.vzome.core.commands.XmlSaveFormat): com.vzome.core.commands.AttributeMap {
+ const attrs: com.vzome.core.commands.AttributeMap = super.setXml(xml, format);
+ if (format.commandEditsCompacted()){
+ attrs.put("axis", (format).parseAxis(xml, "symm", "dir", "index", "sense"));
+ attrs.put("length", format.parseNumber(xml, "len"));
+ }
+ return attrs;
+ }
+
+ static AXIS_ATTR: string = "axis";
+
+ static LENGTH_ATTR: string = "length";
+
+ static PARAM_SIGNATURE: any[][]; public static PARAM_SIGNATURE_$LI$(): any[][] { if (CommandBuildAnchoredSegment.PARAM_SIGNATURE == null) { CommandBuildAnchoredSegment.PARAM_SIGNATURE = [["start", com.vzome.core.construction.Point]]; } return CommandBuildAnchoredSegment.PARAM_SIGNATURE; }
+
+ /**
+ *
+ * @return {java.lang.Object[][]}
+ */
+ public getParameterSignature(): any[][] {
+ return CommandBuildAnchoredSegment.PARAM_SIGNATURE_$LI$();
+ }
+
+ /**
+ *
+ * @return {java.lang.Object[][]}
+ */
+ public getAttributeSignature(): any[][] {
+ return null;
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.construction.ConstructionList} parameters
+ * @param {com.vzome.core.commands.AttributeMap} attrs
+ * @param {*} effects
+ * @return {com.vzome.core.construction.ConstructionList}
+ */
+ public apply(parameters: com.vzome.core.construction.ConstructionList, attrs: com.vzome.core.commands.AttributeMap, effects: com.vzome.core.construction.ConstructionChanges): com.vzome.core.construction.ConstructionList {
+ const result: com.vzome.core.construction.ConstructionList = new com.vzome.core.construction.ConstructionList();
+ if (parameters == null || parameters.size() !== 1)throw new Command.Failure("start parameter must be a single point");
+ const c: any = parameters.get(0);
+ if (!(c != null && c instanceof com.vzome.core.construction.Point))throw new Command.Failure("start parameter must be a single point");
+ const pt1: com.vzome.core.construction.Point = c;
+ const axis: com.vzome.core.math.symmetry.Axis = attrs.get(CommandBuildAnchoredSegment.AXIS_ATTR);
+ const len: com.vzome.core.algebra.AlgebraicNumber = attrs.get(CommandBuildAnchoredSegment.LENGTH_ATTR);
+ const segment: com.vzome.core.construction.Segment = new com.vzome.core.construction.AnchoredSegment(axis, len, pt1);
+ effects['constructionAdded$com_vzome_core_construction_Construction'](segment);
+ result.addConstruction(segment);
+ const pt2: com.vzome.core.construction.Point = new com.vzome.core.construction.SegmentEndPoint(segment);
+ effects['constructionAdded$com_vzome_core_construction_Construction'](pt2);
+ result.addConstruction(pt2);
+ return result;
+ }
+
+ constructor() {
+ super();
+ }
+ }
+ CommandBuildAnchoredSegment["__class"] = "com.vzome.core.commands.CommandBuildAnchoredSegment";
+ CommandBuildAnchoredSegment["__interfaces"] = ["com.vzome.core.commands.Command"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/commands/CommandCentralSymmetry.ts b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandCentralSymmetry.ts
new file mode 100644
index 000000000..5cf66b4b3
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandCentralSymmetry.ts
@@ -0,0 +1,48 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.commands {
+ /**
+ * @author Scott Vorthmann
+ * @class
+ * @extends com.vzome.core.commands.CommandTransform
+ */
+ export class CommandCentralSymmetry extends com.vzome.core.commands.CommandTransform {
+ /**
+ *
+ * @return {java.lang.Object[][]}
+ */
+ public getAttributeSignature(): any[][] {
+ return com.vzome.core.commands.CommandTransform.ATTR_SIGNATURE_$LI$();
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.construction.ConstructionList} parameters
+ * @param {com.vzome.core.commands.AttributeMap} attributes
+ * @param {*} effects
+ * @return {com.vzome.core.construction.ConstructionList}
+ */
+ public apply(parameters: com.vzome.core.construction.ConstructionList, attributes: com.vzome.core.commands.AttributeMap, effects: com.vzome.core.construction.ConstructionChanges): com.vzome.core.construction.ConstructionList {
+ const output: com.vzome.core.construction.ConstructionList = new com.vzome.core.construction.ConstructionList();
+ const center: com.vzome.core.construction.Point = attributes.get(com.vzome.core.commands.CommandTransform.SYMMETRY_CENTER_ATTR_NAME);
+ const params: com.vzome.core.construction.Construction[] = parameters.getConstructions();
+ for(let index = 0; index < params.length; index++) {
+ let param = params[index];
+ {
+ output.addConstruction(param);
+ }
+ }
+ const transform: com.vzome.core.construction.Transformation = new com.vzome.core.construction.PointReflection(center);
+ effects['constructionAdded$com_vzome_core_construction_Construction'](transform);
+ return this.transform(params, transform, effects);
+ }
+
+ constructor() {
+ super();
+ }
+ }
+ CommandCentralSymmetry["__class"] = "com.vzome.core.commands.CommandCentralSymmetry";
+ CommandCentralSymmetry["__interfaces"] = ["com.vzome.core.commands.Command"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/commands/CommandCentroid.ts b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandCentroid.ts
new file mode 100644
index 000000000..e27b226eb
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandCentroid.ts
@@ -0,0 +1,66 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.commands {
+ /**
+ * @author Scott Vorthmann
+ * @class
+ * @extends com.vzome.core.commands.AbstractCommand
+ */
+ export class CommandCentroid extends com.vzome.core.commands.AbstractCommand {
+ static PARAM_SIGNATURE: any[][]; public static PARAM_SIGNATURE_$LI$(): any[][] { if (CommandCentroid.PARAM_SIGNATURE == null) { CommandCentroid.PARAM_SIGNATURE = [[com.vzome.core.commands.Command.GENERIC_PARAM_NAME, com.vzome.core.construction.Point]]; } return CommandCentroid.PARAM_SIGNATURE; }
+
+ static ATTR_SIGNATURE: any[][]; public static ATTR_SIGNATURE_$LI$(): any[][] { if (CommandCentroid.ATTR_SIGNATURE == null) { CommandCentroid.ATTR_SIGNATURE = []; } return CommandCentroid.ATTR_SIGNATURE; }
+
+ /**
+ *
+ * @return {java.lang.Object[][]}
+ */
+ public getParameterSignature(): any[][] {
+ return CommandCentroid.PARAM_SIGNATURE_$LI$();
+ }
+
+ /**
+ *
+ * @return {java.lang.Object[][]}
+ */
+ public getAttributeSignature(): any[][] {
+ return CommandCentroid.ATTR_SIGNATURE_$LI$();
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.construction.ConstructionList} parameters
+ * @param {com.vzome.core.commands.AttributeMap} attrs
+ * @param {*} effects
+ * @return {com.vzome.core.construction.ConstructionList}
+ */
+ public apply(parameters: com.vzome.core.construction.ConstructionList, attrs: com.vzome.core.commands.AttributeMap, effects: com.vzome.core.construction.ConstructionChanges): com.vzome.core.construction.ConstructionList {
+ const result: com.vzome.core.construction.ConstructionList = new com.vzome.core.construction.ConstructionList();
+ if (parameters == null || parameters.size() === 0)throw new Command.Failure("Select two or more balls to compute their centroid.");
+ const params: com.vzome.core.construction.Construction[] = parameters.getConstructions();
+ const verticesList: java.util.List = (new java.util.ArrayList());
+ for(let index = 0; index < params.length; index++) {
+ let param = params[index];
+ {
+ if (param != null && param instanceof com.vzome.core.construction.Point){
+ verticesList.add(param);
+ }
+ }
+ }
+ if (verticesList.isEmpty())throw new Command.Failure("Select two or more balls to compute their centroid.");
+ const points: com.vzome.core.construction.Point[] = [];
+ const centroid: com.vzome.core.construction.CentroidPoint = new com.vzome.core.construction.CentroidPoint(verticesList.toArray(points));
+ effects['constructionAdded$com_vzome_core_construction_Construction'](centroid);
+ result.addConstruction(centroid);
+ return result;
+ }
+
+ constructor() {
+ super();
+ }
+ }
+ CommandCentroid["__class"] = "com.vzome.core.commands.CommandCentroid";
+ CommandCentroid["__interfaces"] = ["com.vzome.core.commands.Command"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/commands/CommandExecuteZomicScript.ts b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandExecuteZomicScript.ts
new file mode 100644
index 000000000..81f8e9d81
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandExecuteZomicScript.ts
@@ -0,0 +1,86 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.commands {
+ /**
+ * @author Scott Vorthmann
+ * @param {com.vzome.core.math.symmetry.IcosahedralSymmetry} symmetry
+ * @class
+ * @extends com.vzome.core.commands.AbstractCommand
+ */
+ export class CommandExecuteZomicScript extends com.vzome.core.commands.AbstractCommand {
+ /**
+ *
+ * @param {com.vzome.core.commands.AttributeMap} attributes
+ * @param {com.vzome.core.commands.XmlSaveFormat} format
+ */
+ public setFixedAttributes(attributes: com.vzome.core.commands.AttributeMap, format: com.vzome.core.commands.XmlSaveFormat) {
+ super.setFixedAttributes(attributes, format);
+ this.symmetry = attributes.get(com.vzome.core.commands.CommandTransform.SYMMETRY_GROUP_ATTR_NAME);
+ if (this.symmetry == null)this.symmetry = (format).parseSymmetry("icosahedral");
+ }
+
+ public constructor(symmetry?: any) {
+ if (((symmetry != null && symmetry instanceof com.vzome.core.math.symmetry.IcosahedralSymmetry) || symmetry === null)) {
+ let __args = arguments;
+ super();
+ if (this.symmetry === undefined) { this.symmetry = null; }
+ this.symmetry = symmetry;
+ } else if (symmetry === undefined) {
+ let __args = arguments;
+ super();
+ if (this.symmetry === undefined) { this.symmetry = null; }
+ this.symmetry = null;
+ } else throw new Error('invalid overload');
+ }
+
+ /*private*/ symmetry: com.vzome.core.math.symmetry.IcosahedralSymmetry;
+
+ public static SCRIPT_ATTR: string = "script";
+
+ static PARAM_SIGNATURE: any[][]; public static PARAM_SIGNATURE_$LI$(): any[][] { if (CommandExecuteZomicScript.PARAM_SIGNATURE == null) { CommandExecuteZomicScript.PARAM_SIGNATURE = [["start", com.vzome.core.construction.Point]]; } return CommandExecuteZomicScript.PARAM_SIGNATURE; }
+
+ static ATTR_SIGNATURE: any[][]; public static ATTR_SIGNATURE_$LI$(): any[][] { if (CommandExecuteZomicScript.ATTR_SIGNATURE == null) { CommandExecuteZomicScript.ATTR_SIGNATURE = [[CommandExecuteZomicScript.SCRIPT_ATTR, com.vzome.core.zomic.program.ZomicStatement]]; } return CommandExecuteZomicScript.ATTR_SIGNATURE; }
+
+ /**
+ *
+ * @return {java.lang.Object[][]}
+ */
+ public getParameterSignature(): any[][] {
+ return CommandExecuteZomicScript.PARAM_SIGNATURE_$LI$();
+ }
+
+ /**
+ *
+ * @return {java.lang.Object[][]}
+ */
+ public getAttributeSignature(): any[][] {
+ return CommandExecuteZomicScript.ATTR_SIGNATURE_$LI$();
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.construction.ConstructionList} parameters
+ * @param {com.vzome.core.commands.AttributeMap} attrs
+ * @param {*} effects
+ * @return {com.vzome.core.construction.ConstructionList}
+ */
+ public apply(parameters: com.vzome.core.construction.ConstructionList, attrs: com.vzome.core.commands.AttributeMap, effects: com.vzome.core.construction.ConstructionChanges): com.vzome.core.construction.ConstructionList {
+ const script: string = attrs.get(CommandExecuteZomicScript.SCRIPT_ATTR);
+ const result: com.vzome.core.construction.ConstructionList = new com.vzome.core.construction.ConstructionList();
+ if (parameters.size() !== 1)throw new Command.Failure("start parameter must be a single connector");
+ const c: com.vzome.core.construction.Construction = parameters.get(0);
+ if (!(c != null && c instanceof com.vzome.core.construction.Point))throw new Command.Failure("start parameter must be a connector");
+ const pt1: com.vzome.core.construction.Point = c;
+ try {
+ this.symmetry.interpretScript(script, "zomic", pt1, this.symmetry, effects);
+ } catch(e) {
+ throw new Command.Failure(e.message, e);
+ }
+ return result;
+ }
+ }
+ CommandExecuteZomicScript["__class"] = "com.vzome.core.commands.CommandExecuteZomicScript";
+ CommandExecuteZomicScript["__interfaces"] = ["com.vzome.core.commands.Command"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/commands/CommandFreePoint.ts b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandFreePoint.ts
new file mode 100644
index 000000000..94e4eae46
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandFreePoint.ts
@@ -0,0 +1,52 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.commands {
+ /**
+ * @author Scott Vorthmann
+ * @class
+ * @extends com.vzome.core.commands.AbstractCommand
+ */
+ export class CommandFreePoint extends com.vzome.core.commands.AbstractCommand {
+ static PARAMS: any[][]; public static PARAMS_$LI$(): any[][] { if (CommandFreePoint.PARAMS == null) { CommandFreePoint.PARAMS = []; } return CommandFreePoint.PARAMS; }
+
+ /**
+ *
+ * @return {java.lang.Object[][]}
+ */
+ public getParameterSignature(): any[][] {
+ return CommandFreePoint.PARAMS_$LI$();
+ }
+
+ /**
+ *
+ * @return {java.lang.Object[][]}
+ */
+ public getAttributeSignature(): any[][] {
+ return null;
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.construction.ConstructionList} parameters
+ * @param {com.vzome.core.commands.AttributeMap} attributes
+ * @param {*} effects
+ * @return {com.vzome.core.construction.ConstructionList}
+ */
+ public apply(parameters: com.vzome.core.construction.ConstructionList, attributes: com.vzome.core.commands.AttributeMap, effects: com.vzome.core.construction.ConstructionChanges): com.vzome.core.construction.ConstructionList {
+ const result: com.vzome.core.construction.ConstructionList = new com.vzome.core.construction.ConstructionList();
+ const loc: com.vzome.core.algebra.AlgebraicVector = attributes.get("where");
+ const pt2: com.vzome.core.construction.Point = new com.vzome.core.construction.FreePoint(loc);
+ effects['constructionAdded$com_vzome_core_construction_Construction'](pt2);
+ result.addConstruction(pt2);
+ return result;
+ }
+
+ constructor() {
+ super();
+ }
+ }
+ CommandFreePoint["__class"] = "com.vzome.core.commands.CommandFreePoint";
+ CommandFreePoint["__interfaces"] = ["com.vzome.core.commands.Command"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/commands/CommandHide.ts b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandHide.ts
new file mode 100644
index 000000000..6eed18a49
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandHide.ts
@@ -0,0 +1,49 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.commands {
+ /**
+ * @author Scott Vorthmann
+ * @class
+ * @extends com.vzome.core.commands.AbstractCommand
+ */
+ export class CommandHide extends com.vzome.core.commands.AbstractCommand {
+ static PARAM_SIGNATURE: any[][]; public static PARAM_SIGNATURE_$LI$(): any[][] { if (CommandHide.PARAM_SIGNATURE == null) { CommandHide.PARAM_SIGNATURE = [[com.vzome.core.commands.Command.GENERIC_PARAM_NAME, com.vzome.core.construction.Construction]]; } return CommandHide.PARAM_SIGNATURE; }
+
+ static ATTR_SIGNATURE: any[][]; public static ATTR_SIGNATURE_$LI$(): any[][] { if (CommandHide.ATTR_SIGNATURE == null) { CommandHide.ATTR_SIGNATURE = []; } return CommandHide.ATTR_SIGNATURE; }
+
+ /**
+ *
+ * @return {java.lang.Object[][]}
+ */
+ public getParameterSignature(): any[][] {
+ return CommandHide.PARAM_SIGNATURE_$LI$();
+ }
+
+ /**
+ *
+ * @return {java.lang.Object[][]}
+ */
+ public getAttributeSignature(): any[][] {
+ return CommandHide.ATTR_SIGNATURE_$LI$();
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.construction.ConstructionList} parameters
+ * @param {com.vzome.core.commands.AttributeMap} attributes
+ * @param {*} effects
+ * @return {com.vzome.core.construction.ConstructionList}
+ */
+ public apply(parameters: com.vzome.core.construction.ConstructionList, attributes: com.vzome.core.commands.AttributeMap, effects: com.vzome.core.construction.ConstructionChanges): com.vzome.core.construction.ConstructionList {
+ throw new Command.Failure("CommandHide apply attempted");
+ }
+
+ constructor() {
+ super();
+ }
+ }
+ CommandHide["__class"] = "com.vzome.core.commands.CommandHide";
+ CommandHide["__interfaces"] = ["com.vzome.core.commands.Command"];
+
+
+}
+
diff --git a/online/src/worker/legacy/ts/com/vzome/core/commands/CommandImportVEFData.ts b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandImportVEFData.ts
new file mode 100644
index 000000000..bc80f1527
--- /dev/null
+++ b/online/src/worker/legacy/ts/com/vzome/core/commands/CommandImportVEFData.ts
@@ -0,0 +1,224 @@
+/* Generated from Java with JSweet 3.2.0-SNAPSHOT - http://www.jsweet.org */
+namespace com.vzome.core.commands {
+ /**
+ * @author Scott Vorthmann
+ * @param {*} projection
+ * @class
+ * @extends com.vzome.core.commands.AbstractCommand
+ */
+ export class CommandImportVEFData extends com.vzome.core.commands.AbstractCommand {
+ public static X: number = 0;
+
+ public static Y: number = 1;
+
+ public static Z: number = 2;
+
+ public static W: number = 3;
+
+ public static VEF_STRING_ATTR_NAME: string = "org.vorthmann.zome.commands.CommandImportVEFData.vef.string";
+
+ public static FIELD_ATTR_NAME: string = "org.vorthmann.zome.commands.CommandImportVEFData.field";
+
+ public static NO_INVERSION_ATTR_NAME: string = "org.vorthmann.zome.commands.CommandImportVEFData.no.inversion";
+
+ static PARAM_SIGNATURE: any[][]; public static PARAM_SIGNATURE_$LI$(): any[][] { if (CommandImportVEFData.PARAM_SIGNATURE == null) { CommandImportVEFData.PARAM_SIGNATURE = [[com.vzome.core.commands.Command.GENERIC_PARAM_NAME, com.vzome.core.construction.Construction]]; } return CommandImportVEFData.PARAM_SIGNATURE; }
+
+ static ATTR_SIGNATURE: any[][]; public static ATTR_SIGNATURE_$LI$(): any[][] { if (CommandImportVEFData.ATTR_SIGNATURE == null) { CommandImportVEFData.ATTR_SIGNATURE = [[CommandImportVEFData.VEF_STRING_ATTR_NAME, String], [com.vzome.core.commands.Command.FIELD_ATTR_NAME, java.io.InputStream], [CommandImportVEFData.NO_INVERSION_ATTR_NAME, java.io.InputStream]]; } return CommandImportVEFData.ATTR_SIGNATURE; }
+
+ /*private*/ mProjection: com.vzome.core.math.Projection;
+
+ public constructor(projection?: any) {
+ if (((projection != null && (projection.constructor != null && projection.constructor["__interfaces"] != null && projection.constructor["__interfaces"].indexOf("com.vzome.core.math.Projection") >= 0)) || projection === null)) {
+ let __args = arguments;
+ super();
+ if (this.mProjection === undefined) { this.mProjection = null; }
+ this.quaternionVector = null;
+ this.mProjection = projection;
+ } else if (projection === undefined) {
+ let __args = arguments;
+ {
+ let __args = arguments;
+ let projection: any = null;
+ super();
+ if (this.mProjection === undefined) { this.mProjection = null; }
+ this.quaternionVector = null;
+ this.mProjection = projection;
+ }
+ } else throw new Error('invalid overload');
+ }
+
+ /**
+ *
+ * @return {java.lang.Object[][]}
+ */
+ public getParameterSignature(): any[][] {
+ return CommandImportVEFData.PARAM_SIGNATURE_$LI$();
+ }
+
+ /**
+ *
+ * @return {java.lang.Object[][]}
+ */
+ public getAttributeSignature(): any[][] {
+ return CommandImportVEFData.ATTR_SIGNATURE_$LI$();
+ }
+
+ /**
+ *
+ * @param {string} attrName
+ * @return {boolean}
+ */
+ public attributeIs3D(attrName: string): boolean {
+ return !("symmetry.axis.segment" === attrName);
+ }
+
+ /*private*/ quaternionVector: com.vzome.core.algebra.AlgebraicVector;
+
+ /**
+ * Only called when migrating a 2.0 model file.
+ * @param {com.vzome.core.algebra.AlgebraicVector} offset
+ */
+ public setQuaternion(offset: com.vzome.core.algebra.AlgebraicVector) {
+ this.quaternionVector = offset;
+ }
+
+ /**
+ *
+ * @param {*} xml
+ * @param {com.vzome.core.commands.XmlSaveFormat} format
+ * @return {com.vzome.core.commands.AttributeMap}
+ */
+ public setXml(xml: org.w3c.dom.Element, format: com.vzome.core.commands.XmlSaveFormat): com.vzome.core.commands.AttributeMap {
+ const attrs: com.vzome.core.commands.AttributeMap = super.setXml(xml, format);
+ this.quaternionVector = format.parseRationalVector(xml, "quaternion");
+ return attrs;
+ }
+
+ /**
+ *
+ * @param {*} result
+ * @param {com.vzome.core.commands.AttributeMap} attributes
+ */
+ public getXml(result: org.w3c.dom.Element, attributes: com.vzome.core.commands.AttributeMap) {
+ if (this.quaternionVector != null)com.vzome.xml.DomUtils.addAttribute(result, "quaternion", this.quaternionVector.toParsableString());
+ super.getXml(result, attributes);
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.commands.AttributeMap} attributes
+ * @param {com.vzome.core.commands.XmlSaveFormat} format
+ */
+ public setFixedAttributes(attributes: com.vzome.core.commands.AttributeMap, format: com.vzome.core.commands.XmlSaveFormat) {
+ if (!attributes.containsKey(CommandImportVEFData.FIELD_ATTR_NAME))attributes.put(CommandImportVEFData.FIELD_ATTR_NAME, format.getField());
+ super.setFixedAttributes(attributes, format);
+ }
+
+ /**
+ *
+ * @param {com.vzome.core.construction.ConstructionList} parameters
+ * @param {com.vzome.core.commands.AttributeMap} attributes
+ * @param {*} effects
+ * @return {com.vzome.core.construction.ConstructionList}
+ */
+ public apply(parameters: com.vzome.core.construction.ConstructionList, attributes: com.vzome.core.commands.AttributeMap, effects: com.vzome.core.construction.ConstructionChanges): com.vzome.core.construction.ConstructionList {
+ const result: com.vzome.core.construction.ConstructionList = new com.vzome.core.construction.ConstructionList();
+ let field: com.vzome.core.algebra.AlgebraicField =