{"version":3,"file":"jsxgraphsrc.mjs","mappings":";;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACL;AACpC;AACA;AACA;AACA;AACA;AACA,wDAAG;AACH;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,cAAc;AACd;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,WAAW;AAC1B,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAkB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAkB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,WAAW;AAC1B,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC,iCAAiC;AACjC,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,iBAAiB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,qBAAqB;AACpC,eAAe,QAAQ;AACvB,eAAe,WAAW;AAC1B;AACA;AACA;AACA;AACA,aAAa,+DAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,mEAAK;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,WAAW;AAC1B,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC,iCAAiC;AACjC,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAe,wDAAG,cAAc,EAAC;;;;;;;;;;;;;;;;;;;AC1iBjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACM;AACS;AACA;AACI;AACd;AACE;AACC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,IAAI,2BAA2B;AAC/B;AACA,wDAAG;AACH;AACA;AACA,SAAS,+DAAI;AACb;AACA;AACA;AACA,gBAAgB,wBAAwB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,2DAAM,CAAC,8DAAK;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,2DAAM,CAAC,8DAAK;AACzC,4BAA4B,2DAAM,CAAC,8DAAK;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD,aAAa;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,4BAA4B;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,gCAAgC;AAC5C;AACA;AACA;AACA;AACA,UAAU,sCAAsC;AAChD,qBAAqB,wBAAwB;AAC7C,QAAQ,+CAA+C;AACvD,mCAAmC;AACnC;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,+DAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,QAAQ,+DAAI;AACZ;AACA;AACA;AACA;AACA;AACA,wDAAG;AACH,IAAI,wDAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,8DAAK;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,8DAAK;AAC5C;AACA;AACA;AACA,4BAA4B,kEAAQ;AACpC;AACA,oBAAoB,kEAAQ;AAC5B;AACA;AACA;AACA;AACA,cAAc,gCAAgC,8DAAK;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,8DAAG;AACzC;AACA;AACA;AACA;AACA,yBAAyB,kEAAQ;AACjC;AACA;AACA;AACA;AACA,oCAAoC,yBAAyB;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,oCAAoC,yBAAyB;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,8DAAK;AACtC;AACA;AACA,wBAAwB,8DAAG;AAC3B;AACA;AACA;AACA;AACA,kBAAkB;AAClB,gCAAgC,kEAAQ;AACxC;AACA;AACA;AACA;AACA,2CAA2C,8DAAG;AAC9C;AACA;AACA;AACA,0CAA0C,8DAAG;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,4BAA4B,8DAAG;AACrD;AACA;AACA;AACA,0CAA0C,8DAAG;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,0CAA0C,8DAAG;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,4EAA4E,8DAAG;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,8DAAG;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,8DAAG;AACpD;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,wBAAwB,8DAAK;AAC3C;AACA;AACA,sBAAsB,kEAAQ;AAC9B;AACA,iCAAiC;AACjC,cAAc,gCAAgC,8DAAK;AACnD;AACA,mCAAmC,8DAAK;AACxC,mCAAmC,8DAAK;AACxC;AACA,gCAAgC,kEAAQ;AACxC;AACA,4BAA4B,kEAAQ;AACpC;AACA,2BAA2B,kEAAQ;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,8DAAG;AAC7C;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,+DAAI;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,mBAAmB;AAC3D;AACA,yCAAyC,8DAAG;AAC5C,qCAAqC,8DAAG;AACxC;AACA,qCAAqC,2DAAM,CAAC,8DAAK;AACjD,gCAAgC,kEAAQ;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,QAAQ;AAChE,qCAAqC,8DAAG;AACxC;AACA,uCAAuC,2DAAM,CAAC,8DAAK;AACnD,0BAA0B;AAC1B;AACA,qCAAqC,8DAAG;AACxC,iCAAiC,8DAAG;AACpC,qCAAqC,2DAAM,CAAC,8DAAK;AACjD,gCAAgC,kEAAQ;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,8BAA8B,kEAAQ;AACtC;AACA,yCAAyC;AACzC;AACA;AACA,cAAc,SAAS,+DAAI;AAC3B;AACA,4BAA4B,kEAAQ;AACpC,wCAAwC;AACxC;AACA;AACA,uCAAuC,8DAAK;AAC5C;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB,qDAAqD,8DAAG;AACxD;AACA,4BAA4B,uBAAuB;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,8DAAK;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,gCAAgC,8DAAK;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,4BAA4B,8DAAG;AACjD,iEAAiE,8DAAG;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,4BAA4B,8DAAG;AACjD,mDAAmD,8DAAG;AACtD,8CAA8C,8DAAG;AACjD;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,wBAAwB,8DAAK;AAC3C,2CAA2C,8DAAK;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kEAAQ;AAC5B,cAAc,gCAAgC,8DAAK;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,+DAAI;AACrC;AACA;AACA;AACA;AACA,+CAA+C,8DAAK;AACpD;AACA;AACA;AACA;AACA,kBAAkB;AAClB,+CAA+C,8DAAK;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,8DAAK;AACxC,mCAAmC,8DAAK;AACxC;AACA,gCAAgC,kEAAQ;AACxC;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,kEAAQ;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,8DAAG;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,4BAA4B,kEAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,QAAQ;AAC5D,oCAAoC,2DAAM;AAC1C,gCAAgC,8DAAK;AACrC,gCAAgC,8DAAG;AACnC;AACA;AACA;AACA,sBAAsB;AACtB,4BAA4B,kEAAQ;AACpC;AACA;AACA,cAAc,SAAS,+DAAI;AAC3B,oBAAoB,kEAAQ;AAC5B;AACA;AACA,uCAAuC,8DAAK;AAC5C,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD,8DAAG;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,eAAe;AAClC;AACA;AACA;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA,2BAA2B,sCAAsC;AACjE;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,eAAe,sCAAsC;AACrD;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,YAAY,sCAAsC;AAClD;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,4CAA4C,8DAAK;AACjD;AACA;AACA,SAAS;AACT;AACA;AACA,sBAAsB;AACtB,mBAAmB,SAAS;AAC5B,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,YAAY,kCAAkC;AAC9C;AACA;AACA,mBAAmB,SAAS;AAC5B,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA,oCAAoC,UAAU;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,+DAAI;AAC5B,kCAAkC,kEAAQ;AAC1C;AACA,iDAAiD,8DAAK;AACtD,0BAA0B;AAC1B,iDAAiD,8DAAK;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,8DAAK;AACpD;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,sBAAsB,2CAA2C;AACjE;AACA,mBAAmB,SAAS;AAC5B,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,oBAAoB,+DAAI;AACxB,wBAAwB,+DAAI;AAC5B,qCAAqC,kEAAQ;AAC7C,sBAAsB,6BAA6B,8DAAK;AACxD,qCAAqC,kEAAQ;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA,0BAA0B;AAC1B,6CAA6C,2DAAM;AACnD,gCAAgC,8DAAK;AACrC;AACA;AACA;AACA;AACA,sBAAsB,6BAA6B,8DAAK;AACxD,qCAAqC,kEAAQ;AAC7C,sBAAsB,6BAA6B,8DAAK;AACxD,qCAAqC,kEAAQ;AAC7C,sBAAsB,qBAAqB,8DAAK;AAChD,qCAAqC,kEAAQ;AAC7C,sBAAsB,qBAAqB,8DAAK;AAChD,yCAAyC,2DAAM;AAC/C,4BAA4B,8DAAK;AACjC,4BAA4B,kEAAQ;AACpC;AACA;AACA;AACA;AACA;AACA,gDAAgD,8DAAK;AACrD,sBAAsB;AACtB,gDAAgD,8DAAK;AACrD;AACA;AACA;AACA;AACA;AACA,8CAA8C,8DAAK;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,gCAAgC,0BAA0B,KAAK,2BAA2B;AAC1F,mBAAmB,OAAO;AAC1B,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,2DAAM;AAC9B;AACA,yBAAyB,oEAAU;AACnC;AACA;AACA,kBAAkB;AAClB,yBAAyB,oEAAU;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,8DAAK;AAClD;AACA;AACA;AACA;AACA;AACA,+BAA+B,8DAAK;AACpC,oCAAoC,2DAAM;AAC1C,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,iCAAiC;AAC7D,wBAAwB,8DAAG;AAC3B;AACA,4BAA4B,8DAAG,YAAY,8DAAG;AAC9C;AACA,kDAAkD,8DAAK;AACvD,0CAA0C,8DAAK;AAC/C;AACA,+CAA+C,8DAAK;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,8DAAK;AACnE;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,gCAAgC,0BAA0B,KAAK,2BAA2B;AAC1F,mBAAmB,OAAO;AAC1B,qBAAqB;AACrB;AACA;AACA;AACA;AACA,qBAAqB,2DAAM;AAC3B;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,gCAAgC,0BAA0B,KAAK,2BAA2B;AAC1F,mBAAmB,OAAO;AAC1B,qBAAqB;AACrB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,4BAA4B;AAC/C,mBAAmB,QAAQ;AAC3B,qBAAqB,WAAW;AAChC;AACA;AACA,8BAA8B,8DAAK;AACnC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,eAAe;AAClC;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,8DAAK;AACvC;AACA;AACA,4BAA4B,6BAA6B;AACzD,2BAA2B,wDAAG;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA,cAAc,2BAA2B,8DAAK;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,8DAAK;AAC7B;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,8DAAK;AAC3C;AACA,sBAAsB,+BAA+B,8DAAK;AAC1D;AACA,sBAAsB,uBAAuB,8DAAK;AAClD;AACA,sBAAsB,uBAAuB,8DAAK;AAClD;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,8DAAK;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,8DAAK;AACnD,oCAAoC,8DAAK;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA,sCAAsC,8DAAK;AAC3C,4BAA4B,8DAAK;AACjC;AACA,cAAc,+BAA+B,8DAAK;AAClD;AACA;AACA,cAAc,+BAA+B,8DAAK;AAClD;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,8DAAK;AAC3C,4BAA4B,8DAAK;AACjC;AACA;AACA;AACA;AACA,wBAAwB,kBAAkB;AAC1C;AACA;AACA,oBAAoB,+DAAI;AACxB;AACA;AACA,sEAAsE;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,SAAS,+DAAI;AAC/B;AACA,kBAAkB,SAAS,+DAAI;AAC/B;AACA,kBAAkB,SAAS,+DAAI,gBAAgB,+DAAI;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,+DAAI;AAC5B,mDAAmD,8DAAK;AACxD;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,8DAAK;AACpD;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,8DAAK;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB;AACA,kBAAkB,SAAS;AAC3B;AACA;AACA;AACA;AACA,0CAA0C,2DAAM;AAChD,oBAAoB,8DAAK;AACzB;AACA;AACA;AACA,cAAc;AACd,0CAA0C,2DAAM,CAAC,8DAAK;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,2DAAM;AACvC,wBAAwB,8DAAK;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,2DAAM;AACvC,wBAAwB,8DAAK;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,+DAAI;AAC7B;AACA;AACA,2CAA2C,8DAAK;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,wBAAwB,iCAAiC;AACzD;AACA,oBAAoB,8DAAG;AACvB;AACA,6CAA6C,8DAAK;AAClD;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,0BAA0B,sBAAsB;AACnE,2BAA2B,yBAAyB;AACpD,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA,uBAAuB,+DAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,iBAAiB;AACpC,mBAAmB,iBAAiB;AACpC;AACA,mBAAmB,iBAAiB;AACpC,mBAAmB,QAAQ;AAC3B;AACA,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,oFAAoF,uBAAuB;AAC3G,mFAAmF,mBAAmB;AACtG,uGAAuG,cAAc;AACrH;AACA,kGAAkG,uFAAuF;AACzL;AACA;AACA,8EAA8E,6BAA6B;AAC3G,6EAA6E,yBAAyB;AACtG;AACA;AACA;AACA;AACA;AACA,mEAAmE,SAAS;AAC5E;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA,uEAAuE,SAAS;AAChF;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA,sBAAsB,+DAAI;AAC1B,qBAAqB,+DAAI;AACzB;AACA;AACA,oBAAoB,+DAAI;AACxB,wBAAwB,+DAAI;AAC5B;AACA;AACA,8BAA8B,8DAAK,wBAAwB,+DAAI;AAC/D;AACA;AACA;AACA,iBAAiB;AACjB;AACA,qBAAqB,+DAAI;AACzB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,mBAAmB;AACxC;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,gBAAgB;AACnC;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,UAAU;AAC7B,mBAAmB,SAAS;AAC5B;AACA,kBAAkB,gCAAgC;AAClD,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA,4BAA4B,SAAS;AACrC,wBAAwB,+DAAI;AAC5B;AACA,sBAAsB;AACtB;AACA,0CAA0C,8DAAK;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,8DAAK;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,+DAAI;AACzB,8BAA8B,kEAAQ;AACtC,gCAAgC,WAAW;AAC3C;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,gCAAgC,WAAW;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,WAAW;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,SAAS,+DAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,YAAY,oCAAoC;AAChD;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,UAAU;AAC7B,mBAAmB,QAAQ;AAC3B;AACA;AACA,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sGAAsG,kBAAkB,gBAAgB;AACxI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,iCAAiC,oBAAoB,GAAG;AAC/F,uCAAuC,iCAAiC,oBAAoB,iBAAiB;AAC7G,uCAAuC,iCAAiC,oBAAoB,gBAAgB;AAC5G,uCAAuC,iCAAiC,oBAAoB,gBAAgB;AAC5G;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA,sGAAsG,kBAAkB,gBAAgB;AACxI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,iCAAiC,oBAAoB,GAAG;AAC/F,uCAAuC,iCAAiC,oBAAoB,iBAAiB;AAC7G,uCAAuC,iCAAiC,oBAAoB,gBAAgB;AAC5G,uCAAuC,iCAAiC,oBAAoB,gBAAgB;AAC5G;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,wBAAwB,2DAAM,CAAC,8DAAK;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,wDAAwD;AACxD;AACA;AACA,wDAAwD;AACxD;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA,wBAAwB,wDAAG;AAC3B;AACA;AACA,uCAAuC;AACvC;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA,0EAA0E,8DAAG;AAC7E;AACA,iCAAiC,8DAAK;AACtC;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB,+BAA+B,8DAAG;AAClC,+BAA+B,8DAAG;AAClC;AACA;AACA;AACA;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,UAAU;AAC7B,mBAAmB,QAAQ;AAC3B;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sGAAsG,kBAAkB,gBAAgB;AACxI;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,yBAAyB;AACpE,2CAA2C,yBAAyB;AACpE,2CAA2C,wBAAwB;AACnE,2CAA2C,wBAAwB;AACnE,eAAe;AACf;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA,sGAAsG,kBAAkB,gBAAgB;AACxI;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,yBAAyB;AACpE,2CAA2C,yBAAyB;AACpE,2CAA2C,wBAAwB;AACnE,2CAA2C,wBAAwB;AACnE,eAAe;AACf;AACA;AACA;AACA;AACA;AACA,wBAAwB,2DAAM,CAAC,8DAAK;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D;AAC9D;AACA;AACA,wDAAwD;AACxD;AACA;AACA,wDAAwD;AACxD;AACA;AACA;AACA,4CAA4C;AAC5C;AACA;AACA,wBAAwB,wDAAG;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB,4BAA4B;AAC5B,cAAc;AACd;AACA,qBAAqB,+DAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,oBAAoB;AAC5C,gCAAgC,QAAQ;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,2BAA2B,mCAAmC;AAC9D;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,+DAAI,oBAAoB,+DAAI;AAChD;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT;AACA;AACA,2BAA2B,gCAAgC;AAC3D;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA,wBAAwB;AACxB;AACA,wBAAwB;AACxB;AACA,wBAAwB;AACxB;AACA,wBAAwB;AACxB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA,4BAA4B;AAC5B;AACA,4BAA4B;AAC5B;AACA,4BAA4B;AAC5B;AACA,4BAA4B;AAC5B;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,+DAAI,oBAAoB,+DAAI;AAChD;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT;AACA;AACA,2BAA2B,mCAAmC;AAC9D;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,+DAAI,oBAAoB,+DAAI;AAChD;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,8DAAK;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,2CAA2C,8DAAK;AAChD;AACA;AACA;AACA,cAAc,2CAA2C,8DAAK;AAC9D;AACA;AACA,kBAAkB;AAClB;AACA;AACA,2CAA2C,8DAAK;AAChD;AACA,sBAAsB,kEAAQ;AAC9B;AACA;AACA,cAAc,2CAA2C,8DAAK;AAC9D;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,2CAA2C,8DAAK;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,8DAAK;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,QAAQ;AAClB,UAAU,QAAQ;AAClB,UAAU,OAAO;AACjB;AACA;AACA,UAAU,QAAQ;AAClB,UAAU,QAAQ;AAClB;AACA,UAAU,OAAO;AACjB;AACA,YAAY,QAAQ;AACpB;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA,gBAAgB,mBAAmB;AACnC,YAAY,+DAAI,0BAA0B,+DAAI;AAC9C;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI,wBAAwB,+DAAI;AAC5C;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,UAAU,SAAS,+DAAI,wBAAwB,+DAAI;AACnD;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAe,wDAAG,cAAc,EAAC;;;;;;;;;;;;;AC39EjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACC;AAC7B;AACA,wDAAG;AACH,IAAI,wDAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAG;AACH,IAAI,wDAAG;AACP;AACA;AACA;AACA,uBAAuB;AACvB,qBAAqB;AACrB;AACA;AACA,mBAAmB,wDAAG,yBAAyB;AAC/C,SAAS;AACT;AACA;AACA;AACA,uBAAuB;AACvB,qBAAqB;AACrB;AACA;AACA,mBAAmB,wDAAG;AACtB,SAAS;AACT;AACA;AACA;AACA,uBAAuB;AACvB,qBAAqB;AACrB;AACA;AACA,oBAAoB,wDAAG,uBAAuB,wDAAG;AACjD,SAAS;AACT;AACA;AACA;AACA;AACA,uBAAuB;AACvB,qBAAqB;AACrB;AACA;AACA;AACA;AACA,gBAAgB,wDAAG;AACnB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB,qBAAqB;AACrB;AACA;AACA,8BAA8B,wDAAG;AACjC;AACA,gBAAgB,wDAAG;AACnB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,yDAAI,mBAAmB,yDAAI;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,yCAAyC,eAAe;AACxD,gEAAgE;AAChE;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,2EAA2E;AAC3E,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA,gBAAgB,yDAAI;AACpB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA,gBAAgB,yDAAI;AACpB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA,gBAAgB,yDAAI;AACpB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA,gBAAgB,yDAAI;AACpB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,eAAe;AAClC,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,yDAAI;AAC3B,iBAAiB,yDAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA,0DAA0D;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,UAAU;AAC7B,mBAAmB,QAAQ;AAC3B,mBAAmB,gBAAgB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,yDAAI;AACjD;AACA;AACA;AACA;AACA;AACA,gBAAgB,yDAAI,gBAAgB,yDAAI;AACxC,6CAA6C;AAC7C;AACA;AACA;AACA;AACA,gBAAgB,yDAAI,gBAAgB,yDAAI;AACxC;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,UAAU;AAC7B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA,iBAAiB,yDAAI;AACrB,gBAAgB,wDAAG;AACnB;AACA;AACA;AACA,iBAAiB,yDAAI;AACrB,gBAAgB,wDAAG;AACnB;AACA;AACA;AACA,iBAAiB,yDAAI;AACrB,gBAAgB,wDAAG;AACnB;AACA;AACA;AACA,gBAAgB,yDAAI;AACpB;AACA;AACA,gBAAgB,wDAAG;AACnB;AACA;AACA;AACA;AACA;AACA,oBAAoB,yDAAI,gBAAgB,yDAAI;AAC5C;AACA;AACA;AACA;AACA,oBAAoB,yDAAI,gBAAgB,yDAAI;AAC5C;AACA;AACA,cAAc;AACd,gBAAgB,wDAAG;AACnB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,uEAAuE;AACvE,iBAAiB,iBAAiB;AAClC,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,QAAQ;AAC1C,oBAAoB,wDAAG;AACvB;AACA;AACA;AACA,oBAAoB,wDAAG;AACvB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC;AACA;AACA,gBAAgB,yDAAI;AACpB;AACA;AACA;AACA,gBAAgB,yDAAI,kBAAkB,yDAAI;AAC1C;AACA;AACA;AACA,gCAAgC,SAAS;AACzC;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,6BAA6B,wDAAG;AAC9C;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,eAAe,iCAAiC;AAChD,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,SAAS;AAC3C,oBAAoB,yDAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,UAAU;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA,sBAAsB;AACtB;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yDAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,OAAO,yDAAyD,oCAAoC;AACzH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,sCAAsC,SAAS;AAC/C,wBAAwB,yDAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,UAAU;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA,sBAAsB;AACtB;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yDAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,UAAU;AAC7B,mBAAmB,QAAQ;AAC3B,mBAAmB,UAAU;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,oBAAoB,QAAQ;AAC5B,oBAAoB,QAAQ;AAC5B,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,gBAAgB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,oBAAoB,wDAAG;AACvB;AACA;AACA;AACA,gBAAgB,wDAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,iEAAe,wDAAG,EAAC;;;;;;;;;;;;;;;;;;;;AC7gCnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACO;AACF;AACC;AACa;AACX;AACS;AACP;AACF;AACpC;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,0CAA0C;AAC1C,kBAAkB;AAClB;AACA;AACA,sDAAsD,gBAAgB;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,4BAA4B;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,SAAS,MAAM,SAAS;AACrC;AACA;AACA,mCAAmC,OAAO;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,gEAAY;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,8DAAK;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,+DAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,6BAA6B;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,+DAAI;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAG;AACH,IAAI,wDAAG;AACP;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA,kDAAkD,SAAS;AAC3D,kDAAkD,SAAS;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,GAAG,aAAa;AACjC;AACA,uGAAuG,cAAc;AACrH;AACA;AACA,4FAA4F,qFAAqF;AACjL,oDAAoD,SAAS;AAC7D,oDAAoD,SAAS;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,GAAG,aAAa;AACnC;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC,qBAAqB,+DAAI;AACzB;AACA;AACA,oBAAoB,+DAAI;AACxB;AACA,kBAAkB,SAAS,+DAAI;AAC/B;AACA;AACA;AACA,2BAA2B,+DAAI;AAC/B,SAAS;AACT;AACA;AACA;AACA,gDAAgD,qCAAqC;AACrF,mBAAmB,OAAO;AAC1B;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA,wBAAwB,2BAA2B;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,0BAA0B,sBAAsB;AACnE,2BAA2B,yBAAyB;AACpD,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,YAAY,+CAA+C;AAC3D;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,8DAAK;AACnC;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,gCAAgC,0BAA0B,KAAK,2BAA2B;AAC1F,mBAAmB,OAAO;AAC1B,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA,oBAAoB,+DAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD,mBAAmB;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,+DAAI;AACxB,gCAAgC,yBAAyB;AACzD;AACA;AACA,4BAA4B,+DAAI;AAChC;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC,wCAAwC,8DAAK;AAC7C;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,gCAAgC,0BAA0B,KAAK,2BAA2B;AAC1F,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,qBAAqB,qBAAqB;AAC1C;AACA;AACA,wBAAwB,2DAAM;AAC9B,2BAA2B,2DAAM;AACjC,qBAAqB,oEAAU;AAC/B;AACA,6BAA6B,8DAAK;AAClC;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,gEAAK;AAChC,2BAA2B,gEAAK;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,WAAW;AAC3C,sEAAsE,gEAAK;AAC3E;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,WAAW;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,+DAAI;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,oBAAoB,qBAAqB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,oBAAoB,qBAAqB;AACzC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B,oBAAoB,qBAAqB;AACzC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B,oBAAoB,qBAAqB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA,oBAAoB,+DAAI;AACxB;AACA,gCAAgC,WAAW;AAC3C;AACA,4BAA4B,+DAAI;AAChC,4BAA4B,+DAAI;AAChC;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,wBAAwB,+DAAI;AAC5B,wBAAwB,+DAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,+DAAI,uBAAuB,+DAAI;AAChE;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,4CAA4C,eAAe,EAAE;AAC7D,oBAAoB,qBAAqB;AACzC;AACA;AACA,gCAAgC,gBAAgB;AAChD;AACA,SAAS;AACT;AACA;AACA;AACA,sBAAsB;AACtB,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,4CAA4C,cAAc,EAAE;AAC5D,oBAAoB,qBAAqB;AACzC;AACA;AACA,gCAAgC,eAAe;AAC/C;AACA,SAAS;AACT;AACA;AACA;AACA,sBAAsB;AACtB,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB,gBAAgB,yCAAyC;AACzD;AACA,oBAAoB,yCAAyC;AAC7D;AACA;AACA,oBAAoB,SAAS;AAC7B,oBAAoB,qBAAqB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,+DAAI;AACxB;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,4BAA4B,+DAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,SAAS;AACzC;AACA,4BAA4B,+DAAI;AAChC;AACA,wCAAwC,WAAW;AACnD;AACA,oCAAoC,+DAAI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA,gCAAgC,+DAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,+DAAI;AACxB,oBAAoB,+DAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA,wBAAwB,gEAAK;AAC7B;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,oBAAoB,+DAAI;AACxB,qBAAqB,+DAAI;AACzB,qBAAqB,+DAAI;AACzB;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,4DAAO;AAC/B,oBAAoB,4DAAO;AAC3B,wBAAwB,+DAAI;AAC5B,oCAAoC,IAAI,4DAAO,wBAAwB;AACvE,iCAAiC,+DAAI,mBAAmB,4DAAO;AAC/D,2CAA2C,4DAAO;AAClD;AACA;AACA;AACA,gCAAgC,oBAAoB;AACpD,4BAA4B,+DAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA,oCAAoC,iBAAiB;AACrD;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA,gBAAgB,+DAAI;AACpB,6CAA6C,sBAAsB;AACnE;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA,yCAAyC,sBAAsB;AAC/D;AACA;AACA;AACA,gCAAgC,WAAW;AAC3C,SAAS;AACT;AACA;AACA,iCAAiC,uCAAuC;AACxE,4BAA4B,uCAAuC;AACnE;AACA;AACA,YAAY,wDAAG;AACf;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA;AACA,yDAAyD;AACzD,kDAAkD,eAAe;AACjE;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,sBAAsB;AAC9C;AACA,oBAAoB,+DAAI;AACxB;AACA;AACA,+BAA+B,+DAAI,kBAAkB,+DAAI;AACzD,kBAAkB,UAAU,+DAAI;AAChC,gEAAgE;AAChE,oBAAoB,wDAAG;AACvB,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA,+DAA+D,eAAe;AAC9E,wBAAwB,+DAAI,oBAAoB,+DAAI;AACpD;AACA,6BAA6B,+DAAI,kDAAkD,+DAAI;AACvF;AACA,+DAA+D,QAAQ;AACvE;AACA;AACA;AACA,wBAAwB,+DAAI;AAC5B;AACA;AACA,+CAA+C,QAAQ,qCAAqC;AAC5F,0CAA0C,8DAAK,sBAAsB,+DAAI;AACzE;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA,0BAA0B,SAAS,+DAAI;AACvC,8DAA8D;AAC9D,yFAAyF,IAAI;AAC7F,gCAAgC,+DAAI;AACpC,4CAA4C,sBAAsB;AAClE;AACA;AACA,8BAA8B;AAC9B;AACA;AACA,0BAA0B;AAC1B,uDAAuD;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,+DAAI;AACpC;AACA;AACA;AACA;AACA;AACA,gCAAgC,+DAAI;AACpC;AACA;AACA;AACA;AACA,gCAAgC,+DAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,8DAAK;AACnD,gCAAgC,+DAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,gEAAK;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,+DAAI;AACpC;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA,oCAAoC,gEAAK;AACzC;AACA;AACA;AACA,oCAAoC,+DAAI;AACxC;AACA;AACA;AACA,gCAAgC,+DAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,8DAAK;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,+DAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,8DAAK;AACnD;AACA;AACA;AACA;AACA;AACA,8CAA8C,8DAAK;AACnD,8CAA8C,8DAAK;AACnD;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,8DAAK;AAC5D;AACA,8CAA8C,8DAAK;AACnD;AACA;AACA;AACA;AACA;AACA,gCAAgC,+DAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,+DAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,gBAAgB;AAC9E;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA,0DAA0D,oBAAoB;AAC9E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,+DAAI;AACpC,kCAAkC,wDAAG;AACrC,qCAAqC,wDAAG,mBAAmB,wDAAG;AAC9D,qCAAqC,wDAAG;AACxC,wCAAwC,+DAAI,sBAAsB,wDAAG;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B,6CAA6C,4DAAO;AACpD,oCAAoC,wDAAG;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,sCAAsC,8DAAK;AAC3C;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,iCAAiC,uCAAuC;AACxE,4BAA4B,uCAAuC;AACnE;AACA;AACA,YAAY,wDAAG;AACf;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,uBAAuB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,4BAA4B,QAAQ;AACpC,wBAAwB,+DAAI;AAC5B;AACA;AACA;AACA;AACA;AACA,gBAAgB,wDAAG;AACnB;AACA,qDAAqD,+DAAI;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,wDAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,+BAA+B;AAClD;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,gBAAgB,wDAAG;AACnB;AACA,qDAAqD,+DAAI;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,iDAAiD;AACjD;AACA,2BAA2B,wCAAwC;AACnE;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA,gCAAgC,YAAY;AAC5C;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,0EAA0E,6BAA6B;AACvG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA,uBAAuB,2DAAM,CAAC,8DAAK;AACnC,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA,uBAAuB,2DAAM,CAAC,8DAAK;AACnC,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA,4BAA4B,8DAAK;AACjC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,wDAAG;AACnB,uBAAuB,+DAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,wDAAG;AACpC;AACA;AACA;AACA;AACA;AACA,oCAAoC,+DAAI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,gBAAgB,wDAAG;AACnB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B,qBAAqB;AACrB;AACA;AACA,oBAAoB,+DAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,qCAAqC,+BAA+B;AACpE;AACA,qBAAqB,OAAO,YAAY,+BAA+B;AACvE;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,8DAAG;AAC9B;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,+DAAI;AAC5B;AACA;AACA;AACA;AACA,oCAAoC,uBAAuB;AAC3D,wBAAwB;AACxB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,8DAAK;AAC5C,kCAAkC,8DAAK;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,4BAA4B;AAC5B;AACA;AACA,YAAY,wDAAG;AACf,gCAAgC,8BAA8B;AAC9D;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,4BAA4B;AAC5B;AACA;AACA,YAAY,wDAAG;AACf,gCAAgC,qBAAqB;AACrD;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,4BAA4B;AAC5B;AACA;AACA,YAAY,wDAAG;AACf,gCAAgC,oBAAoB;AACpD;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,4BAA4B;AAC5B;AACA;AACA,YAAY,wDAAG;AACf,gCAAgC,mBAAmB;AACnD;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,4BAA4B;AAC5B;AACA;AACA,YAAY,wDAAG;AACf,gCAAgC,4BAA4B;AAC5D;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,4BAA4B;AAC5B;AACA;AACA,YAAY,wDAAG;AACf,gCAAgC,oBAAoB;AACpD;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,4BAA4B;AAC5B;AACA;AACA,YAAY,wDAAG;AACf,gCAAgC,SAAS;AACzC;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B;AACA,4BAA4B;AAC5B;AACA;AACA,YAAY,wDAAG;AACf,gCAAgC,YAAY;AAC5C;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B;AACA,4BAA4B;AAC5B;AACA;AACA,YAAY,wDAAG;AACf,gCAAgC,WAAW;AAC3C;AACA,SAAS;AACT;AACA;AACA,+CAA+C,uBAAuB;AACtE,qBAAqB;AACrB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,oEAAoE,uBAAuB;AAC3F,qBAAqB;AACrB;AACA;AACA,mBAAmB,+DAAI;AACvB,SAAS;AACT;AACA;AACA;AACA;AACA,2CAA2C,2BAA2B,KAAK,0BAA0B;AACrG,oEAAoE,4BAA4B;AAChG;AACA,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,2CAA2C,mCAAmC,KAAK,8BAA8B;AACjH;AACA;AACA;AACA,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,6BAA6B,+DAAI;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,qBAAqB,QAAQ;AAC7B;AACA;AACA,oCAAoC,+DAAI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB,gDAAgD,QAAQ;AACxD;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB,gDAAgD,QAAQ;AACxD;AACA;AACA;AACA;AACA,wCAAwC,gCAAgC;AACxE,oCAAoC,+DAAI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B,mBAAmB,SAAS;AAC5B;AACA;AACA,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,wDAAG,QAAQ,8DAAK;AAClD;AACA;AACA;AACA,iDAAiD,8DAAK,oBAAoB,8DAAK;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA,mDAAmD,8DAAK;AACxD;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,8DAAK;AACnC;AACA;AACA;AACA;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,+BAA+B,8DAAK;AAClD;AACA;AACA;AACA,cAAc,+BAA+B,8DAAK;AAClD;AACA;AACA;AACA;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,+BAA+B,8DAAK;AAClD;AACA;AACA;AACA;AACA,cAAc,+BAA+B,8DAAK;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,qBAAqB,0BAA0B;AAC/C;AACA;AACA;AACA;AACA;AACA,kBAAkB,wDAAG,UAAU,wDAAG;AAClC;AACA;AACA,qBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA;AACA,qBAAqB,wDAAG,UAAU,wDAAG;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,eAAe;AACpC;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,+DAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,gDAAgD;AAChD;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,mCAAmC;AACnC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,uDAAuD;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAe,wDAAG,gBAAgB,EAAC;AACnC;AACA,YAAY;;;;;;;;;;;;;;;AC1vFZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACF;AACN;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAG;AACH;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,gBAAgB,OAAO;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yDAAG;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA,wBAAwB,+DAAI;AAC5B,wBAAwB,+DAAI;AAC5B,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,OAAO;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO,2FAA2F;AACjH,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yDAAG;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,WAAW;AAC/B;AACA;AACA;AACA;AACA,gCAAgC,OAAO;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC,gCAAgC,OAAO;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yDAAG,OAAO,yDAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,OAAO;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,OAAO;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB,gBAAgB,OAAO;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE,aAAa;AACrF;AACA;AACA;AACA,0CAA0C,gDAAgD;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,+DAAI;AAC9B,gCAAgC,0CAA0C;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAyB;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,6BAA6B;AACzD;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAyB;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,6BAA6B;AACzD;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAyB;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAyB;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oEAAoE,aAAa;AACjF;AACA;AACA;AACA,0CAA0C,gCAAgC;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,+DAAI;AAC9B,4BAA4B,+DAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0EAA0E,aAAa;AACvF;AACA;AACA;AACA,0CAA0C,MAAM;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,+DAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA,UAAU;AACV;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,gCAAgC,sCAAsC;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,gCAAgC,uCAAuC;AACvE,QAAQ,uCAAuC;AAC/C,QAAQ,uCAAuC;AAC/C;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,WAAW;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,sCAAsC,4BAA4B;AAClE,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,4CAA4C;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,gCAAgC,uCAAuC;AACvE,QAAQ,uCAAuC;AAC/C,QAAQ,uCAAuC;AAC/C;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAAgE,aAAa;AAC7E;AACA;AACA;AACA,0CAA0C,oCAAoC;AAC9E;AACA;AACA;AACA;AACA;AACA,8BAA8B,+DAAI;AAClC,+BAA+B,+DAAI;AACnC,+BAA+B,+DAAI;AACnC,0BAA0B,+DAAI;AAC9B,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,wDAAG;AACf;AACA,0CAA0C,yDAAG;AAC7C,YAAY,wDAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,wDAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,wDAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,+CAA+C;AAChG,6CAA6C,mCAAmC;AAChF;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,gBAAgB,yDAAG;AACnB;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,wBAAwB,qCAAqC;AAC7D,eAAe,UAAU;AACzB,eAAe,cAAc;AAC7B;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,WAAW;AAC1B,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,YAAY;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,yDAAG;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,WAAW;AAC1B,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yDAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,UAAU;AACzB,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB;AACA,eAAe,QAAQ;AACvB;AACA,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,iBAAiB,yDAAG;AACpB;AACA;AACA,qBAAqB,yDAAG;AACxB;AACA,sBAAsB,yDAAG;AACzB,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA,qBAAqB,yDAAG;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,qBAAqB;AACnE,gDAAgD,iBAAiB;AACjE,6CAA6C,iBAAiB;AAC9D,6CAA6C,qBAAqB;AAClE;AACA;AACA;AACA,8CAA8C,iCAAiC;AAC/E;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,oFAAoF;AACxG;AACA;AACA,kDAAkD,qBAAqB;AACvE,oDAAoD,iBAAiB;AACrE,iDAAiD,iBAAiB;AAClE,iDAAiD,qBAAqB;AACtE;AACA;AACA;AACA,kDAAkD,iCAAiC;AACnF;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,yDAAG;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,SAAS;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA;AACA,SAAS;AACT,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA,oBAAoB,WAAW;AAC/B;AACA;AACA,oBAAoB,WAAW;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,WAAW;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,cAAc;AAC7B,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO,8CAA8C;AACpE;AACA,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,QAAQ;AAC9B,YAAY,+DAAI;AAChB;AACA;AACA,gBAAgB,+DAAI;AACpB,cAAc;AACd,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,UAAU;AAC3B;AACA;AACA;AACA;AACA,6CAA6C,OAAO;AACpD,4CAA4C,OAAO;AACnD,4CAA4C,OAAO;AACnD,6CAA6C,OAAO;AACpD;AACA,+DAA+D,cAAc;AAC7E;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,oFAAoF;AACxG;AACA,iDAAiD,OAAO;AACxD,gDAAgD,OAAO;AACvD,gDAAgD,OAAO;AACvD,iDAAiD,OAAO;AACxD;AACA,mEAAmE,cAAc;AACjF;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,kDAAkD,OAAO;AACzD,kDAAkD,OAAO;AACzD,kDAAkD,OAAO;AACzD;AACA;AACA,+DAA+D,cAAc;AAC7E,kFAAkF,aAAa;AAC/F,8EAA8E,aAAa;AAC3F;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,oFAAoF;AACxG;AACA,sDAAsD,OAAO;AAC7D,sDAAsD,OAAO;AAC7D,sDAAsD,OAAO;AAC7D;AACA;AACA,mEAAmE,cAAc;AACjF,sFAAsF,aAAa;AACnG,kFAAkF,aAAa;AAC/F;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,SAAS;AACzC;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,SAAS;AAC5C;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,+CAA+C;AACjE;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,sDAAsD,OAAO;AAC7D,sDAAsD,OAAO;AAC7D,sDAAsD,OAAO;AAC7D;AACA;AACA,mEAAmE,cAAc;AACjF,sFAAsF,aAAa;AACnG;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA,0DAA0D,OAAO;AACjE,0DAA0D,OAAO;AACjE,0DAA0D,OAAO;AACjE;AACA;AACA,uEAAuE,cAAc;AACrF,0FAA0F,aAAa;AACvG;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,uDAAuD;AACzE;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA,sDAAsD,OAAO;AAC7D,sDAAsD,OAAO;AAC7D,sDAAsD,OAAO;AAC7D;AACA;AACA,mEAAmE,cAAc;AACjF,gFAAgF,aAAa;AAC7F;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA,0DAA0D,OAAO;AACjE,0DAA0D,OAAO;AACjE,0DAA0D,OAAO;AACjE;AACA;AACA,uEAAuE,cAAc;AACrF,oFAAoF,aAAa;AACjG;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,UAAU;AAC3B;AACA;AACA;AACA;AACA;AACA,kDAAkD,OAAO;AACzD,kDAAkD,OAAO;AACzD,kDAAkD,OAAO;AACzD;AACA;AACA,+DAA+D,cAAc;AAC7E;AACA;AACA,wDAAwD,aAAa;AACrE;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,oFAAoF;AACxG;AACA,sDAAsD,OAAO;AAC7D,sDAAsD,OAAO;AAC7D,sDAAsD,OAAO;AAC7D;AACA;AACA,mEAAmE,cAAc;AACjF;AACA;AACA,4DAA4D,aAAa;AACzE;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA,wBAAwB,mBAAmB;AAC3C;AACA,kCAAkC,yDAAG;AACrC;AACA;AACA,oBAAoB,wDAAG;AACvB,wBAAwB,8DAAG;AAC3B;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,sBAAsB,gDAAgD;AACtE;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,UAAU;AAC3B;AACA;AACA;AACA;AACA;AACA,kDAAkD,OAAO;AACzD,kDAAkD,OAAO;AACzD,kDAAkD,OAAO;AACzD;AACA;AACA,+DAA+D,cAAc;AAC7E;AACA;AACA,uDAAuD,aAAa;AACpE;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,oFAAoF;AACxG;AACA,sDAAsD,OAAO;AAC7D,sDAAsD,OAAO;AAC7D,sDAAsD,OAAO;AAC7D;AACA;AACA,mEAAmE,cAAc;AACjF;AACA;AACA,2DAA2D,aAAa;AACxE;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B,wBAAwB,SAAS;AACjC;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA,oCAAoC,yDAAG;AACvC,4BAA4B,mBAAmB;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,gBAAgB,UAAU;AAC1B;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,iBAAiB;AAChC;AACA,eAAe,QAAQ;AACvB;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA,mCAAmC,yDAAG;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA,mCAAmC,yDAAG;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,aAAa;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,yDAAG;AACzC;AACA;AACA,sCAAsC,yDAAG;AACzC;AACA;AACA,sCAAsC,yDAAG;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,wBAAwB;AACvC;AACA,eAAe,OAAO;AACtB,oBAAoB,gBAAgB,MAAM,iBAAiB;AAC3D;AACA,eAAe,OAAO;AACtB,iBAAiB,UAAU;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI,oBAAoB,+DAAI;AACxC;AACA;AACA;AACA;AACA;AACA,UAAU,SAAS,+DAAI;AACvB;AACA;AACA,UAAU,SAAS,+DAAI;AACvB;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,+DAAI,mBAAmB,+DAAI;AACjE;AACA;AACA,UAAU;AACV;AACA,YAAY,+DAAI;AAChB;AACA,YAAY,+DAAI;AAChB;AACA;AACA,UAAU;AACV;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,SAAS;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,SAAS;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,SAAS;AACzC,4BAA4B,+DAAI;AAChC;AACA,0BAA0B;AAC1B;AACA;AACA;AACA,4BAA4B,+DAAI;AAChC;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA,4BAA4B,QAAQ;AACpC,gCAAgC,SAAS;AACzC;AACA;AACA;AACA;AACA;AACA,qBAAqB,yDAAG;AACxB,oBAAoB,yDAAG;AACvB,oBAAoB,yDAAG;AACvB,yBAAyB,yDAAG;AAC5B,uBAAuB,yDAAG;AAC1B;AACA;AACA;AACA;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO,kCAAkC,iBAAiB;AACzE;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,eAAe;AAC3C;AACA;AACA,sBAAsB;AACtB;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,4BAA4B,QAAQ;AACpC,wCAAwC,QAAQ;AAChD;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,YAAY;AACZ,YAAY,yBAAyB;AACrC,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB;AACA,iBAAiB,UAAU;AAC3B;AACA;AACA;AACA,aAAa,+DAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,uCAAuC,gCAAgC;AACvE;AACA,eAAe,QAAQ;AACvB,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA;AACA;AACA,UAAU;AACV;AACA,UAAU;AACV;AACA,UAAU;AACV;AACA;AACA,kCAAkC,iBAAiB;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,kCAAkC,iBAAiB;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,UAAU;AACV;AACA,UAAU;AACV,sBAAsB;AACtB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB,+CAA+C,gBAAgB;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,WAAW;AACvC;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,WAAW;AACvC;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,uCAAuC,iBAAiB;AACxD;AACA;AACA,eAAe,gBAAgB;AAC/B;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA,QAAQ,wDAAG;AACX;AACA,KAAK;AACL;AACA;AACA;AACA,YAAY,yDAAyD;AACrE,eAAe,eAAe;AAC9B;AACA;AACA;AACA,kBAAkB,UAAU;AAC5B,kBAAkB,UAAU;AAC5B,kBAAkB,SAAS;AAC3B,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,UAAU;AACzB;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA,gBAAgB,KAAK,aAAa;AAClC;AACA;AACA;AACA,sDAAsD,kBAAkB;AACxE,mGAAmG,cAAc;AACjH;AACA,sFAAsF,qFAAqF;AAC3K;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,eAAe;AACnC;AACA;AACA;AACA,sDAAsD,qCAAqC;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC,gCAAgC,SAAS;AACzC;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,wCAAwC,+BAA+B;AACvE,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,UAAU;AACzB,eAAe,cAAc;AAC7B;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4EAA4E;AAC5E;AACA;AACA,kBAAkB,yDAAG;AACrB;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D;AAC5D;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,UAAU;AACzB,eAAe,cAAc;AAC7B;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yDAAG;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,mDAAmD,+BAA+B;AAClF,QAAQ,8BAA8B,QAAQ;AAC9C;AACA;AACA,eAAe,UAAU;AACzB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,+DAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,UAAU;AACzB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yDAAG;AACrB,sBAAsB,yDAAG;AACzB;AACA;AACA;AACA;AACA,aAAa,+DAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,4CAA4C;AACxE,kBAAkB;AAClB,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,UAAU;AACzB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yDAAG;AACnB,gBAAgB,yDAAG,OAAO,yDAAG;AAC7B,qBAAqB,yDAAG,OAAO,yDAAG,OAAO,yDAAG;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D,mBAAmB,KAAK,aAAa;AAC/F;AACA;AACA,eAAe,OAAO;AACtB;AACA,eAAe,QAAQ;AACvB;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,kBAAkB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,kBAAkB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B,uBAAuB,aAAa;AACpC,uBAAuB,SAAS;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,wDAAG;AAC3B,oCAAoC,OAAO;AAC3C;AACA;AACA,8BAA8B,wDAAG;AACjC;AACA,kBAAkB;AAClB;AACA,wBAAwB,wDAAG;AAC3B,oCAAoC,QAAQ;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B,uBAAuB,aAAa;AACpC,uBAAuB,SAAS;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,wDAAG;AAC3B,oCAAoC,OAAO;AAC3C,8CAA8C;AAC9C;AACA,8BAA8B,wDAAG;AACjC;AACA,kBAAkB;AAClB;AACA,wBAAwB,wDAAG;AAC3B,oCAAoC,QAAQ;AAC5C,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B,uBAAuB,QAAQ;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,QAAQ;AACxC;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B,yBAAyB,OAAO;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,KAAK;AAClC,oBAAoB,wDAAG;AACvB,sBAAsB,wDAAG;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,wDAAG;AACvB,6BAA6B,wDAAG;AAChC,+BAA+B;AAC/B;AACA,4BAA4B,OAAO;AACnC,4BAA4B,wDAAG;AAC/B,8BAA8B,wDAAG;AACjC;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B,uBAAuB,QAAQ;AAC/B,uBAAuB,QAAQ;AAC/B,uBAAuB,OAAO;AAC9B,yBAAyB,QAAQ;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA,4BAA4B,eAAe;AAC3C,4BAA4B,wDAAG;AAC/B;AACA,4BAA4B,4BAA4B;AACxD,gCAAgC,OAAO;AACvC;AACA;AACA;AACA;AACA,4BAA4B,wDAAG;AAC/B;AACA;AACA;AACA;AACA;AACA,4BAA4B,wDAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,wDAAG;AACvC;AACA;AACA;AACA,kCAAkC,wDAAG;AACrC,kCAAkC,wDAAG;AACrC,0BAA0B;AAC1B;AACA;AACA;AACA,wCAAwC,SAAS;AACjD,oCAAoC,wDAAG;AACvC,oCAAoC,OAAO;AAC3C;AACA;AACA;AACA,gCAAgC,wDAAG;AACnC,gCAAgC,wDAAG;AACnC;AACA;AACA;AACA,sDAAsD,SAAS;AAC/D;AACA,gCAAgC,wDAAG;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,wDAAG;AACf;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,wBAAwB,wDAAG;AAC3B;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B,6BAA6B,wDAAG;AAChC;AACA;AACA;AACA;AACA;AACA,yBAAyB,QAAQ;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,YAAY;AACpC,+BAA+B,wDAAG;AAClC;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,kBAAkB;AAC1C,oDAAoD,wDAAG;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO,cAAc;AACpC,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,4CAA4C;AAC3F;AACA;AACA,uBAAuB,OAAO,cAAc;AAC5C,uBAAuB,QAAQ;AAC/B,uBAAuB,QAAQ;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,yDAAG,OAAO,yDAAG;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,OAAO;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,iDAAiD,4CAA4C;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO,cAAc;AAC5C,uBAAuB,QAAQ;AAC/B,uBAAuB,QAAQ;AAC/B,uBAAuB,QAAQ;AAC/B,uBAAuB,OAAO,iBAAiB;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA,QAAQ,wDAAG;AACX;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO,cAAc;AACpC,eAAe,QAAQ;AACvB;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B;AACA;AACA;AACA;AACA;AACA,uDAAuD,qBAAqB;AAC5E;AACA,qDAAqD,qCAAqC;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,SAAS;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,oFAAoF;AACxG;AACA;AACA,2BAA2B,OAAO;AAClC;AACA;AACA;AACA;AACA;AACA,2DAA2D,qBAAqB;AAChF;AACA,yDAAyD,qCAAqC;AAC9F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,SAAS;AACxC;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,aAAa;AACjC;AACA,gBAAgB,wDAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,wDAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,wDAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,iEAAe,yDAAG,SAAS,EAAC;;;;;;;;;;;;;;AC96J5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACP;AAClC;AACA,wDAAG;AACH,IAAI,wDAAG;AACP;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B,mBAAmB,SAAS;AAC5B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA,0CAA0C,mEAAK;AAC/C;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA,kCAAkC,mEAAK;AACvC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,mEAAK;AAC3C;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC,mCAAmC;AACnC;AACA;AACA,oBAAoB,cAAc;AAClC;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,qBAAqB,UAAU;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,wBAAwB;AAC3C,mBAAmB,WAAW;AAC9B;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,mBAAmB,SAAS;AAC5B;AACA,qBAAqB,UAAU;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2EAA2E;AAC3E;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA,kCAAkC;AAClC;AACA,qBAAqB;AACrB;AACA;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,OAAO;AAC1B;AACA,sBAAsB,iBAAiB;AACvC,sBAAsB,gCAAgC,IAAI,iBAAiB;AAC3E,sBAAsB,8BAA8B,IAAI,iBAAiB;AACzE;AACA;AACA,kCAAkC,WAAW,cAAc,WAAW;AACtE,uEAAuE;AACvE;AACA;AACA,mBAAmB,QAAQ,6DAA6D;AACxF,mBAAmB,OAAO;AAC1B,qBAAqB,OAAO,uBAAuB,iBAAiB;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B,mBAAmB,OAAO;AAC1B;AACA,sBAAsB,mBAAmB;AACzC,sBAAsB,gCAAgC,IAAI,mBAAmB;AAC7E,sBAAsB,8BAA8B,IAAI,mBAAmB;AAC3E;AACA;AACA,kCAAkC,WAAW,cAAc,WAAW,cAAc,WAAW;AAC/F,uEAAuE;AACvE;AACA;AACA,mBAAmB,QAAQ,gEAAgE;AAC3F,mBAAmB,OAAO;AAC1B,qBAAqB,OAAO,uBAAuB,mBAAmB;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,uBAAuB;AACvD;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,UAAU;AAC7B,mBAAmB,QAAQ;AAC3B,qBAAqB,UAAU;AAC/B;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,kBAAkB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,gBAAgB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,gBAAgB;AAChD,mCAAmC,wDAAG;AACtC;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,gBAAgB;AACxC;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,eAAe;AACpE,iBAAiB;AACjB;AACA;AACA;AACA,qCAAqC,eAAe;AACpD;AACA,6BAA6B,OAAO;AACpC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,qBAAqB;AACrB;AACA;AACA,mBAAmB,wDAAG;AACtB,SAAS;AACT;AACA;AACA,iCAAiC,kBAAkB;AACnD,mBAAmB,OAAO;AAC1B,mBAAmB,SAAS;AAC5B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,mBAAmB;AAC3C;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,eAAe;AACvC;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA,wBAAwB,eAAe;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA,gBAAgB,wDAAG;AACnB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,sBAAsB,WAAW;AACjC,sBAAsB,WAAW;AACjC,sBAAsB,WAAW;AACjC,wBAAwB,mBAAmB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,oBAAoB,QAAQ;AAC5B,oBAAoB,cAAc;AAClC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,oBAAoB,QAAQ;AAC5B,oBAAoB,cAAc;AAClC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,oBAAoB,QAAQ;AAC5B,oBAAoB,cAAc;AAClC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,oBAAoB,QAAQ;AAC5B,oBAAoB,eAAe;AACnC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,cAAc;AACd;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,eAAe;AAClC,mBAAmB,QAAQ;AAC3B,mBAAmB,mBAAmB;AACtC,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,iBAAiB,0BAA0B;AAC3C,mBAAmB,QAAQ;AAC3B,qBAAqB,MAAM,MAAM,WAAW;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,cAAc;AAC1C;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,iEAAiE,cAAc;AAC/E;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,oEAAoE,oBAAoB;AACxF;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,cAAc;AAClD;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,+CAA+C,YAAY,SAAS;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,SAAS;AAC5B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,gBAAgB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B,yDAAyD;AACzD;AACA,sBAAsB;AACtB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B,8DAA8D;AAC9D;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D;AAC9D,8BAA8B;AAC9B;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,2EAA2E,SAAS,kBAAkB;AACtG;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,SAAS;AAC5B,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD;AACnD;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA,2CAA2C,cAAc,gBAAgB;AACzE;AACA,sBAAsB,cAAc;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,wDAAG;AACvB,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,oBAAoB,wDAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,0BAA0B,wDAAG;AAC7B;AACA,sBAAsB,wDAAG;AACzB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,oBAAoB,uCAAuC;AAC3D;AACA,mBAAmB,qBAAqB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,SAAS;AAC5B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA,sBAAsB,wDAAG;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,gBAAgB;AACxD,0CAA0C,wDAAG;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,wDAAG;AAC7C,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA,iCAAiC,wBAAwB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,4CAA4C,QAAQ,IAAI,OAAO,QAAQ,GAAG,WAAW,QAAQ,GAAG;AAChG,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA,2CAA2C,sBAAsB,sBAAsB;AACvF,SAAS;AACT;AACA;AACA,sDAAsD,SAAS;AAC/D,gBAAgB,KAAK,QAAQ,OAAO,IAAI,OAAO,WAAW,IAAI,OAAO;AACrE,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B,8BAA8B;AAC9B,8BAA8B;AAC9B,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,iBAAiB;AACpC,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,wBAAwB,GAAG,EAAE;AAC7B;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,SAAS;AAC5B,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA,sBAAsB,8DAAG;AACzB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,gBAAgB,eAAe;AACtE,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,SAAS;AAC5B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,sBAAsB;AACnE;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,GAAG;AACtB,qBAAqB,GAAG;AACxB;AACA;AACA,gCAAgC,mEAAK;AACrC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAe,wDAAG,EAAC;;;;;;;;;;;;;;;;AC56DnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC2B;AACa;AACP;AACI;AACF;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,kCAAkC,GAAG,gCAAgC;AACjF,YAAY,8BAA8B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE,sCAAsC;AACxG;AACA;AACA,gBAAgB,8EAA8E;AAC9F,uBAAuB,uCAAuC;AAC9D;AACA;AACA,uBAAuB,uCAAuC;AAC9D;AACA;AACA,+BAA+B,uCAAuC;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,2BAA2B;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,6BAA6B;AACtD;AACA;AACA;AACA,yBAAyB,IAAI,SAAS,MAAM,WAAW;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,cAAc;AACvC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB,uEAAuE,oBAAoB;AAC3F;AACA,wGAAwG,cAAc;AACtH;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB,2EAA2E,oBAAoB;AAC/F,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,gBAAgB;AAC5B;AACA;AACA;AACA;AACA;AACA,yBAAyB,eAAe;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uDAAuD;AACvD;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,2DAA2D;AAC3D;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,6DAA6D;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,eAAe;AACxC;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,cAAc;AAChD;AACA;AACA,qBAAqB;AACrB,oDAAoD,WAAW;AAC/D,mDAAmD,WAAW;AAC9D;AACA;AACA;AACA,+BAA+B,0BAA0B;AACzD;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,kDAAkD,cAAc;AACxF,oEAAoE;AACpE,wDAAwD,WAAW;AACnE,uDAAuD,WAAW;AAClE;AACA;AACA;AACA,mCAAmC,0BAA0B;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,cAAc;AACvC;AACA,gBAAgB;AAChB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,cAAc;AAC3C;AACA,oBAAoB;AACpB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,iBAAiB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,oBAAoB;AACpB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,uCAAuC;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,uCAAuC;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,oCAAoC;AAChD,YAAY,uCAAuC;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,8CAA8C;AAC7D,eAAe,uCAAuC;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,0CAA0C;AACzD,eAAe,uCAAuC;AACtD;AACA;AACA,kDAAkD,uBAAuB;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,4BAA4B;AACrD;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B,gBAAgB;AAChB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC,oBAAoB;AACpB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,aAAa,wBAAwB,oBAAoB;AACrG,2CAA2C,2BAA2B,oBAAoB,oBAAoB,YAAY,UAAU,2CAA2C;AAC/K,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,+BAA+B;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,wBAAwB,SAAS,oBAAoB,KAAK;AAC1D;AACA,sCAAsC,KAAK,mBAAmB,KAAK;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS,oBAAoB,KAAK;AAC1D;AACA,sCAAsC,KAAK,mBAAmB,KAAK;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D,SAAS;AACnE;AACA;AACA;AACA;AACA,gEAAgE,UAAU,iBAAiB;AAC3F;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB;AACxB,4CAA4C;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D,SAAS;AACrE;AACA;AACA;AACA;AACA,kEAAkE,UAAU,iBAAiB;AAC7F;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,+BAA+B;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uEAAuE,sBAAsB;AAC7F,qEAAqE,sBAAsB;AAC3F;AACA;AACA,qDAAqD,uBAAuB,KAAK,sBAAsB;AACvG,qDAAqD,uBAAuB,KAAK,sBAAsB;AACvG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,oDAAoD,uBAAuB,KAAK,sBAAsB;AACtG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,mCAAmC;AAC9E;AACA,6CAA6C,qCAAqC;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,uCAAuC;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,wCAAwC;AAC9F,uDAAuD,oCAAoC;AAC3F;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G,0DAA0D,wCAAwC;AAClG,2DAA2D,oCAAoC;AAC/F;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,gEAAK;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D,2BAA2B;AACvF;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G,gEAAgE,2BAA2B;AAC3F;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8FAA8F,cAAc;AAC5G,oFAAoF,gBAAgB;AACpG,oFAAoF,gBAAgB;AACpG;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,mBAAmB;AAC1E,6DAA6D,mBAAmB;AAChF,2DAA2D,mBAAmB;AAC9E;AACA,oBAAoB;AACpB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,2FAA2F;AACnH,kGAAkG,cAAc;AAChH,wFAAwF,gBAAgB;AACxG,wFAAwF,gBAAgB;AACxG;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,mBAAmB;AAC9E,iEAAiE,mBAAmB;AACpF,+DAA+D,mBAAmB;AAClF;AACA,wBAAwB;AACxB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA,qFAAqF,eAAe;AACpG,qFAAqF,eAAe;AACpG,qFAAqF,gBAAgB;AACrG,mFAAmF,gBAAgB;AACnG,kFAAkF,UAAU;AAC5F,qFAAqF,WAAW;AAChG;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,oBAAoB;AACxE,oDAAoD,oBAAoB;AACxE,mDAAmD,mBAAmB;AACtE,oDAAoD,oBAAoB;AACxE,oDAAoD,oBAAoB;AACxE,oDAAoD,oBAAoB;AACxE,6DAA6D,oBAAoB;AACjF,2DAA2D,oBAAoB;AAC/E;AACA,gBAAgB;AAChB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,2FAA2F;AACnH,yFAAyF,eAAe;AACxG,yFAAyF,eAAe;AACxG,yFAAyF,gBAAgB;AACzG,uFAAuF,gBAAgB;AACvG,sFAAsF,UAAU;AAChG,yFAAyF,WAAW;AACpG;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,oBAAoB;AAC5E,wDAAwD,oBAAoB;AAC5E,uDAAuD,mBAAmB;AAC1E,wDAAwD,oBAAoB;AAC5E,wDAAwD,oBAAoB;AAC5E,wDAAwD,oBAAoB;AAC5E,iEAAiE,oBAAoB;AACrF,+DAA+D,oBAAoB;AACnF;AACA,oBAAoB;AACpB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,SAAS;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gFAAgF,UAAU;AAC1F;AACA;AACA,YAAY;AACZ,0CAA0C;AAC1C;AACA,wBAAwB,cAAc;AACtC,wBAAwB,cAAc;AACtC;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G,oFAAoF,UAAU;AAC9F;AACA;AACA,gBAAgB;AAChB,8CAA8C;AAC9C;AACA,4BAA4B,cAAc;AAC1C,4BAA4B,cAAc;AAC1C;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,kCAAkC;AAChG;AACA;AACA,8DAA8D,iCAAiC;AAC/F;AACA;AACA,8DAA8D,8BAA8B,gBAAgB;AAC5G;AACA;AACA,+DAA+D;AAC/D,gCAAgC;AAChC,oBAAoB;AACpB;AACA;AACA,gEAAgE;AAChE,gCAAgC;AAChC,oBAAoB;AACpB;AACA;AACA,gEAAgE;AAChE,gCAAgC;AAChC,oBAAoB;AACpB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA,kEAAkE,kCAAkC;AACpG;AACA;AACA,kEAAkE,iCAAiC;AACnG;AACA;AACA,kEAAkE,8BAA8B,gBAAgB;AAChH;AACA;AACA,mEAAmE;AACnE,oCAAoC;AACpC,wBAAwB;AACxB;AACA;AACA,oEAAoE;AACpE,oCAAoC;AACpC,wBAAwB;AACxB;AACA;AACA,oEAAoE;AACpE,oCAAoC;AACpC,wBAAwB;AACxB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,gEAAK;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,sCAAsC;AACzE;AACA,gDAAgD,YAAY;AAC5D;AACA,iCAAiC,cAAc;AAC/C;AACA;AACA,oEAAoE,0CAA0C;AAC9G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,2GAA2G;AACnI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oFAAoF;AACpF;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA;AACA,wFAAwF;AACxF;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,iBAAiB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,iBAAiB;AACzD;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB,mBAAmB;AACnB;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA,eAAe;AACf,WAAW;AACX;AACA,sGAAsG,cAAc;AACpH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB,uBAAuB;AACvB;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,mBAAmB;AACnB,eAAe;AACf;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uEAAuE,OAAO;AAC9E,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,aAAa;AACb,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,yGAAyG;AACzG;AACA;AACA;AACA,kDAAkD,4CAA4C,gBAAgB,mBAAmB;AACjI,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA;AACA,sGAAsG,cAAc;AACpH;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,kBAAkB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,4BAA4B;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,4BAA4B;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAyB,0BAA0B,yBAAyB;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,iBAAiB;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,2CAA2C;AAC7F;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA,sDAAsD,2CAA2C;AACjG;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G,+DAA+D,oCAAoC,gCAAgC;AACnI,+DAA+D,SAAS,eAAe;AACvF;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uDAAuD;AACvD;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,2DAA2D;AAC3D;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,gEAAK;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,gEAAK;AACxB,4BAA4B,gEAAK;AACjC,qBAAqB,gEAAK;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,yBAAyB,mBAAmB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,yBAAyB,gEAAK;AAC9B,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,cAAc;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,gEAAK;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,sFAAsF;AAC9G;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA,gEAAgE,oBAAoB;AACpF,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD,eAAe;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,gEAAK;AAC1B,mBAAmB,gEAAK;AACxB;AACA;AACA,8BAA8B,gEAAK;AACnC,4BAA4B,gEAAK;AACjC;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,iBAAiB;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,oBAAoB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,gEAAK;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gEAAK;AAC5B,yBAAyB,gEAAK;AAC9B;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gEAAK;AAC5B,yBAAyB,gEAAK;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,gEAAK;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA;AACA,uBAAuB,gEAAK;AAC5B,yBAAyB,gEAAK;AAC9B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,gEAAK;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,gEAAK;AACxB,4BAA4B,gEAAK;AACjC;AACA;AACA,qBAAqB,gEAAK;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,gEAAK;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,gEAAK;AAC1B;AACA;AACA;AACA;AACA,oCAAoC,8BAA8B,aAAa,4BAA4B;AAC3G;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE,wCAAwC;AAChH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,4BAA4B;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,4BAA4B;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,4BAA4B;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,sBAAsB;AAClD;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,sBAAsB;AAClD;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG,kBAAkB,IAAI,iBAAiB;AAC9I,4BAA4B,UAAU;AACtC;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,iBAAiB;AAC/D;AACA;AACA;AACA,uCAAuC;AACvC;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,IAAI,aAAa,IAAI;AACrD,iCAAiC,IAAI,IAAI,IAAI,aAAa,KAAK;AAC/D;AACA;AACA,qCAAqC,cAAc;AACnD,sCAAsC,aAAa;AACnD;AACA;AACA;AACA,uGAAuG,kBAAkB,IAAI,iBAAiB;AAC9I,4BAA4B,UAAU;AACtC;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG,kBAAkB,IAAI,iBAAiB;AAC9I,4BAA4B,YAAY;AACxC;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,iDAAiD;AACrE;AACA;AACA,uGAAuG,kBAAkB,IAAI,iBAAiB;AAC9I,4BAA4B,cAAc;AAC1C;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG,kBAAkB,IAAI,iBAAiB;AAC9I,4BAA4B,qBAAqB;AACjD;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,oBAAoB;AACpB,oBAAoB;AACpB,oBAAoB;AACpB,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,oBAAoB;AACpB,oBAAoB;AACpB,oBAAoB;AACpB,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ,kBAAkB;AAClD,wBAAwB,QAAQ;AAChC,gBAAgB;AAChB,uBAAuB,UAAU;AACjC,YAAY;AACZ,wGAAwG,cAAc;AACtH;AACA;AACA;AACA,wBAAwB;AACxB;AACA,oCAAoC,QAAQ,kBAAkB;AAC9D,oCAAoC,QAAQ;AAC5C,4BAA4B;AAC5B,kCAAkC,UAAU;AAC5C,wBAAwB;AACxB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,UAAU;AACjC,YAAY;AACZ,wGAAwG,cAAc;AACtH;AACA;AACA;AACA,wBAAwB;AACxB,mCAAmC,UAAU;AAC7C,wBAAwB;AACxB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,UAAU;AACjC,YAAY;AACZ,wGAAwG,cAAc;AACtH;AACA;AACA;AACA,wBAAwB;AACxB,mCAAmC;AACnC,oBAAoB;AACpB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,UAAU;AACjC,YAAY;AACZ,wGAAwG,cAAc;AACtH;AACA;AACA;AACA,wBAAwB;AACxB,mCAAmC,UAAU;AAC7C,wBAAwB;AACxB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,UAAU;AACjC,YAAY;AACZ,wGAAwG,cAAc;AACtH;AACA;AACA;AACA,wBAAwB;AACxB,mCAAmC,UAAU;AAC7C,oBAAoB;AACpB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,UAAU;AACjC,YAAY;AACZ,wGAAwG,cAAc;AACtH;AACA;AACA;AACA,wBAAwB;AACxB,mCAAmC,UAAU;AAC7C,oBAAoB;AACpB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,gBAAgB;AAChB;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA,aAAa;AACb;AACA,gBAAgB;AAChB;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA,aAAa;AACb;AACA,gBAAgB;AAChB;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA,aAAa;AACb;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA,aAAa;AACb;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,uBAAuB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,uBAAuB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,gBAAgB,8DAAG;AACnB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,gEAAK;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA;AACA,uBAAuB,gEAAK;AAC5B,yBAAyB,gEAAK;AAC9B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,gEAAK;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,gEAAK;AACxB;AACA,4BAA4B,gEAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,mBAAmB,gEAAK;AACxB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA,mBAAmB,gEAAK;AACxB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,uBAAuB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,oBAAoB,GAAG;AAC1E,gBAAgB,mBAAmB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yEAAyE,qBAAqB;AAC9F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,2CAA2C;AACpE,yBAAyB,2CAA2C;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA;AACA;AACA,6BAA6B,2CAA2C;AACxE,6BAA6B,2CAA2C;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,QAAQ;AAC7D;AACA,2CAA2C;AAC3C,aAAa;AACb;AACA,2CAA2C;AAC3C,aAAa;AACb;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G,yDAAyD,QAAQ;AACjE,4DAA4D,2BAA2B,qCAAqC;AAC5H,2DAA2D,2BAA2B,qCAAqC;AAC3H;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,kBAAkB;AACrF;AACA;AACA;AACA,gDAAgD;AAChD,4CAA4C,yCAAyC;AACrF;AACA;AACA;AACA,yDAAyD,aAAa,QAAQ,WAAW,gBAAgB;AACzG,yDAAyD,aAAa,QAAQ,WAAW,gBAAgB;AACzG,yDAAyD,aAAa,QAAQ,WAAW,gBAAgB;AACzG,yDAAyD,aAAa,QAAQ,WAAW,gBAAgB;AACzG,yDAAyD,aAAa,QAAQ,WAAW,gBAAgB;AACzG,2DAA2D,aAAa,QAAQ,WAAW,gBAAgB;AAC3G,2DAA2D,aAAa,QAAQ,WAAW,gBAAgB;AAC3G;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA,oDAAoD;AACpD,gDAAgD,yCAAyC;AACzF;AACA;AACA;AACA,6DAA6D,aAAa,QAAQ,WAAW,gBAAgB;AAC7G,6DAA6D,aAAa,QAAQ,WAAW,gBAAgB;AAC7G,6DAA6D,aAAa,QAAQ,WAAW,gBAAgB;AAC7G,6DAA6D,aAAa,QAAQ,WAAW,gBAAgB;AAC7G,6DAA6D,aAAa,QAAQ,WAAW,gBAAgB;AAC7G,+DAA+D,aAAa,QAAQ,WAAW,gBAAgB;AAC/G,+DAA+D,aAAa,QAAQ,WAAW,gBAAgB;AAC/G;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,iBAAiB;AACpF;AACA;AACA,wDAAwD,OAAO;AAC/D,uDAAuD,QAAQ;AAC/D;AACA,oBAAoB;AACpB;AACA;AACA;AACA,gCAAgC,mCAAmC;AACnE;AACA,iCAAiC;AACjC,oBAAoB;AACpB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G,4DAA4D,OAAO;AACnE,2DAA2D,QAAQ;AACnE;AACA,wBAAwB;AACxB;AACA;AACA;AACA,oCAAoC,mCAAmC;AACvE;AACA,qCAAqC;AACrC,wBAAwB;AACxB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C;AAC/C,4CAA4C,yCAAyC;AACrF;AACA,yDAAyD,YAAY,QAAQ,WAAW,gBAAgB;AACxG,yDAAyD,YAAY,QAAQ,WAAW,gBAAgB;AACxG,yDAAyD,YAAY,QAAQ,WAAW,gBAAgB;AACxG,yDAAyD,YAAY,QAAQ,WAAW,gBAAgB;AACxG,yDAAyD,YAAY,QAAQ,WAAW,gBAAgB;AACxG,2DAA2D,YAAY,QAAQ,WAAW,gBAAgB;AAC1G,2DAA2D,YAAY,QAAQ,WAAW,gBAAgB;AAC1G;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA;AACA;AACA,mDAAmD;AACnD,gDAAgD,yCAAyC;AACzF;AACA,6DAA6D,YAAY,QAAQ,WAAW,gBAAgB;AAC5G,6DAA6D,YAAY,QAAQ,WAAW,gBAAgB;AAC5G,6DAA6D,YAAY,QAAQ,WAAW,gBAAgB;AAC5G,6DAA6D,YAAY,QAAQ,WAAW,gBAAgB;AAC5G,6DAA6D,YAAY,QAAQ,WAAW,gBAAgB;AAC5G,+DAA+D,YAAY,QAAQ,WAAW,gBAAgB;AAC9G,+DAA+D,YAAY,QAAQ,WAAW,gBAAgB;AAC9G,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,gEAAK;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC,uBAAuB,gEAAK;AAC5B,yBAAyB,gEAAK;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC,uBAAuB,gEAAK;AAC5B,yBAAyB,gEAAK;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,YAAY,uBAAuB,KAAK,sBAAsB;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,uBAAuB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,uBAAuB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,uBAAuB;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,sBAAsB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uEAAuE,wBAAwB;AAC/F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,kGAAkG;AAC1H;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,4BAA4B;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,kGAAkG;AAC1H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,gCAAgC,IAAI,mCAAmC;AAC7H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yEAAyE,uBAAuB;AAChG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,mBAAmB,aAAa;AAChC,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,8EAA8E,uBAAuB;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,WAAW,WAAW;AAC1D;AACA;AACA,gBAAgB;AAChB;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,kGAAkG;AAC1H;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,WAAW,WAAW;AAC9D;AACA;AACA,oBAAoB;AACpB;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,mBAAmB,aAAa;AAChC,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,iBAAiB;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,oBAAoB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,wBAAwB,kBAAkB,KAAK,iBAAiB;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,IAAI;AAC3C,wCAAwC,KAAK;AAC7C;AACA;AACA,4CAA4C;AAC5C,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,gEAAK;AACxB,qBAAqB,gEAAK;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,6BAA6B;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,uBAAuB,KAAK,uBAAuB;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,+BAA+B;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,qEAAqE;AAChH;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G,+CAA+C,qEAAqE;AACpH;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,uBAAuB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,uBAAuB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,8BAA8B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,gEAAK;AACxB,4BAA4B,gEAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,gEAAK;AAC9B,uBAAuB,gEAAK;AAC5B;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,gEAAK;AACxB,4BAA4B,gEAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,gEAAK;AAC9B,uBAAuB,gEAAK;AAC5B;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,gEAAK;AACxB;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,gEAAK;AACxB,4BAA4B,gEAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,cAAc;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gEAAK;AAC5B,yBAAyB,gEAAK;AAC9B;AACA,kCAAkC,gEAAK;AACvC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,gEAAK;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,yBAAyB,gDAAgD;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,gEAAK;AACxB;AACA,4BAA4B,gEAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D,8BAA8B;AAC1F;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G,gEAAgE,8BAA8B;AAC9F;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,6FAA6F;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE;AACxE;AACA;AACA;AACA;AACA;AACA,4EAA4E;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE;AACxE;AACA;AACA;AACA;AACA;AACA,qFAAqF;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,mBAAmB,GAAG,EAAE,IAAI;AAC9E,6DAA6D;AAC7D;AACA;AACA,kDAAkD,oBAAoB,GAAG,EAAE,GAAG;AAC9E,6DAA6D;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS,IAAI,QAAQ,SAAS,IAAI;AACtE,2BAA2B;AAC3B,gBAAgB;AAChB;AACA,2EAA2E,EAAE;AAC7E;AACA;AACA,YAAY;AACZ,kEAAkE,0BAA0B,EAAE,IAAI;AAClG;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iGAAiG,cAAc;AAC/G;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA,sDAAsD,mBAAmB,GAAG,EAAE,IAAI;AAClF,iEAAiE;AACjE;AACA;AACA,sDAAsD,oBAAoB,GAAG,EAAE,GAAG;AAClF,iEAAiE;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,SAAS,IAAI,QAAQ,SAAS,IAAI;AAC1E,+BAA+B;AAC/B,oBAAoB;AACpB;AACA,+EAA+E,EAAE;AACjF;AACA;AACA,gBAAgB;AAChB,sEAAsE,0BAA0B,EAAE,IAAI;AACtG;AACA;AACA,gBAAgB;AAChB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,wEAAwE,IAAI;AAC9F;AACA;AACA,kCAAkC,mBAAmB;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B,oBAAoB;AACpB;AACA,yCAAyC;AACzC;AACA,+BAA+B;AAC/B,oBAAoB;AACpB;AACA,qDAAqD,wBAAwB;AAC7E;AACA,2CAA2C,qCAAqC;AAChF,2CAA2C;AAC3C,gCAAgC,cAAc,4BAA4B;AAC1E;AACA;AACA,2CAA2C,qCAAqC;AAChF,2CAA2C;AAC3C,gCAAgC,cAAc,4BAA4B;AAC1E;AACA;AACA,mBAAmB,eAAe;AAClC;AACA,mDAAmD,sDAAsD;AACzG;AACA,YAAY;AACZ;AACA,oFAAoF,eAAe;AACnG,mDAAmD,sDAAsD;AACzG;AACA,YAAY;AACZ;AACA;AACA;AACA,qCAAqC,WAAW,UAAU,QAAQ,oCAAoC;AACtG,yBAAyB;AACzB,gBAAgB,GAAG,+BAA+B;AAClD;AACA;AACA;AACA,iGAAiG,cAAc;AAC/G;AACA;AACA;AACA,wBAAwB,6FAA6F;AACrH;AACA,sCAAsC,mBAAmB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC,wBAAwB;AACxB;AACA,6CAA6C;AAC7C;AACA,mCAAmC;AACnC,wBAAwB;AACxB;AACA,yDAAyD,wBAAwB;AACjF;AACA,+CAA+C,qCAAqC;AACpF,+CAA+C;AAC/C,oCAAoC,cAAc,4BAA4B;AAC9E;AACA;AACA,+CAA+C,qCAAqC;AACpF,+CAA+C;AAC/C,oCAAoC,cAAc,4BAA4B;AAC9E;AACA;AACA,uBAAuB,eAAe;AACtC;AACA,uDAAuD,sDAAsD;AAC7G;AACA,gBAAgB;AAChB;AACA,wFAAwF,eAAe;AACvG,uDAAuD,sDAAsD;AAC7G;AACA,gBAAgB;AAChB;AACA;AACA;AACA,yCAAyC,WAAW,UAAU,QAAQ,oCAAoC;AAC1G,6BAA6B;AAC7B,oBAAoB,GAAG,+BAA+B;AACtD;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA,yDAAyD,0CAA0C;AACnG;AACA;AACA;AACA;AACA,uCAAuC,GAAG;AAC1C,8BAA8B;AAC9B;AACA,4DAA4D,uBAAuB,IAAI,mBAAmB;AAC1G;AACA,0CAA0C,sCAAsC;AAChF,oBAAoB,IAAI,0EAA0E;AAClG;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,uFAAuF;AAC/G;AACA;AACA;AACA;AACA,2CAA2C,GAAG;AAC9C,kCAAkC;AAClC;AACA,gEAAgE,uBAAuB,IAAI,mBAAmB;AAC9G;AACA,8CAA8C,sCAAsC;AACpF,wBAAwB,IAAI,0EAA0E;AACtG;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,oCAAoC,GAAG;AACvC,8BAA8B;AAC9B;AACA,4DAA4D,uBAAuB,IAAI,mBAAmB;AAC1G;AACA,uCAAuC,sCAAsC;AAC7E,oBAAoB,IAAI,4DAA4D;AACpF;AACA;AACA;AACA;AACA,iGAAiG,cAAc;AAC/G;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA;AACA;AACA,wCAAwC,GAAG;AAC3C,kCAAkC;AAClC;AACA,gEAAgE,uBAAuB,IAAI,mBAAmB;AAC9G;AACA,2CAA2C,sCAAsC;AACjF,wBAAwB,IAAI,4DAA4D;AACxF;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA,2CAA2C;AAC3C;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,iEAAiE,cAAc,iBAAiB,EAAE,IAAI;AACtG;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,oDAAoD;AACtG,oDAAoD,qCAAqC;AACzF;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G,6DAA6D,oDAAoD;AACjH,+DAA+D,qCAAqC;AACpG;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,YAAY,GAAG,YAAY,IAAI,aAAa;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,sBAAsB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,sBAAsB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,gEAAK;AAC9B;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,gEAAK;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,yBAAyB,+CAA+C;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,sBAAsB,wCAAwC;AAC9D,wBAAwB,0BAA0B;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,wDAAG;AACP;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA,uBAAuB,+DAAI;AAC3B,aAAa;AACb;AACA,uBAAuB,+DAAI,QAAQ,wDAAG;AACtC,aAAa;AACb;AACA,uBAAuB,+DAAI;AAC3B,aAAa;AACb;AACA,sDAAsD,8DAAG;AACzD,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA,gBAAgB;AAChB;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,IAAI;AACvC;AACA;AACA,wCAAwC;AACxC,yCAAyC;AACzC;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA,IAAI,wDAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,WAAW;AAC1B;AACA,IAAI,wDAAG;AACP;AACA,gBAAgB,wDAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,mEAAK;AAC5C;AACA,kBAAkB,4BAA4B,mEAAK;AACnD;AACA;AACA,gCAAgC,oBAAoB;AACpD;AACA;AACA;AACA;AACA;AACA,kBAAkB,4BAA4B,mEAAK;AACnD;AACA,kBAAkB,oBAAoB,mEAAK;AAC3C;AACA,kBAAkB,oBAAoB,mEAAK;AAC3C;AACA,kBAAkB,oBAAoB,mEAAK;AAC3C;AACA,kBAAkB,oBAAoB,mEAAK;AAC3C;AACA,kBAAkB,oBAAoB,mEAAK;AAC3C;AACA,kBAAkB,oBAAoB,mEAAK;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,WAAW;AAC1B;AACA;AACA,IAAI,wDAAG;AACP,gBAAgB,wDAAG;AACnB,4BAA4B,gEAAK;AACjC,qCAAqC,gEAAK;AAC1C,8BAA8B,gEAAK;AACnC,uCAAuC,gEAAK;AAC5C;AACA,2BAA2B,gEAAK;AAChC,oCAAoC,gEAAK;AACzC,6BAA6B,gEAAK;AAClC,sCAAsC,gEAAK;AAC3C;AACA,6BAA6B,gEAAK;AAClC,sCAAsC,gEAAK;AAC3C,+BAA+B,gEAAK;AACpC,wCAAwC,gEAAK;AAC7C;AACA,0BAA0B,gEAAK;AAC/B,mCAAmC,gEAAK;AACxC,4BAA4B,gEAAK;AACjC,qCAAqC,gEAAK;AAC1C;AACA,8BAA8B,gEAAK;AACnC,wCAAwC,gEAAK;AAC7C;AACA,6BAA6B,gEAAK;AAClC,uCAAuC,gEAAK;AAC5C;AACA,8BAA8B,gEAAK;AACnC,2BAA2B,gEAAK;AAChC;AACA,QAAQ,wDAAG;AACX;AACA;AACA;AACA,wDAAG,8BAA8B,wDAAG;AACpC;AACA,iEAAe,wDAAG,QAAQ,EAAC;;;;;;;;;;;;;;;;;;;;ACtlU3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACN;AACD;AACG;AACM;AACI;AACX;AACF;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,8DAAG;AACnB,yBAAyB,kEAAQ;AACjC,2BAA2B,oEAAU;AACrC,yBAAyB,8DAAG;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,2BAA2B,iDAAiD,6BAA6B;AACxH;AACA,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,sDAAsD,+BAA+B;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,wDAAG;AACX;AACA,sBAAsB,wDAAG;AACzB;AACA,QAAQ,wDAAG;AACX;AACA,uBAAuB,wDAAG;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAG,QAAQ,wDAAG;AACd;AACA;AACA,eAAe,QAAQ;AACvB;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA,uDAAuD;AACvD;AACA;AACA;AACA;AACA;AACA,oBAAoB,sBAAsB;AAC1C;AACA;AACA;AACA,uCAAuC,+DAAI;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB;AACjB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,oBAAoB,2BAA2B;AAC/C,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,4BAA4B,+DAAI;AAChC;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB,wDAAG;AACpB,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB;AACA,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB,oBAAoB,+DAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,0FAA0F,QAAQ,qFAAqF;AAC1N;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA,cAAc,SAAS,+DAAI;AAC3B;AACA;AACA;AACA;AACA,cAAc,SAAS,+DAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,UAAU;AACzB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,oBAAoB;AACpB;AACA;AACA,sCAAsC;AACtC,yCAAyC;AACzC,6DAA6D;AAC7D,4FAA4F;AAC5F,qCAAqC;AACrC,sBAAsB;AACtB,cAAc;AACd,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,iBAAiB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yEAAyE,EAAE;AAC3E,oDAAoD;AACpD;AACA,4BAA4B,EAAE;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,iBAAiB;AACjD;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,oBAAoB;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,+DAAI;AAC1D;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,oBAAoB,sBAAsB;AAC1C,mBAAmB,+DAAI;AACvB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,oBAAoB;AACnC,eAAe,QAAQ;AACvB;AACA;AACA;AACA,oBAAoB;AACpB;AACA,+BAA+B,mEAAK;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,mEAAK;AACnC,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,4BAA4B,mEAAK;AAC3C;AACA,wCAAwC;AACxC,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA,0BAA0B,+DAAI;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,gBAAgB,+DAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,8DAAI;AAChB,4BAA4B,8DAAI;AAChC,YAAY,8DAAI,qBAAqB,8DAAI;AACzC;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA,wBAAwB,kBAAkB;AAC1C;AACA,+BAA+B,wDAAG;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,+DAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,aAAa;AACvB;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,gBAAgB,8DAAI;AACpB,gBAAgB,8DAAI;AACpB;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,gBAAgB,wBAAwB;AACxC;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,gBAAgB,wBAAwB;AACxC;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,gBAAgB,wBAAwB;AACxC;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,gBAAgB,OAAO;AACvB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA,kBAAkB,+DAAI;AACtB,kBAAkB,+DAAI;AACtB,kBAAkB,+DAAI;AACtB,8BAA8B,+DAAI;AAClC;AACA,sDAAsD;AACtD;AACA,2BAA2B,YAAY;AACvC;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,QAAQ,mCAAmC;AAC3C,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB,wBAAwB,iBAAiB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,OAAO;AAClD,oBAAoB,+DAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,cAAc,UAAU,+DAAI,iCAAiC,+DAAI;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB,wBAAwB,iBAAiB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,+DAAI,yCAAyC,+DAAI,QAAQ,8DAAG;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,OAAO;AAClD,oBAAoB,+DAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,+CAA+C;AAC/C;AACA,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uEAAuE,qBAAqB;AAC5F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,OAAO;AAClD,oBAAoB,+DAAI;AACxB;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,kBAAkB,+DAAI;AACtB;AACA;AACA;AACA;AACA,gBAAgB,+DAAI,mBAAmB,+DAAI;AAC3C;AACA;AACA,cAAc,SAAS,+DAAI;AAC3B;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA,aAAa,+DAAI;AACjB;AACA;AACA;AACA,aAAa,+DAAI;AACjB;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA,+CAA+C,UAAU;AACzD;AACA;AACA;AACA;AACA,+CAA+C,UAAU;AACzD,yCAAyC,iBAAiB,QAAQ;AAClE;AACA;AACA;AACA,+CAA+C,cAAc;AAC7D,mCAAmC,SAAS;AAC5C;AACA;AACA;AACA,+CAA+C,UAAU;AACzD,gDAAgD,UAAU;AAC1D,4CAA4C,gBAAgB,eAAe;AAC3E;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA,YAAY,+DAAI;AAChB;AACA,wBAAwB,iBAAiB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,0BAA0B;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,0BAA0B;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,8BAA8B;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D,+DAAI;AAC9D;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,6DAA6D,gCAAgC;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,OAAO;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,+DAAI;AAChC;AACA;AACA;AACA;AACA,4CAA4C,kBAAkB;AAC9D,2CAA2C,+DAAI;AAC/C;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,+DAAI,gBAAgB,+DAAI;AACpD;AACA,0BAA0B;AAC1B;AACA;AACA;AACA,4CAA4C,+DAAI;AAChD;AACA;AACA;AACA;AACA,oCAAoC,iBAAiB;AACrD,gCAAgC,+DAAI,sBAAsB,+DAAI;AAC9D;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,gBAAgB;AAC5D;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,+DAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0GAA0G,8DAAG;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D;AAC1D;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,+DAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,8CAA8C;AAC9E;AACA;AACA;AACA;AACA;AACA,gCAAgC,+DAAI;AACpC,4HAA4H;AAC5H,8BAA8B;AAC9B;AACA;AACA;AACA,6IAA6I;AAC7I;AACA,0BAA0B;AAC1B;AACA,qFAAqF;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oFAAoF,6CAA6C;AACjI;AACA;AACA,oCAAoC,8CAA8C,mDAAmD;AACrI;AACA;AACA,mFAAmF,4CAA4C,6CAA6C,+CAA+C;AAC3N,sHAAsH;AACtH,oEAAoE,4CAA4C;AAChH,yGAAyG;AACzG,gCAAgC,+CAA+C;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,6BAA6B;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kFAAkF;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sFAAsF,oDAAoD;AAC1I,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,6BAA6B;AACrE;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA,oCAAoC,6BAA6B;AACjE;AACA;AACA;AACA;AACA;AACA,sEAAsE;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA,kEAAkE;AAClE;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,eAAe;AACvC,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,qBAAqB;AACpC,eAAe,SAAS;AACxB,iBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAY,+DAAI,gBAAgB,+DAAI;AACpC;AACA,kBAAkB,+DAAI;AACtB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,oBAAoB;AACnC,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,oBAAoB;AACnC,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,eAAe;AAC9B,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,UAAU;AACzB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,wBAAwB;AACvC,iBAAiB;AACjB;AACA;AACA,aAAa,+DAAI,iBAAiB,+DAAI;AACtC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,wBAAwB;AACvC,iBAAiB;AACjB;AACA;AACA,aAAa,+DAAI,iBAAiB,+DAAI;AACtC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,WAAW;AAC1B,iBAAiB;AACjB;AACA;AACA,aAAa,+DAAI,gBAAgB,+DAAI;AACrC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,mBAAmB;AAClC,iBAAiB;AACjB;AACA;AACA,aAAa,+DAAI,iBAAiB,+DAAI;AACtC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,UAAU;AACzB,iBAAiB;AACjB;AACA;AACA,aAAa,+DAAI,iBAAiB,+DAAI;AACtC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,wBAAwB;AACvC,eAAe,wBAAwB;AACvC,iBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB,YAAY,+DAAI;AAChB;AACA,YAAY,4DAAQ,kBAAkB,4DAAQ;AAC9C,kBAAkB,4DAAQ;AAC1B,UAAU,SAAS,+DAAI,eAAe,+DAAI;AAC1C;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,SAAS,+DAAI,gBAAgB,+DAAI;AAC3C;AACA,UAAU,SAAS,+DAAI,gBAAgB,+DAAI;AAC3C;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,wBAAwB;AACvC,eAAe,wBAAwB;AACvC,iBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB,YAAY,+DAAI;AAChB;AACA,YAAY,4DAAQ,kBAAkB,4DAAQ;AAC9C,kBAAkB,4DAAQ;AAC1B,UAAU,SAAS,+DAAI,eAAe,+DAAI;AAC1C;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,SAAS,+DAAI,gBAAgB,+DAAI;AAC3C;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,wBAAwB;AACvC,iBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA,YAAY,4DAAQ;AACpB,kBAAkB,4DAAQ;AAC1B,UAAU,SAAS,+DAAI;AACvB;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,SAAS,+DAAI;AACvB;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,cAAc;AAC7B,eAAe,cAAc;AAC7B,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB,YAAY,+DAAI;AAChB;AACA,YAAY,+DAAI,eAAe,+DAAI;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,4DAAQ,kBAAkB,4DAAQ;AAC9C,kBAAkB,4DAAQ;AAC1B,UAAU,SAAS,+DAAI,eAAe,+DAAI;AAC1C;AACA,kBAAkB,8DAAG;AACrB,UAAU,SAAS,+DAAI,gBAAgB,+DAAI;AAC3C;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,SAAS,+DAAI,gBAAgB,+DAAI;AAC3C;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,cAAc;AAC7B,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB,YAAY,+DAAI;AAChB;AACA,YAAY,4DAAQ,kBAAkB,4DAAQ;AAC9C,kBAAkB,4DAAQ;AAC1B,UAAU,SAAS,+DAAI,eAAe,+DAAI;AAC1C;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,SAAS,+DAAI,gBAAgB,+DAAI;AAC3C;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,cAAc;AAC7B,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB,YAAY,+DAAI;AAChB;AACA,YAAY,4DAAQ,kBAAkB,4DAAQ;AAC9C,mBAAmB,4DAAQ;AAC3B,UAAU,SAAS,+DAAI,eAAe,+DAAI;AAC1C;AACA;AACA;AACA,wBAAwB,SAAS;AACjC,yBAAyB,8DAAG;AAC5B;AACA,UAAU,SAAS,+DAAI,gBAAgB,+DAAI;AAC3C,kBAAkB,8DAAG;AACrB,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,eAAe;AAC9B,eAAe,eAAe;AAC9B,iBAAiB;AACjB;AACA;AACA,YAAY,+DAAI;AAChB,YAAY,+DAAI;AAChB;AACA,YAAY,4DAAQ,kBAAkB,4DAAQ;AAC9C,mBAAmB,4DAAQ;AAC3B;AACA,eAAe,8DAAG;AAClB,KAAK;AACL;AACA;AACA,YAAY,4DAAQ,kBAAkB,4DAAQ;AAC9C,mBAAmB,4DAAQ;AAC3B;AACA;AACA,KAAK;AACL;AACA,YAAY,4DAAQ,kBAAkB,4DAAQ;AAC9C,mBAAmB,4DAAQ;AAC3B;AACA;AACA,KAAK;AACL;AACA,YAAY,4DAAQ,kBAAkB,4DAAQ;AAC9C,mBAAmB,4DAAQ;AAC3B;AACA;AACA,KAAK;AACL;AACA,YAAY,4DAAQ,kBAAkB,4DAAQ;AAC9C,mBAAmB,4DAAQ;AAC3B;AACA;AACA,KAAK;AACL;AACA;AACA,aAAa,+DAAI;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,GAAG;AAClB,eAAe,GAAG;AAClB,iBAAiB,GAAG;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,qBAAqB;AACpC;AACA;AACA,2CAA2C,wDAAG,yBAAyB,wDAAG;AAC1E;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,wBAAwB;AACvC;AACA;AACA,eAAe,wDAAG;AAClB,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,wDAAG;AACzB,oBAAoB,wDAAG,6BAA6B,wDAAG;AACvD,0BAA0B,wDAAG;AAC7B;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,8DAAG;AAC1B,sBAAsB,8DAAG;AACzB,uBAAuB,8DAAG;AAC1B,0BAA0B,8DAAG;AAC7B,sBAAsB,8DAAG;AACzB,sBAAsB,8DAAG;AACzB,qBAAqB,8DAAG;AACxB,qBAAqB,kEAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,8DAAG;AACxB,sBAAsB,8DAAG;AACzB,sBAAsB,8DAAG;AACzB,2BAA2B,8DAAG;AAC9B,qBAAqB,8DAAG;AACxB,oBAAoB,8DAAG;AACvB,qBAAqB,8DAAG;AACxB,oBAAoB,8DAAG;AACvB,oBAAoB,8DAAG;AACvB;AACA,qBAAqB,8DAAG;AACxB,uBAAuB,8DAAG;AAC1B,sBAAsB,8DAAG;AACzB,sBAAsB,8DAAG;AACzB,uBAAuB,8DAAG;AAC1B,yBAAyB,8DAAG;AAC5B,qBAAqB,8DAAG;AACxB,qBAAqB,kEAAQ;AAC7B,wBAAwB,8DAAG;AAC3B,uBAAuB,+DAAI;AAC3B,sBAAsB,8DAAG;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,wCAAwC;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,kEAAQ;AACjC,yBAAyB,kEAAQ;AACjC,+BAA+B,8DAAG;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,8BAA8B;AACvE,8CAA8C,sCAAsC;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,wDAAG;AACrB;AACA;AACA,KAAK;AACL;AACA,qBAAqB;AACrB;AACA;AACA,YAAY,+DAAI;AAChB,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA,QAAQ,wDAAG;AACX,KAAK;AACL;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,SAAS,wDAAG;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,SAAS,wDAAG;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,wDAAG;AACvB;AACA;AACA,cAAc,UAAU,wDAAG;AAC3B;AACA,oBAAoB,wDAAG;AACvB;AACA,cAAc;AACd;AACA,oBAAoB,wDAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA,UAAU,SAAS,8DAAG;AACtB;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,uCAAuC,iBAAiB;AACxD,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA,UAAU,SAAS,8DAAG;AACtB;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,+BAA+B,4CAA4C;AAC3E,UAAU;AACV;AACA;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,eAAe,kCAAkC;AACjD,iBAAiB,kCAAkC;AACnD;AACA;AACA;AACA,qBAAqB,IAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oJAAoJ;AACpJ,SAAS;AACT;AACA;AACA;AACA,qBAAqB,+BAA+B;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,WAAW,YAAY,IAAI,WAAW,SAAS;AACvE;AACA;AACA;AACA;AACA,cAAc,4BAA4B;AAC1C,MAAM;AACN,WAAW,qKAAqK,iJAAiJ,OAAO,g/BAAg/B;AACxzC,aAAa,yEAAyE,gEAAgE,OAAO,uSAAuS;AACpc;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kFAAkF;AAClF;AACA;AACA,iGAAiG;AACjG;AACA;AACA,8EAA8E;AAC9E;AACA;AACA,+EAA+E;AAC/E;AACA;AACA,8EAA8E;AAC9E;AACA;AACA,+EAA+E;AAC/E;AACA;AACA,kFAAkF;AAClF;AACA;AACA,8EAA8E;AAC9E;AACA;AACA,8EAA8E;AAC9E;AACA;AACA,+EAA+E;AAC/E;AACA;AACA,+EAA+E;AAC/E;AACA;AACA,+EAA+E;AAC/E;AACA;AACA,+EAA+E;AAC/E;AACA;AACA,+EAA+E;AAC/E;AACA;AACA,+EAA+E;AAC/E;AACA;AACA,+EAA+E;AAC/E;AACA;AACA,+EAA+E;AAC/E;AACA;AACA,qEAAqE;AACrE;AACA;AACA,qEAAqE;AACrE;AACA;AACA,kBAAkB;AAClB;AACA;AACA,oFAAoF;AACpF;AACA;AACA,sFAAsF;AACtF;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sEAAsE,GAAG;AACzE;AACA;AACA,+EAA+E;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mFAAmF;AACnF;AACA;AACA,mGAAmG;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D;AAC1D;AACA;AACA,8EAA8E;AAC9E;AACA;AACA,oFAAoF;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD,4FAA4F,QAAQ,GAAG,MAAM,EAAE,6WAA6W,EAAE,QAAQ,sMAAsM,KAAK,GAAG,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,sWAAsW,EAAE,UAAU,EAAE,UAAU,EAAE,wQAAwQ,EAAE,UAAU,2HAA2H,iBAAiB,qFAAqF,oBAAoB,gBAAgB,gCAAgC,gBAAgB,gCAAgC,gBAAgB,OAAO,0DAA0D,qBAAqB,2DAA2D,8PAA8P,EAAE,SAAS,EAAE,SAAS,eAAe,4BAA4B,2DAA2D,2EAA2E,EAAE,4QAA4Q,eAAe,cAAc,kHAAkH,qBAAqB,+BAA+B,2MAA2M,EAAE,2MAA2M,EAAE,2MAA2M,EAAE,gXAAgX,EAAE,+PAA+P,EAAE,+PAA+P,EAAE,+PAA+P,EAAE,WAAW,yCAAyC,WAAW,gBAAgB,0PAA0P,EAAE,2MAA2M,EAAE,0PAA0P,EAAE,yOAAyO,EAAE,WAAW,EAAE,+PAA+P,eAAe,mCAAmC,GAAG,4QAA4Q,gBAAgB,+PAA+P,EAAE,WAAW,EAAE,mOAAmO,EAAE,6NAA6N,EAAE,6NAA6N,EAAE,6NAA6N,EAAE,WAAW,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,uNAAuN,EAAE,uNAAuN,EAAE,uNAAuN,EAAE,uNAAuN,gBAAgB,sBAAsB,gBAAgB,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,gBAAgB,kBAAkB,gBAAgB,iNAAiN,EAAE,iNAAiN,EAAE,2MAA2M,EAAE,2MAA2M,EAAE,2MAA2M,kGAAkG,OAAO,2LAA2L,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,4CAA4C,WAAW,eAAe,OAAO,iBAAiB,WAAW,uFAAuF,WAAW,2DAA2D,kBAAkB,EAAE,WAAW,6BAA6B,qBAAqB,gBAAgB,4BAA4B,gBAAgB,4BAA4B,gBAAgB,4BAA4B,iBAAiB,cAAc,EAAE,kBAAkB,iBAAiB,WAAW,EAAE,kBAAkB,eAAe,cAAc,gBAAgB,cAAc,gBAAgB,cAAc,gBAAgB,cAAc,iBAAiB,4DAA4D,EAAE,0PAA0P,gBAAgB,0PAA0P,eAAe,qBAAqB,gBAAgB,qBAAqB,6CAA6C,uWAAuW,EAAE,uWAAuW,EAAE,+PAA+P,EAAE,+PAA+P,EAAE,0PAA0P,gBAAgB,4BAA4B,6CAA6C,cAAc,EAAE,WAAW,EAAE,+PAA+P,EAAE,WAAW,wDAAwD,WAAW,gBAAgB,WAAW,EAAE,WAAW,2EAA2E,+PAA+P,EAAE,uWAAuW,EAAE,+PAA+P,EAAE,WAAW,8BAA8B,WAAW,eAAe,uWAAuW;AAClvc,iBAAiB,sCAAsC;AACvD;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+DAA+D;AAC/D;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,wBAAwB,sBAAsB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,kBAAkB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA,kCAAkC;AAClC,sBAAsB;AACtB;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA,sDAAsD;AACtD;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,KAAK;AACL,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AACA;AACA;AACA;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA;AAAM;AACN;AACA,CAAC;AACD,icAAic,UAAU,SAAS;AACpd,aAAa,WAAW;AACxB,CAAC;AACD;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA,CAAC;AACD;AACA;AACA;AACA,iEAAe,wDAAG,WAAW,EAAC;;;;;;;;;;;AClqH9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,EAAE;AACF;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,uBAAuB;AAClC,WAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB,WAAW,SAAS;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,mBAAmB;AACnB;AACA;AACA;AACA,gBAAgB,0BAA0B;AAC1C;AACA;AACA,oBAAoB;AACpB;AACA;AACA,+FAA+F;AAC/F;AACA,mBAAmB,QAAQ;AAC3B;AACA,mBAAmB,UAAU;AAC7B,oFAAoF,uBAAuB;AAC3G;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,UAAU;AAC7B;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA,wBAAwB,gBAAgB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,iDAAiD,+BAA+B,kBAAkB,uBAAuB;AACzH;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,UAAU;AAC/B;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B,4BAA4B;AAC5B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,uCAAuC,iBAAiB;AACxD,4BAA4B,uBAAuB;AACnD;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,sBAAsB;AAC9C;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,iEAAe,GAAG,EAAC;;;;;;;;;;;;;ACjWnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACC;AAC7B;AACA;AACA;AACA;AACA;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,UAAU;AAC9B;AACA;AACA;AACA;AACA;AACA,gCAAgC,UAAU;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,YAAY,oBAAoB;AAChC;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB;AACA;AACA;AACA,aAAa,yDAAI;AACjB;AACA;AACA;AACA,kBAAkB,yDAAI;AACtB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,UAAU;AACzB;AACA;AACA;AACA;AACA;AACA,uBAAuB,yDAAI;AAC3B;AACA;AACA;AACA;AACA,gBAAgB,yDAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAe,wDAAG,aAAa,EAAC;;;;;;;;;;;;;ACrKhC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,oBAAoB;AACxC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA,UAAU;AACV,wBAAwB,OAAO;AAC/B;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA,UAAU;AACV,wBAAwB,OAAO;AAC/B;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,wBAAwB,OAAO;AAC/B;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,wDAAG;AACnB;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA,gCAAgC,OAAO;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,wBAAwB,OAAO;AAC/B;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,4BAA4B,+DAAI;AAChC;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,4BAA4B,+DAAI;AAChC;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA,+BAA+B,+DAAI;AACnC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,YAAY,oGAAoG;AAChH;AACA,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,iBAAiB,UAAU;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,+DAAI,gBAAgB,+DAAI;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,iBAAiB,UAAU;AAC3B;AACA;AACA;AACA;AACA,cAAc,+DAAI,gBAAgB,+DAAI;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,+DAAI,kBAAkB,+DAAI,iBAAiB,+DAAI;AAC5D;AACA;AACA;AACA,YAAY,wDAAG;AACf;AACA;AACA,YAAY,wDAAG;AACf;AACA;AACA;AACA;AACA;AACA,YAAY,wDAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,wDAAG;AACf;AACA;AACA,YAAY,wDAAG;AACf;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,6BAA6B,mDAAmD;AAChF;AACA;AACA,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,QAAQ;AACvC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,yDAAyD,eAAe;AACxE;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,qCAAqC,0DAA0D;AAC/F;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE;AACxE,UAAU;AACV;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,SAAS;AACxB,iBAAiB;AACjB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,6CAA6C;AACjE;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,2CAA2C,mEAAmE;AAC9G;AACA;AACA,mBAAmB,IAAI,EAAE,GAAG,YAAY,KAAK;AAC7C;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAe,wDAAG,KAAK,EAAC;;;;;;;;;;;;AC/6CxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAG,iBAAiB,wDAAG;AACvB;AACA,iEAAe,SAAS,EAAC;AACzB;AACA,WAAW;AACX;;;;;;;;;;;;;;;;;;;AC9JA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACF;AACX;AACa;AACJ;AACD;AACI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAG;AACH;AACA;AACA;AACA,wDAAG;AACH,IAAI,yDAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,iBAAiB;AACpC,mBAAmB,iBAAiB;AACpC,mBAAmB,iBAAiB;AACpC,4BAA4B,6BAA6B;AACzD;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,wDAAG;AACf;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,iBAAiB;AACpC,mBAAmB,iBAAiB;AACpC,mBAAmB,iBAAiB;AACpC;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA,2DAA2D;AAC3D,SAAS;AACT;AACA;AACA;AACA,mBAAmB,iBAAiB;AACpC,mBAAmB,iBAAiB;AACpC,mBAAmB,iBAAiB;AACpC;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA;AACA,2BAA2B,gEAAM;AACjC,oBAAoB,mEAAK;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gEAAM,CAAC,mEAAK;AACnC,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,WAAW;AACjC,sBAAsB,WAAW;AACjC,sBAAsB,WAAW;AACjC,sBAAsB,QAAQ;AAC9B;AACA,wBAAwB,YAAY;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,mBAAmB,UAAU;AAC7B,mBAAmB,WAAW;AAC9B;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gEAAM,CAAC,mEAAK;AACnC,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B,mBAAmB,QAAQ;AAC3B,mBAAmB,WAAW;AAC9B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gEAAM,CAAC,mEAAK;AACnC,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,UAAU;AAC7B,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,yDAAG;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,kCAAkC,yDAAG;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,kBAAkB,yDAAG,qCAAqC,yDAAG;AAC3E;AACA;AACA;AACA;AACA,kCAAkC,yDAAG;AACrC;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,yDAAG;AACrC,yCAAyC,yDAAG;AAC5C,yCAAyC,yDAAG;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,oBAAoB,yDAAG,qBAAqB;AAC5C,oBAAoB,yDAAG,gCAAgC;AACvD;AACA;AACA;AACA,wBAAwB,gEAAM,CAAC,mEAAK;AACpC,SAAS;AACT;AACA;AACA,mCAAmC,sCAAsC;AACzE;AACA;AACA,YAAY,wDAAG;AACf;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA;AACA,iBAAiB,yDAAG;AACpB;AACA;AACA;AACA,iBAAiB,yDAAG;AACpB;AACA,uBAAuB,gEAAM,CAAC,mEAAK,iBAAiB,yDAAG;AACvD,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yDAAG;AACvB,uCAAuC,yDAAG,8BAA8B,yDAAG;AAC3E;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,kBAAkB;AACrC,mBAAmB,kBAAkB;AACrC,mBAAmB,kBAAkB;AACrC,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA,+BAA+B,yDAAG;AAClC;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO,uBAAuB,gBAAgB,GAAG,iBAAiB;AACrF;AACA,qBAAqB;AACrB;AACA;AACA;AACA,qBAAqB,iEAAM,SAAS,iEAAM;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,4BAA4B;AAC/C,mBAAmB,4BAA4B;AAC/C,mBAAmB,4BAA4B;AAC/C;AACA,qBAAqB;AACrB;AACA;AACA,oBAAoB,iEAAM;AAC1B,oBAAoB,iEAAM;AAC1B,oBAAoB,iEAAM;AAC1B;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO,uBAAuB,gBAAgB,GAAG,iBAAiB;AACrF,mBAAmB,SAAS;AAC5B;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,qBAAqB,iEAAM,SAAS,iEAAM;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO,4BAA4B,gBAAgB,GAAG,iBAAiB;AAC1F;AACA,qBAAqB,OAAO,sBAAsB,oBAAoB;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,iBAAiB;AACvE,sDAAsD,iBAAiB;AACvE,sDAAsD,iBAAiB;AACvE;AACA;AACA;AACA;AACA,2BAA2B,iBAAiB;AAC5C;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,oBAAoB;AACpB,oBAAoB;AACpB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA,0DAA0D,iBAAiB;AAC3E,0DAA0D,iBAAiB;AAC3E,0DAA0D,iBAAiB;AAC3E;AACA;AACA;AACA;AACA,+BAA+B,iBAAiB;AAChD;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yDAAG,OAAO,yDAAG;AACnC;AACA;AACA;AACA,qBAAqB,iEAAM,cAAc,iEAAM;AAC/C;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,+DAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,yDAAG,mCAAmC,yDAAG;AACpE;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,OAAO;AAClC;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA,mBAAmB,OAAO,4BAA4B,gBAAgB,GAAG,iBAAiB;AAC1F,mBAAmB,SAAS;AAC5B,2EAA2E,iBAAiB;AAC5F;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,iBAAiB;AACvE,sDAAsD,iBAAiB;AACvE,sDAAsD,iBAAiB;AACvE,sDAAsD,iBAAiB;AACvE;AACA,2BAA2B,iBAAiB;AAC5C,uCAAuC,cAAc;AACrD;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA,0DAA0D,iBAAiB;AAC3E,0DAA0D,iBAAiB;AAC3E,0DAA0D,iBAAiB;AAC3E,0DAA0D,iBAAiB;AAC3E;AACA,+BAA+B,iBAAiB;AAChD,2CAA2C,cAAc;AACzD;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,iBAAiB;AACvE,sDAAsD,iBAAiB;AACvE,sDAAsD,iBAAiB;AACvE,sDAAsD,iBAAiB;AACvE;AACA,wDAAwD,sCAAsC;AAC9F;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,iBAAiB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA,0DAA0D,iBAAiB;AAC3E,0DAA0D,iBAAiB;AAC3E,0DAA0D,iBAAiB;AAC3E,0DAA0D,iBAAiB;AAC3E;AACA,4DAA4D,sCAAsC;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,iBAAiB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,iBAAiB;AACzC;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qFAAqF,MAAM;AAC3F;AACA,sFAAsF,MAAM;AAC5F;AACA;AACA,sFAAsF,iBAAiB;AACvG;AACA,sBAAsB,8BAA8B;AACpD,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kFAAkF,MAAM;AACxF;AACA,mFAAmF,iBAAiB;AACpG;AACA;AACA,mBAAmB,8BAA8B;AACjD,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yDAAG,OAAO,yDAAG;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB,qBAAqB,iEAAM,cAAc,iEAAM;AAC/C,cAAc,SAAS,+DAAI,wCAAwC,mEAAK;AACxE,qBAAqB,iEAAM,uBAAuB,iEAAM;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,UAAU;AAC7B,mBAAmB,YAAY;AAC/B;AACA,mBAAmB,YAAY;AAC/B;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,yDAAG;AACnD;AACA;AACA,gDAAgD,yDAAG;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,yDAAG;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,yDAAG;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,mEAAK;AAC3C;AACA;AACA;AACA;AACA,sCAAsC,mEAAK;AAC3C;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,UAAU;AAC7B,mBAAmB,YAAY;AAC/B;AACA,mBAAmB,YAAY;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,yDAAG;AACnD;AACA;AACA,gDAAgD,yDAAG;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,UAAU,kDAAkD;AAClF;AACA;AACA;AACA;AACA,sBAAsB,UAAU,kDAAkD;AAClF;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,sBAAsB,UAAU,kDAAkD;AAClF;AACA;AACA;AACA;AACA,sBAAsB,UAAU,kDAAkD;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,mEAAK;AACpD;AACA;AACA;AACA,4CAA4C,mEAAK;AACjD,gDAAgD,mEAAK;AACrD;AACA,4BAA4B,yDAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,mEAAK;AACjD,gDAAgD,mEAAK;AACrD;AACA,4BAA4B,yDAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,mEAAK;AAC3C;AACA;AACA;AACA;AACA,sCAAsC,mEAAK;AAC3C;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B,mBAAmB,YAAY;AAC/B,mBAAmB,YAAY;AAC/B,mBAAmB,YAAY;AAC/B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,yDAAG;AAC/C;AACA;AACA;AACA;AACA,4CAA4C,yDAAG;AAC/C;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B,mBAAmB,YAAY;AAC/B,mBAAmB,YAAY;AAC/B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,yDAAG;AAClC;AACA;AACA;AACA,+BAA+B,yDAAG;AAClC;AACA;AACA;AACA,+BAA+B,yDAAG;AAClC;AACA;AACA;AACA,+BAA+B,yDAAG;AAClC;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,iBAAiB;AACrC,oBAAoB,iBAAiB;AACrC,oBAAoB,iBAAiB;AACrC,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA,cAAc;AACd;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA,cAAc;AACd;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,oBAAoB,OAAO;AAC3B;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA,oBAAoB,iBAAiB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,cAAc;AACtC;AACA,oBAAoB,+DAAI;AACxB;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,wCAAwC,yDAAG;AAC3C;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA,wCAAwC,yDAAG;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,oBAAoB,OAAO;AAC3B;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA,mBAAmB,WAAW;AAC9B;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,mEAAK;AACpC,2BAA2B,gEAAM,CAAC,mEAAK;AACvC;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,qCAAqC,aAAa;AAClD,qBAAqB,+DAAI;AACzB,qBAAqB,+DAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,wCAAwC;AACtE,mBAAmB,WAAW;AAC9B,mBAAmB,yDAAyD;AAC5E;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B;AACA,qBAAqB,UAAU,sBAAsB,kBAAkB;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,mEAAK;AAC1C,kCAAkC,mEAAK,iCAAiC,mEAAK;AAC7E;AACA;AACA;AACA,qCAAqC,mEAAK;AAC1C,kCAAkC,mEAAK,iCAAiC,mEAAK;AAC7E;AACA;AACA;AACA;AACA,sCAAsC,mEAAK;AAC3C,yCAAyC,mEAAK;AAC9C,sCAAsC,mEAAK;AAC3C,yCAAyC,mEAAK;AAC9C,sCAAsC,mEAAK;AAC3C,yCAAyC,mEAAK;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,sCAAsC,mEAAK;AAC3C;AACA,yCAAyC,mEAAK;AAC9C,sCAAsC,mEAAK;AAC3C;AACA,yCAAyC,mEAAK;AAC9C;AACA;AACA;AACA;AACA;AACA,sEAAsE,+DAAI;AAC1E;AACA,cAAc;AACd,6BAA6B,mEAAK;AAClC,6BAA6B,mEAAK;AAClC;AACA;AACA;AACA;AACA;AACA,yCAAyC,mEAAK;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,+DAAI;AACtC;AACA;AACA,kBAAkB,8BAA8B,mEAAK;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,+DAAI;AACtC;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,qCAAqC,mEAAK;AAC1C,qCAAqC,mEAAK;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,+DAAI;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA,mCAAmC,gEAAM,CAAC,mEAAK;AAC/C;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,+DAAI;AAC5B;AACA;AACA,6CAA6C,mEAAK;AAClD;AACA;AACA;AACA;AACA,kDAAkD,yDAAG,4BAA4B,yDAAG;AACpF,2CAA2C,gEAAM,CAAC,wDAAG;AACrD;AACA;AACA;AACA,6CAA6C,mEAAK;AAClD;AACA;AACA;AACA;AACA,kDAAkD,yDAAG,4BAA4B,yDAAG;AACpF,2CAA2C,gEAAM,CAAC,wDAAG;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,gEAAM,CAAC,wDAAG;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,+DAAI;AAC9B;AACA,6BAA6B,QAAQ;AACrC,6CAA6C,mEAAK;AAClD,yBAAyB,mEAAK,sBAAsB,mEAAK;AACzD;AACA;AACA,sBAAsB,8BAA8B,mEAAK;AACzD,yBAAyB,mEAAK,qBAAqB,mEAAK;AACxD;AACA;AACA,sBAAsB,8BAA8B,mEAAK,4CAA4C,mEAAK;AAC1G;AACA,4BAA4B,+DAAI;AAChC,gCAAgC,wDAAG,qDAAqD,+DAAI;AAC5F,0BAA0B;AAC1B,gCAAgC,wDAAG;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,oBAAoB;AACpD,4BAA4B,+DAAI,cAAc,+DAAI;AAClD,2CAA2C,wDAAG;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,KAAK;AACzB,oBAAoB,YAAY;AAChC,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,iBAAiB;AACpC;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA,sBAAsB,yDAAG;AACzB;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,oBAAoB,WAAW;AAC/B,oBAAoB,WAAW;AAC/B,oBAAoB,WAAW;AAC/B,qBAAqB,kBAAkB;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA,mBAAmB,yDAAG;AACtB;AACA,mBAAmB,yDAAG;AACtB;AACA,mBAAmB,yDAAG;AACtB;AACA,mBAAmB,yDAAG;AACtB;AACA;AACA,wBAAwB,OAAO;AAC/B,wCAAwC,yDAAG;AAC3C,gCAAgC,OAAO;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,yDAAG;AACvC,mCAAmC;AACnC,mCAAmC;AACnC;AACA,cAAc,6BAA6B,yDAAG;AAC9C,mCAAmC;AACnC,mCAAmC;AACnC;AACA,cAAc;AACd,mCAAmC;AACnC;AACA;AACA;AACA,uCAAuC;AACvC,kBAAkB;AAClB,uCAAuC;AACvC;AACA;AACA,cAAc;AACd,mCAAmC;AACnC;AACA;AACA;AACA,uCAAuC;AACvC,kBAAkB;AAClB,uCAAuC;AACvC;AACA,cAAc;AACd,mCAAmC;AACnC;AACA;AACA;AACA,uCAAuC;AACvC;AACA,kBAAkB;AAClB,uCAAuC;AACvC,kBAAkB;AAClB,uCAAuC;AACvC;AACA;AACA;AACA;AACA,oBAAoB,gEAAM,CAAC,mEAAK;AAChC,oBAAoB,gEAAM,CAAC,mEAAK;AAChC;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,WAAW;AAC9B,qBAAqB,YAAY;AACjC;AACA;AACA,uDAAuD,yDAAG;AAC1D;AACA;AACA;AACA;AACA;AACA,uBAAuB,gEAAM,CAAC,mEAAK;AACnC,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,iBAAiB;AACpC;AACA;AACA,mBAAmB,WAAW;AAC9B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA,0BAA0B,yDAAG;AAC7B,6BAA6B,yDAAG,gDAAgD,yDAAG;AACnF,+BAA+B,gEAAM,CAAC,mEAAK;AAC3C;AACA;AACA,2BAA2B,gEAAM,CAAC,mEAAK;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yDAAG,OAAO,yDAAG;AAClC;AACA;AACA;AACA,uBAAuB,+DAAI;AAC3B,0BAA0B,gEAAM;AAChC,wBAAwB,mEAAK;AAC7B;AACA;AACA;AACA,0BAA0B,gEAAM;AAChC,wBAAwB,mEAAK;AAC7B;AACA;AACA;AACA;AACA;AACA,uBAAuB,gEAAM,CAAC,mEAAK;AACnC,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,iBAAiB;AACpC;AACA;AACA,mBAAmB,WAAW;AAC9B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA,2BAA2B,yDAAG;AAC9B;AACA;AACA,oBAAoB,yDAAG;AACvB;AACA,+BAA+B,gEAAM,CAAC,mEAAK;AAC3C;AACA;AACA,2BAA2B,gEAAM,CAAC,mEAAK;AACvC;AACA;AACA;AACA,2BAA2B,yDAAG;AAC9B;AACA;AACA,oBAAoB,yDAAG;AACvB;AACA,+BAA+B,gEAAM,CAAC,mEAAK;AAC3C;AACA;AACA,2BAA2B,gEAAM,CAAC,mEAAK;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,yDAAG;AAC7B;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B,mBAAmB,QAAQ;AAC3B,mBAAmB,WAAW;AAC9B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,+DAAI;AACxB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,uBAAuB,gEAAM,CAAC,mEAAK;AACnC,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B,mBAAmB,OAAO;AAC1B;AACA,mBAAmB,SAAS;AAC5B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,yDAAG,OAAO,yDAAG,OAAO,yDAAG;AAC9C,uBAAuB,yDAAG,OAAO,yDAAG;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,4BAA4B,yDAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,6DAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,yDAAG,yBAAyB,yDAAG;AAChE,iCAAiC,yDAAG,yBAAyB,yDAAG;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,SAAS;AAC5B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yDAAG;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,YAAY;AACrC,6BAA6B,YAAY;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,yDAAG;AACpC;AACA;AACA;AACA;AACA,gCAAgC,+DAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B,mBAAmB,iBAAiB;AACpC,yDAAyD,2CAA2C;AACpG;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,WAAW;AAC9B,mBAAmB,QAAQ;AAC3B;AACA;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,+DAAI;AACxB;AACA;AACA,wCAAwC,+DAAI,qBAAqB,+DAAI;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB,qBAAqB,6DAAQ;AAC7B,2BAA2B,gEAAM,CAAC,mEAAK;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,uBAAuB,gEAAM,CAAC,mEAAK;AACnC,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,YAAY,8CAA8C;AAC1D,2CAA2C;AAC3C;AACA;AACA,mBAAmB,oBAAoB;AACvC,mBAAmB,oBAAoB;AACvC,mBAAmB,iBAAiB;AACpC,mBAAmB,WAAW;AAC9B,mBAAmB,SAAS;AAC5B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA,qCAAqC,mEAAK;AAC1C;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,iBAAiB,+CAA+C;AAChE,qDAAqD,6BAA6B;AAClF;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,UAAU;AAC7B,mBAAmB,gBAAgB;AACnC,mBAAmB,WAAW;AAC9B,mBAAmB,SAAS;AAC5B;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA,sBAAsB,yDAAG;AACzB,yBAAyB,yDAAG;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA,wBAAwB,WAAW;AACnC,oBAAoB,6DAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,6DAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB,cAAc;AACd;AACA;AACA;AACA,uBAAuB,gEAAM,CAAC,mEAAK;AACnC,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,UAAU;AAC7B,mBAAmB,iBAAiB;AACpC,mBAAmB,WAAW;AAC9B,mBAAmB,SAAS;AAC5B;AACA;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA,oBAAoB,+DAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,gEAAM,CAAC,mEAAK;AAChC;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA,wBAAwB,yDAAG;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,gCAAgC,gBAAgB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA,wCAAwC,gEAAM,CAAC,mEAAK;AACpD,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B,mBAAmB,iBAAiB;AACpC;AACA;AACA;AACA;AACA,oBAAoB,+DAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,YAAY;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,aAAa;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yDAAG;AACzB,sBAAsB,yDAAG;AACzB,oBAAoB,yDAAG;AACvB;AACA,iCAAiC,yDAAG;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,yDAAG;AACrD;AACA;AACA;AACA,kDAAkD,yDAAG;AACrD;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,kCAAkC;AACrD,mBAAmB,kCAAkC;AACrD,mBAAmB,iBAAiB;AACpC,mBAAmB,WAAW;AAC9B;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA,oBAAoB,+DAAI;AACxB;AACA,gBAAgB,wDAAG;AACnB;AACA;AACA;AACA,uFAAuF,yDAAG;AAC1F;AACA;AACA;AACA;AACA,gBAAgB,wDAAG;AACnB;AACA;AACA;AACA;AACA,gBAAgB,yDAAG,OAAO,yDAAG;AAC7B;AACA;AACA;AACA;AACA;AACA,0BAA0B,wDAAG;AAC7B,2BAA2B,gEAAM,CAAC,mEAAK;AACvC;AACA;AACA,YAAY,wDAAG;AACf,YAAY,wDAAG;AACf;AACA,4BAA4B,wDAAG;AAC/B;AACA;AACA;AACA,uBAAuB,gEAAM,CAAC,mEAAK;AACnC,SAAS;AACT;AACA;AACA;AACA,mBAAmB,aAAa;AAChC,mBAAmB,UAAU;AAC7B,mBAAmB,iBAAiB;AACpC,mBAAmB,WAAW;AAC9B,mBAAmB,SAAS;AAC5B;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA,oBAAoB,+DAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gEAAM,CAAC,mEAAK;AACnC,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,sFAAsF;AACtF,sFAAsF;AACtF,sFAAsF;AACtF,sFAAsF;AACtF,cAAc;AACd;AACA,4DAA4D;AAC5D,4DAA4D;AAC5D,4DAA4D;AAC5D,4DAA4D;AAC5D;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,+DAAI;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,mBAAmB,OAAO;AAC1B;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,mBAAmB,OAAO;AAC1B;AACA,mBAAmB,SAAS;AAC5B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,wBAAwB,cAAc;AACtC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B,mBAAmB,iBAAiB;AACpC,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA,oBAAoB,+DAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,mEAAK;AAClC;AACA;AACA;AACA,8BAA8B,mEAAK;AACnC;AACA;AACA;AACA;AACA,+BAA+B,YAAY;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,aAAa;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,0BAA0B;AAC9D;AACA;AACA,yCAAyC,yDAAG;AAC5C,4CAA4C,yDAAG;AAC/C,yCAAyC,yDAAG;AAC5C,4CAA4C,yDAAG;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,SAAS;AAC5B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,yBAAyB,yDAAG;AAC5B;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yDAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yDAAG;AACvB;AACA,wCAAwC,yDAAG;AAC3C;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,sBAAsB;AACzC,mBAAmB,YAAY;AAC/B,mBAAmB,WAAW;AAC9B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB,6CAA6C,mEAAK;AAClD;AACA;AACA,cAAc;AACd,sCAAsC,mEAAK;AAC3C;AACA;AACA;AACA,iCAAiC,yDAAG;AACpC,uBAAuB,yDAAG;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,gEAAM,CAAC,mEAAK;AACnC,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,sBAAsB;AACzC,mBAAmB,UAAU;AAC7B,mBAAmB,WAAW;AAC9B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB,oBAAoB,+DAAI;AACxB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA,gBAAgB,yDAAG;AACnB,uBAAuB,gEAAM,CAAC,mEAAK,iBAAiB,yDAAG;AACvD,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,yDAAG,yBAAyB,yDAAG;AAChE;AACA;AACA;AACA,gBAAgB,yDAAG;AACnB,oBAAoB,yDAAG;AACvB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,YAAY,iBAAiB;AAC7B,mBAAmB,OAAO;AAC1B,mBAAmB,WAAW;AAC9B,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,wDAAG;AACpB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,iBAAiB,6CAA6C;AAC9D;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA,gCAAgC,4BAA4B;AAC5D;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,mCAAmC,gEAAM,CAAC,mEAAK;AAC/C,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,WAAW;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,sCAAsC;AAClE;AACA;AACA;AACA;AACA,4BAA4B,sCAAsC;AAClE;AACA;AACA;AACA;AACA;AACA,oBAAoB,6DAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,mCAAmC,gEAAM;AACzC,oBAAoB,mEAAK;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,aAAa;AAChC,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,aAAa;AACrC,6BAA6B,wDAAG;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,wDAAG;AAC3B;AACA,kBAAkB;AAClB,wBAAwB,wDAAG;AAC3B;AACA,kBAAkB;AAClB,wBAAwB,wDAAG;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,yDAAyD,4CAA4C;AACrG,mBAAmB,WAAW;AAC9B,mBAAmB,YAAY;AAC/B,mBAAmB,WAAW;AAC9B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,+DAAI;AACrB;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,wCAAwC,mEAAK;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,gEAAM,CAAC,mEAAK;AACxC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,sBAAsB;AACzC,mBAAmB,WAAW;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA,wBAAwB,yDAAG;AAC3B;AACA;AACA;AACA;AACA,wBAAwB,yDAAG;AAC3B;AACA;AACA,uDAAuD,gBAAgB,IAAI,YAAY;AACvF;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,yDAAG;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA,sBAAsB,yDAAG,OAAO,yDAAG;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,yDAAG;AACtB,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,uBAAuB;AAC1C,mBAAmB,uBAAuB;AAC1C,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,mEAAK;AAClC,iCAAiC,mEAAK;AACtC;AACA;AACA,kBAAkB,sBAAsB,mEAAK;AAC7C;AACA;AACA,cAAc,sBAAsB,mEAAK;AACzC,iCAAiC,mEAAK;AACtC;AACA,kBAAkB,sBAAsB,mEAAK;AAC7C;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yDAAG;AACrB,kBAAkB,yDAAG;AACrB,kBAAkB,yDAAG;AACrB;AACA,oBAAoB,yDAAG;AACvB,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yDAAG;AACrB;AACA;AACA;AACA,kBAAkB,yDAAG;AACrB;AACA,gBAAgB,yDAAG;AACnB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,2BAA2B,yDAAG;AAC9B;AACA;AACA;AACA;AACA;AACA,2BAA2B,yDAAG;AAC9B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,2BAA2B,oEAAI;AAC/B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,2BAA2B;AAC9C,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,+DAAI,4BAA4B,+DAAI;AAC3D;AACA;AACA,cAAc;AACd,uBAAuB,+DAAI,8BAA8B,+DAAI;AAC7D,uBAAuB,+DAAI,8BAA8B,+DAAI;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA,YAAY,yDAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA,gBAAgB,yDAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,sBAAsB,OAAO;AAC7B,sBAAsB,2BAA2B;AACjD,sBAAsB,OAAO;AAC7B;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yDAAG;AACpB,iBAAiB,yDAAG;AACpB,iBAAiB,yDAAG;AACpB;AACA;AACA;AACA,kBAAkB,yDAAG;AACrB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,6DAAQ;AAC9B;AACA;AACA;AACA;AACA,sBAAsB,6DAAQ;AAC9B;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA,YAAY,gBAAgB;AAC5B;AACA;AACA;AACA;AACA,2DAA2D,8EAA8E;AACzI;AACA,qCAAqC,wFAAwF;AAC7H;AACA,uGAAuG,cAAc;AACrH;AACA,wFAAwF,oFAAoF;AAC5K;AACA;AACA,2DAA2D,8EAA8E;AACzI;AACA,qCAAqC,wFAAwF;AAC7H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,yDAAG;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAe,yDAAG,SAAS,EAAC;;;;;;;;;;;;;;AC59I5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACA;AACQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAG;AACH;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,cAAc;AAC7B,iBAAiB,cAAc;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA,wBAAwB,cAAc;AACtC;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB;AACjB;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,qDAAqD,gCAAgC;AACrF;AACA;AACA,gBAAgB,OAAO;AACvB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,cAAc;AAC7B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA,UAAU;AACV;AACA,UAAU;AACV;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B,eAAe,cAAc;AAC7B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,+DAAI;AACnB,eAAe,+DAAI;AACnB;AACA,YAAY,+DAAI,kBAAkB,+DAAI;AACtC;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,SAAS,+DAAI,mBAAmB,+DAAI;AAC9C;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,SAAS,+DAAI,kBAAkB,+DAAI;AAC7C;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B,eAAe,cAAc;AAC7B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,+DAAI;AACnB,eAAe,+DAAI;AACnB;AACA,YAAY,+DAAI,kBAAkB,+DAAI;AACtC;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,SAAS,+DAAI,mBAAmB,+DAAI;AAC9C;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,SAAS,+DAAI,kBAAkB,+DAAI;AAC7C;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,wBAAwB,+BAA+B;AACvD;AACA;AACA;AACA,QAAQ,wDAAG;AACX,QAAQ,yDAAG,sBAAsB,yDAAG;AACpC,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B,eAAe,cAAc;AAC7B,eAAe,SAAS;AACxB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,+DAAI;AACnB;AACA;AACA,kBAAkB,yDAAG;AACrB;AACA;AACA,eAAe,+DAAI;AACnB,eAAe,+DAAI;AACnB;AACA,YAAY,+DAAI,kBAAkB,+DAAI;AACtC;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,SAAS,+DAAI,mBAAmB,+DAAI;AAC9C;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,SAAS,+DAAI,kBAAkB,+DAAI;AAC7C;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B,eAAe,cAAc;AAC7B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,+DAAI;AACnB,eAAe,+DAAI;AACnB;AACA,YAAY,+DAAI,kBAAkB,+DAAI;AACtC;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,SAAS,+DAAI,mBAAmB,+DAAI;AAC9C;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,SAAS,+DAAI,kBAAkB,+DAAI;AAC7C;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B,eAAe,cAAc;AAC7B,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,+DAAI;AACnB,eAAe,+DAAI;AACnB;AACA,YAAY,+DAAI,kBAAkB,+DAAI;AACtC;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,SAAS,+DAAI,mBAAmB,+DAAI;AAC9C;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,SAAS,+DAAI,kBAAkB,+DAAI;AAC7C;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,gDAAgD,6CAA6C;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO,iBAAiB,iBAAiB;AACxD,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,sDAAsD,uCAAuC;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,mCAAmC;AAC7C;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,kFAAkF;AACtG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,mCAAmC;AACjD;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAmB;AACvC;AACA;AACA,wBAAwB,mBAAmB;AAC3C,gFAAgF,yDAAG;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,kBAAkB;AAClB;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA,eAAe,4CAA4C;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+EAA+E,mBAAmB;AAClG,yDAAyD,GAAG,OAAO,QAAQ,eAAe,OAAO;AACjG;AACA;AACA,0DAA0D,0DAA0D;AACpH,uDAAuD,mCAAmC;AAC1F,UAAU;AACV;AACA,qGAAqG,cAAc;AACnH;AACA;AACA;AACA,eAAe,4CAA4C;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+EAA+E,mBAAmB;AAClG,yDAAyD,GAAG,OAAO,QAAQ,eAAe,OAAO;AACjG;AACA;AACA,0DAA0D,0DAA0D;AACpH,uDAAuD,mCAAmC;AAC1F,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,kEAAkE;AACjF;AACA;AACA;AACA,eAAe,QAAQ,eAAe;AACtC;AACA;AACA;AACA;AACA,eAAe,4CAA4C;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+EAA+E,mBAAmB;AAClG,6DAA6D,GAAG,OAAO;AACvE;AACA;AACA,0DAA0D,0DAA0D;AACpH,uDAAuD,mCAAmC;AAC1F,UAAU;AACV;AACA,qGAAqG,cAAc;AACnH;AACA;AACA;AACA,eAAe,4CAA4C;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+EAA+E,mBAAmB;AAClG,6DAA6D,GAAG,OAAO;AACvE;AACA;AACA,0DAA0D,0DAA0D;AACpH,uDAAuD,mCAAmC;AAC1F,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ,kBAAkB;AACzC,eAAe,QAAQ,sBAAsB;AAC7C,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA,eAAe,8CAA8C;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2EAA2E,mBAAmB;AAC9F,wDAAwD,OAAO,SAAS,GAAG,OAAO;AAClF;AACA;AACA;AACA,0DAA0D,4DAA4D;AACtH,uDAAuD,oBAAoB;AAC3E;AACA,UAAU;AACV;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,eAAe,8CAA8C;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2EAA2E,mBAAmB;AAC9F,wDAAwD,OAAO,SAAS,GAAG,OAAO;AAClF;AACA;AACA,0DAA0D,4DAA4D;AACtH,uDAAuD,oBAAoB;AAC3E,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ,cAAc;AACrC,eAAe,QAAQ,aAAa;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ,UAAU;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ,WAAW;AAClC,eAAe,QAAQ,WAAW;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,kFAAkF;AAClF;AACA,eAAe,QAAQ,WAAW;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA,aAAa,+CAA+C;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uFAAuF,qBAAqB;AAC5G,6DAA6D,OAAO,MAAM,OAAO;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ,qDAAqD,qBAAqB;AAC1E,QAAQ;AACR;AACA;AACA,qGAAqG,cAAc;AACnH;AACA;AACA;AACA,eAAe,8CAA8C;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2EAA2E,mBAAmB;AAC9F,wDAAwD,OAAO,MAAM,OAAO;AAC5E;AACA;AACA,0DAA0D,4DAA4D;AACtH,uDAAuD,oBAAoB;AAC3E,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,8CAA8C;AAC7D;AACA,eAAe,+CAA+C;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2EAA2E,mBAAmB;AAC9F,wDAAwD,OAAO,SAAS,GAAG,OAAO;AAClF;AACA;AACA;AACA,0DAA0D,4DAA4D;AACtH,uDAAuD,mCAAmC;AAC1F;AACA;AACA,sDAAsD,2DAA2D;AACjH;AACA;AACA,wDAAwD,oCAAoC;AAC5F,UAAU;AACV;AACA;AACA,mGAAmG,eAAe,WAAW;AAC7H,8BAA8B,QAAQ,MAAM;AAC5C,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,eAAe,8CAA8C;AAC7D;AACA,eAAe,+CAA+C;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2EAA2E,mBAAmB;AAC9F,wDAAwD,OAAO,SAAS,GAAG,OAAO;AAClF;AACA;AACA,0DAA0D,4DAA4D;AACtH,uDAAuD,mCAAmC;AAC1F;AACA;AACA,sDAAsD,2DAA2D;AACjH;AACA;AACA,wDAAwD,oCAAoC;AAC5F,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,oBAAoB,cAAc;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,wDAAG,uCAAuC;AAC1D,wBAAwB,cAAc;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,cAAc;AAC1C,yCAAyC;AACzC;AACA,cAAc,YAAY,cAAc;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAe,yDAAG,WAAW,EAAC;;;;;;;;;;;;;;;ACr4C9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACC;AACY;AACF;AACvC;AACA;AACA;AACA;AACA;AACA;AACA,wDAAG;AACH;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,eAAe,SAAS;AACxB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yDAAI;AAChB;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,sBAAsB;AACrC,eAAe,SAAS;AACxB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,oCAAoC,mEAAK;AACzC;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,wBAAwB,gEAAM,CAAC,mEAAK;AACpC;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,4BAA4B;AAC3C,eAAe,SAAS;AACxB;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA,aAAa,yDAAI;AACjB;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAe,wDAAG,OAAO,EAAC;;;;;;;;;;;;;;AC9H1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACA;AACQ;AACpC;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAG;AACH,IAAI,wDAAG;AACP;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,wDAAG;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yDAAG;AACnB,qBAAqB,yDAAG;AACxB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,gBAAgB,yDAAG;AACnB,qBAAqB,yDAAG;AACxB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAG;AACH;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,wBAAwB,yDAAG,8BAA8B,yDAAG;AAC5D,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,2BAA2B,yDAAG,8BAA8B,yDAAG;AAC/D,KAAK;AACL;AACA;AACA,2BAA2B,yDAAG;AAC9B,KAAK;AACL;AACA;AACA,+BAA+B,yDAAG;AAClC,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA;AACA;AACA,wDAAG;AACH;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,0BAA0B;AACzC,eAAe,0BAA0B;AACzC;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,0BAA0B;AACzC,eAAe,0BAA0B;AACzC;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,0BAA0B;AACzC,eAAe,0BAA0B;AACzC;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,0BAA0B;AACzC,eAAe,0BAA0B;AACzC;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,0BAA0B;AACzC,eAAe,0BAA0B;AACzC;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,0BAA0B;AACzC;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,0BAA0B;AACzC,eAAe,0BAA0B;AACzC;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,0BAA0B;AACzC;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,0BAA0B;AACzC,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,0BAA0B;AACzC;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,0BAA0B;AACzC;AACA;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,+BAA+B,sCAAsC;AACrE,eAAe,0BAA0B;AACzC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,0BAA0B;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,0BAA0B;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,eAAe,mBAAmB;AAClC,eAAe,mBAAmB;AAClC;AACA;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA,YAAY,+DAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA,yBAAyB,yDAAG;AAC5B,KAAK;AACL;AACA,yBAAyB,yDAAG;AAC5B,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA,yBAAyB,yDAAG;AAC5B,KAAK;AACL;AACA,yBAAyB,yDAAG;AAC5B,KAAK;AACL;AACA,yBAAyB,yDAAG;AAC5B,KAAK;AACL;AACA,yBAAyB,yDAAG;AAC5B,KAAK;AACL;AACA,yBAAyB,yDAAG;AAC5B,KAAK;AACL;AACA,yBAAyB,yDAAG;AAC5B,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAG;AACH,IAAI,yDAAG;AACP,IAAI,yDAAG;AACP;AACA,wDAAG;AACH,IAAI,yDAAG;AACP,IAAI,yDAAG;AACP;AACA,wDAAG;AACH,IAAI,yDAAG;AACP,IAAI,yDAAG;AACP;AACA,wDAAG;AACH,wDAAG;AACH,wDAAG;AACH,wDAAG;AACH;AACA,iEAAe,wDAAG,wBAAwB,EAAC;;;;;;;;;;;;;;ACrqD3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACC;AACK;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,kCAAkC,IAAI,YAAY,IAAI,YAAY,IAAI,eAAe,IAAI;AACzF;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,iCAAiC,IAAI,YAAY,IAAI,YAAY,IAAI;AACrE;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,sBAAsB,EAAE,KAAK,EAAE,KAAK,EAAE;AACtC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,sBAAsB,EAAE,KAAK,EAAE,KAAK,EAAE;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qBAAqB;AAChC;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,yDAAI;AACb;AACA;AACA;AACA,QAAQ,yDAAI,eAAe,yDAAI;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yDAAI;AACZ,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,sBAAsB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qBAAqB;AAChC;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACA,wDAAG;AACH;AACA;AACA,QAAQ,wDAAG;AACX;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qBAAqB;AAChC;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACA,wDAAG;AACH;AACA;AACA,QAAQ,wDAAG;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,oBAAoB,mBAAmB;AACvC,aAAa,QAAQ;AACrB;AACA,wDAAG;AACH,IAAI,wDAAG;AACP,WAAW,wDAAG;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA;AACA,4BAA4B,8DAAG;AAC/B;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,MAAM;AACN;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qBAAqB;AAChC;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA;AACA,wDAAG;AACH;AACA;AACA,QAAQ,wDAAG;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,qBAAqB;AAChC;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,wDAAG;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,OAAO;AACpB;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,cAAc;AACzB;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,wDAAG;AACd;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,wDAAG;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA,aAAa,QAAQ;AACrB;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,wDAAG;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,UAAU,wDAAG;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACA,wDAAG;AACH,cAAc,wDAAG;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,wDAAG;AACd;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;AACA;AACA,wDAAG;AACH,WAAW,wDAAG;AACd;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;AACA;AACA,wDAAG;AACH,WAAW,wDAAG;AACd;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACA,wDAAG;AACH,cAAc,wDAAG;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,eAAe,wDAAG;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,aAAa,QAAQ;AACrB;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,wDAAG;AACb;AACA;AACA,eAAe,wDAAG;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,2BAA2B;AAC5E;AACA;AACA,wDAAG;AACH,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP,IAAI,wDAAG;AACP;AACA;AACA,wDAAG;AACH,IAAI,wDAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D,oCAAoC;AACjG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,gCAAgC;AACrF;AACA;AACA,wDAAG,WAAW,wDAAG;AACjB;AACA,iEAAe,wDAAG,EAAC;;;;;;;;;;;;;;;;ACrlCnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACO;AACU;AACT;AACF;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,OAAO;AAClB,WAAW,WAAW;AACtB,WAAW,SAAS;AACpB;AACA;AACA,wDAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,+DAAI;AACxB;AACA;AACA,QAAQ,gEAAY;AACpB;AACA;AACA;AACA;AACA,wDAAG;AACH,IAAI,wDAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,8DAAG;AACjD;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,YAAY;AAC/B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,8DAAK;AACpC;AACA;AACA;AACA;AACA,0BAA0B,8DAAG,OAAO,8DAAG;AACvC;AACA;AACA,uBAAuB,8DAAG;AAC1B,cAAc;AACd;AACA,uBAAuB,8DAAG;AAC1B;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,OAAO;AAC1B,mBAAmB,SAAS;AAC5B;AACA,mBAAmB,SAAS;AAC5B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,8DAAK;AACpC;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA,8CAA8C,8DAAG;AACjD;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAe,wDAAG,OAAO,EAAC;;;;;;;;;;;;;;;;;;;ACxQ1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACO;AACQ;AACM;AACf;AACE;AACF;AACa;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,8BAA8B;AAC3C;AACA;AACA,wFAAwF,wBAAwB;AAChH,SAAS,YAAY;AACrB;AACA;AACA,WAAW,kBAAkB;AAC7B,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,iBAAiB;AAC5B;AACA;AACA,wDAAG;AACH;AACA;AACA,wCAAwC,8DAAK,mBAAmB,8DAAK;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,+DAAI;AACZ;AACA;AACA;AACA;AACA,qBAAqB,+DAAI;AACzB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,wDAAG,sBAAsB,4DAAe;AACxC,+DAAI,sBAAsB,wDAAG,OAAO,kEAAa;AACjD;AACA,wDAAG;AACH,IAAI,wDAAG;AACP;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,8DAAG;AACzB,oBAAoB,8DAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,oBAAoB,wBAAwB;AAC5C,mBAAmB,wBAAwB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA,uBAAuB,UAAU;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD;AACtD;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,cAAc;AACd,oBAAoB,+DAAI;AACxB;AACA;AACA,mDAAmD,+DAAI;AACvD,0BAA0B;AAC1B,2CAA2C,+DAAI;AAC/C;AACA,sBAAsB;AACtB;AACA;AACA;AACA,0BAA0B;AAC1B,2CAA2C,+DAAI;AAC/C;AACA;AACA,kBAAkB,SAAS,+DAAI;AAC/B;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,6BAA6B,+DAAI;AACjC;AACA;AACA;AACA,2CAA2C,yBAAyB;AACpE,6FAA6F;AAC7F;AACA,iCAAiC;AACjC,gFAAgF;AAChF;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,+DAAI;AAC5B;AACA;AACA;AACA;AACA,oCAAoC,yBAAyB;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,yBAAyB;AACjE,oCAAoC,+DAAI;AACxC;AACA;AACA;AACA,sCAAsC;AACtC,4CAA4C,+DAAI;AAChD;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,uDAAuD;AACvD;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,iDAAiD,kCAAkC,KAAK,uBAAuB;AAC/G;AACA,mBAAmB,wBAAwB;AAC3C,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,iDAAiD,SAAS;AAC1D,mBAAmB,iBAAiB;AACpC;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA,2BAA2B,+DAAI;AAC/B;AACA,cAAc;AACd,oBAAoB,+DAAI;AACxB;AACA,kBAAkB;AAClB,wBAAwB,+DAAI;AAC5B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,iBAAiB;AACpC,qBAAqB,UAAU;AAC/B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,8BAA8B,qBAAqB;AACnD;AACA;AACA;AACA;AACA,2BAA2B,qBAAqB;AAChD;AACA;AACA,oBAAoB,MAAM;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,8DAAG;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,+DAAI;AACxB;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,uDAAuD;AACvD;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B,yBAAyB;AACzB;AACA;AACA,kBAAkB;AAClB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B,qBAAqB;AACrB,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA,4CAA4C;AAC5C;AACA,aAAa;AACb,SAAS;AACT;AACA;AACA,uBAAuB,OAAO;AAC9B,mBAAmB,QAAQ,wBAAwB;AACnD,qBAAqB,QAAQ,sBAAsB,gBAAgB,OAAO;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA,gCAAgC,KAAK;AACrC;AACA;AACA,8DAA8D;AAC9D,iCAAiC;AACjC;AACA,iEAAiE;AACjE;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,uBAAuB,OAAO;AAC9B,mBAAmB,QAAQ,wBAAwB;AACnD,qBAAqB,QAAQ,sBAAsB,gBAAgB,OAAO;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA,gCAAgC,KAAK;AACrC;AACA;AACA,+DAA+D;AAC/D,iCAAiC;AACjC;AACA,iEAAiE;AACjE;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA,+CAA+C,+DAAI;AACnD;AACA;AACA;AACA;AACA,mDAAmD,8DAAK;AACxD,cAAc;AACd,2CAA2C,8DAAK;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,+DAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,QAAQ;AAC1B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,QAAQ;AAC1B,kBAAkB,SAAS;AAC3B,kBAAkB,SAAS;AAC3B;AACA,kBAAkB,SAAS;AAC3B;AACA,mDAAmD,UAAU;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,IAAI,UAAU;AAChE,iEAAiE;AACjE,iDAAiD,YAAY,UAAU;AACvE,iDAAiD,aAAa,YAAY;AAC1E;AACA,iDAAiD,SAAS;AAC1D,iDAAiD,WAAW;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,8BAA8B,mEAAa;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,+DAAI;AAChC,gCAAgC,+DAAI;AACpC;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,IAAI;AACjD,gDAAgD;AAChD;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA,yCAAyC,SAAS,QAAQ,UAAU;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,SAAS;AAC1D,iDAAiD,WAAW;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D;AAC1D,wBAAwB,sBAAsB;AAC9C,0DAA0D;AAC1D;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,cAAc;AACjC,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA,4BAA4B,cAAc;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C;AAC/C,8BAA8B,aAAa,UAAU;AACrD,kDAAkD;AAClD,8BAA8B,cAAc,YAAY;AACxD;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA,4BAA4B,gBAAgB;AAC5C,0DAA0D;AAC1D;AACA,sCAAsC,kBAAkB;AACxD;AACA,4BAA4B,aAAa;AACzC,0DAA0D;AAC1D;AACA,sCAAsC,eAAe;AACrD;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,wBAAwB;AAC3C,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+DAAI;AACpB;AACA;AACA;AACA;AACA,sCAAsC,mBAAmB;AACzD,sCAAsC,qBAAqB;AAC3D;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,wBAAwB;AAC3C,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,SAAS;AACpD,2CAA2C,WAAW;AACtD;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mEAAa;AACjC;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,oBAAoB,QAAQ;AAC5B,oBAAoB,QAAQ;AAC5B,oBAAoB,QAAQ;AAC5B,oBAAoB,OAAO;AAC3B,oBAAoB,UAAU;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,mCAAmC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,8DAAK;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,+DAAI;AACnD;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,+DAAI;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,UAAU;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,eAAe;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,QAAQ;AAC/B,uBAAuB,QAAQ;AAC/B,uBAAuB,QAAQ;AAC/B,uBAAuB,QAAQ;AAC/B,uBAAuB,OAAO;AAC9B,uBAAuB,UAAU;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+DAA+D,QAAQ;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,UAAU;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,kBAAkB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B,wFAAwF,qBAAqB;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iEAAiE;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,uFAAuF,qFAAqF;AAC5K;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,kBAAkB;AAC1D,sCAAsC;AACtC;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,uFAAuF,qFAAqF;AAC5K;AACA,mDAAmD,kBAAkB,gBAAgB,uDAAuD;AAC5I;AACA;AACA;AACA;AACA,uDAAuD,UAAU;AACjE;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA,2DAA2D,UAAU;AACrE;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,wDAAG;AACH;AACA,eAAe,+DAAI;AACnB;AACA;AACA;AACA;AACA;AACA,QAAQ,kEAAa,QAAQ,wDAAG;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAG,yBAAyB,wDAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD,mBAAmB,GAAG,oBAAoB,KAAK,mBAAmB;AAC3H;AACA,oGAAoG,sBAAsB;AAC1H,IAAI,qBAAqB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAG;AACH;AACA;AACA,eAAe,+DAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,wDAAG;AACX,aAAa,+DAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,QAAQ,wDAAG;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,wDAAG;AACX;AACA;AACA;AACA;AACA,QAAQ,8DAAG;AACX,MAAM;AACN;AACA;AACA;AACA,QAAQ,8DAAG;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAG,+BAA+B,wDAAG;AACrC;AACA,iEAAe,wDAAG,KAAK,EAAC;AACxB;AACA;AACA;AACA;AACA;;;;;;;SChxDA;SACA;;SAEA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;SACA;;SAEA;SACA;;SAEA;SACA;SACA;;;;;UCtBA;UACA;UACA;UACA;UACA,yCAAyC,wCAAwC;UACjF;UACA;UACA,E;;;;;UCPA,wF;;;;;;;;;;;;;;;ACAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACC;AAC7B;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAAe,kBAAG,IAAI,EAAC;;;;;;;;;AC/FvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,aAAa;AACb;AACA;AACA,6BAA6B,QAAQ;AACrC;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,aAAa;AACb;AACA;AACA,6BAA6B,OAAO;AACpC;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,gDAAe,mBAAG,UAAU,EAAC;;;;;AC3mB7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,wBAAwB,aAAa;AACrC;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,wBAAwB,aAAa;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB,eAAe,QAAQ,2EAA2E;AAClG;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,iBAAiB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,iBAAiB;AACrC;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,4CAA4C;AAC5C,cAAc;AACd,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,UAAU;AACzB;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,oFAAoF;AACxG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,QAAQ;AAC/B,2BAA2B,OAAO;AAClC;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAe,mBAAG,YAAY,EAAC;;;;;AChb/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACS;AACD;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ,gDAAgD;AACnE,WAAW,QAAQ;AACnB;AACA;AACA;AACA,mBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAI;AACJ,IAAI,mBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,mBAAG;AACpC,iCAAiC,mBAAG;AACpC,iCAAiC,mBAAG;AACpC,iCAAiC,mBAAG;AACpC;AACA,2BAA2B,QAAQ;AACnC,gEAAgE;AAChE,gEAAgE;AAChE,gEAAgE;AAChE;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,sBAAsB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,mBAAmB;AACtC,mBAAmB,QAAQ;AAC3B,qBAAqB,sBAAsB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,QAAQ;AAC5C,gCAAgC,uBAAQ;AACxC;AACA;AACA;AACA;AACA;AACA,oCAAoC,QAAQ;AAC5C,gCAAgC,uBAAQ;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAAe,mBAAG,SAAS,EAAC;;;AClX5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA,mBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAI;AACJ,IAAI,mBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,kBAAkB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,iCAAiC;AACjC,iCAAiC;AACjC,iCAAiC;AACjC,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,6BAA6B;AAC7B,6BAA6B;AAC7B,6BAA6B;AAC7B,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA,4DAA4D,4DAA4D;AACxH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC,sCAAsC;AACtC,sCAAsC;AACtC,sCAAsC;AACtC,sCAAsC;AACtC,6BAA6B;AAC7B;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAAe,mBAAG,YAAY,EAAC;;;;;AC5e/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACA;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,0BAA0B;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,UAAU;AACzB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,UAAU;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA,wCAAwC,UAAU;AAClD;AACA;AACA;AACA,wCAAwC,YAAY;AACpD;AACA;AACA,4CAA4C,YAAY;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,UAAU;AAClD;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA,4CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD,4CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA,wCAAwC,SAAS;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA,gDAAgD,QAAQ;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,QAAQ;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,QAAQ;AACxC;AACA;AACA;AACA;AACA,4CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA;AACA,4CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA,oCAAoC,UAAU;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,SAAS;AACzC;AACA;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,mBAAG;AAC1C;AACA;AACA;AACA;AACA,4CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA,sBAAsB;AACtB;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA,uCAAuC,mBAAG;AAC1C;AACA;AACA;AACA,4CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,QAAQ;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,QAAQ;AAC5D;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,WAAW;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,mBAAG;AAC9C;AACA;AACA;AACA;AACA,gDAAgD,QAAQ;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,mBAAG;AACtC;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,QAAQ;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,QAAQ;AACxC;AACA;AACA;AACA;AACA;AACA,oCAAoC,WAAW;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,QAAQ;AACxC;AACA;AACA;AACA;AACA,qCAAqC,WAAW;AAChD;AACA;AACA;AACA,wCAAwC,QAAQ;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,WAAW;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,QAAQ;AACxC;AACA;AACA,gCAAgC,WAAW;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,YAAY;AACrC;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA,sBAAsB,YAAY;AAClC;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,cAAc;AAC7C;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,uBAAuB,cAAc;AACrC;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,UAAU;AACtC;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,gCAAgC,UAAU;AAC1C;AACA;AACA,cAAc;AACd;AACA,gCAAgC,UAAU;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAAe,kBAAG,SAAS,EAAC;;;;;;;ACn3C5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACF;AACX;AACe;AACN;AACI;AACJ;AACI;AACL;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA,iEAAiE,mBAAG;AACpE;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,+EAA+E,gCAAgC;AAC/G,eAAe,WAAW;AAC1B,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,WAAW;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,WAAW;AAC1B,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,SAAS,gCAAgC,4BAA4B;AACtF;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,+EAA+E,gCAAgC;AAC/G,yEAAyE,mCAAmC;AAC5G;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,WAAW;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,0BAAM,CAAC,wBAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,mBAAG;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA,QAAQ,kBAAG;AACX;AACA;AACA;AACA,4BAA4B;AAC5B,4BAA4B;AAC5B,UAAU;AACV;AACA,6BAA6B;AAC7B,6BAA6B;AAC7B;AACA;AACA;AACA,oBAAoB,eAAe;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,wBAAK;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,wBAAK;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,0BAAM,CAAC,wBAAK;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,wBAAK;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,0BAAM,CAAC,wBAAK;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+BAA+B;AAC/C;AACA;AACA,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,GAAG;AAClB,eAAe,GAAG;AAClB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,sBAAsB,0BAAM,CAAC,wBAAK;AAClC;AACA;AACA;AACA,iBAAiB,mBAAG;AACpB,2BAA2B,wBAAK;AAChC;AACA;AACA;AACA,qBAAqB,mBAAG;AACxB;AACA,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,aAAa;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,sBAAsB,0BAAM,CAAC,wBAAK;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,oBAAoB,wBAAK;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,0BAAM,CAAC,wBAAK;AACpC;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,gBAAgB,sCAAsC;AACtD;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA,iBAAiB,WAAW;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,0BAAM,CAAC,wBAAK;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,wBAAK;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,0BAAM,CAAC,wBAAK;AAChC;AACA;AACA,UAAU;AACV;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,+EAA+E,6BAA6B;AAC5G;AACA,eAAe,WAAW;AAC1B,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,WAAW;AAC5B;AACA;AACA;AACA;AACA;AACA,qBAAqB,0BAAM,CAAC,wBAAK;AACjC,qBAAqB,0BAAM,CAAC,wBAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC;AACrC;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,qCAAqC,aAAa;AAClD,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,YAAY,wBAAK;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,wBAAK;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,wBAAK;AAC/B;AACA;AACA,0BAA0B,wBAAK;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,GAAG;AAClB,eAAe,GAAG;AAClB,eAAe,GAAG;AAClB,eAAe,GAAG;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,0BAAM,CAAC,wBAAK;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,mBAAG;AACzD,yDAAyD,mBAAG;AAC5D;AACA,qBAAqB,0BAAM,CAAC,wBAAK;AACjC;AACA;AACA;AACA;AACA,iBAAiB,0BAAM,CAAC,wBAAK;AAC7B;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,gBAAgB,+BAA+B;AAC/C;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,YAAY;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,0BAAM,CAAC,wBAAK;AAC5B;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,uBAAQ;AACvB,eAAe,uBAAQ;AACvB,eAAe,uBAAQ;AACvB,eAAe,uBAAQ;AACvB;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,0BAAM,CAAC,wBAAK;AAC9B;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,gBAAgB,WAAW;AAC3B,iBAAiB,WAAW;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,WAAW;AAC1B,iBAAiB,UAAU;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,gCAAgC;AACxC;AACA;AACA;AACA;AACA;AACA,eAAe,WAAW;AAC1B,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA,+BAA+B,uDAAuD;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,WAAW;AAClC;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,aAAa;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,0BAAM,CAAC,wBAAK;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,UAAU;AACV;AACA;AACA,UAAU;AACV;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,UAAU,gDAAgD,mBAAG;AAC7D;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAG;AACvB,oBAAoB,mBAAG;AACvB;AACA;AACA;AACA,eAAe,uBAAQ;AACvB,KAAK;AACL;AACA;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA,oBAAoB,mBAAG,OAAO,mBAAG;AACjC;AACA;AACA;AACA;AACA;AACA,eAAe,uBAAQ;AACvB,KAAK;AACL;AACA;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,WAAW;AACzB;AACA;AACA;AACA;AACA;AACA,cAAc,WAAW;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,WAAW;AACzB;AACA;AACA;AACA;AACA;AACA,cAAc,WAAW;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,UAAU;AACV;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,gBAAgB,sCAAsC;AACtD;AACA,eAAe,WAAW;AAC1B,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA,iBAAiB,WAAW;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C;AAC/C;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,+EAA+E,6BAA6B;AAC5G;AACA,eAAe,WAAW;AAC1B,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,WAAW;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,0BAAM,CAAC,wBAAK;AACjC,qBAAqB,0BAAM,CAAC,wBAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,YAAY,wBAAK;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,wBAAK;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,wBAAK;AAC/B;AACA;AACA,0BAA0B,wBAAK;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD,kDAAkD;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yBAAU;AAC5B,cAAc,yBAAU;AACxB;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA,iCAAiC,+BAA+B;AAChE;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAmB;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,YAAY;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,OAAO;AAChC;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,YAAY;AACpC;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAmB;AACvC;AACA;AACA;AACA,wBAAwB,sBAAsB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAkB;AACtC;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,wBAAwB,kBAAkB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,QAAQ;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,YAAY;AACpC;AACA;AACA;AACA,2BAA2B,QAAQ;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAmB;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,0BAAM,CAAC,wBAAK;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,iBAAkB;AAC1B;AACA,gBAAgB,iBAAkB;AAClC,8BAA8B,iBAAkB;AAChD,iCAAiC,iBAAkB;AACnD;AACA;AACA;AACA,iCAAiC,kBAAG;AACpC;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,0BAA0B;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,qBAAqB;AAC7C;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,gCAAgC,QAAQ;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,mBAAG;AACf;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,YAAY,mBAAG;AACf;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,sBAAsB,yBAAyB;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,wBAAwB,oBAAoB;AAC5C;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,YAAY;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B,iCAAiC,uBAAQ;AACzC,iCAAiC,uBAAQ;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,8FAA8F,6BAA6B;AAC3H,eAAe,WAAW;AAC1B,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,WAAW;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE,yCAAyC;AAC1G;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,WAAW;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAAe,mBAAG,KAAK,EAAC;;;AC3hFxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACa;AACb;AACoC;AACR;AACS;AACA;AACJ;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,UAAU;AACrB,WAAW,UAAU;AACrB,WAAW,UAAU;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,mBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,mBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yBAAI;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA,MAAM;AACN;AACA,oBAAoB,mBAAG,OAAO,mBAAG;AACjC;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA,MAAM;AACN;AACA,oBAAoB,mBAAG,OAAO,mBAAG;AACjC;AACA;AACA;AACA;AACA;AACA,mBAAmB,IAAQ;AAC3B;AACA;AACA;AACA;AACA,yBAAI;AACJ,IAAI,mBAAG;AACP;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,iBAAiB;AACjB;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,0DAA0D,mBAAG;AAC7D;AACA,0DAA0D,mBAAG;AAC7D;AACA;AACA;AACA;AACA,8BAA8B,mBAAG;AACjC;AACA;AACA,+BAA+B,UAAU;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,mBAAG;AACjC;AACA;AACA,+BAA+B,UAAU;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,UAAU;AAC7B,mBAAmB,UAAU;AAC7B,mBAAmB,QAAQ;AAC3B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,uBAAQ;AAC3B;AACA,mBAAmB,uBAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,uBAAQ;AAC5B;AACA;AACA;AACA,wDAAwD,mBAAG;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,8BAA8B,mBAAG;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,QAAQ;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC,oBAAoB,uBAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,oDAAoD;AACpD;AACA,kBAAkB;AAClB;AACA;AACA,2BAA2B,uBAAQ;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,mBAAG;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,mBAAG;AAC1C;AACA,oCAAoC,QAAQ;AAC5C,mCAAmC,uBAAQ;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,mBAAG;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,sBAAsB,mBAAG;AACzB;AACA;AACA;AACA;AACA;AACA,2BAA2B,uBAAQ;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAG,OAAO,mBAAG;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB,uBAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA,sBAAsB,mBAAG;AACzB;AACA,sBAAsB,mBAAG;AACzB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA,sBAAsB,mBAAG;AACzB;AACA,sBAAsB,mBAAG,OAAO,mBAAG;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAe,mBAAG,aAAa,EAAC;AAChC;;;AC//BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACoC;AACR;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4EAA4E;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,YAAY;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,WAAW;AACnD;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,mBAAG;AAClB,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,iBAAiB;AACjB;AACA;AACA,iBAAiB;AACjB;AACA;AACA,iBAAiB;AACjB;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yBAAI;AACtB;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI,8BAA8B,yBAAI;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA,kCAAkC,yBAAI;AACtC;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B,8BAA8B,yBAAI;AAClC,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B,8BAA8B,yBAAI;AAClC,4BAA4B,yBAAI;AAChC;AACA,8CAA8C,yBAAI;AAClD;AACA;AACA,8CAA8C,yBAAI;AAClD;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,aAAa;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAAe,mBAAG,SAAS,EAAC;;;ACpvB5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACyC;AACF;AACX;AACS;AACD;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAG;AACH;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,OAAO;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,YAAY;AAC5B,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB;AACA,gBAAgB,OAAO;AACvB,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA,4BAA4B,wBAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,kBAAkB,mBAAG,OAAO,mBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,wBAAK;AAC/B,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,UAAU;AAC9B;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,WAAW;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,kBAAkB,mBAAG,OAAO,mBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,oBAAoB,gBAAgB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,4BAA4B,mBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,OAAO;AACvB,gBAAgB,WAAW;AAC3B;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA,4BAA4B,mBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,UAAU;AAC9B;AACA;AACA;AACA;AACA,oBAAoB,UAAU;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,UAAU;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,uBAAQ;AAC9B;AACA,qBAAqB,uBAAQ;AAC7B,qBAAqB,uBAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,mBAAG;AACtE;AACA,+BAA+B,0BAAM,CAAC,wBAAK;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,0BAAM,CAAC,wBAAK;AACnD,0BAA0B;AAC1B,uCAAuC,0BAAM,CAAC,wBAAK;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA,wBAAwB,mBAAG;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,0BAAM,CAAC,wBAAK;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,uBAAQ;AACpC;AACA,uCAAuC,0BAAM,CAAC,wBAAK;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,wBAAwB;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA,iBAAiB,uBAAQ;AACzB,iBAAiB,uBAAQ;AACzB,iBAAiB,uBAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,sBAAsB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc,uBAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C;AAC/C,+CAA+C;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,uBAAQ,uCAAuC,mBAAG;AACtE;AACA;AACA,oBAAoB,uBAAQ,uCAAuC,mBAAG;AACtE;AACA;AACA;AACA;AACA,+CAA+C;AAC/C,+CAA+C;AAC/C,oBAAoB,uBAAQ,uCAAuC,mBAAG;AACtE;AACA;AACA,oBAAoB,uBAAQ,uCAAuC,mBAAG;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE,mBAAG;AACpE,iEAAiE,mBAAG;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,uBAAQ;AAChC;AACA;AACA,kBAAkB;AAClB,wBAAwB,uBAAQ;AAChC;AACA;AACA,kBAAkB;AAClB,wBAAwB,uBAAQ;AAChC;AACA;AACA,kBAAkB;AAClB,wBAAwB,uBAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,sBAAsB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,WAAW;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA,qDAAqD,SAAS;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,SAAS;AAC1D;AACA;AACA,gCAAgC,uBAAQ;AACxC;AACA;AACA;AACA;AACA,gCAAgC,mBAAG;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,0BAAM,CAAC,wBAAK;AAC/C;AACA;AACA;AACA;AACA,0CAA0C,wBAAK;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,uBAAQ;AACpB;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,OAAO;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA,kCAAkC;AAClC,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,sBAAsB;AACrC,eAAe,SAAS;AACxB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,OAAO;AACvB,gBAAgB,QAAQ;AACxB,gBAAgB,mBAAmB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,OAAO;AACvB,gBAAgB,QAAQ;AACxB,gBAAgB,gBAAgB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,gBAAgB,OAAO;AACvB,gBAAgB,QAAQ;AACxB,gBAAgB,gBAAgB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,uBAAQ;AACpB;AACA;AACA,gBAAgB,uBAAQ;AACxB;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA,kBAAkB;AAClB,oBAAoB,yBAAI;AACxB;AACA,wBAAwB,uBAAQ,oBAAoB,uBAAQ;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA,kBAAkB;AAClB,oBAAoB,yBAAI;AACxB;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,qBAAqB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA,gBAAgB,WAAW;AAC3B;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,wBAAK;AACtC,0BAA0B,wBAAK,iCAAiC,wBAAK;AACrE;AACA,oBAAoB,uBAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,wBAAK;AAClC;AACA;AACA,wBAAwB,YAAY;AACpC;AACA;AACA,wBAAwB,0BAAM;AAC9B,wBAAwB,wBAAK;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,wBAAK;AAClC;AACA;AACA,UAAU,8BAA8B,wBAAK,uBAAuB,yBAAI;AACxE;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,UAAU,sBAAsB,wBAAK;AACrC,wBAAwB,yBAAyB;AACjD;AACA;AACA,UAAU,8BAA8B,wBAAK;AAC7C;AACA;AACA;AACA,wBAAwB,YAAY;AACpC;AACA;AACA,wBAAwB,0BAAM;AAC9B,wBAAwB,wBAAK;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,SAAS,yBAAI;AACvB;AACA,wBAAwB,SAAS;AACjC,oBAAoB,yBAAI;AACxB;AACA;AACA,kBAAkB,SAAS,yBAAI;AAC/B;AACA,2CAA2C,0BAAM,CAAC,wBAAK;AACvD,kBAAkB,SAAS,yBAAI;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kCAAkC;AAClD;AACA;AACA,gBAAgB,kCAAkC;AAClD;AACA;AACA,gBAAgB,QAAQ;AACxB;AACA,gBAAgB,WAAW;AAC3B;AACA,gBAAgB,gBAAgB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,qBAAqB;AACrC;AACA;AACA;AACA;AACA;AACA,gBAAgB,oBAAoB;AACpC;AACA,4DAA4D,sDAAsD;AAClH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,oFAAoF;AACxG;AACA;AACA;AACA;AACA;AACA,oBAAoB,qBAAqB;AACzC;AACA;AACA;AACA;AACA;AACA,oBAAoB,oBAAoB;AACxC;AACA,gEAAgE,sDAAsD;AACtH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,0DAA0D;AAC1E;AACA;AACA,oBAAoB,uCAAuC;AAC3D;AACA,4DAA4D,sDAAsD;AAClH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,oFAAoF;AACxG;AACA;AACA;AACA;AACA,oBAAoB,0DAA0D;AAC9E;AACA;AACA,wBAAwB,uCAAuC;AAC/D;AACA;AACA,gEAAgE,sDAAsD;AACtH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,0DAA0D;AAC1E;AACA;AACA,oBAAoB;AACpB,4BAA4B,uBAAuB,WAAW,SAAS;AACvE;AACA,4DAA4D,sDAAsD;AAClH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,oFAAoF;AACxG;AACA;AACA;AACA;AACA,oBAAoB,0DAA0D;AAC9E;AACA;AACA,wBAAwB;AACxB,gCAAgC,uBAAuB,WAAW,SAAS;AAC3E;AACA;AACA,gEAAgE,sDAAsD;AACtH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA,wDAAwD,sDAAsD;AAC9G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,oFAAoF;AACxG,4DAA4D,sDAAsD;AAClH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,uBAAQ,mEAAmE,mBAAG;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,uBAAQ;AACpB,gBAAgB,mBAAG,OAAO,mBAAG;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,gBAAgB,kCAAkC;AAClD,gBAAgB,kCAAkC;AAClD,gBAAgB,WAAW;AAC3B;AACA,gBAAgB,gBAAgB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,qBAAqB;AACrC;AACA;AACA,oBAAoB,uCAAuC;AAC3D;AACA,4DAA4D,sDAAsD;AAClH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,oFAAoF;AACxG;AACA;AACA;AACA;AACA,oBAAoB,qBAAqB;AACzC;AACA;AACA,wBAAwB,uCAAuC;AAC/D;AACA;AACA,gEAAgE,sDAAsD;AACtH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,gBAAgB,kCAAkC;AAClD,gBAAgB,kCAAkC;AAClD,gBAAgB,WAAW;AAC3B;AACA,gBAAgB,gBAAgB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,qBAAqB;AAC7C;AACA,yDAAyD,6BAA6B;AACtF;AACA;AACA,8BAA8B,sDAAsD;AACpF;AACA,wDAAwD,sDAAsD;AAC9G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,oFAAoF;AACxG;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,qBAAqB;AACjD;AACA,6DAA6D,6BAA6B;AAC1F;AACA;AACA,kCAAkC,sDAAsD;AACxF;AACA;AACA,4DAA4D,sDAAsD;AAClH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kCAAkC;AAClD,gBAAgB,kCAAkC;AAClD,gBAAgB,WAAW;AAC3B;AACA,gBAAgB,gBAAgB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,uCAAuC;AAC3D;AACA;AACA;AACA;AACA;AACA,gBAAgB,0DAA0D;AAC1E;AACA,4DAA4D,sDAAsD;AAClH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,oFAAoF;AACxG;AACA,wBAAwB,uCAAuC;AAC/D;AACA;AACA;AACA;AACA;AACA,oBAAoB,0DAA0D;AAC9E;AACA;AACA,gEAAgE,sDAAsD;AACtH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD;AACtD;AACA,2CAAe,mBAAG,KAAK,EAAC;;;AC9pExB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACA;AACQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAG;AACH;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA,mBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH,IAAI,mBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,oBAAoB;AAC/B,WAAW,QAAQ;AACnB,WAAW,OAAO;AAClB;AACA,mBAAG;AACH;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA;AACA,+BAA+B,sBAAsB;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA,kBAAG;AACH,IAAI,mBAAG;AACP;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,2BAA2B;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,oBAAoB;AAC/B,WAAW,QAAQ;AACnB;AACA,mBAAG;AACH,8BAA8B;AAC9B;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI,gBAAgB,yBAAI;AAChC;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH,IAAI,mBAAG;AACP;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,2BAA2B;AACnD,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,wBAAwB;AAC3C,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,iDAAiD;AACpE;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,oBAAoB,yBAAI;AACxB;AACA;AACA,kBAAkB;AAClB;AACA,gCAAgC,yBAAyB;AACzD;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,iDAAiD;AACpE;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,oBAAoB,yBAAI;AACxB;AACA;AACA,kBAAkB;AAClB;AACA,gCAAgC,yBAAyB;AACzD;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAG;AACvB;AACA,wBAAwB,2BAA2B;AACnD;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,2BAA2B;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAAe,mBAAG,KAAK,EAAC;;;ACzTxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACpC;AACA;AACA,2CAA2C,YAAY;AACvD,wEAAwE,aAAa;AACrF;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,oBAAoB;AACvC,qBAAqB,aAAa;AAClC;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,oBAAoB;AACvC,qBAAqB,aAAa;AAClC;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,oBAAoB;AACvC;AACA,qBAAqB,aAAa;AAClC;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,oBAAoB;AACvC;AACA,qBAAqB,aAAa;AAClC;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,aAAa;AAClC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+EAA+E,kBAAkB;AACjG;AACA;AACA,gCAAgC,kBAAkB;AAClD;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,WAAW,oBAAoB;AAC/B,WAAW,oBAAoB;AAC/B,aAAa,aAAa;AAC1B;AACA,kBAAG;AACH,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,oBAAoB;AAC/B,WAAW,oBAAoB;AAC/B,aAAa,aAAa;AAC1B;AACA,kBAAG;AACH,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,oBAAoB;AAC/B,WAAW,oBAAoB;AAC/B,aAAa,aAAa;AAC1B;AACA,kBAAG;AACH,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,oBAAoB;AAC/B,WAAW,oBAAoB;AAC/B,aAAa,aAAa;AAC1B;AACA,kBAAG;AACH,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,oBAAoB;AAC/B,aAAa,aAAa;AAC1B;AACA,kBAAG;AACH,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,oBAAoB;AAC/B,aAAa,QAAQ;AACrB;AACA,kBAAG;AACH,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,oBAAoB;AAC/B,aAAa,QAAQ;AACrB;AACA,kBAAG;AACH,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,oBAAoB;AAC/B,aAAa;AACb;AACA,kBAAG;AACH,eAAe,kBAAG;AAClB;AACA;AACA,kBAAG,aAAa,kBAAG;AACnB;AACA,8CAAe,kBAAG,QAAQ,EAAC;;;;;AC1V3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACG;AACE;AACP;AACS;AACP;AACF;AAClC;AACA;AACA;AACA,yDAAyD,sBAAsB,GAAG,sBAAsB;AACxG,QAAQ,0BAA0B;AAClC;AACA,yDAAyD,yBAAyB;AAClF;AACA;AACA;AACA;AACA,yEAAyE,gBAAgB,GAAG,eAAe;AAC3G,YAAY,iBAAiB;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,eAAe;AACvE;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,YAAY,iBAAiB,YAAY;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,mCAAmC;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA,kDAAkD,8CAA8C;AAChG,mBAAmB,qBAAqB;AACxC,mBAAmB,QAAQ,OAAO,uDAAuD,uBAAuB;AAChH;AACA,mBAAmB,SAAS,2BAA2B,8CAA8C;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI,sBAAsB,yBAAI;AAC/C;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,iCAAiC,gBAAgB;AACjD,mBAAmB,WAAW,mBAAmB,iBAAiB;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,0BAAO;AAC9B;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,0BAA0B;AAC/D;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,oFAAoF,gBAAgB;AACpG,mBAAmB,WAAW,mBAAmB,iBAAiB;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,0BAAO;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,4BAA4B;AACrE;AACA;AACA,SAAS;AACT;AACA;AACA,mCAAmC,gBAAgB;AACnD;AACA;AACA;AACA,mBAAmB,WAAW,mBAAmB,iBAAiB;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,gCAAgC,gBAAgB;AAChD,mBAAmB,UAAU;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,oFAAoF,eAAe;AACnG,mBAAmB,UAAU,qBAAqB,gBAAgB;AAClE;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C;AAC/C;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,oBAAoB,iBAAiB,QAAQ,gBAAgB;AAC7D,mBAAmB,WAAW;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,oFAAoF,gBAAgB;AACpG,mBAAmB,WAAW,mBAAmB,iBAAiB;AAClE;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C;AAC/C;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,wBAAK;AACzC;AACA,cAAc,6BAA6B,wBAAK;AAChD;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA,yBAAyB,mBAAG;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA,kBAAkB;AAClB,4CAA4C,wBAAK;AACjD;AACA,sBAAsB;AACtB;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA,kBAAkB;AAClB,4CAA4C,wBAAK;AACjD;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA,qCAAqC,yBAAI;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA,sBAAsB;AACtB;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA,qCAAqC,yBAAI;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA,sBAAsB;AACtB;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,UAAU;AAC7B,mBAAmB,QAAQ;AAC3B;AACA,qBAAqB,sBAAsB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,0BAAM,CAAC,wBAAK;AACjC,qBAAqB,0BAAM,CAAC,wBAAK;AACjC;AACA,YAAY,uBAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,qBAAqB,sBAAsB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,UAAU;AAC9B,oBAAoB,YAAY,kDAAkD,qCAAqC;AACvH,oBAAoB,YAAY,mDAAmD,qCAAqC;AACxH,oBAAoB,SAAS,WAAW,mCAAmC;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,wBAAK;AACrC;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,oBAAoB,wBAAK;AACzB;AACA;AACA;AACA;AACA;AACA,oBAAoB,wBAAK;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,YAAY;AAC/B,mBAAmB,YAAY;AAC/B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,wBAAK;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,wBAAK;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,wBAAK;AACzB;AACA;AACA;AACA;AACA;AACA,oBAAoB,wBAAK;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,QAAQ;AAC3B,qBAAqB,sBAAsB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,UAAU;AAC7B;AACA;AACA;AACA;AACA,oCAAoC,YAAY;AAChD;AACA;AACA;AACA;AACA;AACA,mBAAmB,UAAU;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,mBAAmB,aAAa,MAAM,eAAe;AACrD;AACA,mBAAmB,WAAW;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,YAAY;AACjD;AACA;AACA;AACA;AACA,oBAAoB;AACpB,mBAAmB,YAAY,mBAAmB,kBAAkB;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,iDAAiD,kBAAkB,QAAQ,gBAAgB;AAC3F,mBAAmB,YAAY,mBAAmB,kBAAkB;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D,mBAAG;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,oBAAoB,mBAAmB,QAAQ,gBAAgB;AAC/D,mBAAmB,aAAa;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,oCAAoC,kBAAkB;AACtD,mBAAmB,aAAa,mBAAmB,mBAAmB;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,0BAA0B;AAC/D;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA,qDAAqD,YAAY;AACjE;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA,gDAAgD,YAAY;AAC5D;AACA;AACA,kCAAkC,gBAAgB;AAClD;AACA;AACA,mBAAmB,UAAU,mBAAmB,gBAAgB;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,YAAY;AACtD;AACA;AACA,6DAA6D,gBAAgB;AAC7E,mBAAmB,UAAU,oBAAoB,gBAAgB;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,YAAY;AACxD;AACA;AACA,uBAAuB,gBAAgB,QAAQ,iBAAiB;AAChE,mBAAmB,UAAU,oBAAoB,gBAAgB;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA,8GAA8G;AAC9G;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,yBAAI;AAC1C;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,6DAA6D,gBAAgB;AAC7E,mBAAmB,UAAU,oBAAoB,gBAAgB;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,yBAAI;AAChD;AACA,8BAA8B;AAC9B,4CAA4C,yBAAI;AAChD,4CAA4C,yBAAI;AAChD;AACA;AACA,8BAA8B;AAC9B;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B,gCAAgC,kBAAG;AACnC;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC;AACrC;AACA;AACA,8BAA8B;AAC9B,gCAAgC,kBAAG;AACnC;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B,gCAAgC,kBAAG;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB,aAAa,gBAAgB,GAAG,4BAA4B;AAC5D;AACA,oBAAoB,QAAQ;AAC5B,oBAAoB,iBAAiB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,yBAAI,2BAA2B,gBAAgB;AACtE;AACA;AACA,wBAAwB,SAAS;AACjC,oBAAoB,yBAAI;AACxB;AACA,0BAA0B,yBAAI;AAC9B;AACA;AACA,yBAAyB;AACzB;AACA,0BAA0B,yBAAI;AAC9B,iCAAiC,oBAAoB;AACrD;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,0FAA0F,gBAAgB;AAC1G;AACA,mBAAmB,UAAU,qBAAqB,gBAAgB;AAClE,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,kBAAG;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,cAAc;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,aAAa;AAChD,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,aAAa;AACpD,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA,sBAAsB;AACtB;AACA,uCAAuC,aAAa;AACpD,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,iBAAiB,YAAY;AAClD;AACA,mBAAmB,WAAW;AAC9B;AACA;AACA;AACA;AACA,mCAAmC,YAAY;AAC/C;AACA;AACA,yCAAyC,iBAAiB;AAC1D,mBAAmB,WAAW,oBAAoB,iBAAiB;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,0BAA0B;AAC/D,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,OAAO;AAC1B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC,oBAAoB,mBAAG;AACvB;AACA;AACA,gBAAgB,mBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,oBAAoB,MAAM,iBAAiB,IAAI,gBAAgB;AAClF,mBAAmB,OAAO,6BAA6B,0BAA0B;AACjF;AACA;AACA,wDAAwD,YAAY;AACpE;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B;AACA;AACA,wCAAwC,YAAY;AACpD;AACA;AACA,8CAA8C,iBAAiB;AAC/D;AACA;AACA;AACA;AACA;AACA,mBAAmB,UAAU,qBAAqB,iBAAiB;AACnE,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,2CAA2C,YAAY;AACvD;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,MAAM;AACzB,mBAAmB,QAAQ;AAC3B,YAAY,6BAA6B;AACzC;AACA,kDAAkD,YAAY;AAC9D;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,QAAQ;AAC3B;AACA,oDAAoD,YAAY;AAChE;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,MAAM;AAC3B;AACA,0CAA0C,yBAAyB;AACnE;AACA;AACA;AACA,mBAAmB,MAAM;AACzB;AACA,kCAAkC,YAAY;AAC9C;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,QAAQ;AAC3B;AACA;AACA,+CAA+C,YAAY;AAC3D;AACA;AACA;AACA,mBAAmB,MAAM;AACzB,mBAAmB,QAAQ;AAC3B,mBAAmB,MAAM;AACzB;AACA,6DAA6D,YAAY;AACzE;AACA;AACA;AACA;AACA,mBAAmB,MAAM;AACzB,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA,2DAA2D,YAAY;AACvE;AACA;AACA;AACA;AACA,mBAAmB,MAAM;AACzB,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,WAAW;AAC9B;AACA,qEAAqE,YAAY;AACjF;AACA;AACA;AACA;AACA,mBAAmB,MAAM;AACzB,mBAAmB,QAAQ;AAC3B;AACA,mBAAmB,WAAW;AAC9B;AACA,6DAA6D,YAAY;AACzE;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,QAAQ;AAC3B;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA,2DAA2D,YAAY;AACvE;AACA;AACA,6CAA6C,iBAAiB;AAC9D;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA,8CAA8C,YAAY;AAC1D;AACA;AACA,6CAA6C,iBAAiB;AAC9D;AACA;AACA;AACA,oBAAoB,qBAAqB;AACzC;AACA,oDAAoD,YAAY;AAChE;AACA;AACA;AACA,mBAAmB,MAAM;AACzB,mBAAmB,aAAa,+BAA+B;AAC/D;AACA,iDAAiD,YAAY;AAC7D;AACA;AACA;AACA,mBAAmB,MAAM;AACzB,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA,sDAAsD,YAAY;AAClE;AACA;AACA;AACA;AACA,oDAAoD;AACpD,mBAAmB,qBAAqB;AACxC,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,2CAA2C;AAC3C;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA;AACA;AACA,8BAA8B,YAAY;AAC1C;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,SAAS;AAC5B;AACA;AACA,qBAAqB,sBAAsB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,wBAAK;AACrC;AACA;AACA,gCAAgC,uBAAuB;AACvD;AACA;AACA,kBAAkB;AAClB,4CAA4C,wBAAK;AACjD;AACA,sBAAsB,qBAAqB,wBAAK;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,wBAAK;AACjD,4CAA4C,wBAAK;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,sEAAsE,qCAAqC;AAC3G,mBAAmB,qBAAqB;AACxC,qBAAqB,sBAAsB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,wBAAK;AACrC;AACA,gCAAgC,uBAAuB;AACvD;AACA;AACA,kBAAkB;AAClB,4CAA4C,wBAAK;AACjD;AACA,sBAAsB,qBAAqB,wBAAK;AAChD;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,wBAAK;AAC7C,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA;AACA;AACA,4BAA4B,wBAAK;AACjC;AACA,cAAc;AACd,gCAAgC,wBAAK;AACrC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,YAAY,uEAAuE;AACnF;AACA;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA;AACA,gCAAgC,YAAY;AAC5C;AACA;AACA;AACA,4FAA4F;AAC5F;AACA,mBAAmB,MAAM;AACzB,mBAAmB,QAAQ;AAC3B,cAAc,8EAA8E;AAC5F;AACA,8CAA8C,YAAY;AAC1D;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA,mBAAmB,QAAQ;AAC3B;AACA,+CAA+C,YAAY;AAC3D;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA,sCAAsC,YAAY;AAClD;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,wBAAK;AACjC;AACA,cAAc;AACd,wCAAwC,wBAAK;AAC7C;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,sBAAsB;AACzC;AACA,qCAAqC,YAAY;AACjD;AACA;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,QAAQ;AAC3B;AACA;AACA,yCAAyC,YAAY;AACrD;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,QAAQ;AAC3B;AACA,mBAAmB,QAAQ;AAC3B;AACA,4DAA4D,YAAY;AACxE;AACA;AACA;AACA,mBAAmB,qBAAqB,qBAAqB,2BAA2B;AACxF;AACA,mBAAmB,QAAQ;AAC3B;AACA,mBAAmB,QAAQ;AAC3B;AACA,8DAA8D,YAAY;AAC1E;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,QAAQ;AAC3B;AACA,qDAAqD,YAAY;AACjE;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA,uDAAuD,YAAY;AACnE;AACA;AACA;AACA,mBAAmB,MAAM;AACzB,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA,qDAAqD,YAAY;AACjE;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA,mCAAmC,YAAY;AAC/C;AACA;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA,qCAAqC,YAAY;AACjD;AACA;AACA,iDAAiD;AACjD;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA;AACA;AACA,8BAA8B,YAAY;AAC1C;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA,wCAAwC,YAAY;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,YAAY;AACjD;AACA;AACA;AACA;AACA;AACA,uCAAuC,YAAY;AACnD;AACA;AACA;AACA,mFAAmF,SAAS;AAC5F;AACA,6EAA6E,SAAS;AACtF;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE;AAClE;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA,yBAAyB;AACzB;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yFAAyF;AACzF,yFAAyF;AACzF;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,oBAAoB,yBAAI,gBAAgB,yBAAI;AAC5C;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,uCAAuC,kEAAkE;AACzG;AACA,mBAAmB,SAAS;AAC5B,qBAAqB,UAAU;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA,kCAAkC,YAAY;AAC9C;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,0CAA0C,YAAY;AACtD;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,uCAAuC,YAAY;AACnD;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,uCAAuC,YAAY;AACnD;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,OAAO;AAC1B;AACA,8CAA8C,YAAY;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,YAAY;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAAgE,YAAY;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC;AACA;AACA;AACA;AACA,wDAAe,kBAAG,iBAAiB,EAAC;;;ACnxEpC;AACA;AACA;AAC4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,QAAQ,kBAAG;AACd;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAe,kBAAG,UAAU,EAAC;;;AC5O7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACS;AACrC;AACA;AACA;AACA;AACA;AACA,kBAAG,QAAQ,kBAAG;AACd;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB;AACjB,gBAAgB,OAAO;AACvB;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,cAAQ;AAC3B;AACA;AACA;AACA,oBAAoB,kBAAkB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,SAAS,qCAAqC,4BAA4B;AACzF;AACA,gBAAgB,OAAO;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,cAAQ;AAC7B;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAAe,kBAAG,YAAY,EAAC;;;ACnO/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACM;AACE;AACQ;AACJ;AACxC;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,WAAW;AAC1B,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB,eAAe,UAAU;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD;AACtD,cAAc;AACd,oDAAoD;AACpD;AACA,UAAU;AACV;AACA;AACA,cAAc;AACd;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA,4BAA4B,cAAQ;AACpC;AACA;AACA,+BAA+B,MAAM;AACrC,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yBAAI;AACtB;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,MAAM;AACrB,eAAe,WAAW;AAC1B,eAAe,QAAQ;AACvB,eAAe,SAAS;AACxB,eAAe,UAAU;AACzB;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yBAAI;AACtB;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA;AACA,oEAAoE;AACpE,eAAe,QAAQ;AACvB,eAAe,oBAAoB;AACnC,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,SAAS;AACxB,eAAe,UAAU;AACzB;AACA;AACA,YAAY,yBAAI;AAChB;AACA,UAAU;AACV;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,WAAW;AAC1B,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,UAAU;AACzB;AACA;AACA;AACA;AACA;AACA,iBAAiB,kBAAG;AACpB;AACA,YAAY,yBAAI;AAChB;AACA;AACA,UAAU;AACV,UAAU;AACV;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK,kBAAG;AACR,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAe,kBAAG,WAAW,EAAC;;;;;;;;;AC/R9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACpC;AACA;AACA,kEAAkE,0BAA0B;AAC5F,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA,oBAAoB,wCAAwC;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,sCAAsC;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yCAAyC;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,0CAA0C;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kCAAkC;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,sCAAsC;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,qCAAqC;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,uCAAuC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,2BAA2B;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA,mBAAmB,qCAAqC;AACxD;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA,iBAAiB,yBAAI,uBAAuB,yBAAI;AAChD,oBAAoB,yBAAI;AACxB;AACA,kBAAkB;AAClB;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,gBAAgB,yBAAI,QAAQ,kBAAG;AAC/B,uBAAuB,kBAAG;AAC1B;AACA;AACA,uBAAuB,kBAAG;AAC1B,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAe,kBAAG,YAAY,EAAC;;;ACrR/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACO;AACF;AACG;AACO;AACT;AACS;AACF;AACM;AACE;AACX;AACF;AACS;AACX;AACS;AAC3C;AACA;AACA;AACA;AACA;AACA,eAAe,8BAA8B;AAC7C;AACA,WAAW,eAAe;AAC1B;AACA;AACA,WAAW,sBAAsB;AACjC,WAAW,QAAQ;AACnB,WAAW,YAAY;AACvB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ,2CAA2C;AAC9D;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,uBAAuB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA,MAAM,SAAS,kBAAG;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA,QAAQ,yBAAI;AACZ;AACA,oCAAoC;AACpC,6BAA6B,kBAAG;AAChC;AACA,MAAM,SAAS,kBAAG;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,kBAAG;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI,4BAA4B,kBAAG,eAAe,yBAAI;AAC9D;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,yBAAI,UAAU,0BAAO,IAAI;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,yBAAI,QAAQ,kBAAG;AACxD,QAAQ,yBAAI,yBAAyB,kBAAG;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yBAAU;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,0BAAY;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sEAAsE,mCAAmC;AACzG,WAAW,sBAAsB,QAAQ,iCAAiC;AAC1E,QAAQ,mCAAmC;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,uBAAuB;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,iCAAiC;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,wBAAK;AACvC;AACA;AACA;AACA,uCAAuC,wBAAK;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,oCAAoC;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,qBAAqB;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC,sBAAsB,kBAAG,OAAO;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,aAAa,yBAAI;AACjB;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA,wBAAwB,gBAAgB,iDAAiD;AACzF,sEAAsE,kBAAkB;AACxF,4EAA4E,kBAAkB;AAC9F;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,wBAAK;AACrC;AACA;AACA;AACA,gBAAgB,yBAAI,oBAAoB,yBAAI;AAC5C;AACA;AACA;AACA;AACA,cAAc,yBAAyB,wBAAK;AAC5C;AACA,gCAAgC,UAAU,WAAW,WAAW,aAAa,UAAU,SAAS,WAAW,UAAU,WAAW,YAAY;AAC5I,yBAAyB,QAAQ,QAAQ,aAAa,QAAQ,SAAS,WAAW,SAAS,aAAa,SAAS,SAAS,SAAS,WAAW;AAC9I;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,iBAAiB,yBAAI;AACrB,wCAAwC,wBAAK;AAC7C,gCAAgC,wBAAK;AACrC;AACA,oCAAoC,wBAAK;AACzC,8BAA8B;AAC9B,kBAAkB,iCAAiC,wBAAK;AACxD,8BAA8B;AAC9B,kBAAkB,iCAAiC,wBAAK;AACxD,8BAA8B;AAC9B,kBAAkB;AAClB,8BAA8B;AAC9B;AACA,yBAAyB;AACzB;AACA;AACA,wBAAwB,mBAAmB;AAC3C;AACA;AACA;AACA;AACA,qCAAqC,mCAAmC;AACxE;AACA;AACA,4CAA4C,OAAO;AACnD;AACA;AACA;AACA,yBAAyB,yBAAI;AAC7B;AACA;AACA;AACA;AACA;AACA,4BAA4B,mBAAmB;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA,mBAAmB,yBAAI,QAAQ,kBAAG;AAClC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,0CAA0C;AAC1C;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,yBAAI;AACpC;AACA,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA,wBAAwB,yBAAI;AAC5B,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,kBAAG;AAC9B,2BAA2B,kBAAG;AAC9B;AACA;AACA;AACA;AACA,+BAA+B,kBAAG;AAClC,+BAA+B,kBAAG;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,kBAAG;AACtB;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,2BAA2B,kBAAG;AAC9B,2BAA2B,kBAAG;AAC9B;AACA,2BAA2B,kBAAG;AAC9B,2BAA2B,kBAAG;AAC9B;AACA,2BAA2B,kBAAG;AAC9B,2BAA2B,kBAAG;AAC9B;AACA;AACA;AACA,2BAA2B,kBAAG;AAC9B,2BAA2B,kBAAG;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,kBAAG;AAC1B,uBAAuB,kBAAG;AAC1B;AACA;AACA;AACA;AACA,2BAA2B,kBAAG;AAC9B,2BAA2B,kBAAG;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,cAAc;AACjC,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,0IAA0I;AAClK;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,cAAc;AACjC,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B;AACA,qBAAqB,OAAO,iEAAiE;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,kBAAG;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,mBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,WAAW;AACtC;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,UAAU;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,yBAAI,sCAAsC,wBAAK;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,yBAAI;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,yBAAI;AACpC,4DAA4D,wBAAK;AACjE;AACA;AACA,gDAAgD,yBAAU;AAC1D,kCAAkC;AAClC;AACA,gDAAgD,yBAAU;AAC1D;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,yBAAI;AACpD,wCAAwC,yBAAI;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ,qCAAqC,iBAAiB,IAAI,kBAAkB;AACvG,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA,6BAA6B,0BAAM;AACnC,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,yBAAU;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,yCAAyC,wBAAK;AAC9C,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,wBAAK;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ,qCAAqC,kBAAkB;AAClF,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA,gBAAgB,yBAAI,cAAc,yBAAI;AACtC;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,sCAAsC,wBAAK;AAC3C,8BAA8B,wBAAK;AACnC;AACA;AACA,cAAc,+BAA+B,wBAAK;AAClD;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,SAAS;AAC5B,mBAAmB,SAAS;AAC5B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,0BAAM,CAAC,wBAAK;AAClC;AACA;AACA,sBAAsB,0BAAM,CAAC,wBAAK;AAClC;AACA;AACA;AACA,sBAAsB,0BAAM,CAAC,wBAAK;AAClC;AACA;AACA,sBAAsB,0BAAM,CAAC,wBAAK;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO,2CAA2C,0BAA0B;AAC/F,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,iBAAiB;AACnE;AACA;AACA,0CAA0C,wBAAK;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,uBAAuB,wBAAK;AAC9C;AACA;AACA,gCAAgC,kBAAkB;AAClD;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO,2CAA2C,0BAA0B;AAC/F,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,0BAA0B,0BAAM,CAAC,wBAAK;AACtC;AACA;AACA,yBAAyB,0BAAM,CAAC,wBAAK;AACrC;AACA;AACA,yBAAyB,0BAAM,CAAC,wBAAK;AACrC;AACA,wBAAwB,uBAAQ;AAChC;AACA;AACA;AACA;AACA,iBAAiB;AACjB,yDAAyD,gBAAgB;AACzE;AACA;AACA,wBAAwB,uBAAQ,qBAAqB,uBAAQ;AAC7D,4DAA4D,eAAe;AAC3E;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA;AACA,yBAAyB,UAAU;AACnC;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,yBAAI;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,UAAU;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,wBAAK;AAClC;AACA,cAAc,8BAA8B,wBAAK;AACjD;AACA;AACA,cAAc,8BAA8B,wBAAK;AACjD;AACA;AACA;AACA;AACA,cAAc,sBAAsB,wBAAK;AACzC;AACA,4BAA4B,SAAS;AACrC;AACA;AACA,cAAc,sBAAsB,wBAAK;AACzC;AACA;AACA;AACA,cAAc,SAAS,yBAAI,8BAA8B,wBAAK;AAC9D;AACA,cAAc,8BAA8B,wBAAK;AACjD;AACA;AACA;AACA,uCAAuC,SAAS;AAChD;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,kBAAkB;AAClB,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,oBAAoB,WAAW;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,oBAAoB,aAAa;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,oBAAoB,MAAM;AAC1B;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,SAAS;AAC9B;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA,gFAAgF,oBAAoB,cAAc;AAClH;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB,qBAAqB,kEAAkE;AACvF;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,kBAAG;AACrD,4BAA4B,gCAAgC;AAC5D;AACA;AACA;AACA,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA,4BAA4B,kBAAG;AAC/B,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA,4BAA4B,kBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,kBAAG;AAC/C;AACA;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB,kBAAkB;AAClB,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,0CAA0C,kBAAG;AAC7C;AACA;AACA,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA,0CAA0C,kBAAG;AAC7C;AACA;AACA,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,0CAA0C,kBAAG;AAC7C,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,kBAAG;AACvD,4BAA4B,QAAQ;AACpC,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,2EAA2E,kBAAG;AAC9E,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,4CAA4C,kBAAG;AAC/C,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,kBAAG;AACtD,4BAA4B,QAAQ;AACpC,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,2CAA2C,kBAAG;AAC9C;AACA;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB,kBAAkB;AAClB,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA,wBAAwB,kBAAG;AAC3B,sBAAsB;AACtB,wBAAwB,kBAAG;AAC3B,wBAAwB,kBAAG;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,yCAAyC,kBAAG;AAC5C;AACA;AACA,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB;AACA;AACA,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,yCAAyC,kBAAG;AAC5C;AACA;AACA,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB;AACA;AACA,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,uBAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,uBAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,0BAAM,CAAC,wBAAK;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,OAAO;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,uBAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B,oBAAoB,SAAS;AAC7B;AACA,oBAAoB,gBAAgB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D,+BAA+B;AAC3F;AACA,oBAAoB,QAAQ;AAC5B,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,0DAA0D,+BAA+B;AACzF;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA,uCAAuC,gCAAgC;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,2CAA2C,+BAA+B;AAC1E;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,wBAAwB,gCAAgC;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,+CAA+C,+BAA+B;AAC9E;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA,+BAA+B,gCAAgC;AAC/D;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,SAAS;AAC5B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI,uBAAuB,yBAAI;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB,kBAAkB;AAClB;AACA,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,yBAAI;AAC/C;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAyB;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kBAAG;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA,iBAAiB,yBAAI,4CAA4C,yBAAI;AACrE;AACA,iBAAiB,yBAAI,8CAA8C,yBAAI;AACvE;AACA,wCAAwC;AACxC,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB;AACrB;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,gCAAgC,yBAAyB;AACzD;AACA;AACA,oCAAoC,yBAAyB;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAyB;AACrD;AACA,gCAAgC,yBAAyB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,sDAAsD,QAAQ;AAC9D;AACA,gCAAgC,yBAAyB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,yBAAI;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,yBAAI;AACjC,6BAA6B,yBAAI;AACjC,6BAA6B,yBAAI;AACjC,6BAA6B,yBAAI;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB,kBAAkB;AAClB,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,YAAY,mCAAmC;AAC/C;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA,2CAA2C;AAC3C;AACA;AACA,2CAA2C,yBAAI;AAC/C;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,uBAAuB;AAC/C;AACA;AACA;AACA,wBAAwB,yBAAyB;AACjD;AACA,4BAA4B,yBAAyB;AACrD;AACA;AACA;AACA;AACA,oCAAoC,uBAAuB;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,wBAAwB,kBAAG;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,kBAAG;AAC3B,+DAA+D,0BAAO;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,uBAAuB;AAC/C;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC,iDAAiD,wBAAK;AACtD,yCAAyC,wBAAK;AAC9C,yCAAyC,wBAAK;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,4BAA4B;AAC5E;AACA,0BAA0B;AAC1B,iDAAiD,wBAAK;AACtD,iDAAiD,wBAAK;AACtD,iDAAiD,wBAAK;AACtD,yCAAyC,wBAAK;AAC9C;AACA;AACA;AACA;AACA,wCAAwC,yBAAyB;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,4BAA4B;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,uBAAuB;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,oCAAoC,yBAAyB;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,4BAA4B,yBAAyB;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,uBAAuB;AACnD;AACA;AACA;AACA,4BAA4B,uBAAuB;AACnD;AACA;AACA;AACA;AACA;AACA,gCAAgC,yBAAyB;AACzD;AACA,oCAAoC,uBAAuB;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA,sBAAsB,4CAA4C,wBAAK;AACvE;AACA;AACA;AACA,sBAAsB,4CAA4C,wBAAK;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,oCAAoC,yBAAyB;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,kDAAkD,QAAQ;AAC1D;AACA,4BAA4B,yBAAyB;AACrD;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,yBAAI;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA,2CAA2C,yBAAI;AAC/C;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,4BAA4B,6BAA6B;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,OAAO;AACrB,0BAA0B,0BAAM,CAAC,wBAAK;AACtC;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,kBAAkB;AAClB;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,kBAAkB;AAClB;AACA;AACA,kBAAkB;AAClB;AACA;AACA,kBAAkB;AAClB;AACA;AACA,cAAc,kDAAkD;AAChE;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,kBAAkB;AAClB;AACA;AACA,kBAAkB;AAClB;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,yBAAI;AAC7B,gDAAgD,wBAAK;AACrD;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B,uCAAuC,kBAAG;AAC1C;AACA,sBAAsB;AACtB;AACA;AACA,4BAA4B,wBAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA,oCAAoC;AACpC;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kBAAG;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B,4BAA4B,kBAAG,aAAa;AAC5C;AACA,0BAA0B;AAC1B;AACA;AACA,qBAAqB;AACrB;AACA,aAAa;AACb;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kBAAG;AACpB;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kBAAG;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,SAAS;AACT;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kBAAG;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,cAAc;AACd,gBAAgB,kBAAG;AACnB;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,gBAAgB;AACnC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB,2DAA2D;AAC3D;AACA,2GAA2G,cAAc;AACzH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,+DAA+D;AAC/D,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA,sDAAsD;AACtD;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yBAAI;AACtB;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B,gCAAgC,yBAAI;AACpC,gCAAgC,yBAAI;AACpC;AACA,sBAAsB,SAAS,yBAAI;AACnC;AACA;AACA;AACA,0BAA0B;AAC1B,gCAAgC,yBAAI;AACpC,gCAAgC,yBAAI;AACpC;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA,mEAAmE,wBAAK;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,qBAAqB;AACxC,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,qBAAqB;AACxC,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D;AAC7D;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA,iEAAiE,wBAAwB;AACzF;AACA,+DAA+D,wBAAwB;AACvF,oBAAoB;AACpB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA,qEAAqE,wBAAwB;AAC7F;AACA,mEAAmE,wBAAwB;AAC3F,wBAAwB;AACxB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,kBAAG;AAC5B;AACA;AACA,gCAAgC,0BAAM,CAAC,wBAAK;AAC5C;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA,yBAAyB,kBAAG;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,UAAU;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA,yBAAyB,UAAU;AACnC;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,sBAAsB;AACtB;AACA;AACA,0BAA0B;AAC1B;AACA,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,SAAS;AAC5B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA,gBAAgB,yBAAI,cAAc,yBAAI;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,0BAAM,CAAC,wBAAK;AACrC,yBAAyB,0BAAM;AAC/B,oBAAoB,wBAAK;AACzB;AACA;AACA;AACA;AACA,qDAAqD,mBAAG;AACxD,qDAAqD,mBAAG;AACxD,qDAAqD,mBAAG;AACxD,qDAAqD,mBAAG;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,wBAAK;AACvD,0BAA0B;AAC1B,kDAAkD,wBAAK;AACvD;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,YAAY;AACrD;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B,gCAAgC,0BAAK;AACrC;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C;AAC5C;AACA;AACA;AACA,yCAAyC;AACzC,yCAAyC,uBAAuB;AAChE,yCAAyC,yBAAI;AAC7C;AACA;AACA;AACA;AACA,oCAAoC;AACpC,wBAAwB,yBAAI;AAC5B;AACA;AACA,qBAAqB,yBAAI;AACzB,oBAAoB,kBAAG;AACvB,kBAAkB;AAClB,0EAA0E;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,kBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,sBAAsB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,2BAA2B,yBAAI;AAC/B,wBAAwB,yBAAI;AAC5B,wBAAwB,yBAAI;AAC5B;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,8BAA8B,yBAAI;AAClC;AACA;AACA;AACA,cAAc;AACd,8BAA8B,yBAAI;AAClC;AACA;AACA,qBAAqB,0BAAM,CAAC,wBAAK;AACjC,qBAAqB,0BAAM;AAC3B,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB,sBAAsB,yBAAI;AAC1B;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB,sBAAsB,yBAAI,iCAAiC,yBAAI,wCAAwC;AACvG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI,gBAAgB,yBAAI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA,qBAAqB,yBAAI,iCAAiC,yBAAI,wCAAwC;AACtG;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI,gBAAgB,yBAAI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,UAAU;AACnC;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA,wBAAwB,qBAAqB;AAC7C;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,2BAA2B;AAC9C;AACA,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,4BAA4B,mBAAmB;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI,mBAAmB,yBAAI;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,yBAAI;AACpC,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,SAAS,yBAAI;AAC/B;AACA;AACA;AACA;AACA,gCAAgC,yBAAI;AACpC,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,6BAA6B;AACvE;AACA;AACA,kBAAkB,yBAAyB,wBAAK;AAChD,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA,cAAc;AACd,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,2BAA2B;AAC9C;AACA,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,4BAA4B,mBAAmB;AAC/C;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,4BAA4B,mCAAmC;AAC/D;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,SAAS;AAC5B,mBAAmB,SAAS;AAC5B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,uCAAuC,yBAAI;AAC3C;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,kBAAkB,qBAAqB;AACvC,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,UAAU;AACnC;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,wBAAK;AAC5D;AACA,oCAAoC,wBAAwB;AAC5D;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,8BAA8B;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,8BAA8B;AACvD;AACA,iEAAiE,wBAAK;AACtE;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,cAAc;AACd,6BAA6B,UAAU;AACvC;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,mCAAmC;AAChE;AACA;AACA;AACA,4DAA4D,SAAS;AACrE;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,WAAW;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,WAAW;AACpC;AACA;AACA;AACA,2BAA2B,SAAS;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,WAAW;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,uBAAuB,oBAAoB;AAC3C,mBAAmB,UAAU;AAC7B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,YAAY,kBAAG;AACf,gBAAgB,yBAAI;AACpB;AACA,sBAAsB,yBAAI;AAC1B;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,qBAAqB,mBAAmB;AACxC;AACA,kBAAkB,kBAAG,UAAU,kBAAG;AAClC;AACA;AACA,uBAAuB,qBAAqB;AAC5C,mBAAmB,iBAAiB;AACpC,qBAAqB,WAAW;AAChC;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,qBAAqB,oBAAoB;AACzC;AACA,qBAAqB,kBAAG,UAAU,kBAAG;AACrC;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,qBAAqB,WAAW;AAChC;AACA;AACA,gBAAgB,yBAAI,kBAAkB,yBAAI;AAC1C;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,sDAAsD,QAAQ;AAC9D;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,wBAAwB,uBAAuB;AAC/C;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,OAAO;AAC1B;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA,wBAAwB,oBAAoB;AAC5C;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI,YAAY,kBAAG;AACnC,qBAAqB,kBAAG;AACxB,cAAc;AACd;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,gCAAgC,uBAAuB;AACvD;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,yBAAyB,8BAA8B;AACvD;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,SAAS;AAC5B;AACA,mBAAmB,QAAQ;AAC3B,iBAAiB,uBAAuB,KAAK,uBAAuB;AACpE;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,kBAAG;AACzB;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA,mDAAmD,mBAAG;AACtD,mDAAmD,mBAAG;AACtD,mDAAmD,mBAAG;AACtD,mDAAmD,mBAAG;AACtD;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA,wDAAwD;AACxD,wDAAwD;AACxD;AACA;AACA;AACA;AACA,4CAA4C;AAC5C;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA,wDAAwD,mBAAG;AAC3D;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,sBAAsB;AACtB;AACA,wDAAwD,mBAAG;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,6BAA6B,yBAAI;AACjC,6BAA6B,yBAAI;AACjC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA,yBAAyB,0BAAM,CAAC,wBAAK;AACrC,yBAAyB,0BAAM;AAC/B,oBAAoB,wBAAK;AACzB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,iBAAiB,yBAAI;AACrB,iBAAiB,yBAAI;AACrB;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,cAAc;AACd;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,wBAAwB,8BAA8B;AACtD,gBAAgB;AAChB;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA,6BAA6B,aAAa;AAC1C,6BAA6B,aAAa;AAC1C;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,kDAAkD;AAClD;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,4BAA4B,8BAA8B;AAC1D,oBAAoB;AACpB;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA,iCAAiC,aAAa;AAC9C,iCAAiC,aAAa;AAC9C;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA,sDAAsD;AACtD;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,sBAAsB;AAC9C;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA,+BAA+B,yBAAI,kBAAkB,yBAAI;AACzD,kBAAkB,UAAU,yBAAI;AAChC,gEAAgE;AAChE,oBAAoB,kBAAG;AACvB,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,yBAAI;AACpC,kEAAkE,gBAAgB;AAClF,kEAAkE,gBAAgB;AAClF;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI,+BAA+B,yBAAI;AACnE;AACA;AACA,4BAA4B,yBAAI,+BAA+B,yBAAI;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,yBAAI;AACxC,6CAA6C,yBAAI;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,yBAAI;AAC3D,8BAA8B,SAAS,yBAAI;AAC3C,+DAA+D,wBAAK;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,yBAAI;AAC3D,8BAA8B,SAAS,yBAAI;AAC3C,0DAA0D,wBAAK;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA,6BAA6B,yBAAI;AACjC,8BAA8B,yBAAI;AAClC;AACA;AACA,0BAA0B;AAC1B,kDAAkD,wBAAK;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,yBAAI;AACzC;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,yBAAI,6BAA6B,yBAAI;AAC9D;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,WAAW;AAC9B,mBAAmB,SAAS;AAC5B;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,0BAA0B;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,0BAAK;AAC9C;AACA;AACA;AACA,uCAAuC,0BAAK;AAC5C;AACA;AACA;AACA,kDAAkD,0BAAK;AACvD;AACA;AACA;AACA,gDAAgD,0BAAK;AACrD;AACA;AACA;AACA,yBAAyB;AACzB,sBAAsB,SAAS,yBAAI;AACnC,wBAAwB,kBAAG;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,wBAAwB;AAC3C;AACA,mBAAmB,SAAS;AAC5B;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,gBAAgB,eAAe;AAC3C;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA,kBAAkB,SAAS,yBAAI;AAC/B;AACA;AACA,kBAAkB,SAAS,yBAAI;AAC/B;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,iBAAiB,yBAAI,mBAAmB,yBAAI,iBAAiB,yBAAI;AACjE;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA,wBAAwB,WAAW;AACnC;AACA;AACA,cAAc;AACd,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,mBAAmB,sBAAsB,kBAAkB;AAC9E,mBAAmB,QAAQ,6DAA6D,kBAAkB;AAC1G,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI,cAAc,yBAAI;AACtC;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,eAAe,iCAAiC;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,kBAAG;AAClC;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,uCAAuC,mBAAG,YAAY,kBAAG;AACzD;AACA;AACA,mCAAmC,mBAAG;AACtC,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,uCAAuC,mBAAG,YAAY,kBAAG;AACzD;AACA;AACA;AACA,2CAA2C,mBAAG,YAAY,kBAAG;AAC7D;AACA;AACA;AACA;AACA,mCAAmC,mBAAG;AACtC;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,+CAA+C,SAAS;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,iBAAiB;AACjB;AACA,mCAAmC,qBAAqB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA,mBAAmB;AACnB;AACA,uCAAuC,qBAAqB;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,eAAe;AAChE;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B,yBAAyB,kBAAkB;AAC3C;AACA;AACA;AACA;AACA,iDAAiD,gBAAgB;AACjE;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE,kBAAG;AACrE;AACA;AACA;AACA,kEAAkE,kBAAG;AACrE;AACA;AACA;AACA,kEAAkE,kBAAG;AACrE;AACA;AACA;AACA,kEAAkE,kBAAG;AACrE;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,+CAA+C,oCAAoC;AACnF,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,gCAAgC,yBAAI,sBAAsB,0BAAO;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,8BAA8B;AACpE;AACA,mBAAmB,OAAO;AAC1B;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,4CAA4C;AAC5C;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,mCAAmC;AACnC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,0CAA0C;AAC1C;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA,gDAAgD;AAChD;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B;AACA;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B;AACA;AACA,gDAAgD;AAChD;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B;AACA;AACA,kDAAkD;AAClD;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B;AACA;AACA,gDAAgD;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,qBAAqB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA,gDAAgD;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,qBAAqB;AACxC;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA,YAAY,mCAAmC;AAC/C;AACA;AACA,mDAAmD;AACnD;AACA;AACA;AACA;AACA;AACA,YAAY,mCAAmC;AAC/C;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA,YAAY,mCAAmC;AAC/C;AACA;AACA,mDAAmD;AACnD;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA,oBAAoB,WAAW;AAC/B;AACA;AACA,eAAe,mDAAmD,aAAa,KAAK,IAAI;AACxF,eAAe,yCAAyC,cAAc;AACtE;AACA,eAAe;AACf,yDAAyD,mCAAmC;AAC5F;AACA,eAAe;AACf;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA,wBAAwB,iFAAiF;AACzG;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,eAAe,wCAAwC,eAAe;AACtE,eAAe,iDAAiD,yBAAyB,IAAI;AAC7F,eAAe;AACf,eAAe,gDAAgD,cAAc;AAC7E;AACA,eAAe;AACf;AACA;AACA;AACA,6BAA6B,aAAa;AAC1C;AACA,YAAY;AACZ,oDAAoD;AACpD,eAAe;AACf;AACA,qEAAqE,eAAe;AACpF,8FAA8F,qBAAqB;AACnH;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,sDAAsD,wBAAwB;AACtG,oEAAoE;AACpE,wDAAwD;AACxD;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,oBAAoB,yBAAI;AACxB;AACA,kBAAkB,SAAS,yBAAI;AAC/B;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA,cAAc,SAAS,yBAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kBAAG;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA,8BAA8B;AAC9B;AACA;AACA;AACA,gCAAgC,kBAAG;AACnC,oCAAoC,yBAAI;AACxC;AACA,0BAA0B;AAC1B;AACA,0BAA0B;AAC1B;AACA;AACA,qBAAqB;AACrB;AACA,aAAa;AACb;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,iBAAiB,kBAAG;AACpB;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA,oBAAoB,WAAW;AAC/B;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA,4DAA4D,UAAU,gBAAgB,UAAU,IAAI,cAAc;AAClH;AACA,+CAA+C,SAAS;AACxD;AACA,+CAA+C,qBAAqB;AACpE;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA,sBAAsB;AACtB,kCAAkC;AAClC;AACA;AACA;AACA,sBAAsB;AACtB;AACA,sBAAsB,mCAAmC;AACzD;AACA;AACA,uDAAuD,mCAAmC;AAC1F;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA,wFAAwF,oFAAoF;AAC5K;AACA,0DAA0D,UAAU,gBAAgB,UAAU,IAAI,cAAc;AAChH;AACA,6CAA6C,SAAS;AACtD;AACA,6CAA6C,qBAAqB;AAClE;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA,sBAAsB;AACtB,kCAAkC;AAClC;AACA;AACA;AACA,sBAAsB;AACtB;AACA,sBAAsB,mCAAmC;AACzD;AACA;AACA,qDAAqD,mCAAmC;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,uBAAQ;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA,uCAAuC,uBAAQ;AAC/C,uCAAuC,uBAAQ;AAC/C,uCAAuC,uBAAQ;AAC/C,uCAAuC,uBAAQ;AAC/C,wCAAwC,uBAAQ;AAChD,wCAAwC,uBAAQ;AAChD,qCAAqC,mBAAG;AACxC,qCAAqC,mBAAG;AACxC,sCAAsC,mBAAG;AACzC;AACA;AACA,yBAAyB;AACzB;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,uBAAQ;AACzC;AACA;AACA,gCAAgC,OAAO;AACvC;AACA;AACA,gCAAgC,OAAO;AACvC;AACA,iCAAiC,OAAO,CAAC,uBAAQ,kBAAkB,uBAAQ;AAC3E,iCAAiC,OAAO,CAAC,uBAAQ,kBAAkB,uBAAQ;AAC3E;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA,8BAA8B,OAAO;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAe,kBAAG,MAAM,EAAC;;;ACtlQzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACS;AACJ;AACL;AACE;AACE;AACG;AAC3C;AACA;AACA,2DAA2D,2BAA2B;AACtF;AACA;AACA,WAAW,MAAM;AACjB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yEAAyE,sBAAsB;AAC/F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,cAAc;AAC7B,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,yBAAI;AACnC;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,4BAA4B;AAClE;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,wBAAwB;AACnF;AACA;AACA;AACA;AACA,gBAAgB,IAAI,0BAAO,kBAAkB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,kBAAG,6BAA6B,iBAAgB;AAChD;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,QAAQ;AAC3B,qBAAqB,MAAM;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,6EAA6E;AAC7E;AACA,2DAA2D;AAC3D;AACA;AACA;AACA,sEAAsE;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA,sBAAsB;AACtB;AACA,sBAAsB;AACtB;AACA,sBAAsB;AACtB;AACA,sBAAsB;AACtB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA,sBAAsB;AACtB;AACA,sBAAsB;AACtB;AACA,sBAAsB;AACtB;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,+DAA+D;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,MAAM;AACzB,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,qBAAqB;AACxC;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA,gCAAgC,kBAAG;AACnC;AACA;AACA,8BAA8B;AAC9B;AACA;AACA,yBAAyB;AACzB,sBAAsB;AACtB;AACA;AACA,gCAAgC,kBAAG;AACnC;AACA,8BAA8B;AAC9B;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA,4BAA4B,oBAAoB;AAChD,wBAAwB,yBAAI;AAC5B;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wFAAwF;AACxF,gCAAgC,sBAAsB;AACtD;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sEAAsE;AACtE;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,+EAA+E;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,wBAAK;AACjD;AACA;AACA;AACA;AACA,4DAA4D;AAC5D,mEAAmE;AACnE;AACA;AACA,6DAA6D;AAC7D,mEAAmE;AACnE;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,0BAA0B;AAC/D,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA,cAAc,kBAAkB,0BAAO;AACvC,wBAAwB,0BAAO;AAC/B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,gBAAgB,yBAAI,kBAAkB,yBAAI;AAC1C;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA,cAAc,kBAAkB,0BAAO;AACvC,wBAAwB,0BAAO;AAC/B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,kEAAkE;AAClE;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,uBAAQ;AACpC;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sEAAsE;AACtE,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,aAAa;AACrC;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,UAAU;AAC7B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qEAAqE,gBAAgB;AACrF;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,2BAA2B,0BAAK;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,gCAAgC,kBAAG;AACnC;AACA;AACA,qBAAqB;AACrB,mDAAmD;AACnD,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,2BAA2B,0BAAK;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA;AACA,yBAAyB;AACzB,sBAAsB;AACtB;AACA;AACA;AACA,yBAAyB;AACzB;AACA,kBAAkB;AAClB;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,wCAAwC,wBAAK;AAC7C,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,wBAAwB,kBAAG;AAC3B;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,kDAAkD,yBAAI;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI,mBAAmB,yBAAI;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wEAAwE;AACxE;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA,6DAA6D;AAC7D;AACA;AACA,6DAA6D;AAC7D;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,MAAM;AAC1B,oBAAoB,YAAY;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD,uDAAuD;AACvD;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,oCAAoC;AACpC;AACA,mBAAmB,SAAS;AAC5B;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,MAAM;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,yBAAI;AACtD;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gEAAgE;AAChE;AACA,qCAAqC;AACrC,+BAA+B;AAC/B,6CAA6C,UAAU,kBAAkB,wCAAwC;AACjH,wCAAwC;AACxC;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,SAAS;AAC5B;AACA,qBAAqB,UAAU;AAC/B;AACA;AACA,oEAAoE,sBAAsB;AAC1F;AACA;AACA;AACA;AACA,oCAAoC,sBAAsB;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,aAAa;AACb,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,QAAQ;AAC3B;AACA;AACA,mBAAmB,SAAS;AAC5B;AACA,oBAAoB,cAAc;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAAe,kBAAG,YAAY,EAAC;;;AC73E/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACiB;AACJ;AACL;AACE;AACJ;AACS;AAC3C;AACA;AACA,2DAA2D,2BAA2B;AACtF;AACA;AACA;AACA;AACA;AACA,WAAW,MAAM;AACjB;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA,+FAA+F;AAC/F,SAAS,yBAAI,QAAQ,kBAAG;AACxB;AACA,QAAQ,kBAAG;AACX,QAAQ,kBAAG;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,6BAA6B,iBAAgB;AAChD;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA,mBAAmB,MAAM;AACzB,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,cAAc;AACd,gBAAgB,kBAAG;AACnB;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA,oBAAoB,yBAAI,mBAAmB,yBAAI;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD;AACvD;AACA;AACA;AACA;AACA;AACA,4BAA4B,uBAAQ;AACpC;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,aAAa;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,2BAA2B,0BAAK;AAChC;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA,gCAAgC,wBAAK;AACrC;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,6EAA6E;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI,2BAA2B,wBAAK;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,+BAA+B,yBAAI;AACnC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAAe,kBAAG,YAAY,EAAC;;;ACnxC/B;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,QAAQ,kBAAG;AACd;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB;AACA;AACA,UAAU;AACV;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAAe,kBAAG,KAAK,EAAC;;;AC1DxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACiB;AACJ;AACP;AACE;AACA;AACE;AACC;AACL;AACS;AACA;AAC3C;AACA;AACA;AACA,mEAAmE,2BAA2B;AAC9F;AACA;AACA;AACA,WAAW,MAAM;AACjB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA,oBAAoB,IAAI;AACxB;AACA;AACA;AACA,QAAQ,kBAAG;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,SAAS,kBAAG;AAClB;AACA,8BAA8B,kBAAG;AACjC;AACA,UAAU;AACV;AACA;AACA;AACA,8BAA8B,eAAe;AAC7C,qDAAqD;AACrD;AACA;AACA;AACA;AACA,kBAAG,gCAAgC,iBAAgB;AACnD;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,SAAS;AACzC;AACA;AACA,kBAAkB;AAClB,gCAAgC,SAAS;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,qBAAqB,0BAAM,CAAC,wBAAK;AACjC,qBAAqB,0BAAM,CAAC,wBAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,0BAAM,CAAC,wBAAK;AACjC,qBAAqB,0BAAM,CAAC,wBAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,2BAA2B,0BAAK;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uEAAuE,gBAAgB;AACvF;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,yBAAyB,0BAAM,CAAC,wBAAK;AACrC,yBAAyB,0BAAM,CAAC,wBAAK;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,uBAAQ;AACpB;AACA;AACA,yBAAyB,0BAAM,CAAC,wBAAK;AACrC,yBAAyB,0BAAM,CAAC,wBAAK;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,UAAU;AACtC;AACA;AACA;AACA;AACA,2BAA2B,SAAS;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C;AAC/C;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,2BAA2B,0BAAK;AAChC;AACA;AACA;AACA;AACA;AACA,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,2BAA2B,yBAAI;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4DAA4D;AAC5D,mEAAmE;AACnE;AACA;AACA,6DAA6D;AAC7D,mEAAmE;AACnE;AACA;AACA;AACA,kBAAkB;AAClB,iCAAiC,uBAAQ,YAAY,mBAAG;AACxD;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI,kBAAkB,yBAAI;AAC1C;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,uBAAQ;AACpC;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,aAAa;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qCAAqC,wBAAK;AAC1C;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qCAAqC,wBAAK;AAC1C;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,kBAAG;AACpC;AACA;AACA;AACA,sCAAsC,kBAAG;AACzC;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAAe,kBAAG,eAAe,EAAC;;;AChqDlC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACiB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,QAAQ,mCAAmC;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC;AACA,qCAAqC;AACrC;AACA,0CAA0C;AAC1C;AACA;AACA;AACA,kCAAkC;AAClC;AACA,oCAAoC;AACpC;AACA,mCAAmC;AACnC;AACA,qCAAqC;AACrC;AACA;AACA;AACA,mCAAmC;AACnC;AACA,qCAAqC;AACrC;AACA;AACA;AACA,qCAAqC;AACrC;AACA,uCAAuC;AACvC;AACA;AACA;AACA,qCAAqC;AACrC;AACA,uCAAuC;AACvC;AACA;AACA;AACA,qDAAqD;AACrD;AACA,0CAA0C;AAC1C;AACA,4CAA4C;AAC5C;AACA,kCAAkC;AAClC;AACA,oCAAoC;AACpC;AACA,sDAAsD;AACtD;AACA,6EAA6E;AAC7E;AACA;AACA;AACA,mCAAmC;AACnC;AACA,qCAAqC;AACrC;AACA,wCAAwC;AACxC;AACA;AACA;AACA,kDAAkD;AAClD;AACA,oDAAoD;AACpD;AACA,kCAAkC;AAClC;AACA,oCAAoC;AACpC;AACA,2DAA2D;AAC3D;AACA,qEAAqE;AACrE;AACA,6DAA6D;AAC7D;AACA,2DAA2D;AAC3D;AACA,8CAA8C;AAC9C;AACA,oDAAoD;AACpD;AACA,iDAAiD;AACjD;AACA,sDAAsD;AACtD;AACA,qDAAqD;AACrD;AACA;AACA;AACA,8BAA8B;AAC9B;AACA,8BAA8B;AAC9B;AACA,8CAA8C;AAC9C;AACA,sCAAsC;AACtC;AACA,kCAAkC;AAClC;AACA,qCAAqC;AACrC;AACA,qCAAqC;AACrC;AACA,wCAAwC;AACxC;AACA,uDAAuD;AACvD;AACA,4DAA4D;AAC5D;AACA,8DAA8D;AAC9D;AACA,qDAAqD;AACrD;AACA,mCAAmC;AACnC;AACA,mCAAmC;AACnC;AACA,qCAAqC;AACrC;AACA;AACA;AACA,qCAAqC;AACrC;AACA,uCAAuC;AACvC;AACA,8CAA8C;AAC9C;AACA,wCAAwC,cAAc;AACtD;AACA,kCAAkC;AAClC;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,4BAA4B,iBAAgB;AAC/C;AACA,yCAAe,kBAAG,WAAW,EAAC;;;AC7N9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC2B;AACM;AACE;AACnC;AACoC;AACM;AACP;AACS;AACA;AACM;AACR;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA,QAAQ,0BAAO;AACf;AACA,YAAY,kBAAG;AACf,YAAY,0BAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf,YAAY,0BAAO;AACnB;AACA;AACA,YAAY,kBAAG;AACf,YAAY,0BAAO;AACnB;AACA;AACA;AACA,YAAY,kBAAG,aAAa,kBAAG;AAC/B,YAAY,0BAAO;AACnB;AACA;AACA,YAAY,kBAAG,aAAa,0BAAO;AACnC,YAAY,0BAAO;AACnB,YAAY,0BAAO;AACnB;AACA;AACA,eAAe,0BAAO;AACtB,KAAK;AACL;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB,gBAAgB,QAAQ;AACxB;AACA,gBAAgB,QAAQ;AACxB;AACA,iBAAiB,kBAAkB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,yBAAI;AAClB;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,GAAW;AACtC,UAAU;AACV,2BAA2B,GAAW;AACtC,UAAU;AACV,2BAA2B,MAAc;AACzC,UAAU;AACV,2BAA2B,EAAU;AACrC;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,mBAAmB,yBAAI;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA,wBAAwB,yBAAI;AAC5B;AACA,sBAAsB,yBAAI;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,kBAAG;AACX,KAAK;AACL;AACA;AACA;AACA,eAAe,eAAe;AAC9B,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,kBAAG;AACxB;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA,sEAAsE,sBAAsB,OAAO;AACnG;AACA,8CAA8C;AAC9C;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,WAAW;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,eAAe;AAC9B,eAAe,QAAQ;AACvB,YAAY,iBAAiB;AAC7B,qDAAqD,kBAAkB;AACvE;AACA,iBAAiB,WAAW;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB,kBAAkB,SAAS;AAC3B,kBAAkB,SAAS;AAC3B,kBAAkB,SAAS;AAC3B,kBAAkB,QAAQ;AAC1B,kBAAkB,QAAQ;AAC1B,kBAAkB,QAAQ;AAC1B,kBAAkB,QAAQ;AAC1B,kBAAkB,SAAS;AAC3B,kBAAkB,gBAAgB;AAClC,kBAAkB,SAAS;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,8CAA8C,yBAAI,QAAQ,kBAAG;AAC7D,oBAAoB,kBAAG;AACvB;AACA,kBAAkB,yBAAI,UAAU,0BAAO;AACvC;AACA;AACA,qBAAqB,kBAAG;AACxB;AACA;AACA,sBAAsB,yBAAI;AAC1B,sBAAsB,yBAAI;AAC1B,oBAAoB,yBAAI;AACxB,oBAAoB,yBAAI;AACxB,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,UAAK;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,yBAAI;AAC3B,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA,2BAA2B,yBAAI;AAC/B;AACA;AACA,2BAA2B,yBAAI;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mFAAmF;AACnF;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,eAAe;AAC9B,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA,eAAe,UAAU;AACzB,iBAAiB,WAAW;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,kBAAkB;AAC/B,+BAA+B;AAC/B;AACA;AACA;AACA,aAAa,uBAAuB;AACpC,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,kBAAkB;AAC/B,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,kBAAG;AACxB;AACA;AACA;AACA;AACA,oBAAoB,UAAK;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,WAAU;AAClB;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,eAAe;AAC9B,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA,eAAe,UAAU;AACzB,iBAAiB,WAAW;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,kBAAG;AACxB;AACA;AACA;AACA;AACA,oBAAoB,UAAK;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,WAAU;AAClB;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,kBAAkB;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,kBAAG;AAClB,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,kBAAG;AACX,QAAQ,kBAAG;AACX;AACA;AACA;AACA;AACA;AACA,IAAI,kBAAG;AACP,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,kBAAG;AACnC;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA,0BAA0B;AAC1B,4BAA4B,kBAAG;AAC/B;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,wBAAwB,kBAAG;AAC3B;AACA;AACA;AACA;AACA;AACA,wBAAwB,oBAAoB;AAC5C;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,oCAAoC,iBAAiB;AACrD;AACA;AACA;AACA,2BAA2B,yBAAI;AAC/B,2BAA2B,yBAAI;AAC/B;AACA,yBAAyB,yBAAI;AAC7B;AACA;AACA;AACA;AACA,kEAAkE;AAClE,sEAAsE;AACtE,6EAA6E;AAC7E,sFAAsF;AACtF;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA,8DAA8D;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA,yBAAyB;AACzB;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,wBAAwB,kBAAG;AAC3B;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,+CAAe,kBAAG,SAAS,EAAC;;;;;;;ACr6B5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACF;AACS;AACR;AACQ;AACP;AACW;AAC/C;AACA;AACA;AACA;AACA;AACA,0FAA0F,wBAAwB;AAClH,SAAS,YAAY,GAAG,aAAa,MAAM,oBAAoB;AAC/D;AACA;AACA,WAAW,kBAAkB;AAC7B,WAAW,OAAO;AAClB,WAAW,QAAQ,2DAA2D,yBAAyB;AACvG,IAAI,2BAA2B;AAC/B;AACA;AACA,kBAAG;AACH,wCAAwC,wBAAK,oBAAoB,wBAAK;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,0BAA0B;AACjD;AACA,kBAAG,uBAAuB,2BAAe;AACzC,yBAAI,sBAAsB,kBAAG,QAAQ,4BAAa;AAClD;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,0DAA0D,4BAA4B;AACtF;AACA,mBAAmB,SAAS;AAC5B;AACA;AACA,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,wBAAwB,iCAAiC;AACzD;AACA,oBAAoB,mBAAG;AACvB;AACA,uCAAuC,wBAAK;AAC5C;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,eAAe;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,uBAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,wBAAK;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,YAAY,kBAAG;AACf,mBAAmB,0BAAO;AAC1B,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ,sDAAsD,gCAAgC;AACjH;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf,gCAAgC,SAAS;AACzC,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf,gCAAgC,SAAS;AACzC,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,oDAAoD,cAAc;AAClE,kEAAkE,oBAAoB;AACtF,qEAAqE,oBAAoB;AACzF;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA,wDAAwD,cAAc;AACtE,sEAAsE,oBAAoB;AAC1F,yEAAyE,oBAAoB;AAC7F;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,mBAAG;AAC5B;AACA,gBAAgB,yBAAI;AACpB;AACA,cAAc,6BAA6B,wBAAK;AAChD;AACA,0BAA0B,kBAAG;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,uBAAQ;AAChC;AACA;AACA,sBAAsB;AACtB;AACA;AACA,kBAAkB;AAClB,2BAA2B,uBAAQ;AACnC;AACA,cAAc,6BAA6B,wBAAK;AAChD;AACA;AACA;AACA;AACA,cAAc,6BAA6B,wBAAK;AAChD,uBAAuB,uBAAQ;AAC/B,uBAAuB,uBAAQ;AAC/B,cAAc,qBAAqB,wBAAK;AACxC;AACA;AACA;AACA;AACA;AACA,4BAA4B,kBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA,sBAAsB,uBAAQ;AAC9B,uBAAuB,uBAAQ;AAC/B,cAAc,qBAAqB,wBAAK;AACxC,uBAAuB,uBAAQ;AAC/B,uBAAuB,uBAAQ;AAC/B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,sEAAsE;AACjF;AACA;AACA;AACA;AACA;AACA,WAAW,oCAAoC;AAC/C,8FAA8F,wBAAwB;AACtH;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA,sDAAsD,gBAAgB;AACtE,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA,oEAAoE,sBAAsB;AAC1F;AACA;AACA;AACA,oDAAoD,aAAa;AACjE;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K,kEAAkE,aAAa;AAC/E;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,WAAW,yBAAI;AACf,SAAS,4BAAa,QAAQ,kBAAG;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,0CAA0C;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4EAA4E,uBAAuB;AACnG,2EAA2E,mBAAmB;AAC9F,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,uFAAuF;AACjL;AACA;AACA;AACA,sEAAsE,6BAA6B;AACnG,qEAAqE,yBAAyB;AAC9F;AACA;AACA,kBAAG;AACH;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,yDAAyD;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,uBAAQ;AACnB;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,wBAAK;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,yDAAyD;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,sFAAsF;AAChL;AACA;AACA;AACA;AACA;AACA,gFAAgF,SAAS;AACzF,2FAA2F,SAAS;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,gFAAgF,gBAAgB;AAChG;AACA;AACA,8CAA8C,gCAAgC;AAC9E,sEAAsE,gBAAgB;AACtF,iEAAiE,oBAAoB;AACrF;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,sFAAsF;AACtG,yFAAyF,gBAAgB;AACzG;AACA;AACA,uDAAuD,gCAAgC;AACvF,+EAA+E,gBAAgB;AAC/F,0EAA0E,oBAAoB;AAC9F,QAAQ;AACR;AACA;AACA;AACA;AACA,2DAA2D,gBAAgB;AAC3E;AACA,kGAAkG,gBAAgB;AAClH;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG,oEAAoE,gBAAgB;AACpF;AACA,2GAA2G,gBAAgB;AAC3H;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,YAAY,yBAAI;AAChB;AACA,UAAU;AACV;AACA;AACA;AACA,oBAAoB,mBAAmB;AACvC;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,yCAAyC;AAClF;AACA;AACA,iBAAiB,wBAAK,sBAAsB,wBAAK;AACjD;AACA,cAAc,UAAU,wBAAK,sBAAsB,wBAAK,qBAAqB,wBAAK;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,uBAAQ;AACnB;AACA;AACA,cAAc,wBAAK;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,wBAAK;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,oDAAoD;AAC5D;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,gCAAgC;AAC3C,WAAW,gCAAgC;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6GAA6G,aAAa;AAC1H;AACA,wFAAwF,qFAAqF;AAC7K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6GAA6G,aAAa;AAC1H;AACA,wFAAwF,qFAAqF;AAC7K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,wBAAK;AACrC,wCAAwC,wBAAK;AAC7C;AACA,gCAAgC,wBAAK;AACrC,wCAAwC,wBAAK;AAC7C;AACA,wDAAwD,wBAAK;AAC7D,yDAAyD,wBAAK;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0EAA0E;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,0BAA0B,kBAAG;AAChC,kBAAG,2BAA2B,kBAAG;AACjC,kBAAG,iCAAiC,kBAAG;AACvC,kBAAG,sCAAsC,kBAAG;AAC5C,kBAAG,8BAA8B,kBAAG;AACpC;AACA,4CAAe,kBAAG,MAAM,EAAC;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC1/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACM;AACS;AACA;AACI;AACZ;AACF;AACU;AACP;AACpC;AACA;AACA;AACA;AACA;AACA,QAAQ,wBAAwB;AAChC,SAAS,WAAW,GAAG,YAAY,MAAM,YAAY;AACrD;AACA;AACA,WAAW,kBAAkB;AAC7B,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA,kBAAG;AACH,wCAAwC,wBAAK,mBAAmB,wBAAK;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,uBAAuB;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAyB,KAAK,4BAA4B;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,kBAAG;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,kBAAG,sBAAsB,2BAAe;AACxC;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,uBAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,mBAAG;AACtB;AACA,mBAAmB,mBAAG;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,0BAAM,CAAC,wBAAK;AACnC,6BAA6B,wBAAK;AAClC;AACA;AACA;AACA;AACA,oBAAoB,mBAAG;AACvB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,mBAAG;AAC/B;AACA;AACA,2CAA2C,mBAAG;AAC9C,6BAA6B,uBAAQ;AACrC;AACA;AACA,sBAAsB;AACtB,6BAA6B,uBAAQ;AACrC;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,mBAAG;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,wBAAwB,yBAAI;AAC5B;AACA,4BAA4B,yBAAI;AAChC;AACA,0BAA0B;AAC1B,4DAA4D,wBAAK;AACjE;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA,4BAA4B,yBAAI;AAChC;AACA,0BAA0B;AAC1B,4DAA4D,wBAAK;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA,qBAAqB,mBAAG,aAAa,mBAAG;AACxC;AACA;AACA,yCAAyC,wBAAK;AAC9C;AACA;AACA;AACA,yCAAyC,wBAAK;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,mBAAG;AAC3B;AACA,wDAAwD,wBAAK;AAC7D;AACA;AACA;AACA;AACA,sBAAsB;AACtB,wDAAwD,wBAAK;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,wBAAwB,mBAAG;AAC3B;AACA;AACA,wDAAwD,wBAAK;AAC7D;AACA;AACA;AACA;AACA,sBAAsB;AACtB,wDAAwD,wBAAK;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,wBAAK;AACzB;AACA;AACA;AACA,oBAAoB,wBAAK;AACzB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,mBAAG,gDAAgD,mBAAG,OAAO,mBAAG;AACzF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,eAAe,uBAAuB,KAAK,sBAAsB;AACjE;AACA,sBAAsB,WAAW;AACjC,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA,6CAA6C,mBAAG;AAChD;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA,6CAA6C,mBAAG;AAChD;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,wDAAwD,uBAAuB;AAC/E,YAAY,uBAAuB;AACnC,mBAAmB,SAAS;AAC5B,YAAY,sBAAsB;AAClC,mBAAmB,SAAS;AAC5B,YAAY,sBAAsB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,uBAAuB,0BAAM;AAC7B,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gDAAgD,0BAAM;AACtD,oBAAoB,wBAAK;AACzB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,0BAAM,CAAC,wBAAK;AACrC,yBAAyB,0BAAM,CAAC,wBAAK;AACrC;AACA;AACA;AACA;AACA,gBAAgB,uBAAQ;AACxB;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,2BAA2B,0BAAM,CAAC,wBAAK;AACvC;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,2BAA2B,0BAAM,CAAC,wBAAK;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,mBAAG;AAC/C;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,mBAAG;AAC/C;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,qBAAqB,yBAAI;AACzB,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA,oBAAoB,mBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA,kCAAkC,mBAAG;AACrC;AACA,kBAAkB;AAClB,6CAA6C,mBAAG;AAChD,sDAAsD,mBAAG;AACzD;AACA;AACA;AACA;AACA,oBAAoB,mBAAG,sBAAsB,mBAAG;AAChD;AACA,kBAAkB;AAClB,8CAA8C,mBAAG;AACjD,uDAAuD,mBAAG;AAC1D;AACA;AACA;AACA;AACA;AACA,uBAAuB,0BAAM,CAAC,wBAAK;AACnC,SAAS;AACT;AACA;AACA;AACA,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,0BAA0B,sBAAsB,0BAA0B;AAC7F,YAAY,yBAAyB;AACrC,qBAAqB,UAAU;AAC/B;AACA;AACA;AACA,uBAAuB,yBAAI;AAC3B;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,SAAS,yBAAI;AAC/B;AACA;AACA;AACA;AACA,6BAA6B,0BAAM,CAAC,wBAAK;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,uBAAQ,sBAAsB,YAAY;AACvE;AACA,6BAA6B,yBAAU;AACvC;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,cAAc;AACd;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,gBAAgB,kBAAkB;AAClC,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,cAAc;AACd;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,gBAAgB,kBAAkB;AAClC;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,wBAAwB;AAC3C,qBAAqB,UAAU;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,yBAAI;AACnC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,YAAY,2BAAe;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,uBAAuB;AAClD;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,2BAA2B,uBAAuB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,mDAAmD,kEAAkE,iBAAiB;AACjJ;AACA;AACA,WAAW,iDAAiD;AAC5D;AACA;AACA,WAAW,UAAU;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA,mDAAmD,uBAAuB;AAC1E,0DAA0D,gBAAgB;AAC1E;AACA;AACA;AACA;AACA,kGAAkG,cAAc;AAChH;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA,uDAAuD,uBAAuB;AAC9E,8DAA8D,gBAAgB;AAC9E;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,gDAAgD,cAAc;AAC9D;AACA;AACA;AACA,4FAA4F,cAAc;AAC1G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,oDAAoD,cAAc;AAClE;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,wCAAwC;AACnF,4FAA4F,cAAc;AAC1G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA,gEAAgE,wCAAwC;AACxG,QAAQ;AACR;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB,YAAY,yBAAI;AAChB;AACA,UAAU,SAAS,yBAAI,yBAAyB,yBAAI;AACpD;AACA,UAAU,SAAS,yBAAI,2BAA2B,yBAAI;AACtD;AACA;AACA,UAAU;AACV,YAAY,yBAAI;AAChB;AACA;AACA;AACA,iBAAiB,kBAAG;AACpB;AACA,UAAU,SAAS,yBAAI,yBAAyB,yBAAI;AACpD;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA,UAAU,SAAS,yBAAI;AACvB;AACA,UAAU,SAAS,yBAAI,yBAAyB,yBAAI;AACpD;AACA,UAAU,SAAS,yBAAI,2BAA2B,yBAAI;AACtD;AACA;AACA,UAAU;AACV,YAAY,yBAAI;AAChB;AACA;AACA;AACA,iBAAiB,kBAAG;AACpB;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB,iBAAiB,kBAAG;AACpB;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,gBAAgB,yBAAI;AACpB;AACA;AACA,uBAAuB,yBAAI;AAC3B,cAAc,SAAS,yBAAI;AAC3B;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB,iBAAiB,kBAAG;AACpB;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,QAAQ,yBAAI;AACZ;AACA,QAAQ,yBAAI;AACZ,QAAQ,yBAAI;AACZ;AACA;AACA,eAAe,yBAAI;AACnB,iBAAiB,kBAAG;AACpB;AACA;AACA;AACA,MAAM;AACN;AACA,QAAQ,yBAAI;AACZ;AACA,QAAQ,yBAAI;AACZ,QAAQ,yBAAI;AACZ,QAAQ,yBAAI;AACZ;AACA;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB,iBAAiB,kBAAG;AACpB;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,yBAAyB,kBAAG;AAC/B;AACA;AACA;AACA,oDAAoD,YAAY,MAAM;AACtE,QAAQ,yBAAyB;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,iCAAiC,kEAAkE;AAC9G;AACA;AACA,WAAW,iBAAiB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA;AACA,2DAA2D,gBAAgB,IAAI;AAC/E,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mFAAmF,qBAAqB;AACxG;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,0BAAM;AACnD,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA,6CAA6C,0BAAM;AACnD,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,4BAA4B,kBAAG;AAClC;AACA;AACA;AACA;AACA,IAAI,YAAY,MAAM;AACtB,QAAQ,yBAAyB,6BAA6B,sBAAsB;AACpF;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,iCAAiC,kEAAkE,iBAAiB;AAC/H;AACA,WAAW,sBAAsB;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA,cAAc,wBAAK;AACnB;AACA;AACA;AACA;AACA;AACA,kBAAG,0BAA0B,kBAAG;AAChC;AACA;AACA;AACA,oDAAoD,YAAY,MAAM;AACtE,QAAQ,yBAAyB,sCAAsC,sBAAsB,4BAA4B,aAAa;AACtI;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,iCAAiC,kEAAkE,iBAAiB;AAC/H;AACA,WAAW,sBAAsB;AACjC;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA;AACA,gBAAgB,6FAA6F;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,wBAAK;AACjD;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA,MAAM,SAAS,yBAAI;AACnB;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,yBAAI;AACpC,UAAU;AACV,gCAAgC,yBAAI;AACpC,UAAU;AACV,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yBAAI;AAC1B,UAAU;AACV,sBAAsB,yBAAI;AAC1B,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,8BAA8B;AAC9B;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,8BAA8B;AAC9B;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,kBAAG;AAC3C,wCAAwC,kBAAG;AAC3C;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB,4CAA4C,yBAAI;AAChD;AACA,qBAAqB,yBAAI;AACzB,4CAA4C,yBAAI;AAChD;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA,0BAA0B;AAC1B;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA,gCAAgC,qCAAqC;AACrE;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA,0BAA0B;AAC1B;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA,gCAAgC,qCAAqC;AACrE;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,kBAAG;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,yBAAyB,kBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,QAAQ;AACnB,WAAW,qBAAqB;AAChC;AACA;AACA,iDAAiD,SAAS,aAAa,cAAc;AACrF;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K,6DAA6D,SAAS,aAAa,cAAc;AACjG;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,UAAU,SAAS,yBAAI;AACvB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,2BAA2B,wBAAK;AAChC;AACA;AACA,MAAM;AACN,2BAA2B,wBAAK;AAChC,mBAAmB,wBAAK;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,yBAAI;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,wBAAK;AAC5C;AACA,0BAA0B;AAC1B;AACA,0BAA0B;AAC1B,gCAAgC,uBAAQ;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,mBAAmB;AAC3D;AACA,yCAAyC,mBAAG;AAC5C,qCAAqC,mBAAG;AACxC;AACA;AACA,2CAA2C,wBAAK;AAChD;AACA;AACA;AACA,oCAAoC,uBAAQ;AAC5C;AACA;AACA;AACA;AACA,6BAA6B,uBAAQ;AACrC,6BAA6B,uBAAQ;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,QAAQ;AAChE,yCAAyC,mBAAG,WAAW,mBAAG;AAC1D,qCAAqC,mBAAG;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,mBAAG;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,wBAAK;AAC5C;AACA,0BAA0B;AAC1B,gCAAgC,uBAAQ;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,oBAAoB,wBAAK;AAC/B;AACA;AACA;AACA;AACA;AACA,mCAAmC,wBAAK;AACxC;AACA,sBAAsB;AACtB,4BAA4B,uBAAQ;AACpC;AACA;AACA;AACA;AACA;AACA,gCAAgC,sBAAsB;AACtD;AACA;AACA,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,2BAA2B,wBAAK;AAChC,mBAAmB,wBAAK;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,mBAAG;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA,mBAAmB,wBAAK;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,oDAAoD;AAC/D;AACA,WAAW,QAAQ,oDAAoD,oCAAoC;AAC3G;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA,gBAAgB,oBAAoB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,YAAY,yBAAI;AAChB,gBAAgB,yBAAI;AACpB;AACA,UAAU,SAAS,yBAAI;AACvB;AACA,gBAAgB,yBAAI;AACpB,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,2BAA2B,wBAAK;AAChC;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,4BAA4B,mBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,gBAAgB;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,4BAA4B,wBAAK;AACvC;AACA,MAAM,4BAA4B,wBAAK;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,yBAAI;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,wBAAK;AAC5C;AACA,0BAA0B;AAC1B;AACA,0BAA0B;AAC1B,gCAAgC,uBAAQ;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,mBAAmB;AAC3D;AACA,yCAAyC,mBAAG;AAC5C,qCAAqC,mBAAG;AACxC;AACA;AACA,2CAA2C,wBAAK;AAChD;AACA;AACA;AACA,oCAAoC,uBAAQ;AAC5C;AACA;AACA;AACA,6BAA6B,uBAAQ;AACrC,6BAA6B,uBAAQ;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,QAAQ;AAChE,yCAAyC,mBAAG,WAAW,mBAAG;AAC1D,qCAAqC,mBAAG;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,mBAAG;AAC5B,yBAAyB,mBAAG;AAC5B;AACA,yBAAyB,mBAAG;AAC5B;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,mBAAG;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,wBAAK;AAC5C;AACA,0BAA0B;AAC1B,gCAAgC,uBAAQ;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,oBAAoB,wBAAK;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,sBAAsB;AACtD;AACA;AACA,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,sBAAsB;AACtD;AACA,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,sBAAsB;AACtD;AACA,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,YAAY;AACvB,WAAW,YAAY;AACvB;AACA;AACA,iFAAiF,qFAAqF;AACtK;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6GAA6G,aAAa;AAC1H;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA,oCAAoC,wBAAK;AACzC,oCAAoC,wBAAK;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,mBAAG,YAAY,mBAAG;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,oDAAoD;AAC5D;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,gCAAgC;AAC3C,WAAW,gCAAgC;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6GAA6G,aAAa;AAC1H;AACA,wFAAwF,qFAAqF;AAC7K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6GAA6G,aAAa;AAC1H;AACA,wFAAwF,qFAAqF;AAC7K;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,wBAAK;AACrC,wCAAwC,wBAAK;AAC7C;AACA,gCAAgC,wBAAK;AACrC,wCAAwC,wBAAK;AAC7C;AACA,6BAA6B,yBAAI;AACjC,8BAA8B,yBAAI;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,uCAAuC;AAClD;AACA;AACA;AACA;AACA;AACA,oDAAoD,wBAAwB,cAAc,UAAU,gBAAgB;AACpH,oDAAoD,gBAAgB;AACpE;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA,+DAA+D,wBAAwB,cAAc,UAAU,gBAAgB;AAC/H,+DAA+D,gBAAgB;AAC/E;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,UAAU,yBAAI;AACd;AACA;AACA,wBAAwB,wBAAK,sCAAsC,wBAAK;AACxE,oCAAoC,wBAAK;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,4BAA4B,kBAAG;AAClC,kBAAG,2BAA2B,kBAAG;AACjC,kBAAG,8BAA8B,kBAAG;AACpC,kBAAG,0BAA0B,kBAAG;AAChC,kBAAG,gCAAgC,kBAAG;AACtC,kBAAG,8BAA8B,kBAAG;AACpC;AACA,2CAAe,kBAAG,KAAK,EAAC;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AC7gGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACO;AACD;AACS;AACP;AACpC;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,QAAQ;AACnB;AACA,WAAW,QAAQ;AACnB;AACA,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yBAAI;AAC1B;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,gBAAgB,wBAAK;AACrB,wBAAwB,wBAAK;AAC7B;AACA,wBAAwB,yBAAI;AAC5B;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA,MAAM;AACN;AACA;AACA;AACA,gBAAgB,qBAAqB;AACrC;AACA;AACA,yCAAyC,yBAAI;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,eAAe,yBAAyB;AACxC,mBAAmB,OAAO;AAC1B;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC,oBAAoB,yBAAI;AACxB;AACA,kBAAkB,SAAS,yBAAI;AAC/B;AACA;AACA;AACA;AACA,2BAA2B,yBAAI;AAC/B,SAAS;AACT;AACA;AACA;AACA,eAAe;AACf,gDAAgD,uBAAuB;AACvE,mBAAmB,OAAO;AAC1B;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,oEAAoE,uBAAuB;AAC3F,qBAAqB;AACrB;AACA;AACA,mBAAmB,yBAAI;AACvB,SAAS;AACT;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA,6BAA6B,yBAAI;AACjC;AACA,wCAAwC;AACxC;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,wBAAK;AAC9C;AACA;AACA;AACA;AACA,gCAAgC,gCAAgC;AAChE,4BAA4B,mBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA,wDAAwD,mBAAmB;AAC3E;AACA,cAAc;AACd;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA,kBAAkB;AAClB;AACA,kBAAkB,SAAS,yBAAI;AAC/B;AACA,kBAAkB,SAAS,yBAAI;AAC/B;AACA,kBAAkB;AAClB;AACA,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA,4BAA4B,uBAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB,gCAAgC;AAChC,kBAAkB;AAClB,wBAAwB,uBAAQ;AAChC,sCAAsC,mBAAG;AACzC;AACA;AACA,wBAAwB,uBAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA,gCAAgC;AAChC,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,wBAAK;AAC9C,wBAAwB,yBAAI;AAC5B;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,wBAAK,oCAAoC,mBAAG;AACxF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,oBAAoB,yBAAI;AACxB,oBAAoB,yBAAI;AACxB;AACA;AACA,kBAAkB;AAClB,oBAAoB,yBAAI;AACxB,oBAAoB,yBAAI;AACxB;AACA;AACA,kBAAkB,SAAS,yBAAI;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,yBAAI;AACzC,6DAA6D,wBAAK;AAClE,kEAAkE,wBAAK;AACvE;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA,yDAAyD,wBAAK;AAC9D;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,oCAAoC,wBAAK;AACzC,oCAAoC,mBAAG;AACvC;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,qBAAqB,WAAW;AAChC;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,wBAAwB,oBAAoB;AAC5C;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,iCAAiC;AACpD;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,6CAA6C,iCAAiC;AAC9E,mBAAmB,iBAAiB,kBAAkB,iBAAiB,wBAAwB,iBAAiB;AAChH,qBAAqB,WAAW;AAChC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,6CAA6C,iCAAiC;AAC9E,mBAAmB,WAAW,OAAO,iBAAiB;AACtD,qBAAqB,WAAW;AAChC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW,OAAO,iBAAiB;AACtD,qBAAqB,WAAW;AAChC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,iBAAiB,kBAAkB,iBAAiB,wBAAwB,iBAAiB;AAChH;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,WAAW,OAAO,iBAAiB;AACtD,qBAAqB,WAAW;AAChC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW,OAAO,iBAAiB;AACtD,qBAAqB,WAAW;AAChC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,kBAAkB;AACrC;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,iBAAiB,kBAAkB,iBAAiB,wBAAwB,iBAAiB;AAChH,mBAAmB,QAAQ;AAC3B;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW,OAAO,iBAAiB;AACtD,mBAAmB,QAAQ;AAC3B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW,OAAO,iBAAiB;AACtD,qBAAqB,WAAW;AAChC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,+BAA+B,sCAAsC,KAAK;AAC1E;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,+BAA+B,qCAAqC,KAAK;AACzE;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,+BAA+B,wCAAwC,KAAK;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,wCAAwC;AACpF,2CAA2C,wCAAwC;AACnF,0CAA0C,wCAAwC;AAClF,0CAA0C,wCAAwC;AAClF;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,+EAA+E,+EAA+E;AAC9J;AACA;AACA,4CAA4C,wCAAwC;AACpF,2CAA2C,wCAAwC;AACnF,0CAA0C,wCAAwC;AAClF,0CAA0C,wCAAwC;AAClF;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,wCAAwC;AACpF,2CAA2C,wCAAwC;AACnF,0CAA0C,wCAAwC;AAClF,0CAA0C,wCAAwC;AAClF;AACA,sCAAsC,qBAAqB;AAC3D;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,+EAA+E,+EAA+E;AAC9J;AACA;AACA,4CAA4C,wCAAwC;AACpF,2CAA2C,wCAAwC;AACnF,0CAA0C,wCAAwC;AAClF,0CAA0C,wCAAwC;AAClF,sCAAsC,qBAAqB;AAC3D;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,wCAAwC;AACpF,2CAA2C,4CAA4C;AACvF,0CAA0C,4CAA4C;AACtF,0CAA0C,wCAAwC;AAClF;AACA,sCAAsC,qBAAqB;AAC3D;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,+EAA+E,+EAA+E;AAC9J;AACA;AACA,4CAA4C,wCAAwC;AACpF,2CAA2C,4CAA4C;AACvF,0CAA0C,4CAA4C;AACtF,0CAA0C,wCAAwC;AAClF,sCAAsC,qBAAqB;AAC3D;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,wCAAwC;AACpF,2CAA2C,4CAA4C;AACvF,0CAA0C,4CAA4C;AACtF,0CAA0C,wCAAwC;AAClF;AACA,sCAAsC,qBAAqB;AAC3D;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,+EAA+E,+EAA+E;AAC9J;AACA;AACA,4CAA4C,wCAAwC;AACpF,2CAA2C,4CAA4C;AACvF,0CAA0C,4CAA4C;AACtF,0CAA0C,wCAAwC;AAClF,sCAAsC,qBAAqB;AAC3D;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,wCAAwC;AACpF,2CAA2C,kDAAkD;AAC7F,0CAA0C,4CAA4C;AACtF,0CAA0C,wCAAwC;AAClF;AACA,sCAAsC,qBAAqB;AAC3D;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,+EAA+E,+EAA+E;AAC9J;AACA;AACA,4CAA4C,wCAAwC;AACpF,2CAA2C,kDAAkD;AAC7F,0CAA0C,4CAA4C;AACtF,0CAA0C,wCAAwC;AAClF,sCAAsC,qBAAqB;AAC3D;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,wCAAwC;AACpF,2CAA2C,kDAAkD;AAC7F,0CAA0C,4CAA4C;AACtF,0CAA0C,wCAAwC;AAClF,sCAAsC,wCAAwC;AAC9E;AACA,sCAAsC,qBAAqB;AAC3D;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,+EAA+E,+EAA+E;AAC9J;AACA;AACA,4CAA4C,wCAAwC;AACpF,2CAA2C,kDAAkD;AAC7F,0CAA0C,4CAA4C;AACtF,0CAA0C,wCAAwC;AAClF,sCAAsC,wCAAwC;AAC9E;AACA,sCAAsC,qBAAqB;AAC3D;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,2CAA2C;AAC5F,iDAAiD,oEAAoE;AACrH,gDAAgD,+DAA+D;AAC/G,iDAAiD,8DAA8D;AAC/G;AACA;AACA,gDAAgD,sBAAsB;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,2CAA2C;AAC5F,iDAAiD,oEAAoE;AACrH,gDAAgD,+DAA+D;AAC/G,iDAAiD,8DAA8D;AAC/G;AACA;AACA,gDAAgD,sBAAsB;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,kBAAG;AACH,eAAe,yBAAI;AACnB,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,0BAA0B,kBAAG;AAChC;AACA,4CAAe,kBAAG,MAAM,EAAC;AACzB;AACA;AACA;AACA;;;AC/iCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACe;AACV;AACE;AACD;AACe;AACb;AACpC;AACA;AACA;AACA;AACA;AACA,4FAA4F,wBAAwB;AACpH,SAAS,cAAc;AACvB;AACA;AACA,WAAW,WAAW;AACtB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA,kBAAG;AACH;AACA,wCAAwC,wBAAK,qBAAqB,wBAAK;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,YAAY,wBAAK;AACjB;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,MAAM;AACN;AACA,MAAM;AACN,YAAY,yBAAI;AAChB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,kBAAG,wBAAwB,2BAAe;AAC1C;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA,wBAAwB,0BAAM,CAAC,wBAAK;AACpC;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,mBAAmB,mBAAG;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,sBAAsB,WAAW;AACjC,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,oBAAoB,yBAAI;AACxB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,wBAAK;AAC7B;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,uBAAuB;AACnD,yCAAyC,0BAAM;AAC/C,wBAAwB,wBAAK;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,kCAAkC,+BAA+B;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,yBAAI;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,sBAAa;AAC7B;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,wBAAwB;AAC3C,qBAAqB,YAAY;AACjC;AACA;AACA,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,wBAAwB;AAC3C,qBAAqB,QAAQ;AAC7B;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,gBAAgB,wBAAwB;AACxC;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C;AAC3C;AACA,iBAAiB,yBAAI;AACrB,2BAA2B,0BAAM,CAAC,wBAAK;AACvC;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,2BAA2B,0BAAM,CAAC,wBAAK;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,0BAAM,CAAC,wBAAK;AACvC;AACA;AACA,uBAAuB,0BAAM,CAAC,wBAAK;AACnC,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,0BAA0B,sBAAsB,0BAA0B,gBAAgB,yBAAyB;AACtI,qBAAqB,YAAY;AACjC;AACA;AACA;AACA,uBAAuB,yBAAI;AAC3B;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,gDAAgD,6CAA6C,gBAAgB;AACxH,QAAQ,wBAAwB;AAChC;AACA,YAAY,gBAAgB,KAAK,gBAAgB;AACjD,gDAAgD,iBAAiB;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,yFAAyF,qFAAqF;AAC9K;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,6BAA6B,eAAe,qBAAqB;AAClH,+FAA+F,cAAc;AAC7G;AACA;AACA,kFAAkF,qFAAqF;AACvK;AACA;AACA;AACA;AACA,iDAAiD,6BAA6B,eAAe,qBAAqB;AAClH,IAAI;AACJ;AACA;AACA,2CAA2C,uBAAuB;AAClE,kDAAkD,gBAAgB;AAClE;AACA,yDAAyD,SAAS,cAAc;AAChF;AACA,sGAAsG,cAAc;AACpH;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,uDAAuD,uBAAuB;AAC9E,8DAA8D,gBAAgB;AAC9E;AACA,qEAAqE,SAAS,cAAc;AAC5F;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,gDAAgD,cAAc;AAC9D,4DAA4D,+BAA+B,cAAc;AACzG,6CAA6C,qBAAqB;AAClE;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,oDAAoD,cAAc;AAClE,gEAAgE,+BAA+B,cAAc;AAC7G,iDAAiD,qBAAqB;AACtE;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,6BAA6B,wBAAK;AAClC,QAAQ,yBAAI;AACZ;AACA,eAAe,yBAAI;AACnB;AACA;AACA,sEAAsE,sBAAsB;AAC5F,aAAa;AACb;AACA,aAAa,kBAAG;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,oBAAoB;AACpC,YAAY,yBAAI;AAChB;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA,cAAc;AACd;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA,0BAA0B,yBAAI,kBAAkB,yBAAI;AACpD;AACA,iBAAiB,kBAAG;AACpB,MAAM;AACN,SAAS,yBAAI,mBAAmB,yBAAI,qBAAqB,yBAAI;AAC7D,QAAQ,yBAAI;AACZ;AACA;AACA,iBAAiB,kBAAG;AACpB,MAAM;AACN,SAAS,yBAAI,mBAAmB,yBAAI,qBAAqB,yBAAI;AAC7D,QAAQ,yBAAI;AACZ;AACA;AACA,iBAAiB,kBAAG;AACpB,MAAM,+BAA+B,wBAAK,wBAAwB,yBAAI;AACtE;AACA,iBAAiB,kBAAG;AACpB,MAAM,+BAA+B,wBAAK,wBAAwB,yBAAI;AACtE;AACA,iBAAiB,kBAAG;AACpB,MAAM,+BAA+B,wBAAK,sBAAsB,yBAAI;AACpE;AACA,iBAAiB,kBAAG;AACpB,MAAM,+BAA+B,wBAAK,sBAAsB,yBAAI;AACpE;AACA,iBAAiB,kBAAG;AACpB,MAAM;AACN;AACA,QAAQ,yBAAI;AACZ,QAAQ,yBAAI;AACZ,QAAQ,yBAAI;AACZ;AACA;AACA;AACA,YAAY,kBAAG;AACf,iBAAiB,kBAAG;AACpB,UAAU;AACV;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,cAAc;AAC9B,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,2BAA2B,kBAAG;AACjC;AACA,6CAAe,kBAAG,OAAO,EAAC;AAC1B;AACA;AACA;AACA;;;ACjiCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACF;AACL;AACS;AACA;AACP;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,iDAAiD,2EAA2E,iBAAiB;AACxJ;AACA,WAAW,iDAAiD,yEAAyE,iBAAiB;AACtJ;AACA,WAAW,QAAQ;AACnB,WAAW,QAAQ,0DAA0D;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,0FAA0F,2FAA2F;AACrL;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB,sBAAsB,yBAAI;AAC1B,qBAAqB,yBAAI;AACzB;AACA;AACA,gBAAgB,OAAO;AACvB;AACA;AACA;AACA;AACA,UAAU,SAAS,yBAAI;AACvB;AACA;AACA,UAAU,SAAS,yBAAI,2BAA2B,yBAAI;AACtD;AACA;AACA,UAAU,SAAS,yBAAI;AACvB;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,oBAAoB,yBAAI;AACxB,MAAM,SAAS,yBAAI,2BAA2B,yBAAI;AAClD;AACA,MAAM;AACN;AACA,YAAY,yBAAI;AAChB;AACA;AACA,UAAU;AACV;AACA;AACA,UAAU,SAAS,yBAAI,2BAA2B,yBAAI;AACtD;AACA;AACA,UAAU,SAAS,yBAAI;AACvB;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,wBAAK;AACtB;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,0BAAM,CAAC,wBAAK;AAChC,8BAA8B,wBAAK,kCAAkC,wBAAK;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,OAAO;AACvB,YAAY,yBAAI;AAChB;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,iDAAiD,2EAA2E,iBAAiB;AACxJ;AACA,WAAW,iDAAiD,yEAAyE,iBAAiB;AACtJ;AACA,WAAW,QAAQ,6DAA6D;AAChF,WAAW,QAAQ,yDAAyD;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,0FAA0F,2FAA2F;AACrL;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB,sBAAsB,yBAAI;AAC1B,qBAAqB,yBAAI;AACzB;AACA;AACA,gBAAgB,OAAO;AACvB;AACA;AACA;AACA;AACA,UAAU,SAAS,yBAAI;AACvB;AACA;AACA,UAAU,SAAS,yBAAI,2BAA2B,yBAAI;AACtD;AACA;AACA,UAAU,SAAS,yBAAI;AACvB;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,oBAAoB,yBAAI;AACxB,MAAM,SAAS,yBAAI,2BAA2B,yBAAI;AAClD;AACA,MAAM;AACN;AACA,YAAY,yBAAI;AAChB;AACA;AACA,UAAU;AACV;AACA;AACA,UAAU,SAAS,yBAAI,2BAA2B,yBAAI;AACtD;AACA;AACA,UAAU,SAAS,yBAAI;AACvB;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,iBAAiB,wBAAK;AACtB;AACA;AACA,gBAAgB,OAAO;AACvB,YAAY,yBAAI;AAChB;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,0BAA0B;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,0FAA0F,2FAA2F;AACrL;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB,sBAAsB,yBAAI;AAC1B,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,SAAS,yBAAI;AACnB;AACA;AACA,MAAM,SAAS,yBAAI,2BAA2B,yBAAI;AAClD;AACA;AACA,MAAM,SAAS,yBAAI;AACnB;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,uBAAQ;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,uBAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,uBAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,wBAAK;AACtB;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,iFAAiF;AAC5F,WAAW,2CAA2C;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,0FAA0F,2FAA2F;AACrL;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB,sBAAsB,yBAAI;AAC1B,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA,MAAM;AACN;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA,cAAc,SAAS,yBAAI;AAC3B;AACA;AACA,cAAc,SAAS,yBAAI,2BAA2B,yBAAI;AAC1D;AACA;AACA,cAAc,SAAS,yBAAI;AAC3B;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,mBAAG;AAChB,cAAc,mBAAG;AACjB,aAAa,mBAAG;AAChB,cAAc,mBAAG;AACjB;AACA,oBAAoB,OAAO;AAC3B,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA,8BAA8B,mBAAG,2BAA2B,mBAAG;AAC/D,8BAA8B,mBAAG,2BAA2B,mBAAG;AAC/D;AACA,cAAc;AACd,4BAA4B,OAAO;AACnC,gCAAgC,OAAO;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,uBAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,OAAO;AAClC;AACA,+BAA+B,OAAO;AACtC;AACA;AACA;AACA,iCAAiC,OAAO;AACxC;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,mBAAG;AACnB,UAAU;AACV,gBAAgB,mBAAG;AACnB,UAAU;AACV,gBAAgB,mBAAG;AACnB;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,wBAAK;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,4BAA4B,kBAAG;AAClC,kBAAG,8BAA8B,kBAAG;AACpC,kBAAG,6BAA6B,kBAAG;AACnC,kBAAG,0BAA0B,kBAAG;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;;;AC5oCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACO;AACF;AACc;AACJ;AACP;AACO;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,OAAO;AAClB;AACA,WAAW,QAAQ,4DAA4D;AAC/E,QAAQ,0BAA0B;AAClC;AACA,kBAAG;AACH,wCAAwC,wBAAK,sBAAsB,wBAAK;AACxE;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,6BAA6B;AACxD;AACA;AACA;AACA;AACA;AACA,gBAAgB,qBAAqB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,8BAA8B;AAC9C;AACA,YAAY,yBAAI;AAChB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,kBAAG;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,kBAAG,yBAAyB,2BAAe;AAC3C;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,mBAAmB,uBAAQ;AAC3B,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,0BAAM,CAAC,wBAAK;AACvC;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,0BAA0B;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,0BAAM,CAAC,wBAAK;AACnC,SAAS;AACT;AACA,wBAAwB,kBAAG,UAAU,kBAAG;AACxC;AACA;AACA;AACA;AACA,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAyB;AACrD;AACA;AACA;AACA;AACA,iCAAiC,yBAAI;AACrC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAyB;AACrD;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA,4BAA4B,uBAAQ;AACpC,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA,iDAAiD,qBAAqB;AACtE,4DAA4D,yBAAyB;AACrF,uGAAuG,cAAc;AACrH;AACA;AACA,4FAA4F,sFAAsF;AAClL;AACA,mDAAmD,qBAAqB;AACxE,8DAA8D,yBAAyB;AACvF,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,iDAAiD,6BAA6B;AAC9E;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAyB;AACjD;AACA;AACA;AACA,YAAY,2BAAe;AAC3B,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW,mCAAmC;AACjE,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA,wBAAwB,0BAA0B;AAClD;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,qBAAqB,aAAa;AAClC;AACA,qEAAqE,qBAAqB;AAC1F;AACA;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G,yEAAyE,qBAAqB;AAC9F;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,mBAAmB,WAAW;AAC9B,qBAAqB,aAAa;AAClC;AACA;AACA,qEAAqE,qBAAqB;AAC1F;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G,yEAAyE,qBAAqB;AAC9F;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,YAAY;AACpC,oBAAoB,yBAAI,6CAA6C;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,gCAAgC,gBAAgB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW,mCAAmC,iBAAiB;AAClF,qBAAqB,aAAa;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,sBAAsB;AAC9C;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,iBAAiB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,QAAQ;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,sBAAsB;AAC9C,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,sBAAsB;AAClD,kDAAkD,yBAAyB;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,qBAAqB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,uBAAuB,2BAAe;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAyB;AACrD;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,wBAAwB,0BAA0B;AAClD;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ,+DAA+D,0BAA0B,KAAK,2BAA2B;AACpJ,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,qBAAqB,aAAa;AAClC;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,0BAAM;AAC9B,2BAA2B,0BAAM;AACjC;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAU;AAC3B,8DAA8D,mBAAmB;AACjF;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,sBAAsB,4BAA4B;AAClD;AACA;AACA;AACA,mBAAmB,aAAa;AAChC;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA,uBAAuB,kBAAG;AAC1B,0BAA0B,kBAAG;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,gBAAgB;AACxC;AACA;AACA;AACA,wBAAwB,aAAa;AACrC;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,WAAW;AACvC;AACA;AACA;AACA,oCAAoC,kBAAG;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,gCAAgC,kBAAG;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,wDAAwD,oCAAoC;AAC5F;AACA,sDAAsD,oBAAoB;AAC1E;AACA;AACA,mBAAmB,aAAa;AAChC;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA,sEAAsE,kBAAkB;AACxF,uGAAuG,cAAc;AACrH;AACA;AACA,gGAAgG,oFAAoF;AACpL;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,wBAAwB;AACxB;AACA;AACA,2EAA2E,kBAAkB;AAC7F,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA,wDAAwD,oCAAoC;AAC5F;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA,gGAAgG,oFAAoF;AACpL;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA,0DAA0D,oCAAoC;AAC9F;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,sFAAsF;AAC1K;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,yCAAyC,qBAAqB;AAC9D,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,sFAAsF;AAC1K;AACA,2CAA2C,qBAAqB;AAChE,KAAK;AACL;AACA;AACA;AACA,2BAA2B,oBAAoB;AAC/C,2BAA2B,oBAAoB;AAC/C,2BAA2B,oBAAoB;AAC/C,2BAA2B,oBAAoB;AAC/C;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,sFAAsF;AAC1K,2BAA2B,oBAAoB;AAC/C,2BAA2B,oBAAoB;AAC/C,2BAA2B,oBAAoB;AAC/C,2BAA2B,oBAAoB;AAC/C;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,gDAAgD,cAAc;AAC9D,2CAA2C,UAAU;AACrD,2CAA2C,UAAU;AACrD,6CAA6C,UAAU;AACvD,gDAAgD,WAAW,kBAAkB;AAC7E,kDAAkD,WAAW,iBAAiB;AAC9E;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,oDAAoD,cAAc;AAClE,+CAA+C,UAAU;AACzD,+CAA+C,UAAU;AACzD,iDAAiD,UAAU;AAC3D,oDAAoD,WAAW,kBAAkB;AACjF,sDAAsD,WAAW,iBAAiB;AAClF;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,qBAAqB,wBAAK;AAC1B,QAAQ,yBAAI;AACZ;AACA;AACA;AACA,sBAAsB,yBAAI;AAC1B,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,aAAa,kBAAG;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,4BAA4B;AACvC;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,sFAAsF;AAC1K;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,sFAAsF;AAC1K;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA,mDAAmD,uBAAuB;AAC1E,0DAA0D,gBAAgB;AAC1E;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,uDAAuD,uBAAuB;AAC9E,8DAA8D,gBAAgB;AAC9E;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,gBAAgB,OAAO;AACvB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,UAAU;AACV,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA,wBAAwB,wBAAK;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,UAAU,gBAAgB;AAC7E;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0DAA0D,UAAU,gBAAgB;AACpF;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,iDAAiD;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,yBAAI;AAClB;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,4BAA4B,kBAAG;AAClC,kBAAG,mCAAmC,kBAAG;AACzC,kBAAG,mCAAmC,kBAAG;AACzC,kBAAG,kCAAkC,kBAAG;AACxC;AACA,8CAAe,kBAAG,QAAQ,EAAC;AAC3B;AACA;AACA;AACA;AACA;;;AC5hDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACO;AACA;AACF;AACU;AACA;AACM;AACE;AACjB;AACS;AACA;AACR;AACF;AACG;AACpC;AACA;AACA;AACA,0FAA0F,wBAAwB;AAClH,SAAS,YAAY,MAAM,qBAAqB;AAChD;AACA,WAAW,kBAAkB;AAC7B,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA;AACA,kBAAG;AACH,wCAAwC,wBAAK,oBAAoB,wBAAK;AACtE;AACA;AACA;AACA;AACA;AACA,qBAAqB,4BAA4B;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,gCAAgC;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,gCAAgC;AACnD;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,0BAA0B,KAAK,6BAA6B;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,kBAAG,uBAAuB,2BAAe;AACzC;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA,kCAAkC,6BAA6B;AAC/D,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,0BAAM;AACnC,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,kCAAkC,6BAA6B;AAC/D,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,0BAAM;AACpC,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ,oBAAoB,sBAAsB,KAAK,qBAAqB;AAC/F,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ,oBAAoB,sBAAsB,KAAK,qBAAqB;AAC/F,mBAAmB,SAAS;AAC5B;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ,oBAAoB,sBAAsB,KAAK,qBAAqB;AAC/F,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ,oBAAoB,sBAAsB,KAAK,qBAAqB;AAC/F,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,6BAA6B,0BAAM,CAAC,wBAAK;AACzC;AACA;AACA;AACA;AACA;AACA,uBAAuB,uBAAQ;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,mBAAG;AAChC,wBAAwB,mBAAG;AAC3B;AACA;AACA;AACA;AACA;AACA,oCAAoC,WAAW;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA,6CAA6C,0BAAM,CAAC,wBAAK;AACzD;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,gCAAgC,SAAS;AACzC;AACA;AACA,8BAA8B,uBAAQ;AACtC,sBAAsB;AACtB;AACA;AACA,sCAAsC,uBAAQ;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,uBAAQ;AAC9C;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B,kCAAkC,uBAAQ;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,SAAS;AACtD,yCAAyC,0BAAM;AAC/C,wBAAwB,wBAAK;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,IAAI;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,2BAA2B,uBAAuB,KAAK,sBAAsB;AAC7E,uBAAuB,4BAA4B;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uEAAuE,qBAAqB;AAC5F,0DAA0D;AAC1D,mCAAmC;AACnC;AACA,oDAAoD,iCAAiC;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,OAAO;AACtC,oCAAoC,QAAQ;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,iCAAiC;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,OAAO;AACtC,mCAAmC,QAAQ;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,2GAA2G;AACnI,mFAAmF,qBAAqB;AACxG,sEAAsE;AACtE,4DAA4D;AAC5D;AACA,gEAAgE,iCAAiC;AACjG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,IAAI;AAC5C,6CAA6C,KAAK;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE,iCAAiC;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,IAAI;AAC5C,6CAA6C,KAAK;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA,uDAAuD,mCAAmC;AAC1F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC,4CAA4C;AAC5C;AACA;AACA;AACA,2BAA2B;AAC3B;AACA,wGAAwG,cAAc;AACtH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA,2DAA2D,mCAAmC;AAC9F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC;AACpC,gDAAgD;AAChD;AACA;AACA;AACA,+BAA+B;AAC/B;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA,4BAA4B,wBAAK;AACjC;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,4BAA4B,wBAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,wBAAwB,IAAI;AAC5B,sBAAsB;AACtB,wBAAwB,IAAI;AAC5B,sBAAsB;AACtB,wBAAwB,IAAI;AAC5B,sBAAsB;AACtB,wBAAwB,IAAI;AAC5B,sBAAsB;AACtB,wBAAwB,IAAI;AAC5B;AACA;AACA,kBAAkB;AAClB;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,oBAAoB,IAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,GAAG;AACtC,gCAAgC,wBAAwB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,SAAS;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,uBAAQ;AACtC;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,oCAAoC,mBAAG;AACvC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,6BAA6B,uCAAuC;AACpE,mBAAmB,WAAW;AAC9B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAG;AACvB,iCAAiC,wBAAK;AACtC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,0BAA0B,sBAAsB,0BAA0B,gBAAgB,yBAAyB;AACtI,qBAAqB,WAAW;AAChC;AACA;AACA;AACA,uBAAuB,yBAAI;AAC3B;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,OAAO;AACvC,4BAA4B,yBAAI;AAChC;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC,wBAAwB,yBAAI;AAC5B;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,8BAA8B;AACjD,mBAAmB,8BAA8B;AACjD,mBAAmB,wBAAwB;AAC3C,mBAAmB,wBAAwB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,yBAAyB,yBAAI;AAC7B,oBAAoB,yBAAI;AACxB;AACA,kBAAkB,SAAS,yBAAI,sBAAsB,yBAAI;AACzD;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc,UAAU,yBAAI;AAC5B;AACA;AACA,sBAAsB,mBAAG;AACzB;AACA;AACA;AACA;AACA,cAAc;AACd,yBAAyB,yBAAI;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI,sBAAsB,yBAAI;AAC9C;AACA,qBAAqB,yBAAI;AACzB,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,4BAA4B,yBAAI;AAChC,cAAc;AACd;AACA;AACA,gBAAgB,yBAAI;AACpB,4BAA4B,yBAAI;AAChC,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,sBAAa;AAC7B;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,uBAAQ;AACzB,iBAAiB,uBAAQ;AACzB;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,mBAAmB,yBAAI;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,0BAAM,CAAC,wBAAK;AACjC;AACA,gBAAgB,mBAAG;AACnB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,gBAAgB,mBAAG;AACnB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,0BAAM,CAAC,wBAAK;AACnC,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,2BAA2B,0BAAM,CAAC,wBAAK;AACvC;AACA;AACA,iBAAiB,yBAAI;AACrB,2BAA2B,0BAAM,CAAC,wBAAK;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,0BAAM,CAAC,wBAAK;AAChC,mBAAmB,uBAAQ;AAC3B;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC,uCAAuC,yBAAI;AAC3C;AACA,qBAAqB;AACrB,uCAAuC,yBAAI;AAC3C;AACA,qBAAqB;AACrB;AACA,yBAAyB,uBAAQ;AACjC;AACA,uBAAuB,uBAAQ;AAC/B;AACA;AACA,qBAAqB;AACrB;AACA;AACA,uBAAuB,uBAAQ;AAC/B;AACA;AACA,qBAAqB;AACrB;AACA;AACA,uBAAuB,uBAAQ;AAC/B;AACA;AACA,qBAAqB;AACrB;AACA;AACA,uBAAuB,uBAAQ;AAC/B;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,iCAAiC,wBAAK;AACtC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,+CAA+C,wBAAK;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,wCAAwC,aAAa;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kEAAkE;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,sBAAsB;AAC9D,wCAAwC,sBAAsB;AAC9D;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,uFAAuF,qFAAqF;AAC5K,yDAAyD,sBAAsB,cAAc,sBAAsB;AACnH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,OAAO;AACtD,+FAA+F,cAAc;AAC7G;AACA,uFAAuF,oFAAoF;AAC3K;AACA;AACA,mDAAmD,OAAO;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C,oCAAoC;AAC9E;AACA;AACA,4BAA4B;AAC5B;AACA,+FAA+F,cAAc;AAC7G;AACA,uFAAuF,kFAAkF;AACzK;AACA,2DAA2D,oCAAoC,yBAAyB,mBAAmB;AAC3I;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,wCAAwC;AACpF,4CAA4C,wCAAwC;AACpF,8CAA8C,wCAAwC;AACtF,0CAA0C,wCAAwC;AAClF;AACA;AACA,iBAAiB,6DAA6D,GAAG;AACjF;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,+EAA+E,kFAAkF;AACjK;AACA;AACA,4CAA4C,wCAAwC;AACpF,4CAA4C,wCAAwC;AACpF,8CAA8C,wCAAwC;AACtF,0CAA0C,wCAAwC;AAClF;AACA;AACA,iBAAiB,6DAA6D,GAAG;AACjF;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA,mDAAmD,uBAAuB;AAC1E,0DAA0D,gBAAgB;AAC1E;AACA,4DAA4D,mBAAmB;AAC/E;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,uDAAuD,uBAAuB;AAC9E,8DAA8D,gBAAgB;AAC9E;AACA,gEAAgE,mBAAmB;AACnF;AACA,QAAQ;AACR;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,QAAQ,yBAAI;AACZ,sBAAsB,wBAAK;AAC3B,yBAAyB,wBAAK;AAC9B,yBAAyB,wBAAK;AAC9B,yBAAyB,wBAAK;AAC9B,yBAAyB,wBAAK;AAC9B;AACA,yBAAyB,wBAAK;AAC9B,mBAAmB,yBAAI;AACvB,UAAU,sBAAsB,wBAAK;AACrC,mBAAmB,yBAAI;AACvB,UAAU,sBAAsB,wBAAK;AACrC,iBAAiB,yBAAI;AACrB;AACA;AACA,mBAAmB,yBAAI;AACvB,UAAU;AACV,mBAAmB,yBAAI;AACvB;AACA,eAAe,yBAAI;AACnB;AACA,iBAAiB,kBAAG;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,eAAe,kBAAG;AAClB;AACA;AACA,kBAAG,0BAA0B,kBAAG;AAChC;AACA;AACA,oDAAoD;AACpD,gEAAgE,aAAa;AAC7E;AACA;AACA;AACA;AACA;AACA,WAAW,0CAA0C;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,oBAAoB;AAC5D;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K,mEAAmE,oBAAoB;AACvF;AACA;AACA;AACA;AACA;AACA,wCAAwC,oBAAoB;AAC5D;AACA,sCAAsC,kBAAkB;AACxD;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA,mEAAmE,oBAAoB,iBAAiB,kBAAkB;AAC1H;AACA;AACA,kBAAG;AACH;AACA,0CAA0C;AAC1C,iCAAiC,WAAW;AAC5C;AACA,WAAW,yBAAI;AACf,WAAW,yBAAI;AACf;AACA,eAAe,kBAAG;AAClB;AACA;AACA,kBAAG,kCAAkC,kBAAG;AACxC,kBAAG,yBAAyB,kBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,WAAW;AACxB;AACA;AACA;AACA;AACA,yCAAyC,mBAAmB;AAC5D,yCAAyC,mBAAmB;AAC5D,wCAAwC,mBAAmB;AAC3D,wCAAwC,mBAAmB;AAC3D;AACA,sCAAsC,cAAc;AACpD,gFAAgF,cAAc;AAC9F;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA,6CAA6C,mBAAmB;AAChE,6CAA6C,mBAAmB;AAChE,4CAA4C,mBAAmB;AAC/D,4CAA4C,mBAAmB;AAC/D;AACA,0CAA0C,cAAc;AACxD,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B,wBAAwB,yBAAI;AAC5B;AACA;AACA,oCAAoC,uBAAuB;AAC3D,gCAAgC,yBAAI;AACpC;AACA,8BAA8B;AAC9B;AACA;AACA;AACA,gCAAgC,yBAAI;AACpC;AACA,8BAA8B;AAC9B;AACA;AACA;AACA,sBAAsB;AACtB,oCAAoC,oBAAoB;AACxD,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA,8BAA8B,SAAS,yBAAI;AAC3C,4CAA4C,oBAAoB;AAChE,wCAAwC,yBAAI;AAC5C;AACA,sCAAsC;AACtC;AACA;AACA;AACA,wCAAwC,yBAAI;AAC5C;AACA,sCAAsC;AACtC;AACA;AACA;AACA,8BAA8B;AAC9B,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,uBAAQ;AAChC;AACA;AACA,uBAAuB,uBAAQ;AAC/B,aAAa;AACb;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA,aAAa,kBAAG;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,2BAA2B,kBAAG;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iBAAiB;AAC5B,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qEAAqE,WAAW;AAChF,0DAA0D,oBAAoB,IAAI,cAAc;AAChG;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yEAAyE,WAAW;AACpF,8DAA8D,oBAAoB,IAAI,cAAc;AACpG;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,yBAAI,wBAAwB,yBAAI;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,yBAAI;AACb,UAAU,yBAAI,0BAA0B,yBAAI;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,yBAAI,wBAAwB,yBAAI;AACzC;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,QAAQ,yBAAI;AACZ;AACA;AACA,oBAAoB,iBAAiB;AACrC;AACA,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA,MAAM;AACN;AACA,oBAAoB,cAAc;AAClC,gBAAgB,yBAAI;AACpB;AACA,cAAc,SAAS,yBAAI;AAC3B;AACA;AACA,cAAc,SAAS,yBAAI;AAC3B;AACA,oBAAoB,yBAAI;AACxB;AACA,kBAAkB;AAClB;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA,kBAAkB;AAClB;AACA;AACA,cAAc,SAAS,yBAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,2BAA2B,mBAAG;AAC9B;AACA;AACA;AACA;AACA,oBAAoB,cAAc;AAClC,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,uBAAQ;AACrC;AACA,aAAa,kBAAG;AAChB;AACA;AACA,gBAAgB,QAAQ;AACxB;AACA,YAAY,yBAAI;AAChB,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,mCAAmC,kBAAG;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB,aAAa,WAAW;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,4EAA4E,gBAAgB;AAC5F,yEAAyE,kBAAkB;AAC3F,4EAA4E,oBAAoB;AAChG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,yBAAyB;AACzD,wBAAwB,eAAe,uBAAuB;AAC9D,mBAAmB,eAAe,sBAAsB;AACxD,kCAAkC;AAClC,gBAAgB;AAChB;AACA;AACA;AACA;AACA,gEAAgE,oCAAoC;AACpG;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,gFAAgF,gBAAgB;AAChG,6EAA6E,kBAAkB;AAC/F,gFAAgF,oBAAoB;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,yBAAyB;AAC7D,4BAA4B,eAAe,uBAAuB;AAClE,uBAAuB,eAAe,sBAAsB;AAC5D,sCAAsC;AACtC,oBAAoB;AACpB;AACA;AACA;AACA;AACA,oEAAoE,oCAAoC;AACxG;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,yBAAI,wBAAwB,yBAAI;AACzC;AACA;AACA;AACA;AACA;AACA,SAAS,yBAAI,wBAAwB,yBAAI;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,QAAQ,yBAAI;AACZ;AACA;AACA,oBAAoB,iBAAiB;AACrC;AACA,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA,MAAM;AACN;AACA,oBAAoB,cAAc;AAClC,gBAAgB,yBAAI;AACpB;AACA,cAAc,SAAS,yBAAI;AAC3B;AACA;AACA,cAAc,SAAS,yBAAI;AAC3B;AACA,oBAAoB,yBAAI;AACxB;AACA,kBAAkB;AAClB;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA,kBAAkB;AAClB;AACA;AACA,cAAc,SAAS,yBAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,cAAc;AAClC,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,kBAAG;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA,cAAc,QAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,mCAAmC,kBAAG;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,gFAAgF;AAC3F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,YAAY;AACvE,2BAA2B;AAC3B;AACA,gCAAgC,kBAAkB;AAClD,kBAAkB;AAClB;AACA;AACA,qDAAqD,4CAA4C;AACjG,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK,2BAA2B;AAC3B,2DAA2D,YAAY;AACvE,uDAAuD,kBAAkB,oBAAoB,gBAAgB;AAC7G;AACA,qDAAqD,4CAA4C;AACjG,IAAI;AACJ;AACA;AACA;AACA;AACA,2DAA2D,YAAY;AACvE,2BAA2B;AAC3B,2BAA2B;AAC3B;AACA,oCAAoC,kBAAkB;AACtD,kBAAkB;AAClB;AACA;AACA;AACA,qDAAqD,4CAA4C;AACjG,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK,2DAA2D,YAAY;AACvE,2BAA2B;AAC3B,2BAA2B;AAC3B;AACA,oCAAoC,kBAAkB;AACtD,kBAAkB;AAClB;AACA;AACA;AACA,qDAAqD,4CAA4C;AACjG,IAAI;AACJ;AACA;AACA,kBAAG;AACH;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,uBAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,+BAA+B,kBAAG;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,wFAAwF,sFAAsF;AAC9K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,wBAAK,wBAAwB,yBAAI;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,wBAAK;AAC3C;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA,uCAAuC,wBAAK;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,+BAA+B,kBAAG;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,eAAe,gBAAgB;AAC/B;AACA;AACA;AACA;AACA;AACA,mGAAmG,cAAc;AACjH;AACA,4FAA4F,qFAAqF;AACjL;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,iCAAiC,kBAAG;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB;AACA;AACA,yGAAyG,oBAAoB;AAC7H,6CAA6C,QAAQ;AACrD;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,6GAA6G,oBAAoB;AACjI,iDAAiD,QAAQ;AACzD;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,qDAAqD,wBAAK;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA,SAAS,uBAAQ;AACjB,SAAS,uBAAQ;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,+BAA+B,kBAAG;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,kCAAkC;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,gCAAgC;AAC/E;AACA,+DAA+D,sCAAsC;AACrG;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA,mDAAmD,gCAAgC;AACnF;AACA,mEAAmE,sCAAsC;AACzG;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,IAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,kCAAkC;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,gCAAgC;AAC/E;AACA,wDAAwD,sCAAsC;AAC9F;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA,mDAAmD,gCAAgC;AACnF;AACA,4DAA4D,sCAAsC;AAClG;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,IAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kCAAkC;AAC7C,WAAW,kCAAkC;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,gCAAgC;AAC/E;AACA,6DAA6D,sCAAsC;AACnG;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA,mDAAmD,gCAAgC;AACnF;AACA,iEAAiE,sCAAsC;AACvG;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,IAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,oCAAoC,kBAAG;AAC1C,kBAAG,sCAAsC,kBAAG;AAC5C,kBAAG,+BAA+B,kBAAG;AACrC;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,WAAW;AACzB,cAAc,WAAW;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,iBAAiB;AAC5B,WAAW,iBAAiB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,eAAe;AAC9D;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA,mDAAmD,eAAe;AAClE;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,+CAA+C,iDAAiD;AAChG;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA,mDAAmD,iDAAiD;AACpG;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,mFAAmF;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,gBAAgB,0BAA0B,gBAAgB;AACnF;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA,6BAA6B,gBAAgB,0BAA0B,gBAAgB;AACvF;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA,gBAAgB,SAAS;AACzB,mBAAmB,yBAAI;AACvB;AACA,YAAY,yBAAI;AAChB,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,4BAA4B,kBAAG;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,qCAAqC;AACzC,IAAI,qCAAqC;AACzC,IAAI,4BAA4B;AAChC,IAAI,8BAA8B;AAClC,IAAI,0BAA0B;AAC9B,IAAI,4BAA4B;AAChC;AACA;AACA;AACA,WAAW,iBAAiB;AAC5B;AACA,WAAW,iBAAiB;AAC5B;AACA,WAAW,iBAAiB;AAC5B;AACA,WAAW,gBAAgB;AAC3B;AACA;AACA,WAAW,gBAAgB;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,uBAAuB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA,2BAA2B,uBAAuB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,UAAU,yBAAI;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,gCAAgC,yBAAI,yBAAyB,yBAAI;AACjE,gBAAgB,yBAAI;AACpB,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,gCAAgC,yBAAI,yBAAyB,yBAAI;AACjE,gBAAgB,yBAAI;AACpB,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,iBAAiB,yBAAI;AACrB,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,YAAY;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,kCAAkC,kBAAG;AACxC;AACA;AACA,4CAAe,kBAAG,MAAM,EAAC;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;;;ACx/GZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACe;AACT;AACK;AACA;AACH;AACK;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,mDAAmD;AAC1F,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA;AACA,6CAA6C,mDAAmD;AAChG,IAAI;AACJ;AACA;AACA;AACA,gDAAgD,cAAc;AAC9D,2DAA2D,mBAAmB;AAC9E,4CAA4C,mBAAmB;AAC/D;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,oDAAoD,cAAc;AAClE,+DAA+D,mBAAmB;AAClF,gDAAgD,mBAAmB;AACnE;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,iCAAiC;AACjC,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,wBAAK;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,uBAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,uBAAQ;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uEAAuE,kBAAkB,KAAK,sBAAsB;AACpH;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,QAAQ,kBAAG;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA,mFAAmF,8BAA8B;AACjH;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA,qBAAqB,uBAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,UAAU;AACV;AACA,UAAU;AACV;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,yBAAyB,0BAAM,CAAC,wBAAK;AACrC;AACA;AACA;AACA;AACA;AACA,qBAAqB,mBAAG;AACxB,gBAAgB,mBAAG;AACnB,6BAA6B,0BAAM,CAAC,wBAAK;AACzC;AACA;AACA,2CAA2C,wBAAK;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,uBAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA,6BAA6B,0BAAM,CAAC,wBAAK;AACzC;AACA,+CAA+C,wBAAK;AACpD;AACA;AACA;AACA,kBAAkB,uBAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,uBAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,0BAAM;AAC/B,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,mBAAG;AACrB;AACA;AACA;AACA;AACA,4BAA4B,uBAAQ,mBAAmB,uBAAQ;AAC/D;AACA,uBAAuB,0BAAM,CAAC,wBAAK;AACnC,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,MAAM;AACnC;AACA;AACA,uBAAuB,MAAM;AAC7B;AACA,mBAAmB,kBAAG;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,kBAAG,wBAAwB,kBAAG;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,qBAAqB;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,+BAA+B,kBAAG;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,oCAAoC,kBAAG;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA,kBAAG;AACH;AACA,WAAW,kBAAG;AACd;AACA;AACA,kBAAG,6BAA6B,kBAAG;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA,kBAAG;AACH;AACA,WAAW,kBAAG;AACd;AACA;AACA,kBAAG,6BAA6B,kBAAG;;;AC7qBnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACe;AACT;AACa;AACR;AACE;AACL;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA;AACA,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,6DAA6D;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,oCAAoC;AAC7E,yCAAyC,eAAe;AACxD;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA;AACA,4CAA4C,oCAAoC;AAChF,4CAA4C,eAAe;AAC3D;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA,gDAAgD,cAAc;AAC9D;AACA,gCAAgC,aAAa,WAAW,cAAc,gBAAgB,cAAc;AACpG,6DAA6D;AAC7D,4CAA4C,0CAA0C;AACtF;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,oDAAoD,cAAc;AAClE;AACA,oCAAoC,aAAa,WAAW,cAAc,gBAAgB,cAAc;AACxG,iEAAiE;AACjE,gDAAgD,0CAA0C;AAC1F;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,QAAQ;AACjC,0BAA0B;AAC1B;AACA,UAAU;AACV,6BAA6B,kBAAkB;AAC/C,2BAA2B,iBAAiB;AAC5C;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,QAAQ;AACrC,8BAA8B;AAC9B;AACA,cAAc;AACd,iCAAiC,kBAAkB;AACnD,+BAA+B,iBAAiB;AAChD;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,wBAAK;AACzC,oCAAoC,wBAAK;AACzC,SAAS,yBAAI,wBAAwB,yBAAI;AACzC,SAAS,yBAAI,wBAAwB,yBAAI;AACzC,SAAS,yBAAI,yBAAyB,yBAAI,2BAA2B,yBAAI;AACzE;AACA;AACA,MAAM;AACN,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA,cAAc,wBAAK;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,YAAY;AAC7C;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,sBAAsB;AACtB,sBAAsB;AACtB;AACA;AACA,YAAY,uBAAQ;AACpB,YAAY,uBAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,uBAAQ;AACxB,kBAAkB,UAAU,yBAAyB;AACrD;AACA;AACA;AACA,gBAAgB,yBAAU;AAC1B;AACA,gBAAgB,mBAAG;AACnB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,uBAAQ;AACxB,kBAAkB,UAAU,yBAAyB;AACrD;AACA;AACA;AACA,gBAAgB,yBAAU;AAC1B;AACA,gBAAgB,mBAAG;AACnB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,uBAAuB,kBAAG;AAC1B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,mBAAG;AACnB,gBAAgB,uBAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAU;AAC1B;AACA;AACA;AACA,gBAAgB,yBAAU;AAC1B;AACA,qCAAqC,0BAAM,CAAC,wBAAK;AACjD,qCAAqC,0BAAM,CAAC,wBAAK;AACjD,qCAAqC,0BAAM,CAAC,wBAAK;AACjD;AACA;AACA,iCAAiC,mBAAG;AACpC,iCAAiC,mBAAG;AACpC,iCAAiC,mBAAG;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,uBAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,qBAAqB;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,mDAAmD;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA,uBAAuB,kBAAG;AAC1B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,uBAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,yBAAI;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,uBAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ,sBAAsB,qBAAqB,KAAK,oBAAoB;AACjG;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,kDAAkD,wBAAK;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,cAAc;AACd;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,0BAAM,CAAC,wBAAK;AACzC;AACA,+CAA+C,wBAAK;AACpD;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,uBAAQ;AAC5B;AACA,mBAAmB,uBAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,iBAAiB,SAAS;AAC1B;AACA;AACA;AACA,6BAA6B,0BAAM,CAAC,wBAAK;AACzC;AACA,+CAA+C,wBAAK;AACpD;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,uBAAQ;AAC5B;AACA,mBAAmB,uBAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,uBAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,0BAAM;AAC/B,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,mBAAG;AACrB;AACA;AACA;AACA;AACA,4BAA4B,uBAAQ,mBAAmB,uBAAQ;AAC/D;AACA,uBAAuB,0BAAM,CAAC,wBAAK;AACnC,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,mCAAmC;AACnD;AACA;AACA,eAAe,iBAAiB;AAChC;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA,UAAU,SAAS,yBAAI;AACvB;AACA,UAAU,SAAS,yBAAI,qBAAqB,yBAAI;AAChD;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,kBAAG;AACX;AACA;AACA;AACA;AACA,sEAAsE,gBAAgB;AACtF;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ,+DAA+D,0BAA0B,KAAK,2BAA2B;AACpJ,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA,wBAAwB,0BAAM;AAC9B,2BAA2B,0BAAM;AACjC;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAU;AAC3B,8DAA8D,mBAAmB;AACjF;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,kBAAG;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,kBAAG,2BAA2B,kBAAG;AACjC;AACA;AACA;AACA,8CAA8C,cAAc;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA,kBAAG;AACH;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,uCAAuC,kBAAG;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,QAAQ;AACjC,0BAA0B;AAC1B;AACA,UAAU;AACV,6BAA6B,kBAAkB;AAC/C,2BAA2B,iBAAiB;AAC5C;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,QAAQ;AACrC,8BAA8B;AAC9B;AACA,cAAc;AACd,iCAAiC,kBAAkB;AACnD,+BAA+B,iBAAiB;AAChD;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA,WAAW,kBAAG;AACd;AACA;AACA,kBAAG,gCAAgC,kBAAG;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA,kBAAG;AACH;AACA,WAAW,kBAAG;AACd;AACA;AACA,kBAAG,gCAAgC,kBAAG;AACtC;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,6BAA6B;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA,WAAW,6CAA6C;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,mCAAmC;AACvF,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA;AACA,oDAAoD,mCAAmC;AACvF,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,oCAAoC;AAC7E,yCAAyC,eAAe;AACxD;AACA,+DAA+D,UAAU;AACzE,oDAAoD,UAAU;AAC9D;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA;AACA,4CAA4C,oCAAoC;AAChF,4CAA4C,eAAe;AAC3D;AACA,kEAAkE,UAAU;AAC5E,uDAAuD,UAAU;AACjE,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,cAAc;AAC9D;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,oDAAoD,cAAc;AAClE;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,wBAAK;AACzC,oCAAoC,wBAAK;AACzC,SAAS,yBAAI,wBAAwB,yBAAI;AACzC,SAAS,yBAAI,wBAAwB,yBAAI;AACzC;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA,SAAS,yBAAI;AACb,yCAAyC,MAAM,wBAAK,oBAAoB;AACxE;AACA;AACA,QAAQ,yBAAI;AACZ;AACA,MAAM;AACN;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yBAAyB;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,uBAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,uBAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,iBAAiB;AACpC,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,SAAS;AAC5D;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,UAAU;AACjE;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,SAAS;AAC5D;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,UAAU;AACjE;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,yBAAyB,mBAAG;AAC5B;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,0CAA0C,wBAAK,iBAAiB,mBAAG;AACnE,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B;AAC/B,MAAM;AACN;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA,cAAc,wBAAK;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,uBAAQ;AACrB,aAAa,uBAAQ;AACrB;AACA;AACA;AACA;AACA;AACA,YAAY,mBAAG;AACf;AACA,YAAY,mBAAG;AACf;AACA;AACA,YAAY,mBAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,uBAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,0EAA0E,mBAAG;AAC7E;AACA;AACA;AACA;AACA;AACA,qCAAqC;AACrC,UAAU;AACV;AACA,qCAAqC;AACrC,UAAU;AACV;AACA,qCAAqC;AACrC,UAAU;AACV;AACA,qCAAqC;AACrC;AACA,wCAAwC,eAAe;AACvD;AACA;AACA;AACA;AACA,oCAAoC,gBAAgB;AACpD;AACA;AACA;AACA,cAAc,yBAAI;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,uBAAQ;AAC5B,qBAAqB,uBAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA,MAAM;AACN,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB;AACA;AACA;AACA,sEAAsE,8BAA8B;AACpG;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,UAAU;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA,gBAAgB,yBAAI,uBAAuB,yBAAI;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,uBAAQ;AACxB,iBAAiB,uBAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,mBAAG;AACrB;AACA;AACA;AACA;AACA,gBAAgB,uBAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,uBAAQ,mBAAmB,uBAAQ;AAC/D;AACA,uBAAuB,0BAAM,CAAC,wBAAK;AACnC,UAAU;AACV;AACA;AACA;AACA;AACA,mBAAmB,yBAAI;AACvB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,kBAAG,0BAA0B,kBAAG;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD,UAAU;AACnE,oDAAoD,mCAAmC;AACvF,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA,yDAAyD,UAAU;AACnE,oDAAoD,mCAAmC;AACvF,IAAI;AACJ;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,SAAS,kBAAG;AACZ;AACA;AACA;AACA,kBAAkB,uBAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,mCAAmC,kBAAG;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,UAAU;AAChE,oDAAoD,mCAAmC;AACvF,+FAA+F,cAAc;AAC7G;AACA;AACA,kFAAkF,qFAAqF;AACvK;AACA;AACA;AACA;AACA,sDAAsD,UAAU;AAChE,oDAAoD,mCAAmC;AACvF,IAAI;AACJ;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,SAAS,kBAAG;AACZ;AACA;AACA;AACA,kBAAkB,uBAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,gCAAgC,kBAAG;;;ACz7DtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,2BAA2B;AAChD,uBAAuB,iBAAiB;AACxC;AACA,UAAU,qBAAqB;AAC/B,UAAU,eAAe;AACzB,UAAU,cAAc;AACxB,UAAU,mBAAmB;AAC7B,UAAU,2BAA2B;AACrC,UAAU,eAAe;AACzB,UAAU,eAAe;AACzB,UAAU,kBAAkB;AAC5B,UAAU,aAAa;AACvB,UAAU,2BAA2B;AACrC,UAAU,eAAe;AACzB,UAAU,oBAAoB;AAC9B,UAAU,yBAAyB;AACnC,UAAU,2BAA2B;AACrC,UAAU,iBAAiB;AAC3B;AACA;AAC4B;AACM;AACS;AACA;AACJ;AACH;AACK;AACzC;AACA;AACA;AACA;AACiD;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,oBAAoB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,oCAAoC,wBAAK;AACzC;AACA,YAAY,yBAAI;AAChB;AACA,MAAM;AACN,QAAQ,yBAAI;AACZ,oCAAoC,wBAAK;AACzC;AACA,YAAY,yBAAI;AAChB;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,uBAAQ;AAC/B;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,gBAAgB;AACnC,gBAAgB,OAAO;AACvB,eAAe,oBAAoB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mGAAmG,cAAc;AACjH;AACA,6FAA6F,qFAAqF;AAClL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,oCAAoC,wBAAK;AACzC;AACA;AACA,YAAY,yBAAI;AAChB,MAAM;AACN,QAAQ,yBAAI;AACZ,oCAAoC,wBAAK;AACzC;AACA;AACA,YAAY,yBAAI;AAChB,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,SAAS,kBAAG;AACZ;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,2BAA2B;AACzD;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,oBAAoB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,oCAAoC,wBAAK;AACzC;AACA,YAAY,yBAAI;AAChB;AACA,MAAM;AACN,QAAQ,yBAAI;AACZ,oCAAoC,wBAAK;AACzC;AACA,YAAY,yBAAI;AAChB;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,uBAAQ;AAC/B;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,gBAAgB;AACjE,IAAI,iBAAiB;AACrB;AACA,YAAY,OAAO;AACnB,WAAW,oBAAoB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,yFAAyF,qFAAqF;AAC9K;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,oCAAoC,wBAAK;AACzC;AACA;AACA,YAAY,yBAAI;AAChB,MAAM;AACN,QAAQ,yBAAI;AACZ,oCAAoC,wBAAK;AACzC;AACA;AACA,YAAY,yBAAI;AAChB,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,QAAQ,kBAAG;AACX;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA,WAAW,yBAAI;AACf,SAAS,kBAAG;AACZ;AACA;AACA;AACA,uBAAuB,uBAAQ;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,qBAAqB;AAChC,WAAW,UAAU,yCAAyC,uBAAuB,KAAK,uBAAuB;AACjH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,gBAAgB,oBAAoB;AACpC;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,QAAQ,yBAAI;AACZ;AACA,kBAAkB,yBAAI;AACtB;AACA;AACA,MAAM,6DAA6D,wBAAK;AACxE;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,mBAAG;AACzD,sDAAsD,mBAAG;AACzD;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,sDAAsD,mBAAG;AACzD,sDAAsD,mBAAG;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA,WAAW,oBAAoB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,gBAAgB,oBAAoB;AACpC;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,QAAQ,yBAAI;AACZ,QAAQ,yBAAI;AACZ;AACA,kBAAkB,yBAAI;AACtB;AACA;AACA;AACA,MAAM;AACN,QAAQ,yBAAI;AACZ,oCAAoC,wBAAK;AACzC;AACA,YAAY,yBAAI;AAChB;AACA;AACA,MAAM;AACN,QAAQ,yBAAI;AACZ,oCAAoC,wBAAK;AACzC;AACA,YAAY,yBAAI;AAChB;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,oBAAoB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,0CAA0C;AAC3F;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD,0CAA0C;AAC/F;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,oBAAoB;AACpC;AACA;AACA;AACA;AACA;AACA,kBAAkB,yBAAI;AACtB;AACA;AACA,MAAM,SAAS,yBAAI;AACnB;AACA,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA,MAAM,SAAS,yBAAI;AACnB;AACA,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,mBAAG;AAC9B;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA,SAAS;AACT,iBAAiB,wBAAK;AACtB;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA,kBAAG;AACH;AACA;AACA,cAAc,yBAAI;AAClB,QAAQ,yBAAI,wBAAwB,yBAAI,wBAAwB,yBAAI;AACpE;AACA,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,uBAAQ;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA,eAAe,yBAAI;AACnB,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,gBAAgB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,mBAAmB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,wBAAK;AACjC,4BAA4B,wBAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA,yBAAyB,mBAAG;AAC5B,yBAAyB,mBAAG;AAC5B;AACA;AACA,aAAa;AACb;AACA,yBAAyB,mBAAG;AAC5B,yBAAyB,mBAAG;AAC5B;AACA;AACA,aAAa;AACb;AACA,yBAAyB,mBAAG;AAC5B,yBAAyB,mBAAG;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA,yBAAyB,mBAAG;AAC5B,yBAAyB,mBAAG;AAC5B;AACA;AACA,aAAa;AACb;AACA,yBAAyB,mBAAG;AAC5B,yBAAyB,mBAAG;AAC5B;AACA;AACA,aAAa;AACb;AACA,yBAAyB,mBAAG;AAC5B,yBAAyB,mBAAG;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,WAAW,GAAG,sBAAsB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,cAAc,+BAA+B;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mFAAmF,cAAc;AACjG;AACA;AACA,uFAAuF,qFAAqF;AAC5K;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,OAAO;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC,oBAAoB;AAC1D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,2FAA2F,qFAAqF;AAChL;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,cAAc,yBAAI;AAClB,QAAQ,yBAAI,wBAAwB,yBAAI,wBAAwB,yBAAI;AACpE;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA,2BAA2B,uBAAQ;AACnC;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,2FAA2F,qFAAqF;AAChL;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,cAAc,yBAAI;AAClB;AACA;AACA,QAAQ,yBAAI;AACZ,QAAQ,yBAAI;AACZ,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,mBAAG;AAC3B,wBAAwB,mBAAG;AAC3B,wBAAwB,mBAAG;AAC3B;AACA,+BAA+B,0BAAM;AACrC,wBAAwB,wBAAK;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,cAAc,yBAAI;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB,YAAY,kBAAG;AACf;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA,eAAe,yBAAI;AACnB,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,cAAc,yBAAI;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB,YAAY,kBAAG;AACf;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA,eAAe,yBAAI;AACnB,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA,4BAA4B,mBAAG;AAC/B,4BAA4B,mBAAG;AAC/B,4BAA4B,mBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,mDAAmD;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,uBAAuB;AAC1E;AACA,oDAAoD,UAAU;AAC9D,0DAA0D,WAAW;AACrE;AACA;AACA;AACA;AACA,0GAA0G,cAAc;AACxH,4DAA4D,kCAAkC;AAC9F;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,mBAAmB;AACtF,0DAA0D,mBAAmB;AAC7E;AACA;AACA,0CAA0C,aAAa,WAAW,cAAc,gBAAgB,cAAc;AAC9G,uEAAuE;AACvE,0DAA0D,4DAA4D;AACtH;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA,uDAAuD,uBAAuB;AAC9E;AACA,wDAAwD,UAAU;AAClE,8DAA8D,WAAW;AACzE;AACA;AACA;AACA;AACA,8GAA8G,cAAc;AAC5H,gEAAgE,kCAAkC;AAClG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,mBAAmB;AACtF,0DAA0D,mBAAmB;AAC7E;AACA;AACA,0CAA0C,aAAa,WAAW,cAAc,gBAAgB,cAAc;AAC9G,uEAAuE;AACvE,0DAA0D,4DAA4D;AACtH;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA,gBAAgB,oBAAoB;AACpC;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA,QAAQ,yBAAI;AACZ,cAAc,yBAAI;AAClB,MAAM;AACN,oCAAoC,wBAAK;AACzC,oCAAoC,wBAAK;AACzC,4BAA4B,wBAAK;AACjC,oCAAoC,wBAAK;AACzC;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,wBAAK;AACzC;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,kBAAG,+BAA+B,iBAAiB;AAC3D;AACA,QAAQ,yBAAI;AACZ,YAAY,kBAAG;AACf;AACA;AACA,MAAM,8BAA8B,wBAAK;AACzC,YAAY,kBAAG;AACf,MAAM,8BAA8B,wBAAK;AACzC,YAAY,kBAAG;AACf,MAAM,sBAAsB,wBAAK;AACjC,YAAY,kBAAG;AACf,MAAM,8BAA8B,wBAAK;AACzC;AACA;AACA,oBAAoB,yBAAI;AACxB,kBAAkB,kBAAG;AACrB;AACA;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,gBAAgB,kBAAG;AACnB;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC;AAChC;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,qDAAqD;AAChE;AACA;AACA,sDAAsD,iBAAiB;AACvE;AACA,oDAAoD,UAAU;AAC9D,+DAA+D,WAAW;AAC1E;AACA;AACA;AACA;AACA,0GAA0G,cAAc;AACxH,iEAAiE,kCAAkC;AACnG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,mBAAmB;AACtF,+DAA+D,mBAAmB;AAClF;AACA;AACA,0CAA0C,aAAa,WAAW,cAAc,gBAAgB,cAAc;AAC9G,uEAAuE;AACvE,+DAA+D,4DAA4D;AAC3H;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA,0DAA0D,iBAAiB;AAC3E;AACA,wDAAwD,UAAU;AAClE,mEAAmE,WAAW;AAC9E;AACA;AACA;AACA;AACA,8GAA8G,cAAc;AAC5H,qEAAqE,kCAAkC;AACvG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE,mBAAmB;AACtF,+DAA+D,mBAAmB;AAClF;AACA;AACA,0CAA0C,aAAa,WAAW,cAAc,gBAAgB,cAAc;AAC9G,uEAAuE;AACvE,+DAA+D,4DAA4D;AAC3H;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA,gBAAgB,oBAAoB;AACpC;AACA;AACA;AACA,WAAW,yBAAI;AACf,QAAQ,yBAAI;AACZ;AACA,cAAc,yBAAI;AAClB,MAAM;AACN,oCAAoC,wBAAK;AACzC,oCAAoC,wBAAK;AACzC,4BAA4B,wBAAK;AACjC,oCAAoC,wBAAK;AACzC;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,gBAAgB,yBAAI;AACpB;AACA,YAAY,yBAAI;AAChB,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,kBAAG,wCAAwC,gBAAgB;AACnE,QAAQ,yBAAI;AACZ,YAAY,kBAAG;AACf;AACA;AACA,MAAM,8BAA8B,wBAAK;AACzC,YAAY,kBAAG;AACf,MAAM,8BAA8B,wBAAK;AACzC,YAAY,kBAAG;AACf,MAAM,sBAAsB,wBAAK;AACjC,YAAY,kBAAG;AACf,MAAM,8BAA8B,wBAAK;AACzC;AACA;AACA,oBAAoB,yBAAI;AACxB,kBAAkB,kBAAG;AACrB;AACA;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,gBAAgB,kBAAG;AACnB;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,oBAAoB;AACpE;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,qBAAqB;AAChC;AACA,mDAAmD,8BAA8B;AACjF;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH,aAAa,kBAAG;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,iBAAiB;AAC5B;AACA;AACA,0DAA0D,uBAAuB;AACjF;AACA,+FAA+F,cAAc;AAC7G;AACA,2FAA2F,qFAAqF;AAChL,0EAA0E,uBAAuB;AACjG;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI,oDAAoD,wBAAK;AACrE;AACA;AACA,MAAM;AACN,QAAQ,yBAAI;AACZ,oCAAoC,wBAAK;AACzC;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA,eAAe,yBAAI;AACnB,eAAe,yBAAI;AACnB;AACA;AACA;AACA,kCAAkC,0BAAM;AACxC,4BAA4B,wBAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,kCAAkC,0BAAM;AACxC,4BAA4B,wBAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,kCAAkC;AAClC,sBAAsB,uBAAQ;AAC9B;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,sBAAsB,yBAAI;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,eAAe,uBAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,wBAAwB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,wBAAwB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,kBAAG;AACrB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,UAAU;AACrB;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,mFAAmF,6EAA6E;AAChK;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,aAAa;AAC5D,+FAA+F,cAAc;AAC7G;AACA;AACA,mFAAmF,6EAA6E;AAChK;AACA,gDAAgD,aAAa;AAC7D,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,mCAAmC;AAC1F;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA,2DAA2D,mCAAmC;AAC9F;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,WAAW,yBAAI;AACf,oCAAoC,wBAAK;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,uBAAQ;AAC5B,wBAAwB,wBAAK;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,mBAAG;AAC5B,gBAAgB,mBAAG;AACnB;AACA,qBAAqB,uBAAQ;AAC7B,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,oCAAoC,wBAAK;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,SAAS;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,aAAa;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,WAAW;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,mBAAmB;AAC/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,YAAY,yBAAI;AAChB;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,kCAAkC,kBAAG;AACxC,kBAAG,6BAA6B,kBAAG;AACnC,kBAAG,kCAAkC,kBAAG;AACxC,kBAAG,4BAA4B,kBAAG;AAClC,kBAAG,iCAAiC,kBAAG;AACvC,kBAAG,yCAAyC,kBAAG;AAC/C,kBAAG,iCAAiC,kBAAG;AACvC,kBAAG,6BAA6B,kBAAG;AACnC,kBAAG,6BAA6B,kBAAG;AACnC,kBAAG,6BAA6B,kBAAG;AACnC,kBAAG,6BAA6B,kBAAG;AACnC,kBAAG,kCAAkC,kBAAG;AACxC,kBAAG,gCAAgC,kBAAG;AACtC,kBAAG,yCAAyC,kBAAG;AAC/C,kBAAG,6BAA6B,kBAAG;AACnC,kBAAG,kCAAkC,kBAAG;AACxC,kBAAG,kCAAkC,kBAAG;AACxC,kBAAG,uCAAuC,kBAAG;AAC7C,kBAAG,yCAAyC,kBAAG;AAC/C,kBAAG,+BAA+B,kBAAG;AACrC,kBAAG,+BAA+B,kBAAG;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;ACx5FA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACM;AACE;AACK;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,mBAAmB;AAC9B;AACA;AACA;AACA,sCAAsC;AACtC,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,aAAa,qFAAqF;AAClG,2CAA2C;AAC3C,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,QAAQ;AACR;AACA,IAAI;AACJ,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,gBAAgB;AAChB;AACA,YAAY;AACZ,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,IAAI;AACJ,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,YAAY;AACZ,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,IAAI;AACJ,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,YAAY;AACZ,QAAQ;AACR;AACA;AACA,kBAAG;AACH,cAAc,mBAAG;AACjB;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA,4BAA4B,UAAU;AACtC;AACA;AACA;AACA,iCAAiC,IAAI;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,yBAAI,0BAA0B,yBAAI;AAC3C;AACA;AACA,SAAS,yBAAI,0BAA0B,yBAAI;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,kBAAkB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB,IAAI,yBAAI;AACR;AACA;AACA;AACA,IAAI,yBAAI;AACR,IAAI,yBAAI;AACR;AACA;AACA,qBAAqB,wBAAK;AAC1B;AACA;AACA;AACA,IAAI,yBAAI;AACR,IAAI,yBAAI;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,wBAAK;AAC1B;AACA;AACA;AACA;AACA,uCAAuC;AACvC,uCAAuC;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD,yBAAI;AACvD,8CAA8C,yBAAI;AAClD,8CAA8C,yBAAI;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB,YAAY,kBAAG;AACf;AACA;AACA,YAAY,yBAAI;AAChB,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,UAAU;AACV;AACA,2BAA2B,yBAAI;AAC/B;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,UAAU;AACV;AACA,2BAA2B,yBAAI;AAC/B;AACA;AACA;AACA,sFAAsF;AACtF;AACA,cAAc;AACd;AACA;AACA,UAAU;AACV,sFAAsF;AACtF;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,uBAAuB,yBAAI;AAC3B,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA;AACA,iBAAiB,mBAAG;AACpB,iBAAiB,mBAAG;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,wBAAwB;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA,6BAA6B,wBAAwB;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA,UAAU;AACV,6BAA6B,wBAAwB;AACrD,iCAAiC,wBAAwB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,QAAQ;AAChE,wDAAwD,QAAQ;AAChE;AACA;AACA;AACA;AACA;AACA;AACA,wDAAwD,yBAAI;AAC5D,wDAAwD,yBAAI;AAC5D;AACA;AACA;AACA,6DAA6D,yBAAI;AACjE,wDAAwD,yBAAI;AAC5D,wDAAwD,yBAAI;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,UAAU,OAAO;AACjB,kCAAkC;AAClC,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,UAAU,OAAO;AACjB,kCAAkC;AAClC,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,uBAAuB,yBAAI;AAC3B,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA;AACA,iBAAiB,mBAAG;AACpB,iBAAiB,mBAAG;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,wBAAwB;AACrD,iCAAiC,wBAAwB;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,mBAAG;AACjC;AACA;AACA;AACA,8BAA8B,mBAAG;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB,oBAAoB,yBAAI;AACxB;AACA;AACA,UAAU;AACV;AACA,6BAA6B,wBAAwB;AACrD,0BAA0B,mBAAG;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA,6BAA6B,wBAAwB;AACrD,0BAA0B,mBAAG;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,yBAAyB,kBAAG;;;;;AC1hC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACO;AACF;AACU;AACT;AACE;AACW;AAC/C;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB,uBAAuB,kBAAkB;AACzC;AACA,0FAA0F,wBAAwB;AAClH,SAAS,aAAa;AACtB;AACA;AACA,WAAW,kBAAkB;AAC7B,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,iBAAiB;AAC5B,YAAY,OAAO;AACnB;AACA;AACA,kBAAG;AACH,wCAAwC,wBAAK,oBAAoB,wBAAK;AACtE;AACA;AACA;AACA,aAAa,yBAAI;AACjB,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,kBAAG;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,kBAAG,uBAAuB,2BAAe;AACzC,yBAAI,sBAAsB,kBAAG,QAAQ,4BAAa;AAClD;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,0BAAM,CAAC,wBAAK;AAChC;AACA;AACA;AACA,kBAAkB,mBAAG,eAAe;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC,gCAAgC,OAAO;AACvC,+BAA+B,mBAAG;AAClC;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,4BAA4B,sBAAsB;AAClD;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,oBAAoB,wBAAwB;AAC5C;AACA,oBAAoB,wBAAwB;AAC5C;AACA,qBAAqB,qBAAqB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,gBAAgB,cAAc,gBAAgB;AAC1F;AACA;AACA;AACA,kCAAkC,yBAAyB,cAAc,yBAAyB;AAClG;AACA;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,oFAAoF;AAC5G;AACA;AACA,gDAAgD,gBAAgB,cAAc,gBAAgB;AAC9F;AACA;AACA;AACA,sCAAsC,yBAAyB,cAAc,yBAAyB;AACtG;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA,yBAAyB;AACzB;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,6BAA6B;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,0FAA0F,qFAAqF;AAC/K;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,SAAS,4BAAa,QAAQ,kBAAG;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,0BAA0B,kBAAG;AAChC;AACA,iDAAe,kBAAG,MAAM,EAAC;AACzB;AACA;AACA;AACA;;;AClbA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACM;AACO;AACF;AACH;AACC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,mBAAmB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,sFAAsF,qFAAqF;AAC3K;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ,+FAA+F,cAAc;AAC7G;AACA;AACA,sFAAsF,qFAAqF;AAC3K;AACA;AACA;AACA;AACA,QAAQ;AACR,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,aAAa;AACjC,oBAAoB,aAAa;AACjC,sBAAsB;AACtB,QAAQ;AACR;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA,wBAAwB,aAAa;AACrC,wBAAwB,aAAa;AACrC,0BAA0B;AAC1B,YAAY;AACZ;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA,YAAY;AACZ;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,oBAAoB;AACrC,iBAAiB,mBAAmB;AACpC;AACA,aAAa,oCAAoC;AACjD;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA,qBAAqB,oBAAoB;AACzC,qBAAqB,mBAAmB;AACxC;AACA,iBAAiB,oCAAoC;AACrD;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,IAAI;AACrB,2BAA2B,KAAK;AAChC,uBAAuB;AACvB;AACA,eAAe;AACf,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA,qBAAqB,IAAI;AACzB,+BAA+B,KAAK;AACpC,2BAA2B;AAC3B;AACA,mBAAmB;AACnB,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC;AACA;AACA;AACA;AACA,sBAAsB,oFAAoF;AAC1G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,yBAAI;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA,0BAA0B,mBAAG;AAC7B;AACA,UAAU;AACV,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,yBAAyB,yBAAI;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,mBAAG,wBAAwB,mBAAG;AAC1D;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,wBAAK;AAC3D;AACA,gCAAgC,mBAAG;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,KAAK;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,0BAAM,CAAC,wBAAK;AAChC;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yEAAyE;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,2BAA2B,kBAAG;AACjC;AACA;AACA;AACA;;;AC1lBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACF;AACO;AACzC;AACA;AACA;AACA;AACA,QAAQ,kBAAkB;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,eAAe,cAAc;AAC7B,eAAe,QAAQ;AACvB;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA,YAAY,yBAAI,mBAAmB,yBAAI;AACvC;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA,kBAAkB,SAAS,yBAAI,QAAQ,mBAAG;AAC1C,0BAA0B,mBAAG;AAC7B,kBAAkB;AAClB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,iCAAiC,yBAAI;AACrC;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,yBAAI;AAC7C;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,iCAAiC,wBAAK,kBAAkB,wBAAK,qBAAqB,wBAAK;AACvF;AACA,yDAAyD,yBAAI;AAC7D;AACA;AACA;AACA;AACA,yDAAyD,wBAAK;AAC9D;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,cAAc;AAC7B,iBAAiB;AACjB;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd,uDAAuD,yBAAI;AAC3D;AACA,kBAAkB;AAClB;AACA;AACA,sBAAsB;AACtB;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,cAAc;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB,cAAc;AACd,uDAAuD,yBAAI;AAC3D,oBAAoB,yBAAI;AACxB,kBAAkB;AAClB;AACA,wBAAwB,yBAAI;AAC5B;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAAe,kBAAG,aAAa,E;;AC1Y/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACa;AACR;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,aAAa;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D,YAAY;AACzE,+FAA+F,cAAc;AAC7G;AACA;AACA,sFAAsF,qFAAqF;AAC3K;AACA;AACA;AACA,iEAAiE,aAAa;AAC9E,MAAM;AACN;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA,qBAAqB,6BAA6B;AAClD,qBAAqB,6BAA6B;AAClD;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,yBAAI;AAC3B,SAAS;AACT;AACA;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,2BAAe;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,kBAAG;AACtB;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,gCAAgC,kBAAG;AACtC;AACA;AACA;AACA;AACA,gEAAgE,uBAAuB;AACvF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,+BAA+B;AAC1C,iDAAiD,uBAAuB;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2DAA2D,kCAAkC;AAC7F,yEAAyE,SAAS;AAClF;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA,+DAA+D,kCAAkC;AACjG,6EAA6E,SAAS;AACtF;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,yBAAI;AAClB;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA,YAAY,yBAAI;AAChB,wBAAwB,sBAAsB;AAC9C;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI,oBAAoB,yBAAI;AACxC;AACA,UAAU,SAAS,yBAAI,oBAAoB,yBAAI;AAC/C;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,cAAc;AACd,iCAAiC,YAAY;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA;AACA;AACA,eAAe,MAAM;AACrB;AACA;AACA,gBAAgB,uBAAuB;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,cAAc;AACd;AACA;AACA,kBAAkB;AAClB,0BAA0B,yBAAI;AAC9B;AACA,cAAc;AACd;AACA;AACA,kBAAkB;AAClB,0BAA0B,yBAAI;AAC9B;AACA;AACA,UAAU,SAAS,yBAAI;AACvB,wBAAwB,gBAAgB;AACxC,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,sBAAsB;AACtB,iCAAiC,yBAAI;AACrC;AACA,kBAAkB;AAClB;AACA;AACA,sBAAsB;AACtB,iCAAiC,yBAAI;AACrC;AACA;AACA;AACA;AACA;AACA,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,yBAAI;AACvC;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA,mBAAmB,yBAAI;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,kBAAG,gCAAgC,kBAAG;;;ACvftC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACpC;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA,4BAA4B,kBAAkB;AAC9C;AACA;AACA,gCAAgC,qBAAqB;AACrD;AACA;AACA;AACA,0BAA0B;AAC1B;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,sBAAsB;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,4BAA4B,gBAAgB;AAC5C;AACA;AACA;AACA,gCAAgC,gBAAgB;AAChD;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,sBAAsB;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,4BAA4B,+BAA+B;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,sBAAsB;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,4BAA4B,4BAA4B;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,2BAA2B;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAe,kBAAG,WAAW,EAAC;;;AC5O9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACe;AACR;AACF;AACU;AACM;AACX;AACF;AACF;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,wBAAwB,WAAW,aAAa;AACxD;AACA;AACA,WAAW,kBAAkB;AAC7B,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA;AACA,oBAAoB,cAAc;AAClC;AACA;AACA,MAAM,iCAAiC,yBAAI;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,yBAAI;AAClB,oBAAoB,SAAS;AAC7B;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kBAAkB;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,uBAAuB,2BAAe;AACzC;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA,oBAAoB,kBAAkB;AACtC,oBAAoB,OAAO;AAC3B,oBAAoB,OAAO;AAC3B,oBAAoB,QAAQ;AAC5B,qBAAqB,iBAAiB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAkB;AACtC,oBAAoB,OAAO;AAC3B,oBAAoB,OAAO;AAC3B,oBAAoB,QAAQ;AAC5B,qBAAqB,iBAAiB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAkB;AACtC,oBAAoB,OAAO;AAC3B,oBAAoB,OAAO;AAC3B,oBAAoB,QAAQ;AAC5B,qBAAqB,cAAc;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,uBAAQ;AACzB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAkB;AACtC,oBAAoB,OAAO;AAC3B,oBAAoB,OAAO;AAC3B,oBAAoB,QAAQ;AAC5B,qBAAqB,UAAU;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,yBAAI;AACvB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,kBAAkB;AAClB;AACA;AACA,gCAAgC,kBAAkB;AAClD;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yBAAI;AAC1B;AACA,wBAAwB,cAAc;AACtC,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI,wBAAwB,yBAAI;AACxD;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI,wBAAwB,yBAAI;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI,wBAAwB,yBAAI;AACpD;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAkB;AACtC,oBAAoB,OAAO;AAC3B,oBAAoB,OAAO;AAC3B,oBAAoB,QAAQ;AAC5B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,cAAc;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAkB;AACtC,oBAAoB,OAAO;AAC3B,oBAAoB,QAAQ;AAC5B,qBAAqB,SAAS,aAAa,0BAA0B;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,QAAQ;AAC5C,4CAA4C,yBAAI;AAChD;AACA;AACA;AACA,wCAAwC,cAAc;AACtD,4CAA4C,yBAAI;AAChD;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA,6CAA6C,0BAAM;AACnD,wBAAwB,wBAAK;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA,4BAA4B,cAAc;AAC1C;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,cAAc;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAkB;AACtC,oBAAoB,OAAO;AAC3B,oBAAoB,QAAQ;AAC5B,qBAAqB,QAAQ,YAAY,2CAA2C;AACpF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,0BAAM;AACrC,wBAAwB,wBAAK;AAC7B;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,gEAAgE,gBAAgB;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,iBAAiB;AACzC;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC,4BAA4B,iBAAiB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,iBAAiB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,4BAA4B,iBAAiB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,4BAA4B,iBAAiB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,iBAAiB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,4BAA4B,oBAAoB;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,4BAA4B,iBAAiB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,cAAc;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,oCAAoC;AACnF;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA,4BAA4B;AAC5B,gBAAgB;AAChB;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA,gCAAgC;AAChC,oBAAoB;AACpB;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,+CAA+C,wCAAwC;AACvF;AACA,8DAA8D,iDAAiD;AAC/G,yBAAyB,mCAAmC;AAC5D,mCAAmC,oCAAoC;AACvE,mCAAmC,iCAAiC;AACpE,mCAAmC,iCAAiC;AACpE,mCAAmC,sCAAsC;AACzE,mCAAmC,mCAAmC;AACtE,mCAAmC,mCAAmC;AACtE,mCAAmC,uCAAuC;AAC1E,mCAAmC,mCAAmC;AACtE,mCAAmC,iCAAiC;AACpE,mCAAmC;AACnC;AACA;AACA,gDAAgD;AAChD;AACA,2FAA2F;AAC3F;AACA;AACA,kDAAkD,wBAAwB;AAC1E;AACA,kBAAkB,KAAK;AACvB,yCAAyC,2EAA2E;AACpH;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,sFAAsF;AACtG,4EAA4E,iDAAiD;AAC7H,uCAAuC,mCAAmC;AAC1E,uCAAuC,oCAAoC;AAC3E,uCAAuC,iCAAiC;AACxE,uCAAuC,iCAAiC;AACxE,uCAAuC,sCAAsC;AAC7E,uCAAuC,mCAAmC;AAC1E,uCAAuC,mCAAmC;AAC1E,uCAAuC,uCAAuC;AAC9E,uCAAuC,mCAAmC;AAC1E,uCAAuC,iCAAiC;AACxE,uCAAuC;AACvC;AACA;AACA,oDAAoD;AACpD;AACA,+FAA+F;AAC/F;AACA;AACA,gEAAgE,wBAAwB;AACxF;AACA,gCAAgC,KAAK;AACrC,kDAAkD,2EAA2E;AAC7H;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kEAAkE,WAAW;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG,sEAAsE,WAAW;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,yDAAyD,6CAA6C;AACtG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,0FAA0F;AAC1G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA,gCAAgC,yBAAI;AACpC,YAAY,yBAAI;AAChB;AACA,mBAAmB,yBAAI;AACvB;AACA,wBAAwB,UAAU;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,yBAAI;AACjC,4BAA4B,SAAS;AACrC,gCAAgC,sBAAsB;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,gCAAgC,wBAAwB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,uCAAuC,0BAAK;AAC5C;AACA;AACA;AACA;AACA,kBAAkB;AAClB,qCAAqC,0BAAK;AAC1C;AACA;AACA;AACA;AACA,kBAAkB;AAClB,gDAAgD,0BAAK;AACrD;AACA;AACA;AACA;AACA,kBAAkB;AAClB,8CAA8C,0BAAK;AACnD;AACA;AACA;AACA,oCAAoC,kBAAG;AACvC,kBAAkB;AAClB,oCAAoC,kBAAG;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,eAAe,kBAAG;AAClB;AACA;AACA,kBAAG,0BAA0B,kBAAG;AAChC;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,wBAAwB,WAAW,cAAc;AACzD;AACA;AACA;AACA;AACA;AACA,WAAW,kBAAkB;AAC7B,WAAW,OAAO;AAClB,YAAY,QAAQ;AACpB;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA,sBAAsB,0BAAM,CAAC,wBAAK;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,wBAAwB,2BAAe;AAC1C;AACA;AACA;AACA;AACA;AACA,YAAY,kBAAkB;AAC9B,YAAY,QAAQ;AACpB;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA,uBAAuB,0BAAM;AAC7B,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA;AACA,gBAAgB,6BAA6B;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC,UAAU,cAAc,YAAY,gBAAgB;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,QAAQ;AACnB,WAAW,QAAQ;AACnB;AACA;AACA,iDAAiD,0CAA0C;AAC3F;AACA;AACA;AACA;AACA,uCAAuC,6DAA6D;AACpG,oCAAoC,+CAA+C;AACnF;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,0FAA0F;AAC1G;AACA;AACA;AACA;AACA,2CAA2C,6DAA6D;AACxG,wCAAwC,+CAA+C;AACvF;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,2BAA2B;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,2BAA2B;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA,MAAM;AACN;AACA;AACA;AACA,eAAe,kBAAG;AAClB;AACA;AACA,kBAAG,2BAA2B,kBAAG;AACjC;AACA,4CAAe;AACf,WAAW,kBAAG;AACd,YAAY,kBAAG;AACf;AACA;AACA,CAAC,EAAC;;;AC/hDF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACO;AACD;AACE;AACpC;AACA;AACA;AACA;AACA,QAAQ,wBAAwB;AAChC,SAAS,sBAAsB;AAC/B;AACA,WAAW,WAAW;AACtB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH,wBAAwB,wBAAK;AAC7B,gBAAgB,wBAAK;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA,qBAAqB,eAAe;AACpC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,QAAQ;AAC3B;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA;AACA,wBAAwB,mBAAmB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,yBAAI;AACrC;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,iCAAiC,yBAAI;AACrC;AACA,2DAA2D;AAC3D,2DAA2D;AAC3D;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,yBAAI;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA,4BAA4B,mBAAG;AAC/B;AACA;AACA;AACA,sBAAsB;AACtB;AACA,4BAA4B,mBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,qCAAqC,yBAAI;AACzC,kBAAkB;AAClB;AACA,qCAAqC,yBAAI;AACzC;AACA,gDAAgD,yBAAI;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B,gCAAgC,yBAAI;AACpC;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,iCAAiC,yBAAI;AACrC;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,iCAAiC,yBAAI;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,OAAO;AACvC,oCAAoC,OAAO;AAC3C,gDAAgD,yBAAI;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,WAAW;AAC9B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,mBAAmB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,yBAAI;AACrC;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,iCAAiC,yBAAI;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,4CAA4C,yBAAI,2BAA2B,yBAAI;AAC/E,qCAAqC,yBAAI;AACzC;AACA,kBAAkB;AAClB,qCAAqC,yBAAI;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,mBAAG;AACjC;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,mDAAmD,yBAAI;AACvD;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,mBAAG;AACrC,kCAAkC,mBAAG;AACrC;AACA;AACA,SAAS;AACT;AACA;AACA,iDAAiD,YAAY,GAAG,WAAW,GAAG,YAAY,GAAG,cAAc;AAC3G;AACA;AACA;AACA;AACA;AACA,mBAAmB,qBAAqB;AACxC,mBAAmB,QAAQ;AAC3B,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,SAAS,yBAAI;AAC3B;AACA,cAAc;AACd;AACA;AACA;AACA,mBAAmB,mBAAG;AACtB,SAAS;AACT;AACA;AACA,wEAAwE,YAAY,GAAG,WAAW,GAAG,YAAY,GAAG,eAAe;AACnI;AACA;AACA,mBAAmB,iBAAiB;AACpC;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,kCAAkC,mBAAG;AACrC,kBAAkB;AAClB,wBAAwB,mBAAG;AAC3B,+CAA+C,wBAAK;AACpD;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAkB;AACtC;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA,cAAc;AACd;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAkB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,4BAA4B,eAAe;AAC3C;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA,wBAAwB,kBAAG;AAC3B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,eAAe;AACnC,qBAAqB,eAAe;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,mBAAG;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,qCAAqC;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,UAAU;AACrD,kDAAkD,gBAAgB,YAAY,kBAAkB;AAChG,4CAA4C,cAAc;AAC1D;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,+CAA+C,UAAU;AACzD,sDAAsD,gBAAgB,YAAY,iBAAiB;AACnG,gDAAgD,cAAc;AAC9D;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,cAAc;AAC9D,4CAA4C,cAAc;AAC1D;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA,oDAAoD,cAAc;AAClE,gDAAgD,cAAc;AAC9D;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,UAAU;AACrD;AACA,2CAA2C,sBAAsB;AACjE;AACA;AACA,oDAAoD,eAAe;AACnE,4CAA4C,cAAc;AAC1D;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,+CAA+C,UAAU;AACzD;AACA,+CAA+C,sBAAsB;AACrE;AACA;AACA,wDAAwD,eAAe;AACvE,gDAAgD,cAAc;AAC9D;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,kBAAkB;AACnE,oDAAoD,eAAe;AACnE,+CAA+C,kBAAkB;AACjE,uDAAuD,cAAc;AACrE;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA,qDAAqD,iBAAiB;AACtE,wDAAwD,cAAc;AACtE,mDAAmD,iBAAiB;AACpE,2DAA2D,cAAc;AACzE;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,gBAAgB;AAC3D,4CAA4C,cAAc;AAC1D;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA,+CAA+C,eAAe;AAC9D,gDAAgD,cAAc;AAC9D;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,eAAe;AAC9B;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,eAAe;AAClC;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C,cAAc;AAC5D;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA,kDAAkD,cAAc;AAChE;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,kBAAkB;AACxE,mDAAmD,kBAAkB;AACrE;AACA;AACA;AACA,8CAA8C,gBAAgB;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,2CAA2C,cAAc;AACzD;AACA,6DAA6D,eAAe;AAC5E;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA,sDAAsD,kBAAkB;AACxE,mDAAmD,kBAAkB;AACrE;AACA;AACA;AACA,8CAA8C,gBAAgB;AAC9D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,2CAA2C,cAAc;AACzD;AACA,6DAA6D,eAAe;AAC5E;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,2CAA2C,YAAY;AACvD,2CAA2C,YAAY;AACvD,2DAA2D,eAAe;AAC1E;AACA;AACA,uEAAuE,iBAAiB;AACxF;AACA;AACA;AACA;AACA;AACA,iEAAiE,cAAc;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,iBAAiB;AACxB;AACA;AACA;AACA;AACA,OAAO,aAAa;AACpB,wBAAwB,oBAAoB;AAC5C;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG,+CAA+C,YAAY;AAC3D,+CAA+C,YAAY;AAC3D,+DAA+D,eAAe;AAC9E;AACA;AACA,2EAA2E,iBAAiB;AAC5F;AACA;AACA;AACA;AACA;AACA,qEAAqE,cAAc;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iBAAiB;AAC5B;AACA;AACA;AACA;AACA,WAAW,aAAa;AACxB,4BAA4B,oBAAoB;AAChD;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH,eAAe,kBAAG;AAClB;AACA;AACA,kBAAG,8BAA8B,kBAAG;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,uCAAuC;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,eAAe;AACxC;AACA;AACA;AACA;AACA;AACA;AACA,gDAAgD,0BAA0B;AAC1E;AACA;AACA,oDAAoD,mBAAmB;AACvE;AACA,2EAA2E,mBAAmB;AAC9F;AACA,sCAAsC,kCAAkC;AACxE,sCAAsC,oCAAoC;AAC1E;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,eAAe;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD,0BAA0B;AAC9E;AACA;AACA,wDAAwD,mBAAmB;AAC3E;AACA,+EAA+E,mBAAmB;AAClG;AACA,0CAA0C,kCAAkC;AAC5E,0CAA0C,oCAAoC;AAC9E;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH,eAAe,kBAAG;AAClB;AACA;AACA,kBAAG,gCAAgC,kBAAG;AACtC;AACA,qDAAe,kBAAG,eAAe,EAAC;AAClC;;;AC5yCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACO;AACD;AACS;AACP;AACpC;AACA;AACA;AACA;AACA,uBAAuB,0BAA0B;AACjD;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA,gDAAgD,oCAAoC;AACpF,0CAA0C,kBAAkB;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB,MAAM;AACN,uBAAuB;AACvB;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,6FAA6F;AAC7G,sDAAsD,kBAAkB;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC;AACpC,kBAAkB;AAClB,uCAAuC;AACvC;AACA;AACA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,wCAAwC,wBAAK,qBAAqB,wBAAK;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,yBAAI;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,kBAAG,wBAAwB,2BAAe;AAC1C;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA,mEAAmE,6BAA6B;AAChG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,mBAAG;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+DAA+D,mBAAmB;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA,wBAAwB,yBAAyB;AACjD;AACA,gCAAgC,wBAAK;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA,iCAAiC,QAAQ;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,gDAAgD,wBAAK;AACrD,iDAAiD,wBAAK;AACtD;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,2DAA2D,iBAAiB;AAC5E;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,4DAA4D,kBAAkB;AAC9E;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,sEAAsE,2BAA2B;AACjG;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,oDAAoD,uCAAuC;AAC3F;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA,gCAAgC,wBAAK;AACrC;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,yBAAI;AAC/B;AACA,+BAA+B,yBAAI;AACnC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,eAAe;AAClC,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA,sCAAsC,eAAe;AACrD;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA,sCAAsC,gBAAgB;AACtD;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,cAAc,gFAAgF;AACjH;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,SAAS,yBAAI;AAC3B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,mEAAmE,mBAAmB;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA,SAAS;AACT;AACA,sBAAsB;AACtB;AACA;AACA;AACA,SAAS;AACT;AACA,sBAAsB;AACtB;AACA;AACA;AACA,SAAS;AACT;AACA,sBAAsB;AACtB;AACA;AACA;AACA,SAAS;AACT;AACA,sBAAsB;AACtB;AACA;AACA;AACA,SAAS;AACT;AACA,sBAAsB;AACtB;AACA;AACA;AACA,SAAS;AACT;AACA,sBAAsB;AACtB;AACA;AACA;AACA,SAAS;AACT;AACA,sBAAsB;AACtB;AACA;AACA;AACA,SAAS;AACT;AACA,sBAAsB;AACtB;AACA;AACA;AACA,SAAS;AACT;AACA,sBAAsB;AACtB;AACA;AACA;AACA,SAAS;AACT;AACA,sBAAsB;AACtB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,SAAS;AACxC;AACA;AACA,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAyB;AACjD;AACA;AACA,gCAAgC,wBAAK;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,WAAW;AACtB,WAAW,OAAO;AAClB,WAAW,QAAQ,kGAAkG;AACrH,aAAa,YAAY;AACzB;AACA,kBAAG;AACH;AACA;AACA;AACA,WAAW,yBAAI;AACf,eAAe,kBAAG;AAClB;AACA;AACA,kBAAG,2BAA2B,kBAAG;AACjC;AACA,6CAAe,kBAAG,OAAO,EAAC;AAC1B;AACA;AACA;AACA;;;ACp7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACM;AACS;AACA;AACR;AACQ;AACV;AACG;AACpC;AACA;AACA;AACA;AACA;AACA,WAAW,UAAU;AACrB,WAAW,cAAc;AACzB,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA,kBAAG;AACH,6CAA6C,wBAAK,oBAAoB,wBAAK;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,uBAAuB,2BAAe;AACzC;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,QAAQ;AAC9B,wBAAwB,UAAU;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,wBAAK;AAChD;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,wBAAK;AACxC;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,mBAAG;AACnC;AACA;AACA,gCAAgC,mBAAG;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ,+DAA+D,0BAA0B,KAAK,2BAA2B;AACpJ,mBAAmB,OAAO;AAC1B,mBAAmB,OAAO;AAC1B,qBAAqB,WAAW;AAChC;AACA;AACA;AACA,wBAAwB,0BAAM;AAC9B,2BAA2B,0BAAM;AACjC;AACA;AACA;AACA,mCAAmC,wBAAK;AACxC;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,mBAAG;AACpD,+DAA+D,mBAAG;AAClE;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,iDAAiD,mBAAG;AACpD,+DAA+D,mBAAG;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,wBAAK;AAChD;AACA;AACA;AACA;AACA,wCAAwC,mBAAG,4BAA4B,mBAAG;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,wBAAK;AAChD;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAG;AACvB,oBAAoB,mBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,SAAS,mBAAG,mBAAmB,mBAAG;AACpD;AACA;AACA;AACA;AACA,kBAAkB,SAAS,mBAAG,mBAAmB,mBAAG;AACpD;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,kCAAkC,uBAAQ;AAC1C,iCAAiC,uBAAQ;AACzC;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,mBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,8BAA8B,WAAW;AACzC;AACA;AACA,kDAAkD;AAClD;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,wBAAK;AAChD,uCAAuC,wBAAK;AAC5C,2BAA2B,uBAAQ;AACnC;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,0BAAM;AACrC,wBAAwB,wBAAK;AAC7B;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB,+BAA+B,0BAAM;AACrC,wBAAwB,wBAAK;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,cAAc,SAAS,yBAAI;AAC3B;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,eAAe,mCAAmC;AAClD;AACA,oBAAoB,YAAY;AAChC,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,aAAa,+BAA+B;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,mBAAG;AACzB;AACA;AACA;AACA;AACA;AACA,2CAA2C,wBAAK;AAChD;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,0BAAM,CAAC,wBAAK;AACrC,yBAAyB,0BAAM,CAAC,wBAAK;AACrC;AACA;AACA;AACA,iDAAiD,mBAAG;AACpD;AACA;AACA;AACA;AACA;AACA,iDAAiD,mBAAG;AACpD;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,gBAAgB,uBAAQ;AACxB;AACA;AACA,gBAAgB,uBAAQ;AACxB;AACA;AACA,cAAc;AACd;AACA;AACA,gBAAgB,uBAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,YAAY;AAChC,oBAAoB,YAAY;AAChC,qBAAqB,kBAAkB;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,wBAAK;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,mBAAG;AACnB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,gEAAgE,4BAA4B,GAAG,iCAAiC;AAChI,gBAAgB;AAChB;AACA,oBAAoB,YAAY;AAChC,oBAAoB,YAAY;AAChC;AACA;AACA;AACA;AACA,sBAAsB,mBAAG;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,wBAAK;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,KAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,mBAAG;AAChC;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oEAAoE,QAAQ;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,mBAAG;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,gDAAgD,0CAA0C;AAC1F,+DAA+D,kCAAkC;AACjG;AACA,+BAA+B,YAAY;AAC3C,+BAA+B,YAAY;AAC3C,+BAA+B,YAAY;AAC3C,+BAA+B,YAAY;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA,qCAAqC,0CAA0C;AAC/E;AACA;AACA,oBAAoB,YAAY;AAChC,oBAAoB,YAAY;AAChC,oBAAoB,YAAY;AAChC,oBAAoB,YAAY;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,wBAAK;AAChD;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,6BAA6B,0BAAM,CAAC,wBAAK;AACzC,2CAA2C,wBAAK;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,0DAA0D,4BAA4B,KAAK,uBAAuB;AAClH;AACA,oBAAoB,YAAY;AAChC,oBAAoB,YAAY;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA,oCAAoC,yBAAI;AACxC;AACA;AACA;AACA,2CAA2C,wBAAK;AAChD;AACA;AACA;AACA;AACA,wBAAwB,4BAA4B;AACpD,+CAA+C,wBAAK;AACpD;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,iCAAiC,0BAAM,CAAC,wBAAK;AAC7C;AACA,+CAA+C,wBAAK;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD,yBAAI;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,oBAAoB,QAAQ;AAC5B,oBAAoB,WAAW;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,mBAAmB,YAAY;AAC/B,mBAAmB,SAAS;AAC5B,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAG;AACvB;AACA,oBAAoB,mBAAG;AACvB,oBAAoB,mBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,WAAW;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,uBAAQ;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,mBAAG;AAC/B;AACA;AACA;AACA,4BAA4B,mBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC,gDAAgD;AAChD;AACA,8BAA8B,yBAAyB;AACvD;AACA;AACA;AACA;AACA,8BAA8B,OAAO;AACrC;AACA;AACA;AACA;AACA;AACA,0BAA0B,gBAAgB;AAC1C,gDAAgD;AAChD;AACA,8BAA8B,yBAAyB;AACvD;AACA;AACA;AACA;AACA,8BAA8B,OAAO;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,sBAAsB;AACtB;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B,oBAAoB,cAAc;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,4CAA4C,yBAAI;AAChD,sBAAsB;AACtB,oCAAoC,yBAAI;AACxC;AACA,kBAAkB;AAClB;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,oBAAoB,eAAe;AACnC,oBAAoB,eAAe;AACnC,oBAAoB,eAAe;AACnC,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA,yCAAyC,mBAAG;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,oBAAoB,YAAY;AAChC,oBAAoB,YAAY;AAChC,oBAAoB,YAAY;AAChC,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC,wBAAwB;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,qBAAqB,WAAW;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,aAAa;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA,2BAA2B,yBAAI;AAC/B;AACA;AACA;AACA;AACA,4BAA4B,kBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,eAAe;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA,wBAAwB,wBAAwB;AAChD,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA,wBAAwB,wBAAwB;AAChD,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,yBAAyB,KAAK,wBAAwB;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD,QAAQ;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,oBAAoB;AAC/B,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,yFAAyF;AACzF;AACA;AACA;AACA,6CAA6C,kCAAkC;AAC/E,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA;AACA,gBAAgB,6FAA6F;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA,mCAAmC;AACnC,MAAM;AACN;AACA;AACA;AACA;AACA,oCAAoC,wBAAK;AACzC,oCAAoC,wBAAK;AACzC;AACA,iBAAiB,kBAAG;AACpB,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,oBAAoB;AAC/B,WAAW,QAAQ;AACnB;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,yEAAyE;AAC7J;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C,+BAA+B;AAC1E;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA,+CAA+C,+BAA+B;AAC9E;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,6BAA6B;AACzE,4CAA4C,0CAA0C;AACtF,4CAA4C,0CAA0C;AACtF;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA,gDAAgD,6BAA6B;AAC7E,gDAAgD,0CAA0C;AAC1F,gDAAgD,0CAA0C;AAC1F;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA,qCAAqC,wBAAK;AAC1C,wCAAwC,wBAAK;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,SAAS;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,0BAA0B,kBAAG;AAChC,kBAAG,yBAAyB,kBAAG;AAC/B,kBAAG,0BAA0B,kBAAG;AAChC;AACA,4CAAe,kBAAG,MAAM,EAAC;AACzB;AACA;AACA;AACA;AACA;AACA;;;ACv2DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,QAAQ,kBAAG;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD;AAClD;AACA;AACA;AACA,sCAAsC;AACtC,sDAAsD;AACtD,0BAA0B;AAC1B;AACA,qCAAqC;AACrC;AACA,6CAA6C;AAC7C;AACA;AACA;AACA,sBAAsB;AACtB;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA,sBAAsB;AACtB,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA,oCAAoC,SAAS;AAC7C;AACA;AACA;AACA;AACA,kBAAkB;AAClB,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA;AACA;AACA,4BAA4B,cAAc;AAC1C;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA,uCAAuC,eAAe;AACtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,UAAU;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,UAAU;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA,oBAAoB,qBAAqB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA,0CAAe,kBAAG,KAAK,EAAC;;;ACn1BxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,2BAA2B,iDAAiD,6BAA6B;AACxH;AACA,WAAW,QAAQ;AACnB,WAAW,SAAS;AACpB;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,yBAAI;AACxC,oCAAoC,yBAAI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,yBAAI;AACpC,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,yBAAI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,yBAAI;AACxC,oCAAoC,yBAAI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,yBAAI;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,yBAAI;AAC5C,wCAAwC,yBAAI;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,yBAAI;AAChD,4CAA4C,yBAAI;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,yBAAI;AACpC,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,yBAAI;AACxC,oCAAoC,yBAAI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,yBAAI;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,yBAAI;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,yBAAI;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,yBAAI;AAC5C,wCAAwC,yBAAI;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,yBAAI;AAC5C,wCAAwC,yBAAI;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,yBAAI;AACpC,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,yBAAI;AAC5C;AACA;AACA;AACA;AACA,wCAAwC,yBAAI;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,yBAAI;AACxC,oCAAoC,yBAAI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,yBAAI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,yBAAI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,yBAAI;AAChD,4CAA4C,yBAAI;AAChD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C,yBAAI;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,kBAAkB,SAAS,yBAAI;AAC/B,gCAAgC,6BAA6B;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC,0EAA0E;AAC1E;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,4BAA4B,SAAS;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,eAAe;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B,kDAAkD;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yCAAe,kBAAG,GAAG,EAAC;;;ACtnDtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACC;AAC7B;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,cAAc;AAC7B,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,cAAc;AAC7B;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,GAAG;AAClB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,0CAA0C,mBAAmB;AAC7D,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,2BAA2B,yBAAyB;AACpD,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,mBAAmB,yBAAI;AACvB;AACA;AACA,oBAAoB,sBAAsB;AAC1C;AACA;AACA;AACA,cAAc,yBAAI,eAAe,kBAAG;AACpC,kCAAkC,OAAO;AACzC,kBAAkB,yBAAI;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,qBAAqB;AACpC,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,KAAK;AACL;AACA;AACA,0EAA0E,yBAAyB;AACnG,QAAQ,6BAA6B;AACrC,eAAe,WAAW;AAC1B,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,4BAA4B;AACxD;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA,sBAAsB,SAAS,yBAAI;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,UAAU;AACzB,QAAQ,kBAAkB,IAAI,uBAAuB;AACrD,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,oBAAoB,cAAc;AAClC;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B,oCAAoC,gBAAgB;AACpD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,WAAW;AAC1B,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,qBAAqB;AACzC;AACA;AACA;AACA;AACA,gKAAgK;AAChK;AACA;AACA;AACA;AACA;AACA;AACA,6DAA6D;AAC7D;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAyB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB;AACvB;AACA;AACA;AACA;AACA,oBAAoB,uBAAuB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,WAAW;AAC1B,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,qBAAqB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB,uBAAuB;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAyB;AAC7C;AACA;AACA;AACA;AACA;AACA,iEAAiE,yBAAI;AACrE,uBAAuB;AACvB;AACA;AACA;AACA;AACA,oBAAoB,uBAAuB;AAC3C;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2CAAe,kBAAG,KAAK,EAAC;;;AC/bxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA;AACA,WAAW,mDAAmD;AAC9D,uCAAuC,iBAAiB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA,4CAA4C,+CAA+C;AAC3F;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA,gDAAgD,+CAA+C;AAC/F;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,qBAAqB;AAC/C,4BAA4B,wCAAwC;AACpE,8BAA8B,mBAAmB;AACjD,0BAA0B,iCAAiC;AAC3D;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA,8BAA8B,qBAAqB;AACnD,gCAAgC,wCAAwC;AACxE,kCAAkC,mBAAmB;AACrD,8BAA8B,iCAAiC;AAC/D;AACA;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB,mBAAmB,yBAAI;AACvB;AACA,UAAU,SAAS,yBAAI,yBAAyB,yBAAI;AACpD;AACA,UAAU,SAAS,yBAAI,2BAA2B,yBAAI;AACtD;AACA,UAAU;AACV,YAAY,yBAAI;AAChB;AACA;AACA;AACA,mBAAmB,yBAAI;AACvB,iBAAiB,kBAAG;AACpB,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB,mBAAmB,yBAAI;AACvB;AACA,UAAU,SAAS,yBAAI,yBAAyB,yBAAI;AACpD;AACA,UAAU,SAAS,yBAAI,2BAA2B,yBAAI;AACtD;AACA,UAAU;AACV,YAAY,yBAAI;AAChB;AACA;AACA;AACA,mBAAmB,yBAAI;AACvB,iBAAiB,kBAAG;AACpB,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,yBAAyB,kBAAG;AAC/B;AACA;AACA;AACA;;;AC7PA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACK;AACA;AACzC;AACA;AACA;AACA,QAAQ,OAAO;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA,WAAW,UAAU;AACrB,WAAW,oBAAoB;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA,oFAAoF,qFAAqF;AACzK;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA,oDAAoD,wBAAK;AACzD;AACA;AACA,MAAM,qDAAqD,wBAAK;AAChE;AACA,eAAe,yBAAI;AACnB;AACA;AACA,MAAM;AACN;AACA,oCAAoC,wBAAK;AACzC,QAAQ,yBAAI;AACZ;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA,qCAAqC,kBAAkB;AACvD,qCAAqC,kBAAkB;AACvD;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,YAAY;AAClE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,kBAAG;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,kCAAkC,kBAAG;AACxC;AACA;AACA;AACA;;;AC7RA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACM;AACE;AACpC;AACA,IAAI,aAAI;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,KAAK;AAClC,IAAI,aAAa;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,iDAAiD;AAC5D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE;AACnE;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,+FAA+F,cAAc;AAC7G;AACA;AACA,uFAAuF,qFAAqF;AAC5K,sEAAsE;AACtE;AACA,qBAAqB,YAAY;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,IAAI;AACJ,+FAA+F,cAAc;AAC7G;AACA;AACA,kFAAkF,qFAAqF;AACvK;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,IAAI;AACJ,IAAI;AACJ;AACA;AACA,kEAAkE,oCAAoC;AACtG,kEAAkE;AAClE;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB,gBAAgB,wBAAwB;AACxC;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG,sEAAsE,oCAAoC;AAC1G,sEAAsE;AACtE;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,oBAAoB,wBAAwB;AAC5C;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA;AACA,IAAI,kBAAG,wCAAwC,aAAI;AACnD;AACA;AACA;AACA;AACA,kBAAG,6BAA6B,kBAAG;AACnC;AACA;AACA;AACA;;;ACvPA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACM;AACE;AACpC;AACA;AACA;AACA;AACA;AACA,IAAI,UAAI;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,KAAK;AAC/B,IAAI,aAAa;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,wDAAwD;AACnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oEAAoE,yBAAyB;AAC7F;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,kCAAkC,gBAAgB,WAAW;AAClG;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA,uFAAuF,qFAAqF;AAC5K,wEAAwE,yBAAyB;AACjG;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,uEAAuE,qCAAqC;AAC5G;AACA,iGAAiG,cAAc;AAC/G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA,uEAAuE,qCAAqC;AAC5G,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yFAAyF,cAAc;AACvG;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,+DAA+D,0DAA0D;AACzH;AACA,QAAQ;AACR;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA,sCAAsC,oBAAoB,YAAY;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,qBAAqB;AACtC;AACA;AACA,2EAA2E,oCAAoC;AAC/G,uEAAuE;AACvE;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,oBAAoB,wBAAwB;AAC5C;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA,oBAAoB,oFAAoF;AACxG,+EAA+E,oCAAoC;AACnH,2EAA2E;AAC3E;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB,wBAAwB,wBAAwB;AAChD;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,kBAAG,oCAAoC,UAAI;AAC/C,IAAI,kBAAG;AACP;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,SAAS;AACT;AACA;AACA,IAAI,kBAAG;AACP;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,SAAS;AACT;AACA;AACA,IAAI,kBAAG;AACP;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,0BAA0B,kBAAG;AAChC;AACA;AACA;AACA;;;ACtaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACM;AACE;AACpC;AACA,IAAI,WAAI;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,KAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,0DAA0D;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,SAAS;AACxD;AACA;AACA;AACA;AACA,KAAK,KAAK;AACV;AACA;AACA;AACA,uCAAuC;AACvC,SAAS;AACT;AACA,+FAA+F,cAAc;AAC7G;AACA,sFAAsF,qFAAqF;AAC3K,+CAA+C,SAAS;AACxD;AACA;AACA;AACA;AACA,KAAK,KAAK;AACV;AACA;AACA;AACA,uCAAuC;AACvC,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,+DAA+D,oCAAoC;AACnG,2DAA2D;AAC3D;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR,QAAQ,wBAAwB;AAChC;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,2EAA2E,oCAAoC;AAC/G,uEAAuE;AACvE;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,oBAAoB,wBAAwB;AAC5C;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;AACA;AACA,uCAAuC;AACvC,QAAQ,mDAAmD;AAC3D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yFAAyF,cAAc;AACvG;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA,UAAU,IAAI,mDAAmD;AACjE;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6EAA6E,YAAY;AACzF;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA,sCAAsC;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB,wBAAwB,kBAAG;AAC3B;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,IAAI,kBAAG,qCAAqC,WAAI;AAChD,IAAI,kBAAG;AACP;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,SAAS;AACT;AACA;AACA,IAAI,kBAAG;AACP;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,SAAS;AACT;AACA;AACA,IAAI,kBAAG;AACP;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,2BAA2B,kBAAG;AACjC;AACA;AACA;AACA;;;AChUA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA,WAAW,uBAAuB;AAClC,WAAW,OAAO;AAClB;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,oEAAoE,eAAe;AACnF;AACA,2EAA2E,4BAA4B;AACvG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA,wEAAwE,eAAe;AACvF;AACA,+EAA+E,4BAA4B;AAC3G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,SAAS,yBAAI,wBAAwB,yBAAI,2BAA2B,yBAAI;AACxE,SAAS,yBAAI;AACb,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB,iBAAiB,yBAAI;AACrB,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA,uCAAuC;AACvC,UAAU;AACV,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yBAAI;AAC1B,sBAAsB,yBAAI;AAC1B,oBAAoB,yBAAI;AACxB;AACA;AACA,sBAAsB,yBAAI;AAC1B,sBAAsB,yBAAI;AAC1B,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,cAAc;AAC/C,qCAAqC,cAAc;AACnD;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA,mBAAmB,yBAAI;AACvB;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,kBAAG,gCAAgC,kBAAG;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA,WAAW,iBAAiB;AAC5B,WAAW,OAAO;AAClB;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,oEAAoE,eAAe;AACnF;AACA,2EAA2E,4BAA4B;AACvG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA,wEAAwE,eAAe;AACvF;AACA,+EAA+E,4BAA4B;AAC3G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,SAAS,yBAAI,2BAA2B,yBAAI;AAC5C,SAAS,yBAAI;AACb,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,UAAU;AACzB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,yBAAI;AACvB;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,kBAAG,+BAA+B,kBAAG;;;ACtarC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACL;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB,WAAW,qBAAqB;AAChC,WAAW,iBAAiB;AAC5B;AACA;AACA;AACA,2CAA2C,qCAAqC;AAChF,qCAAqC,oDAAoD;AACzF;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,+CAA+C,qCAAqC;AACpF,yCAAyC,qDAAqD;AAC9F;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,sDAAsD,SAAS,aAAa,WAAW,cAAc;AACrG,qCAAqC,gEAAgE;AACrG,qCAAqC,+CAA+C,uBAAuB;AAC3G;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,0DAA0D,SAAS,aAAa,WAAW,cAAc;AACzG,yCAAyC,gEAAgE;AACzG,yCAAyC,+CAA+C,uBAAuB;AAC/G;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,sDAAsD,SAAS,eAAe;AAC9E,qCAAqC,mEAAmE;AACxG,qCAAqC,8DAA8D;AACnG,qCAAqC,gEAAgE;AACrG;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,0DAA0D,SAAS,eAAe;AAClF,yCAAyC,mEAAmE;AAC5G,yCAAyC,8DAA8D;AACvG,yCAAyC,gEAAgE;AACzG;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,oEAAoE;AACpE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,wEAAwE;AACxE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,8DAA8D,aAAa,oBAAoB;AAC/F,+CAA+C,+DAA+D;AAC9G;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,kEAAkE,aAAa,oBAAoB;AACnG,mDAAmD,+DAA+D;AAClH;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA,SAAS,wBAAK,qBAAqB,wBAAK,mBAAmB,wBAAK;AAChE,SAAS,wBAAK,sBAAsB,wBAAK;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,wBAAK;AAChC,eAAe,yBAAI;AACnB;AACA,MAAM,4BAA4B,wBAAK;AACvC,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC;AACrC;AACA,MAAM,4BAA4B,wBAAK;AACvC,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA,qCAAqC;AACrC;AACA,MAAM,oBAAoB,wBAAK;AAC/B,eAAe,yBAAI;AACnB,MAAM,oBAAoB,wBAAK;AAC/B,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA,sBAAsB,yBAAI;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,0BAA0B,yBAAI;AAC9B;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,wBAAK;AAChC;AACA,0BAA0B,eAAe;AACzC,0BAA0B,eAAe;AACzC;AACA;AACA;AACA;AACA;AACA,sBAAsB,yBAAI;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd,oBAAoB,yBAAI;AACxB,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA,kBAAkB,qCAAqC;AACvD;AACA,2DAA2D,wCAAwC;AACnG,sBAAsB;AACtB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,MAAM,4BAA4B,wBAAK;AACvC;AACA;AACA;AACA,8BAA8B,6CAA6C;AAC3E,8BAA8B,6CAA6C;AAC3E;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,8BAA8B,qDAAqD;AACnF,8BAA8B,qDAAqD;AACnF;AACA;AACA;AACA;AACA;AACA,MAAM,4BAA4B,wBAAK;AACvC;AACA;AACA,8BAA8B,yCAAyC;AACvE,8BAA8B,sBAAsB;AACpD;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,8BAA8B,sBAAsB;AACpD,8BAA8B,yCAAyC;AACvE;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,8BAA8B,4BAA4B;AAC1D;AACA;AACA;AACA;AACA;AACA,MAAM,oBAAoB,wBAAK;AAC/B;AACA;AACA,8BAA8B,2BAA2B;AACzD;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA,MAAM,oBAAoB,wBAAK;AAC/B;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,+BAA+B,kBAAG;;;AC5drC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACO;AACF;AACU;AACT;AACE;AACW;AAC/C;AACA;AACA;AACA;AACA,0GAA0G,wBAAwB;AAClI,SAAS,qBAAqB;AAC9B;AACA;AACA,WAAW,kBAAkB;AAC7B,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB,WAAW,iBAAiB;AAC5B,YAAY,OAAO;AACnB;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,QAAQ,wBAAK;AACb,QAAQ,wBAAK;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,iBAAiB,yBAAI;AACrB,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,kBAAG;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,kBAAG,+BAA+B,2BAAe;AACjD,yBAAI,sBAAsB,kBAAG,gBAAgB,4BAAa;AAC1D;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,0BAAM,CAAC,wBAAK;AAChC;AACA;AACA;AACA,kBAAkB,mBAAG,eAAe;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,SAAS;AACrC,gCAAgC,OAAO;AACvC,+BAA+B,mBAAG;AAClC;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,4BAA4B,sBAAsB;AAClD;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,oBAAoB,uBAAuB;AAC3C;AACA,oBAAoB,wBAAwB;AAC5C;AACA,qBAAqB,mBAAmB;AACxC;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA,yBAAyB;AACzB;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC;AACvC,sBAAsB,UAAU,OAAO,WAAW;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ,2DAA2D,UAAU,OAAO;AAC/F,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA,0CAA0C,SAAS;AACnD;AACA,YAAY,6HAA6H;AACzI;AACA,QAAQ;AACR;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,8CAA8C,SAAS;AACvD;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,0CAA0C,SAAS;AACnD;AACA,YAAY,kCAAkC,eAAe,cAAc,aAAa,aAAa,KAAK,SAAS,QAAQ;AAC3H;AACA,QAAQ;AACR;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG,8CAA8C,SAAS;AACvD;AACA,+CAA+C,eAAe,cAAc,aAAa,aAAa;AACtG;AACA,YAAY;AACZ;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA,kDAAkD,iDAAiD;AACnG,kDAAkD,kDAAkD;AACpG,kDAAkD,iDAAiD;AACnG;AACA;AACA,YAAY,8HAA8H;AAC1I;AACA,QAAQ;AACR;AACA;AACA;AACA,4DAA4D,mCAAmC;AAC/F;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,kFAAkF;AAClG;AACA;AACA,sDAAsD,iDAAiD;AACvG,sDAAsD,kDAAkD;AACxG,sDAAsD,iDAAiD;AACvG;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,gEAAgE,mCAAmC;AACnG;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,SAAS,4BAAa,QAAQ,kBAAG;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,kCAAkC,kBAAG;AACxC,kBAAG,uBAAuB,kBAAG;AAC7B;AACA,oDAAe,kBAAG,cAAc,EAAC;AACjC;AACA;AACA;AACA;;;ACjeA;AACA;AAC2B;AACQ;AACnC;AACA,kBAAG,QAAQ,0BAAO;AAClB;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAyB,WAAW,eAAe,kBAAG,cAAc;AACrF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAyB,WAAW,eAAe,kBAAG,gBAAgB;AACvF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAyB,WAAW,eAAe,kBAAG,eAAe;AACtF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB;AACtB,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,4CAA4C;AAC9D,kBAAkB,qDAAqD;AACvE,KAAK;AACL;AACA;AACA;AACA;AACA,iBAAiB,0BAA0B;AAC3C;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,kBAAG;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,eAAe;AACvD;AACA;AACA,4BAA4B;AAC5B,yCAAyC,gBAAgB;AACzD,yCAAyC,gBAAgB;AACzD,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB;AACxB,gCAAgC,eAAe,SAAS,gBAAgB;AACxE;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,eAAe;AAC3D;AACA;AACA,gCAAgC;AAChC,6CAA6C,gBAAgB;AAC7D,6CAA6C,gBAAgB;AAC7D,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,kBAAkB,0BAA0B;AAC5C,kBAAkB;AAClB,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,0BAA0B;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,0BAA0B;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,0BAA0B;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB;AACzB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,uCAAuC;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,0BAA0B;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,0BAA0B;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,2BAA2B;AAC7C;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,yBAAyB,+CAA+C;AACxE;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,4BAA4B;AACrD;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,aAAa;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,gEAAgE;AAC1F,2BAA2B,qCAAqC;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,iBAAiB;AACjB,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC;AACpC;AACA,oBAAoB;AACpB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA,wBAAwB;AACxB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,aAAa;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,gEAAgE;AAC1F,2BAA2B,qCAAqC;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,iBAAiB;AACjB,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC;AACpC;AACA,oBAAoB;AACpB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA,wBAAwB;AACxB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,aAAa;AAC3E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,gEAAgE;AAC1F,2BAA2B,qCAAqC;AAChE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,iBAAiB;AACjB,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC;AACpC;AACA,oBAAoB;AACpB;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA,wBAAwB,qFAAqF;AAC7G;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA,wBAAwB;AACxB;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,gHAAgH;AACzI;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,CAAC;AACD;AACA,gDAAe,kBAAG,QAAQ,EAAC;;;AC7+C3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACF;AACH;AACF;AACS;AACA;AACT;AACe;AACA;AACjD;AACA;AACA;AACA;AACA,uFAAuF,wBAAwB;AAC/G,SAAS,cAAc;AACvB;AACA;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA,kBAAG;AACH,wCAAwC,wBAAK,qBAAqB,wBAAK;AACvE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,+BAA+B;AACvC,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA,KAAK;AACL;AACA,kBAAG,wBAAwB,2BAAe;AAC1C;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,OAAO;AACtB;AACA;AACA,eAAe,QAAQ;AACvB;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,wBAAwB;AACvC;AACA,eAAe,SAAS;AACxB;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,gBAAgB,eAAe;AACvC;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,cAAc,SAAS,yBAAI;AAC3B;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA,UAAU;AACV;AACA,aAAa,yBAAI,mBAAmB,yBAAI,iBAAiB,yBAAI;AAC7D;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA,oBAAoB,WAAW;AAC/B;AACA,UAAU;AACV,YAAY,yBAAI;AAChB,YAAY,yBAAI;AAChB,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAG;AACvB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,cAAc,mBAAG;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,mBAAG;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,+DAA+D,mBAAG;AAClE,+DAA+D,mBAAG;AAClE,mEAAmE,mBAAG;AACtE;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,mBAAG;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yDAAyD;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA,gBAAgB,mBAAG;AACnB;AACA;AACA,0CAA0C;AAC1C;AACA,UAAU,gCAAgC;AAC1C;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,mBAAG;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,2CAA2C;AAC3C,2CAA2C;AAC3C,2CAA2C;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,mBAAG;AACnB,gBAAgB,mBAAG;AACnB;AACA;AACA;AACA;AACA,gBAAgB,uBAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,mBAAG;AACjB;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA,iCAAiC,mBAAG;AACpC,mCAAmC,mBAAG;AACtC;AACA;AACA;AACA,6BAA6B,mBAAG;AAChC,6BAA6B,mBAAG;AAChC,+BAA+B,mBAAG;AAClC,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA;AACA;AACA,4BAA4B,mBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,mBAAG;AACpC,cAAc;AACd,iCAAiC,mBAAG;AACpC,iCAAiC,mBAAG;AACpC,mCAAmC,mBAAG;AACtC;AACA;AACA;AACA,6BAA6B,mBAAG;AAChC,+BAA+B,mBAAG;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,mBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8DAA8D,qBAAqB;AACnF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,mBAAG;AAClB,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,yBAAI;AACjB,aAAa,yBAAI;AACjB,aAAa,yBAAI;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mDAAmD;AACnD,mDAAmD;AACnD,6EAA6E;AAC7E,6EAA6E;AAC7E;AACA;AACA;AACA;AACA;AACA,gCAAgC,mBAAG;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD,iDAAiD;AACjD,2EAA2E;AAC3E,2EAA2E;AAC3E;AACA;AACA,gCAAgC,mBAAG;AACnC;AACA,oBAAoB,mBAAG,YAAY,mBAAG;AACtC;AACA;AACA;AACA;AACA;AACA,gCAAgC,mBAAG;AACnC;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,uBAAuB;AACtC,eAAe,uBAAuB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,wBAAK;AACtC,gCAAgC,wBAAK;AACrC;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAmB;AACvC;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC,wBAAK;AACtC,gCAAgC,wBAAK;AACrC;AACA,gCAAgC,wBAAK;AACrC,gCAAgC,wBAAK;AACrC;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,mBAAmB;AAC3C;AACA;AACA;AACA;AACA,uCAAuC,mCAAmC;AAC1E;AACA;AACA;AACA;AACA;AACA,4BAA4B,cAAc;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB,wBAAwB,mBAAmB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,yBAAI,mBAAmB,yBAAI;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,6BAA6B,2BAA2B;AACxD;AACA;AACA,eAAe,OAAO;AACtB,eAAe,SAAS;AACxB;AACA;AACA;AACA;AACA,oBAAoB,mBAAG,2BAA2B,mBAAG;AACrD;AACA;AACA;AACA,UAAU;AACV,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,gBAAgB,cAAc;AAC9B,gBAAgB,UAAU;AAC1B,gBAAgB,UAAU;AAC1B,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,YAAY,mBAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA,gBAAgB,mBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,gBAAgB,WAAW;AAC3B,gBAAgB,OAAO;AACvB,gBAAgB,OAAO;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,mBAAG;AAChB,YAAY,mBAAG;AACf;AACA;AACA,iDAAiD;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,mBAAG;AAC/C;AACA,sBAAsB,mBAAG;AACzB,cAAc;AACd;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA,kBAAkB,mBAAG;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C,mBAAG;AAC/C;AACA;AACA,sBAAsB,mBAAG;AACzB;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B,mBAAG;AAChC;AACA;AACA;AACA;AACA,gBAAgB,mBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,mBAAG;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,WAAW;AAC1B,eAAe,OAAO;AACtB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uCAAuC,mBAAG;AAC1C,uCAAuC,mBAAG;AAC1C,uCAAuC,mBAAG;AAC1C,uCAAuC,mBAAG;AAC1C,uCAAuC,mBAAG;AAC1C,uCAAuC,mBAAG;AAC1C;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,aAAa;AAC5B,eAAe,aAAa;AAC5B,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,mBAAG;AACf;AACA;AACA,YAAY,mBAAG;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,mBAAG;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,mBAAG;AACf;AACA;AACA;AACA;AACA,YAAY,mBAAG;AACf;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,mBAAG;AACf;AACA;AACA;AACA,YAAY,uBAAQ;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,uBAAQ;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,uBAAQ;AAC1B;AACA,qBAAqB,mBAAG,gBAAgB,mBAAG;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,sBAAsB;AAC1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,mBAAmB;AAC/C;AACA,yBAAyB,uBAAQ;AACjC,4BAA4B,uBAAQ;AACpC,yBAAyB,uBAAQ;AACjC,4BAA4B,uBAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,mBAAmB;AAC3C,iCAAiC,uBAAQ;AACzC;AACA;AACA;AACA;AACA,iCAAiC,uBAAQ;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,iBAAiB;AACjB,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yBAAI;AAC1B,sBAAsB,yBAAI;AAC1B;AACA;AACA;AACA,mBAAmB,yBAAI,2BAA2B,yBAAI;AACtD,mBAAmB,yBAAI,2BAA2B,yBAAI;AACtD;AACA,sBAAsB,gBAAgB;AACtC;AACA,0BAA0B,gBAAgB;AAC1C;AACA,oBAAoB,yBAAI;AACxB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,gBAAgB;AACtC;AACA,0BAA0B,gBAAgB;AAC1C;AACA,oBAAoB,yBAAI;AACxB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,mBAAG;AACpB,UAAU;AACV;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,mBAAG;AACpB,UAAU;AACV;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,mBAAG;AACtB,UAAU;AACV;AACA,mBAAmB,mBAAG;AACtB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,0BAAM,CAAC,wBAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,kBAAG;AACnB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAG;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAG,2DAA2D,gBAAgB;AAClG;AACA;AACA;AACA;AACA,QAAQ,kBAAG;AACX,KAAK;AACL;AACA;AACA;AACA;AACA;AACA,eAAe,OAAO;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA;AACA;AACA,YAAY,kBAAG;AACf;AACA;AACA,QAAQ,kBAAG;AACX;AACA;AACA;AACA,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;AACA;AACA,uEAAuE,gBAAgB,GAAG,gBAAgB,OAAO,kBAAkB;AACnI;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,mBAAmB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,aAAa;AACxC,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,gBAAgB;AAC5B;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,kCAAkC,eAAe,2DAA2D;AAC5H;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,aAAa;AAC5C,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,gBAAgB;AAChC;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,aAAa;AACxC;AACA,6BAA6B,gBAAgB;AAC7C,6BAA6B;AAC7B;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,gBAAgB;AAC5B;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,+CAA+C,eAAe,8CAA8C;AAC5H;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,aAAa;AAC5C;AACA,iCAAiC,gBAAgB;AACjD,iCAAiC;AACjC;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,gBAAgB;AAChC;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,aAAa;AACxC;AACA;AACA;AACA;AACA;AACA,8BAA8B,WAAW,mBAAmB;AAC5D,8BAA8B,WAAW,mBAAmB;AAC5D,8BAA8B,WAAW,mBAAmB;AAC5D;AACA;AACA,iCAAiC,eAAe;AAChD,iCAAiC,eAAe;AAChD,iCAAiC,eAAe;AAChD,iCAAiC,eAAe;AAChD,iCAAiC,eAAe;AAChD,iCAAiC;AACjC,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,gBAAgB;AAC5B;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,+CAA+C,eAAe,8CAA8C;AAC5H;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,aAAa;AAC5C;AACA;AACA;AACA;AACA;AACA,kCAAkC,WAAW,mBAAmB;AAChE,kCAAkC,WAAW,mBAAmB;AAChE,kCAAkC,WAAW,mBAAmB;AAChE;AACA;AACA,qCAAqC,eAAe;AACpD,qCAAqC,eAAe;AACpD,qCAAqC,eAAe;AACpD,qCAAqC,eAAe;AACpD,qCAAqC,eAAe;AACpD,qCAAqC;AACrC,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,gBAAgB;AAChC;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,aAAa;AACxC;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,gBAAgB;AAC5B;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,+CAA+C,eAAe,8CAA8C;AAC5H;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,aAAa;AAC5C;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,gBAAgB;AAChC;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,aAAa;AACxC;AACA;AACA;AACA;AACA;AACA,8BAA8B,WAAW,mBAAmB;AAC5D,8BAA8B,WAAW,mBAAmB;AAC5D,8BAA8B,WAAW,mBAAmB;AAC5D;AACA;AACA;AACA,4BAA4B;AAC5B,gBAAgB;AAChB;AACA;AACA,4BAA4B;AAC5B,gBAAgB;AAChB;AACA;AACA,4BAA4B;AAC5B,gBAAgB;AAChB;AACA;AACA;AACA,4BAA4B;AAC5B,gBAAgB;AAChB;AACA;AACA;AACA,4BAA4B;AAC5B,gBAAgB;AAChB;AACA;AACA;AACA,4BAA4B;AAC5B,gBAAgB;AAChB;AACA;AACA,iCAAiC,eAAe;AAChD,iCAAiC,eAAe;AAChD,iCAAiC,eAAe;AAChD,iCAAiC,eAAe;AAChD,iCAAiC,eAAe;AAChD,iCAAiC,eAAe;AAChD,kCAAkC,eAAe;AACjD,kCAAkC,eAAe;AACjD,kCAAkC,eAAe;AACjD,kCAAkC,eAAe;AACjD,kCAAkC,eAAe;AACjD,kCAAkC;AAClC;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,gBAAgB;AAC5B;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,+CAA+C,eAAe,8CAA8C;AAC5H;AACA;AACA;AACA;AACA;AACA;AACA,+BAA+B,aAAa;AAC5C;AACA;AACA;AACA;AACA;AACA,kCAAkC,WAAW,mBAAmB;AAChE,kCAAkC,WAAW,mBAAmB;AAChE,kCAAkC,WAAW,mBAAmB;AAChE;AACA;AACA;AACA,gCAAgC;AAChC,oBAAoB;AACpB;AACA;AACA,gCAAgC;AAChC,oBAAoB;AACpB;AACA;AACA,gCAAgC;AAChC,oBAAoB;AACpB;AACA;AACA;AACA,gCAAgC;AAChC,oBAAoB;AACpB;AACA;AACA;AACA,gCAAgC;AAChC,oBAAoB;AACpB;AACA;AACA;AACA,gCAAgC;AAChC,oBAAoB;AACpB;AACA;AACA,qCAAqC,eAAe;AACpD,qCAAqC,eAAe;AACpD,qCAAqC,eAAe;AACpD,qCAAqC,eAAe;AACpD,qCAAqC,eAAe;AACpD,qCAAqC,eAAe;AACpD,sCAAsC,eAAe;AACrD,sCAAsC,eAAe;AACrD,sCAAsC,eAAe;AACrD,sCAAsC,eAAe;AACrD,sCAAsC,eAAe;AACrD,sCAAsC;AACtC;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,gBAAgB;AAChC,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,oCAAoC;AACzD;AACA;AACA,0BAA0B,+BAA+B,gBAAgB;AACzE,2BAA2B,iCAAiC;AAC5D;AACA;AACA,8BAA8B,mBAAmB;AACjD,8BAA8B,mBAAmB;AACjD;AACA,+BAA+B,oBAAoB;AACnD,+BAA+B,oBAAoB;AACnD;AACA,+BAA+B,eAAe;AAC9C,+BAA+B;AAC/B,SAAS;AACT;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,+CAA+C,eAAe,8CAA8C;AAC5H;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,oCAAoC;AAChE;AACA,iCAAiC,+BAA+B,gBAAgB;AAChF,kCAAkC,iCAAiC;AACnE;AACA,qCAAqC,mBAAmB;AACxD,qCAAqC,mBAAmB;AACxD,sCAAsC,oBAAoB;AAC1D,sCAAsC,oBAAoB;AAC1D,sCAAsC,eAAe;AACrD,sCAAsC;AACtC,gBAAgB;AAChB,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA,oBAAoB;AACpB,2BAA2B;AAC3B;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA,oBAAoB;AACpB,2BAA2B;AAC3B;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA,oBAAoB;AACpB,2BAA2B;AAC3B;AACA;AACA,QAAQ;AACR;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,oFAAoF;AACpG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,wBAAwB;AACxB,+BAA+B;AAC/B;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,wBAAwB;AACxB,+BAA+B;AAC/B;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA,wBAAwB;AACxB,+BAA+B;AAC/B;AACA;AACA,YAAY;AACZ;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA,2BAA2B;AAC3B;AACA,WAAW,yBAAI;AACf,eAAe,kBAAG;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc,yBAAI;AAClB;AACA;AACA,cAAc,yBAAI;AAClB;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,QAAQ,yBAAI;AACZ,SAAS,yBAAI;AACb;AACA;AACA,MAAM;AACN;AACA;AACA,QAAQ,yBAAI;AACZ,SAAS,yBAAI;AACb;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA,4CAA4C;AAC5C;AACA,QAAQ,yBAAI;AACZ,SAAS,yBAAI;AACb;AACA;AACA,MAAM;AACN;AACA;AACA,QAAQ,yBAAI;AACZ,SAAS,yBAAI;AACb;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA,4CAA4C;AAC5C;AACA,QAAQ,yBAAI;AACZ,SAAS,yBAAI;AACb;AACA;AACA,MAAM;AACN;AACA;AACA,QAAQ,yBAAI;AACZ,SAAS,yBAAI;AACb;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA,8CAA8C;AAC9C;AACA;AACA;AACA;AACA;AACA,iCAAiC,yBAAI;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD,6BAA6B;AAC9E,cAAc;AACd,iDAAiD,6BAA6B;AAC9E;AACA;AACA;AACA;AACA,oBAAoB,uBAAuB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB,qCAAqC,yBAAI,2BAA2B,yBAAI,2BAA2B,yBAAI;AACvG;AACA;AACA,cAAc;AACd;AACA;AACA,kBAAkB;AAClB,qCAAqC,yBAAI,2BAA2B,yBAAI,2BAA2B,yBAAI;AACvG;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,2BAA2B,kBAAG;AACjC;AACA,6CAAe,kBAAG,OAAO,EAAC;;;ACp0F1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,QAAQ;AACnB;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,QAAQ,kBAAG;AACd;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,sBAAsB;AAC1C;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA,2BAA2B,yBAAI,kBAAkB,yBAAI;AACrD,cAAc,UAAU,yBAAI;AAC5B,4DAA4D;AAC5D,gBAAgB,kBAAG;AACnB,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC,0BAA0B,kBAAG;AAC7B,6BAA6B,kBAAG,mBAAmB,kBAAG;AACtD,6BAA6B,kBAAG;AAChC,gCAAgC,yBAAI;AACpC,gCAAgC,kBAAG;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB,mBAAmB,yBAAI;AACvB;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,kBAAkB,qBAAqB;AACvC,kBAAkB,0BAA0B,sBAAsB;AAClE,0BAA0B,yBAAyB;AACnD,oBAAoB,mBAAmB;AACvC;AACA;AACA;AACA,mBAAmB,yBAAI;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,SAAS;AAC7B;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,uCAAuC,sCAAsC;AAC7E,eAAe,eAAe;AAC9B;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA,eAAe,OAAO;AACtB,eAAe,OAAO;AACtB;AACA;AACA,iBAAiB,OAAO;AACxB;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,CAAC;AACD;AACA,gDAAe,kBAAG,kBAAkB,EAAC;;;ACjPrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,oBAAoB,uBAAuB;AAC3C;AACA;AACA;AACA,MAAM;AACN,oBAAoB,uBAAuB;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA,gBAAgB,uBAAuB;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0CAA0C;AAC1C;AACA;AACA;AACA,cAAc;AACd;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,gBAAgB,uBAAuB;AACvC;AACA;AACA;AACA;AACA;AACA,oBAAoB,kBAAkB;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,yBAAI;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,uBAAuB;AACvC;AACA;AACA,oBAAoB,kBAAkB;AACtC,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA,mEAAmE;AACnE;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,2BAA2B,kBAAG;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,aAAa;AACxB;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,4BAA4B;AAC5B;AACA;AACA;AACA;AACA,kBAAG,2BAA2B,kBAAG;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,+BAA+B;AAC1C;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,WAAW,yBAAI;AACf,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA,UAAU;AACV,gBAAgB,yBAAI;AACpB;AACA,cAAc;AACd,4BAA4B,uBAAuB;AACnD,2BAA2B,yBAAI;AAC/B;AACA;AACA;AACA,YAAY,yBAAI;AAChB,iBAAiB,yBAAI;AACrB,UAAU;AACV,wBAAwB,4BAA4B;AACpD,wBAAwB,yBAAI;AAC5B;AACA;AACA,YAAY,yBAAI;AAChB,iBAAiB,yBAAI;AACrB,UAAU;AACV,wBAAwB,4BAA4B;AACpD,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,kBAAG;AAChB,aAAa,kBAAG;AAChB,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,2BAA2B,kBAAG;;;ACnZjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACL;AACF;AACS;AAC3C;AACA;AACA;AACA;AACA,kGAAkG,yBAAyB;AAC3H,SAAS,gBAAgB;AACzB;AACA;AACA;AACA,WAAW,YAAY;AACvB,WAAW,WAAW;AACtB,WAAW,OAAO;AAClB,WAAW,iBAAiB;AAC5B,WAAW,QAAQ;AACnB;AACA;AACA,kBAAG;AACH;AACA;AACA,6CAA6C,wBAAK,uBAAuB,wBAAK;AAC9E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,mBAAG;AACrB;AACA,gBAAgB,mBAAG,oEAAoE;AACvF;AACA,QAAQ,mBAAG,mBAAmB,mBAAG;AACjC;AACA;AACA;AACA;AACA,kBAAkB,mBAAG;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,kBAAG,0BAA0B,kBAAG;AAChC,yBAAI,sBAAsB,kBAAG,WAAW,kBAAG;AAC3C;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oEAAoE;AACpE;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,wBAAwB;AAC3C,qBAAqB,cAAc;AACnC;AACA;AACA,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,wBAAwB;AAC3C,qBAAqB,QAAQ;AAC7B;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B,uBAAuB,mBAAG;AAC1B;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,yBAAI;AAC9B;AACA;AACA,kBAAkB,mBAAG;AACrB;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,0BAA0B,mBAAG;AAC7B;AACA,0BAA0B,mBAAG;AAC7B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,yDAAyD,oDAAoD,gBAAgB,0BAA0B,wBAAwB;AAC1L;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA,eAAe,yBAAI;AACnB,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA,aAAa,kBAAG;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,6BAA6B,kBAAG;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,uCAAuC;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,iCAAiC;AACzD,wBAAwB,iCAAiC;AACzD,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,+CAA+C,eAAe,8CAA8C;AAC5H;AACA;AACA;AACA;AACA;AACA,+BAA+B,iCAAiC;AAChE,+BAA+B,iCAAiC;AAChE,+BAA+B;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB;AACA,WAAW,uBAAQ;AACnB,+CAA+C,gBAAgB;AAC/D;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,wBAAK;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,yCAAyC,kBAAG;;;ACxZ/C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACL;AACF;AACS;AAC3C;AACA;AACA;AACA,gGAAgG,yBAAyB;AACzH,SAAS,eAAe;AACxB;AACA;AACA,WAAW,YAAY;AACvB,WAAW,gBAAgB;AAC3B,WAAW,uBAAuB;AAClC,WAAW,QAAQ,2DAA2D,2BAA2B;AACzG,IAAI,2BAA2B;AAC/B;AACA;AACA,kBAAG;AACH,6CAA6C,wBAAK,sBAAsB,wBAAK;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oFAAoF,4BAA4B;AAChH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0GAA0G,mBAAmB;AAC7H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA,KAAK;AACL;AACA;AACA,kBAAG,yBAAyB,kBAAG;AAC/B,yBAAI,sBAAsB,kBAAG,UAAU,kBAAG;AAC1C;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,6BAA6B,0BAA0B;AACvD;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,8BAA8B,yBAAI;AAClC;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,4BAA4B,mBAAmB;AAC/C;AACA;AACA,wBAAwB,yBAAI;AAC5B,6CAA6C,yBAAI;AACjD;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,8BAA8B,yBAAI;AAClC;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,4BAA4B,mBAAmB;AAC/C,yCAAyC,yBAAI;AAC7C;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,SAAS;AAC5B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,yCAAyC;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,sBAAsB,qBAAqB;AAC3C,sBAAsB,0BAA0B,sBAAsB;AACtE,8BAA8B,yBAAyB;AACvD,wBAAwB,mBAAmB;AAC3C;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,wBAAwB,iCAAiC;AACzD;AACA,oBAAoB,mBAAG;AACvB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,uBAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,wBAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,wBAAK;AACjC;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,wBAAK;AACzB;AACA;AACA;AACA,8BAA8B,mBAAG;AACjC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,SAAS,8DAA8D;AAC5F;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,aAAa;AAChC,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uBAAuB,mBAAG;AAC1B;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,OAAO;AACzB,kBAAkB,QAAQ;AAC1B,kBAAkB,QAAQ;AAC1B,kBAAkB,UAAU;AAC5B,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,iBAAiB;AACjB,eAAe;AACf;AACA;AACA;AACA,kDAAkD,aAAa;AAC/D,qDAAqD,aAAa;AAClE;AACA,aAAa;AACb,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,iBAAiB;AACjB,eAAe;AACf;AACA;AACA;AACA,kDAAkD,aAAa;AAC/D,qDAAqD,aAAa;AAClE;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA,kDAAkD;AAClD;AACA;AACA;AACA;AACA,oCAAoC;AACpC;AACA;AACA;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA,oDAAoD;AACpD;AACA;AACA;AACA,gDAAgD;AAChD;AACA;AACA;AACA,mCAAmC;AACnC;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB,+BAA+B,mBAAG;AAClC,+BAA+B,mBAAG;AAClC,+BAA+B,mBAAG;AAClC;AACA;AACA;AACA;AACA;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,wBAAwB;AAC1C;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,YAAY;AAC/B,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ,8CAA8C,kCAAkC;AAC3G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,wDAAwD;AAC7E,WAAW;AACX;AACA,uGAAuG,cAAc;AACrH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,wDAAwD;AAC3E,YAAY;AACZ;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,uDAAuD;AACvD;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD;AACpD,oDAAoD;AACpD,oDAAoD;AACpD;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA;AACA;AACA,wDAAwD;AACxD;AACA;AACA,wDAAwD;AACxD;AACA;AACA,4BAA4B,yBAAI;AAChC,iDAAiD;AACjD;AACA;AACA,iBAAiB;AACjB,aAAa;AACb,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB;AACA,WAAW,uEAAuE;AAClF;AACA,WAAW,sCAAsC;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ,kDAAkD,mBAAmB;AACrE,kDAAkD,mCAAmC,IAAI,gCAAgC;AACzH,yFAAyF,gCAAgC;AACzH;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,+CAA+C,eAAe,8CAA8C;AAC5H;AACA;AACA;AACA;AACA,iBAAiB;AACjB,uDAAuD,mBAAmB;AAC1E,uDAAuD,mCAAmC,IAAI,mBAAmB;AACjH,8FAA8F,gCAAgC;AAC9H,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,4BAA4B,iCAAiC;AAC7D,4BAA4B,iCAAiC;AAC7D,4BAA4B;AAC5B;AACA;AACA;AACA;AACA,uDAAuD,0BAA0B;AACjF,sDAAsD,0BAA0B;AAChF;AACA;AACA,8DAA8D,iBAAiB;AAC/E;AACA;AACA,8DAA8D,wCAAwC;AACtG,yDAAyD,yBAAyB;AAClF;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,gCAAgC,iCAAiC;AACjE,gCAAgC,iCAAiC;AACjE,gCAAgC;AAChC;AACA;AACA;AACA;AACA,2DAA2D,0BAA0B;AACrF,0DAA0D,0BAA0B;AACpF;AACA;AACA,kEAAkE,iBAAiB;AACnF;AACA;AACA,kEAAkE,wCAAwC;AAC1G,6DAA6D,yBAAyB;AACtF;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,SAAS,yBAAI;AACb;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,QAAQ,yBAAI;AACZ,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,MAAM;AACN;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sFAAsF;AACtF;AACA;AACA,WAAW,yBAAI;AACf,aAAa,kBAAG;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA,kBAAG,4BAA4B,kBAAG;AAClC;;;ACp3BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACE;AACP;AACF;AAClC;AACA;AACA;AACA,gGAAgG,yBAAyB,WAAW,eAAe;AACnJ;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,UAAU;AACrB,WAAW,UAAU;AACrB,WAAW,UAAU;AACrB,WAAW,UAAU;AACrB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA,kBAAG;AACH,6CAA6C,wBAAK,sBAAsB,wBAAK;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4CAA4C;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,YAAY,yBAAI;AAChB;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA,KAAK;AACL;AACA,kBAAG,yBAAyB,kBAAG;AAC/B,yBAAI,sBAAsB,kBAAG,UAAU,kBAAG;AAC1C;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA,qBAAqB,aAAa;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,4BAA4B,WAAW;AACvC;AACA;AACA,cAAc,SAAS,yBAAI;AAC3B;AACA,4BAA4B,WAAW;AACvC;AACA;AACA,cAAc;AACd,oBAAoB,yBAAI;AACxB,oBAAoB,yBAAI;AACxB,oBAAoB,yBAAI;AACxB;AACA,mCAAmC,qBAAqB;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,yBAAI;AAC1D,oBAAoB,yBAAI;AACxB;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,cAAc;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA,kBAAkB;AAClB;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,kBAAkB,mBAAG;AACrB,wBAAwB,cAAc;AACtC,sBAAsB,mBAAG;AACzB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,wCAAwC;AACxC;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,wCAAwC;AACxC;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,wCAAwC;AACxC;AACA,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,aAAa;AAClC;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,cAAc;AACtC;AACA;AACA;AACA,wBAAwB,SAAS;AACjC;AACA;AACA,kBAAkB;AAClB;AACA;AACA,4BAA4B,cAAc;AAC1C,wBAAwB,mBAAG;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,sCAAsC,YAAY;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,uBAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,2CAA2C;AACtD;AACA;AACA,WAAW,yBAAyB;AACpC;AACA,WAAW,mBAAmB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA,QAAQ;AACR;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI,4DAA4D,wBAAK;AACjF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,iCAAiC,yBAAI;AAC3C,cAAc,mBAAG;AACjB;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,aAAa,kBAAG;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,4BAA4B,kBAAG;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,OAAO;AACnB;AACA,WAAW,uBAAuB;AAClC;AACA,WAAW,OAAO;AAClB;AACA,WAAW,OAAO;AAClB;AACA,WAAW,OAAO;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA,SAAS,yBAAI,wBAAwB,yBAAI,2BAA2B,yBAAI;AACxE,SAAS,yBAAI;AACb,SAAS,yBAAI;AACb,SAAS,yBAAI;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,gBAAgB;AAC/B;AACA,iBAAiB,QAAQ;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB,iBAAiB,yBAAI;AACrB,iBAAiB,yBAAI;AACrB,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,eAAe;AACjD,sCAAsC,eAAe;AACrD,0CAA0C,eAAe;AACzD;AACA,0BAA0B,mBAAG;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB,oBAAoB,yBAAI;AACxB,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,yBAAI;AACvB;AACA,KAAK;AACL;AACA;AACA;AACA;AACA,kBAAG,kCAAkC,kBAAG;;;AC3qBxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACL;AACF;AACS;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8FAA8F,yBAAyB,WAAW,cAAc;AAChJ;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,eAAe;AAC1B,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA,kBAAG;AACH,6CAA6C,wBAAK,qBAAqB,wBAAK;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gFAAgF;AAChF,YAAY,YAAY;AACxB;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA,KAAK;AACL;AACA,kBAAG,wBAAwB,kBAAG;AAC9B,yBAAI,sBAAsB,kBAAG,SAAS,kBAAG;AACzC;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA,6BAA6B,kBAAkB;AAC/C;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI,wDAAwD,wBAAK;AAClF;AACA;AACA,cAAc,SAAS,yBAAI;AAC3B,2BAA2B,yBAAI;AAC/B;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,4BAA4B,2BAA2B;AACvD,sCAAsC,yBAAI;AAC1C;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,iBAAiB;AACpC;AACA,qBAAqB,OAAO;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,wBAAwB,iCAAiC;AACzD;AACA,oBAAoB,mBAAG;AACvB;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,oBAAoB;AACvC;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAyB;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,mBAAG,2BAA2B,mBAAG;AACrD,iDAAiD,yBAAI,2BAA2B,yBAAI;AACpF;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,mBAAG;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB;AACA,WAAW,uDAAuD;AAClE,mBAAmB,4BAA4B,KAAK,2BAA2B;AAC/E;AACA,WAAW,qEAAqE;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb,mDAAmD,mBAAmB;AACtE;AACA,kEAAkE,SAAS,cAAc,WAAW,gBAAgB;AACpH;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA,iBAAiB;AACjB,uDAAuD,mBAAmB;AAC1E;AACA,sEAAsE,sBAAsB,cAAc,WAAW,gBAAgB;AACrI;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,4BAA4B,iBAAiB;AAC7C,4BAA4B,iBAAiB;AAC7C,4BAA4B;AAC5B;AACA;AACA;AACA,kDAAkD,QAAQ;AAC1D,kDAAkD,QAAQ;AAC1D,yDAAyD,QAAQ;AACjE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA,qBAAqB,cAAc;AACnC;AACA,QAAQ;AACR;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,gCAAgC,iBAAiB;AACjD,gCAAgC,iBAAiB;AACjD,gCAAgC;AAChC;AACA;AACA;AACA,sDAAsD,QAAQ;AAC9D,sDAAsD,QAAQ;AAC9D,6DAA6D,QAAQ;AACrE;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,yBAAyB,cAAc;AACvC;AACA,YAAY;AACZ;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA,0BAA0B,kBAAkB;AAC5C,0BAA0B,kBAAkB;AAC5C,0BAA0B;AAC1B;AACA;AACA;AACA;AACA,gDAAgD,SAAS;AACzD,gDAAgD,SAAS;AACzD;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+CAA+C,SAAS;AACxD,0EAA0E,oBAAoB;AAC9F;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA,yCAAyC,kBAAkB;AAC3D,yCAAyC,kBAAkB;AAC3D,yCAAyC;AACzC;AACA;AACA;AACA;AACA,gEAAgE,SAAS;AACzE,gEAAgE,SAAS;AACzE;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,+DAA+D,SAAS;AACxE,0FAA0F,oBAAoB;AAC9G;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA,4BAA4B,wBAAK;AACjC,QAAQ,yBAAI;AACZ;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,yBAAI;AACb,uCAAuC,yBAAI,wBAAwB,yBAAI;AACvE;AACA;AACA,uCAAuC;AACvC,iBAAiB,yBAAI;AACrB,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA,wBAAwB;AACxB,iBAAiB,kBAAG;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA,cAAc,eAAe;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA,UAAU;AACV,aAAa,yBAAI,gDAAgD,wBAAK;AACtE,YAAY,yBAAI;AAChB;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,kBAAG;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,yBAAI;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC,yBAAI;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,2BAA2B,kBAAG;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gGAAgG,wBAAwB,WAAW,eAAe;AAClJ;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,eAAe;AAC1B,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA,kBAAG;AACH,6CAA6C,wBAAK,sBAAsB,wBAAK;AAC7E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,iBAAiB;AAC3C;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,iBAAiB;AAC3C;AACA,cAAc;AACd,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,mFAAmF,kBAAkB,KAAK,aAAa;AACvH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mFAAmF,0BAA0B,KAAK;AAClH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA,KAAK;AACL;AACA,kBAAG,yBAAyB,kBAAG;AAC/B,yBAAI,sBAAsB,kBAAG,UAAU,kBAAG;AAC1C;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB,mBAAG;AACpB,iBAAiB,mBAAG;AACpB,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,8BAA8B,wBAAwB,KAAK,wBAAwB;AACnF;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI,0DAA0D,wBAAK;AACnF;AACA,cAAc,SAAS,yBAAI;AAC3B,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,4BAA4B,4BAA4B;AACxD,uCAAuC,yBAAI;AAC3C;AACA;AACA;AACA,gBAAgB,yBAAI,0DAA0D,wBAAK;AACnF;AACA,cAAc,SAAS,yBAAI;AAC3B,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,4BAA4B,4BAA4B;AACxD,uCAAuC,yBAAI;AAC3C;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,yBAAyB,YAAY,KAAK,WAAW;AACrD;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,mBAAG;AAC7B;AACA,kBAAkB,mBAAG;AACrB,gCAAgC,mBAAG,OAAO,mBAAG;AAC7C,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA,qBAAqB,mBAAG;AACxB;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,mBAAmB;AAC/C;AACA;AACA;AACA;AACA;AACA,oCAAoC,mBAAmB;AACvD;AACA,iCAAiC,uBAAQ;AACzC,oCAAoC,uBAAQ;AAC5C,iCAAiC,uBAAQ;AACzC,oCAAoC,uBAAQ;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,mBAAG;AAC3B;AACA;AACA;AACA;AACA,oCAAoC,mBAAmB;AACvD;AACA;AACA,iCAAiC,uBAAQ;AACzC,oCAAoC,uBAAQ;AAC5C,iCAAiC,uBAAQ;AACzC,oCAAoC,uBAAQ;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,mBAAmB;AACnD,yCAAyC,uBAAQ;AACjD;AACA;AACA;AACA;AACA,yCAAyC,uBAAQ;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA,cAAc;AACd;AACA,qBAAqB,yBAAI;AACzB,qBAAqB,yBAAI;AACzB,qBAAqB,yBAAI;AACzB,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA;AACA,qBAAqB,mBAAG;AACxB,qBAAqB,mBAAG;AACxB,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA,4BAA4B,OAAO;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,OAAO;AACvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA,wBAAwB,iCAAiC;AACzD;AACA,qBAAqB,mBAAG;AACxB,qBAAqB,mBAAG;AACxB;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,uBAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uGAAuG;AACvG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB;AACA;AACA,WAAW,8GAA8G;AACzH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,kFAAkF;AAC7F;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,4BAA4B,iBAAiB;AAC7C,4BAA4B,iBAAiB;AAC7C,4BAA4B;AAC5B;AACA;AACA;AACA,mDAAmD,QAAQ;AAC3D;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,gCAAgC,iBAAiB;AACjD,gCAAgC,iBAAiB;AACjD,gCAAgC;AAChC;AACA;AACA;AACA,uDAAuD,QAAQ;AAC/D;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,4BAA4B,iBAAiB;AAC7C,4BAA4B,iBAAiB;AAC7C,4BAA4B;AAC5B;AACA;AACA;AACA,mDAAmD,QAAQ;AAC3D;AACA;AACA;AACA;AACA,qBAAqB,eAAe;AACpC,mBAAmB;AACnB,QAAQ;AACR;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,gCAAgC,iBAAiB;AACjD,gCAAgC,iBAAiB;AACjD,gCAAgC;AAChC;AACA;AACA;AACA,uDAAuD,QAAQ;AAC/D;AACA;AACA;AACA;AACA,yBAAyB,eAAe;AACxC,uBAAuB;AACvB,YAAY;AACZ;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA,qCAAqC,kCAAkC;AACvE,qCAAqC,kCAAkC;AACvE,qCAAqC;AACrC;AACA;AACA;AACA,4DAA4D,SAAS;AACrE;AACA,0FAA0F,qBAAqB;AAC/G,0FAA0F,qBAAqB;AAC/G;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA,yCAAyC,kCAAkC;AAC3E,yCAAyC,kCAAkC;AAC3E,yCAAyC;AACzC;AACA;AACA;AACA,gEAAgE,SAAS;AACzE;AACA,8FAA8F,qBAAqB;AACnH,8FAA8F,qBAAqB;AACnH;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,4BAA4B,iBAAiB;AAC7C,4BAA4B,iBAAiB;AAC7C,4BAA4B;AAC5B;AACA;AACA;AACA,kDAAkD,QAAQ;AAC1D,kDAAkD,QAAQ;AAC1D,mDAAmD,QAAQ;AAC3D;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,gCAAgC,iBAAiB;AACjD,gCAAgC,iBAAiB;AACjD,gCAAgC;AAChC;AACA;AACA;AACA,sDAAsD,QAAQ;AAC9D,sDAAsD,QAAQ;AAC9D,uDAAuD,QAAQ;AAC/D;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,4BAA4B,iBAAiB;AAC7C,4BAA4B,iBAAiB;AAC7C,4BAA4B;AAC5B;AACA;AACA;AACA,mDAAmD,QAAQ;AAC3D;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA,oBAAoB,cAAc;AAClC,oBAAoB;AACpB,QAAQ;AACR;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,gCAAgC,iBAAiB;AACjD,gCAAgC,iBAAiB;AACjD,gCAAgC;AAChC;AACA;AACA;AACA,uDAAuD,QAAQ;AAC/D;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA,wBAAwB,cAAc;AACtC,wBAAwB;AACxB,YAAY;AACZ;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA,4BAA4B,yBAAI,0BAA0B,yBAAI;AAC9D;AACA;AACA,gBAAgB,yBAAI;AACpB,iBAAiB,yBAAI;AACrB,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,gCAAgC,wBAAK;AACrC,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA,UAAU;AACV;AACA,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,kBAAG;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA;AACA,aAAa;AACb;AACA,yBAAyB,iBAAiB;AAC1C,yBAAyB,iBAAiB;AAC1C;AACA;AACA;AACA;AACA;AACA,4CAA4C;AAC5C,4CAA4C;AAC5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,4BAA4B,kBAAG;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,yBAAyB;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,cAAc;AACtC,wBAAwB,cAAc;AACtC,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,+CAA+C,eAAe,8CAA8C;AAC5H;AACA;AACA;AACA;AACA;AACA,gCAAgC,cAAc;AAC9C,gCAAgC,cAAc;AAC9C,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA,eAAe,yBAAI;AACnB;AACA;AACA,WAAW,uBAAQ;AACnB,gBAAgB,OAAO;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,wBAAK;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,uCAAuC,kBAAG;;;ACh0D7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACP;AACS;AACP;AACpC;AACA;AACA;AACA;AACA,gGAAgG,yBAAyB;AACzH,SAAS,eAAe;AACxB;AACA;AACA,WAAW,YAAY;AACvB,WAAW,gBAAgB;AAC3B,WAAW,uBAAuB;AAClC,WAAW,QAAQ,2DAA2D,2BAA2B;AACzG,IAAI,2BAA2B;AAC/B;AACA;AACA,kBAAG;AACH,6CAA6C,wBAAK,qBAAqB,wBAAK;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0GAA0G,mBAAmB;AAC7H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA,KAAK;AACL;AACA,kBAAG,wBAAwB,kBAAG;AAC9B,yBAAI,sBAAsB,kBAAG,SAAS,kBAAG;AACzC;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,8BAA8B,yBAAI;AAClC;AACA,cAAc;AACd;AACA,4BAA4B,OAAO;AACnC;AACA;AACA,wBAAwB,yBAAI;AAC5B,6CAA6C,yBAAI;AACjD;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA,8BAA8B,yBAAI;AAClC;AACA,cAAc;AACd;AACA,4BAA4B,OAAO;AACnC,yCAAyC,yBAAI;AAC7C;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA,2CAA2C,mBAAG;AAC9C;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mBAAmB,OAAO;AAC1B,mBAAmB,SAAS;AAC5B,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA,6CAA6C;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,uBAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,wBAAK;AACjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,wBAAK;AACjC;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,wBAAK;AACzB;AACA;AACA;AACA,8BAA8B,mBAAG;AACjC;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,qBAAqB,SAAS,8DAA8D;AAC5F;AACA;AACA,8CAA8C,mBAAG;AACjD;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB;AACA,WAAW,uFAAuF;AAClG;AACA;AACA,WAAW,8CAA8C;AACzD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA,QAAQ;AACR;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,+CAA+C,eAAe,8CAA8C;AAC5H;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA,YAAY;AACZ;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,yBAAI;AAClC;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sFAAsF;AACtF;AACA;AACA,WAAW,yBAAI;AACf,aAAa,kBAAG;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qDAAqD;AACrD;AACA;AACA;AACA;AACA,kBAAG,2BAA2B,kBAAG;;;ACxdjC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACQ;AACF;AAClC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,0BAA0B;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA,UAAU;AACV,wBAAwB,OAAO;AAC/B,uBAAuB,yBAAI;AAC3B;AACA;AACA,oBAAoB,OAAO;AAC3B,oBAAoB,yBAAI;AACxB,oBAAoB,yBAAI;AACxB;AACA;AACA,aAAa,kBAAG;AAChB,aAAa,kBAAG;AAChB,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA,6BAA6B,mBAAG;AAChC;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,OAAO;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oDAAoD;AACpD;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA,UAAU;AACV,wBAAwB,OAAO;AAC/B,uBAAuB,yBAAI;AAC3B;AACA;AACA,oBAAoB,OAAO;AAC3B,oBAAoB,yBAAI;AACxB,oBAAoB,yBAAI;AACxB;AACA;AACA,aAAa,kBAAG;AAChB,aAAa,kBAAG;AAChB,oBAAoB,OAAO;AAC3B;AACA;AACA;AACA;AACA,6BAA6B,mBAAG;AAChC;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,4BAA4B,kBAAG;;;ACnNlC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACL;AACF;AAClC;AACA;AACA;AACA,oGAAoG,yBAAyB,WAAW,iBAAiB;AACzJ;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,eAAe;AAC1B,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA,kBAAG;AACH;AACA;AACA,6CAA6C,wBAAK,wBAAwB,wBAAK;AAC/E;AACA;AACA;AACA;AACA;AACA;AACA,2BAA2B,2BAA2B;AACtD;AACA;AACA;AACA;AACA;AACA,gBAAgB,qBAAqB;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,2BAA2B,kBAAG;AACjC,yBAAI,sBAAsB,kBAAG,YAAY,kBAAG;AAC5C;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,0BAA0B,mBAAG;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,OAAO;AAClB;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ,qBAAqB,wBAAK;AAC1B,QAAQ,yBAAI;AACZ;AACA;AACA;AACA,sBAAsB,yBAAI;AAC1B,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,MAAM,SAAS,yBAAI,gDAAgD,yBAAI;AACvE;AACA;AACA;AACA,MAAM;AACN,iBAAiB,yBAAI;AACrB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,kBAAG;AAChB;AACA;AACA;AACA,gBAAgB,mBAAmB;AACnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,8BAA8B,kBAAG,kB;;AC7MpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACL;AACF;AAClC;AACA;AACA;AACA,+FAA+F,yBAAyB,WAAW,cAAc;AACjJ;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,UAAU;AACrB,WAAW,UAAU;AACrB,WAAW,UAAU;AACrB,WAAW,UAAU;AACrB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA,kBAAG;AACH,6CAA6C,wBAAK,qBAAqB,wBAAK;AAC5E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA,KAAK;AACL;AACA,kBAAG,wBAAwB,kBAAG;AAC9B,yBAAI,sBAAsB,kBAAG,SAAS,kBAAG;AACzC;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,yBAAI;AACxB,oCAAoC,yBAAI;AACxC,kBAAkB,SAAS,yBAAI;AAC/B;AACA;AACA,gCAAgC,QAAQ;AACxC,2CAA2C,yBAAI;AAC/C;AACA,kBAAkB;AAClB;AACA,wBAAwB,yBAAI;AAC5B;AACA,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,qBAAqB,SAAS;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,mBAAG;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB;AACrB,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,cAAc;AACtC;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA,gCAAgC,cAAc;AAC9C,4BAA4B,mBAAG;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B,mBAAG;AACjC,sBAAsB,mBAAG;AACzB;AACA;AACA;AACA,gCAAgC,OAAO;AACvC;AACA;AACA;AACA,yBAAyB,mBAAG;AAC5B;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,QAAQ;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,mBAAG;AAC/B;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA,gCAAgC,IAAI,IAAI,IAAI,KAAK,MAAM;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,aAAa,kBAAG;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,2BAA2B,kBAAG;AACjC;;;ACtYA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACL;AACpC;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA,6CAA6C,wBAAK,2BAA2B,wBAAK;AAClF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB,sBAAsB;AACtB,wBAAwB;AACxB,sBAAsB;AACtB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,yBAAI;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,2BAA2B;AAC3C;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA,KAAK;AACL;AACA,kBAAG,8BAA8B,kBAAG;AACpC,yBAAI,sBAAsB,kBAAG,eAAe,kBAAG;AAC/C;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,2BAA2B;AACnD;AACA;AACA;AACA;AACA,4BAA4B,QAAQ;AACpC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,gBAAgB;AACxC;AACA;AACA,YAAY;AACZ,yBAAyB,gBAAgB;AACzC,yBAAyB,gBAAgB;AACzC,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,sDAAsD;AAC9E;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,gBAAgB;AAC5C;AACA;AACA,gBAAgB;AAChB,6BAA6B,gBAAgB;AAC7C,6BAA6B,gBAAgB;AAC7C,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,sDAAsD;AAClF;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,gBAAgB;AACxC;AACA;AACA,YAAY;AACZ,yBAAyB,gBAAgB;AACzC,yBAAyB,gBAAgB;AACzC,yBAAyB;AACzB;AACA;AACA,mDAAmD,qBAAqB;AACxE,sEAAsE,kCAAkC;AACxG;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ,gCAAgC,gBAAgB;AAChD,gCAAgC,iBAAiB;AACjD;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,gBAAgB;AAC5C;AACA;AACA,gBAAgB;AAChB,6BAA6B,gBAAgB;AAC7C,6BAA6B,gBAAgB;AAC7C,6BAA6B;AAC7B;AACA;AACA,uDAAuD,qBAAqB;AAC5E,0EAA0E,kCAAkC;AAC5G;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR,oCAAoC,gBAAgB;AACpD,oCAAoC,iBAAiB;AACrD;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,gBAAgB;AACxC;AACA;AACA,YAAY;AACZ,yBAAyB,gBAAgB;AACzC,yBAAyB,gBAAgB;AACzC,yBAAyB;AACzB;AACA;AACA,oEAAoE,WAAW;AAC/E;AACA;AACA,mBAAmB,mBAAmB,sBAAsB;AAC5D,mBAAmB,mBAAmB,qBAAqB;AAC3D,mBAAmB,mBAAmB,oBAAoB;AAC1D,mBAAmB,mBAAmB,qBAAqB;AAC3D;AACA,mBAAmB,mBAAmB,qBAAqB;AAC3D,mBAAmB,mBAAmB,oBAAoB;AAC1D,mBAAmB,mBAAmB,mBAAmB;AACzD,sBAAsB,mBAAmB;AACzC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,gBAAgB;AAC5C;AACA;AACA,gBAAgB;AAChB,6BAA6B,gBAAgB;AAC7C,6BAA6B,gBAAgB;AAC7C,6BAA6B;AAC7B;AACA;AACA,wEAAwE,WAAW;AACnF;AACA;AACA,uBAAuB,mBAAmB,sBAAsB;AAChE,uBAAuB,mBAAmB,qBAAqB;AAC/D,uBAAuB,mBAAmB,oBAAoB;AAC9D,uBAAuB,mBAAmB,qBAAqB;AAC/D;AACA,uBAAuB,mBAAmB,qBAAqB;AAC/D,uBAAuB,mBAAmB,oBAAoB;AAC9D,uBAAuB,mBAAmB,mBAAmB;AAC7D,0BAA0B,mBAAmB;AAC7C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,gBAAgB;AACxC;AACA;AACA,YAAY;AACZ,yBAAyB,gBAAgB;AACzC,yBAAyB,gBAAgB;AACzC,yBAAyB;AACzB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,gBAAgB;AAC5C;AACA;AACA,gBAAgB;AAChB,6BAA6B,gBAAgB;AAC7C,6BAA6B,gBAAgB;AAC7C,6BAA6B;AAC7B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB,sBAAsB;AACtB,wBAAwB;AACxB,sBAAsB;AACtB;AACA;AACA;AACA,QAAQ,yBAAI,gDAAgD,wBAAK;AACjE;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,YAAY,yBAAI;AAChB;AACA,wBAAwB,QAAQ;AAChC;AACA;AACA,UAAU,SAAS,yBAAI;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,sBAAsB,yBAAI;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,QAAQ;AACxB,eAAe,yBAAI;AACnB;AACA;AACA;AACA;AACA;AACA,YAAY,yBAAI,iCAAiC,yBAAI,mBAAmB,yBAAI;AAC5E,4DAA4D,KAAK;AACjE,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa,kBAAG;AAChB,uBAAuB;AACvB,gBAAgB,QAAQ;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,iCAAiC,kBAAG;;;AC3rBvC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACL;AACF;AACO;AACE;AAC3C;AACA;AACA;AACA;AACA;AACA,kGAAkG,yBAAyB;AAC3H,SAAS,gBAAgB;AACzB;AACA;AACA,WAAW,YAAY;AACvB,WAAW,QAAQ;AACnB,oDAAoD;AACpD,iDAAiD;AACjD;AACA,WAAW,aAAa;AACxB,WAAW,aAAa;AACxB;AACA;AACA,WAAW,QAAQ,2DAA2D,2BAA2B;AACzG,IAAI,2BAA2B;AAC/B;AACA;AACA,kBAAG;AACH,6CAA6C,wBAAK,uBAAuB,wBAAK;AAC9E;AACA;AACA;AACA;AACA;AACA;AACA;AACA,uDAAuD;AACvD,qDAAqD;AACrD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA,4BAA4B,yBAAI;AAChC;AACA;AACA;AACA;AACA;AACA,QAAQ,yBAAI;AACZ;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA,YAAY,yBAAI;AAChB;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA;AACA;AACA,KAAK;AACL;AACA,kBAAG,0BAA0B,kBAAG;AAChC,yBAAI,sBAAsB,kBAAG,WAAW,kBAAG;AAC3C;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,wBAAwB;AAC3C,qBAAqB,cAAc;AACnC;AACA;AACA,gCAAgC,yBAAI;AACpC;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,wBAAwB;AAC3C,qBAAqB,QAAQ;AAC7B;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kCAAkC,mBAAG;AACrC;AACA;AACA;AACA,8CAA8C,mBAAG;AACjD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,6BAA6B,kCAAkC;AAC/D;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,uBAAQ;AAC5B,oBAAoB,yBAAI;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,gCAAgC,6CAA6C,mBAAmB,MAAM,0BAA0B;AAC3I,wGAAwG,kBAAkB;AAC1H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,iCAAiC;AACzD,wBAAwB,iCAAiC;AACzD,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,+CAA+C,eAAe,8CAA8C;AAC5H;AACA;AACA;AACA;AACA;AACA,gCAAgC,iCAAiC;AACjE,gCAAgC,iCAAiC;AACjE,gCAAgC;AAChC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA,4BAA4B,iCAAiC;AAC7D,4BAA4B,iCAAiC;AAC7D,4BAA4B;AAC5B;AACA;AACA;AACA;AACA,uDAAuD,0BAA0B;AACjF,sDAAsD,0BAA0B;AAChF;AACA;AACA,8DAA8D,iBAAiB;AAC/E;AACA;AACA,8DAA8D,wCAAwC;AACtG,yDAAyD,yBAAyB;AAClF;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,qFAAqF;AACrG;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB;AACA,gCAAgC,iCAAiC;AACjE,gCAAgC,iCAAiC;AACjE,gCAAgC;AAChC;AACA;AACA;AACA;AACA,2DAA2D,0BAA0B;AACrF,0DAA0D,0BAA0B;AACpF;AACA;AACA,kEAAkE,iBAAiB;AACnF;AACA;AACA,kEAAkE,wCAAwC;AAC1G,6DAA6D,yBAAyB;AACtF;AACA,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf;AACA,gBAAgB,oBAAoB;AACpC,YAAY,yBAAI;AAChB;AACA;AACA,cAAc;AACd;AACA;AACA,uBAAuB,yBAAI;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,UAAU;AACV;AACA;AACA;AACA;AACA,QAAQ,yBAAI,oBAAoB,yBAAI;AACpC;AACA,iBAAiB,kBAAG;AACpB;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN,QAAQ,yBAAI;AACZ,SAAS,yBAAI,mBAAmB,yBAAI,qBAAqB,yBAAI;AAC7D;AACA;AACA,iBAAiB,kBAAG;AACpB,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,6BAA6B,kBAAG;;;AC9nBnC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AACa;AACP;AACS;AACP;AACpC;AACA;AACA;AACA,oGAAoG,yBAAyB,WAAW,iBAAiB;AACzJ;AACA;AACA;AACA,WAAW,QAAQ;AACnB,WAAW,UAAU;AACrB,WAAW,UAAU;AACrB,WAAW,UAAU;AACrB,WAAW,UAAU;AACrB,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,WAAW,QAAQ;AACnB;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,QAAQ,wBAAK;AACb,QAAQ,wBAAK;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA,iDAAiD;AACjD;AACA;AACA,eAAe,QAAQ;AACvB,eAAe,QAAQ;AACvB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qBAAqB,yBAAI;AACzB;AACA,KAAK;AACL;AACA,kBAAG,2BAA2B,kBAAG;AACjC,yBAAI,sBAAsB,kBAAG,YAAY,kBAAG;AAC5C;AACA,kBAAG;AACH,IAAI,kBAAG;AACP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB,yBAAI;AACtB,kBAAkB,yBAAI;AACtB,kBAAkB,yBAAI;AACtB,kBAAkB,yBAAI;AACtB,kBAAkB,yBAAI;AACtB,kBAAkB,yBAAI;AACtB;AACA;AACA;AACA,mCAAmC,gBAAgB;AACnD;AACA,uCAAuC,gBAAgB;AACvD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA,sDAAsD,yBAAI;AAC1D;AACA;AACA;AACA;AACA;AACA,wBAAwB,cAAc;AACtC;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA;AACA,kBAAkB,mBAAG;AACrB,wBAAwB,cAAc;AACtC,sBAAsB,mBAAG;AACzB;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,mBAAmB,QAAQ;AAC3B,mBAAmB,QAAQ;AAC3B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,2CAA2C;AAC3C;AACA,kBAAkB,QAAQ;AAC1B,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,2CAA2C;AAC3C;AACA,kBAAkB,QAAQ;AAC1B,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,2CAA2C;AAC3C;AACA,kBAAkB,QAAQ;AAC1B,kBAAkB,QAAQ;AAC1B;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,WAAW;AACvC,gCAAgC,WAAW;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,WAAW;AACvC,gCAAgC,WAAW;AAC3C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB;AACpB,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB,yBAAI;AACpB;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,cAAc;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,WAAW;AACvC;AACA;AACA;AACA,gCAAgC,WAAW;AAC3C;AACA;AACA,0BAA0B;AAC1B;AACA;AACA,oCAAoC,cAAc;AAClD,gCAAgC,mBAAG;AACnC;AACA;AACA;AACA;AACA,0BAA0B;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,sCAAsC,YAAY;AAClD;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,mBAAmB,uBAAQ;AAC3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iEAAiE;AACjE;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB;AACA,WAAW,0DAA0D;AACrE;AACA;AACA,WAAW,wCAAwC;AACnD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,+CAA+C,eAAe,8CAA8C;AAC5H;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAM;AACN;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,WAAW,yBAAI;AACf,aAAa,kBAAG;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,wCAAwC,kBAAG;AAC9C;AACA;AACA,6DAA6D;AAC7D,mBAAmB,eAAe;AAClC;AACA;AACA,iCAAiC;AACjC;AACA;AACA;AACA;AACA;AACA,YAAY,WAAW;AACvB,WAAW,6BAA6B;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,eAAe;AACvC,wBAAwB,eAAe;AACvC,QAAQ;AACR;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAI;AACJ;AACA,+FAA+F,cAAc;AAC7G;AACA;AACA;AACA,gBAAgB,+CAA+C,eAAe,8CAA8C;AAC5H;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B,eAAe;AAC3C,4BAA4B,eAAe;AAC3C,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR,QAAQ;AACR;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA,SAAS;AACT;AACA;AACA,SAAS;AACT,YAAY,yBAAI;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG,oCAAoC,kBAAG;;;AC7lB1C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA,eAAe,QAAQ;AACvB,iBAAiB,OAAO;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oCAAoC,eAAe;AACnD,qCAAqC,eAAe;AACpD,qCAAqC,gBAAgB;AACrD,qCAAqC,gBAAgB;AACrD,qCAAqC,iCAAiC;AACtE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,cAAc;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,cAAc;AACd;AACA;AACA,mGAAmG,cAAc;AACjH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC;AACxC;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wCAAwC,eAAe;AACvD,yCAAyC,eAAe;AACxD,yCAAyC,gBAAgB;AACzD,yCAAyC,gBAAgB;AACzD,yCAAyC,iCAAiC;AAC1E;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB,cAAc;AACtC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,kBAAkB;AAClB;AACA,cAAc;AACd;AACA,YAAY;AACZ;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAoB,QAAQ;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA;AACA,cAAc;AACd;AACA,cAAc;AACd;AACA;AACA,4BAA4B,qBAAqB;AACjD,wBAAwB,kBAAG,kDAAkD,kBAAG;AAChF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gDAAe,kBAAG,QAAQ,EAAC;;;ACtS3B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,8BAA8B;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AAC4B;AAC5B;AACA;AACA;AACA;AACA;AACA,kBAAG;AACH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,iBAAiB;AACjB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA;AACA;AACA,QAAQ;AACR;AACA;AACA,gDAAe,mDAAG,I;;ACvZlB;AAC2B;AACM,CAAC;AACL;AACJ;AACD;AACE;AACC;AACH;AACK;AACP;AACS;AACR;AACC;AACI;AACL;AACC;AACQ;AACJ;AACE;AACF;AACJ;AACA;AACG;AACK;AACN;AACG;AACJ;AACH;AACC;AACI;AACD;AACO;AACR;AACD;AACC;AACC;AACE;AACD;AACF;AACC;AACG;AACE;AACG;AACP;AACH;AACC;AACI;AACC;AACL;AACS;AACR;AACA;AACD;AACD;AACG;AACF;AACI;AACG;AACA;AACJ;AACJ;AACC;AACE;AACA;AACG;AACJ;AACC;AACS;AACL;AACH;AACC;AACK;AACD;AACA;AACT;AACA;AACG;AACJ;AACG;AACD;AACA;AACG;AACJ;AACC;AACE;AACH;AACM;AACJ;AACC;AACG;AACC;AAC/B;AACA;AACA;AACA;AACA;AACA;AACA;AACO,yBAAyB,kBAAG;AAC5B,uBAAuB,kBAAG;AAC1B,aAAa,kBAAG;AAChB,eAAe,kBAAG;AAClB,iBAAiB,kBAAG;AACpB,YAAY,kBAAG;AACf,gBAAgB,kBAAG;AACnB,eAAe,kBAAG;AAClB,MAAM,YAAQ,GAAG,kBAAG;AACpB,gBAAgB,kBAAG;AACnB,oBAAoB,kBAAG;AAC9B;AACA;AACO,cAAc,kBAAG;AACjB,cAAc,kBAAG;AACjB,eAAe,kBAAG;AAClB,gBAAgB,kBAAG;AACnB,oBAAoB,kBAAG;AACvB,eAAe,kBAAG;AAClB,sBAAsB,kBAAG;AACzB,cAAc,kBAAG;AACjB,wBAAwB,kBAAG;AAC3B,cAAc,kBAAG;AACjB,MAAM,SAAK,GAAG,kBAAG;AACjB,mBAAmB,kBAAG;AACtB,eAAe,kBAAG;AAClB,aAAa,kBAAG;AAChB,cAAc,kBAAG;AACjB,gBAAgB,kBAAG;AACnB,aAAa,kBAAG;AAChB,cAAc,kBAAG;AACjB,uBAAuB,kBAAG;AAC1B,eAAe,kBAAG;AAClB,eAAe,kBAAG;AACzB;AACA;AACO,gBAAgB,kBAAG;AACnB,iBAAiB,kBAAG;AACpB,mBAAmB,kBAAG;AACtB,sBAAsB,kBAAG;AACzB,aAAa,kBAAG;AAChB,mBAAmB,kBAAG;AACtB,wBAAwB,kBAAG;AAC3B,cAAc,kBAAG;AACjB,qBAAqB,kBAAG;AACxB,kBAAkB,kBAAG;AACrB,4BAA4B,kBAAG;AAC/B,uBAAuB,kBAAG;AAC1B,2BAA2B,kBAAG;AAC9B,uBAAuB,kBAAG;AAC1B,yBAAyB,kBAAG;AAC5B,oBAAoB,kBAAG;AACvB,cAAc,kBAAG;AACjB,iBAAiB,kBAAG;AACpB,kBAAkB,kBAAG;AACrB,iBAAiB,kBAAG;AACpB,iBAAiB,kBAAG;AACpB,YAAY,kBAAG;AACf,mBAAmB,kBAAG;AACtB,4BAA4B,kBAAG;AAC/B,mBAAmB,kBAAG;AACtB,mBAAmB,kBAAG;AACtB,iBAAiB,kBAAG;AACpB,uBAAuB,kBAAG;AAC1B,8BAA8B,kBAAG;AACjC,8BAA8B,kBAAG;AACjC,wBAAwB,kBAAG;AAC3B,sBAAsB,kBAAG;AACzB,kBAAkB,kBAAG;AACrB,oBAAoB,kBAAG;AACvB,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB,kBAAkB,kBAAG;AACrB,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB,kBAAkB,kBAAG;AACrB,kBAAkB,kBAAG;AACrB,mBAAmB,kBAAG;AACtB,mBAAmB,kBAAG;AACtB,iBAAiB,kBAAG;AACpB,kBAAkB,kBAAG;AACrB,gBAAgB,kBAAG;AACnB,eAAe,kBAAG;AAClB,eAAe,kBAAG;AAClB,iBAAiB,kBAAG;AACpB,iBAAiB,kBAAG;AACpB,gBAAgB,kBAAG;AACnB,kBAAkB,kBAAG;AACrB,oBAAoB,kBAAG;AACvB,sBAAsB,kBAAG;AACzB,iBAAiB,kBAAG;AACpB,sBAAsB,kBAAG;AACzB,gCAAgC,kBAAG;AACnC,oBAAoB,kBAAG;AACvB,wBAAwB,kBAAG;AAC3B,sBAAsB,kBAAG;AACzB,aAAa,kBAAG;AAChB,qBAAqB,kBAAG;AACxB,cAAc,kBAAG;AACjB,2BAA2B,kBAAG;AAC9B,sBAAsB,kBAAG;AACzB,wBAAwB,kBAAG;AAC3B,uBAAuB,kBAAG;AAC1B,wBAAwB,kBAAG;AAC3B,+BAA+B,kBAAG;AAClC,oBAAoB,kBAAG;AACvB,gBAAgB,kBAAG;AACnB,eAAe,kBAAG;AAClB,eAAe,kBAAG;AAClB,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB,gBAAgB,kBAAG;AACnB,kBAAkB,kBAAG;AACrB,iBAAiB,kBAAG;AACpB,iBAAiB,kBAAG;AACpB,qBAAqB,kBAAG;AACxB,iBAAiB,kBAAG;AACpB,gBAAgB,kBAAG;AACnB,uBAAuB,kBAAG;AAC1B,8BAA8B,kBAAG;AACjC,oBAAoB,kBAAG;AACvB,oBAAoB,kBAAG;AACvB,aAAa,kBAAG;AAChB,kBAAkB,kBAAG;AACrB,gBAAgB,kBAAG;AACnB,qBAAqB,kBAAG;AACxB,eAAe,kBAAG;AAClB,aAAa,kBAAG;AAChB,mBAAmB,kBAAG;AACtB,iBAAiB,kBAAG;AACpB,qBAAqB,kBAAG;AACxB,oBAAoB,kBAAG;AACvB,6BAA6B,kBAAG;AAChC,2BAA2B,kBAAG;AAC9B,aAAa,kBAAG;AACvB;AACA;AACA,IAAI,kBAAG;AACP,iBAAiB,kBAAG;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS;AACT;AACA,EAAE,SAAS,kBAAG;AACd,eAAe,kBAAG;AAClB;AACA;AACA,0CAAe,kBAAG,EAAC","sources":["webpack://jsxgraph-types-fix/./src/parser/geonext.js","webpack://jsxgraph-types-fix/./src/base/coordselement.js","webpack://jsxgraph-types-fix/./src/utils/env.js","webpack://jsxgraph-types-fix/./src/base/element.js","webpack://jsxgraph-types-fix/./src/math/numerics.js","webpack://jsxgraph-types-fix/./src/utils/type.js","webpack://jsxgraph-types-fix/./src/options.js","webpack://jsxgraph-types-fix/./src/parser/jessiecode.js","webpack://jsxgraph-types-fix/./src/jxg.js","webpack://jsxgraph-types-fix/./src/utils/event.js","webpack://jsxgraph-types-fix/./src/math/math.js","webpack://jsxgraph-types-fix/./src/base/constants.js","webpack://jsxgraph-types-fix/./src/math/geometry.js","webpack://jsxgraph-types-fix/./src/math/statistics.js","webpack://jsxgraph-types-fix/./src/utils/expect.js","webpack://jsxgraph-types-fix/./src/math/ia.js","webpack://jsxgraph-types-fix/./src/utils/color.js","webpack://jsxgraph-types-fix/./src/base/coords.js","webpack://jsxgraph-types-fix/./src/base/text.js","webpack://jsxgraph-types-fix/webpack/bootstrap","webpack://jsxgraph-types-fix/webpack/runtime/define property getters","webpack://jsxgraph-types-fix/webpack/runtime/hasOwnProperty shorthand","webpack://jsxgraph-types-fix/./src/utils/xml.js","webpack://jsxgraph-types-fix/./src/math/probfuncs.js","webpack://jsxgraph-types-fix/./src/math/extrapolate.js","webpack://jsxgraph-types-fix/./src/math/qdt.js","webpack://jsxgraph-types-fix/./src/math/bqdt.js","webpack://jsxgraph-types-fix/./src/math/nlp.js","webpack://jsxgraph-types-fix/./src/math/plot.js","webpack://jsxgraph-types-fix/./src/math/implicitplot.js","webpack://jsxgraph-types-fix/./src/math/metapost.js","webpack://jsxgraph-types-fix/./src/math/clip.js","webpack://jsxgraph-types-fix/./src/math/poly.js","webpack://jsxgraph-types-fix/./src/math/complex.js","webpack://jsxgraph-types-fix/./src/renderer/abstract.js","webpack://jsxgraph-types-fix/./src/utils/encoding.js","webpack://jsxgraph-types-fix/./src/utils/base64.js","webpack://jsxgraph-types-fix/./src/reader/file.js","webpack://jsxgraph-types-fix/./src/base/composition.js","webpack://jsxgraph-types-fix/./src/base/board.js","webpack://jsxgraph-types-fix/./src/renderer/svg.js","webpack://jsxgraph-types-fix/./src/renderer/vml.js","webpack://jsxgraph-types-fix/./src/utils/uuid.js","webpack://jsxgraph-types-fix/./src/renderer/canvas.js","webpack://jsxgraph-types-fix/./src/renderer/no.js","webpack://jsxgraph-types-fix/./src/jsxgraph.js","webpack://jsxgraph-types-fix/./src/base/point.js","webpack://jsxgraph-types-fix/./src/base/line.js","webpack://jsxgraph-types-fix/./src/base/group.js","webpack://jsxgraph-types-fix/./src/base/circle.js","webpack://jsxgraph-types-fix/./src/element/conic.js","webpack://jsxgraph-types-fix/./src/base/polygon.js","webpack://jsxgraph-types-fix/./src/base/curve.js","webpack://jsxgraph-types-fix/./src/element/arc.js","webpack://jsxgraph-types-fix/./src/element/sector.js","webpack://jsxgraph-types-fix/./src/element/composition.js","webpack://jsxgraph-types-fix/./src/element/grid.js","webpack://jsxgraph-types-fix/./src/base/image.js","webpack://jsxgraph-types-fix/./src/element/slider.js","webpack://jsxgraph-types-fix/./src/parser/prefix.js","webpack://jsxgraph-types-fix/./src/element/measure.js","webpack://jsxgraph-types-fix/./src/parser/datasource.js","webpack://jsxgraph-types-fix/./src/base/chart.js","webpack://jsxgraph-types-fix/./src/base/transformation.js","webpack://jsxgraph-types-fix/./src/base/turtle.js","webpack://jsxgraph-types-fix/./src/base/ticks.js","webpack://jsxgraph-types-fix/./src/utils/zip.js","webpack://jsxgraph-types-fix/./src/parser/ca.js","webpack://jsxgraph-types-fix/./src/utils/dump.js","webpack://jsxgraph-types-fix/./src/element/comb.js","webpack://jsxgraph-types-fix/./src/element/slopetriangle.js","webpack://jsxgraph-types-fix/./src/element/checkbox.js","webpack://jsxgraph-types-fix/./src/element/input.js","webpack://jsxgraph-types-fix/./src/element/button.js","webpack://jsxgraph-types-fix/./src/element/vectorfield.js","webpack://jsxgraph-types-fix/./src/element/smartlabel.js","webpack://jsxgraph-types-fix/./src/base/foreignobject.js","webpack://jsxgraph-types-fix/./src/options3d.js","webpack://jsxgraph-types-fix/./src/3d/view3d.js","webpack://jsxgraph-types-fix/./src/3d/element3d.js","webpack://jsxgraph-types-fix/./src/3d/box3d.js","webpack://jsxgraph-types-fix/./src/3d/circle3d.js","webpack://jsxgraph-types-fix/./src/3d/point3d.js","webpack://jsxgraph-types-fix/./src/3d/curve3d.js","webpack://jsxgraph-types-fix/./src/3d/linspace3d.js","webpack://jsxgraph-types-fix/./src/3d/text3d.js","webpack://jsxgraph-types-fix/./src/3d/ticks3d.js","webpack://jsxgraph-types-fix/./src/3d/polygon3d.js","webpack://jsxgraph-types-fix/./src/3d/face3d.js","webpack://jsxgraph-types-fix/./src/3d/polyhedron3d.js","webpack://jsxgraph-types-fix/./src/3d/sphere3d.js","webpack://jsxgraph-types-fix/./src/3d/surface3d.js","webpack://jsxgraph-types-fix/./src/parser/3dmodels.js","webpack://jsxgraph-types-fix/./src/themes/mono_thin.js","webpack://jsxgraph-types-fix/./src/index.js"],"sourcesContent":["/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Parser helper routines. The methods in here are for parsing expressions in Geonext Syntax.\r\n * @namespace\r\n */\r\nJXG.GeonextParser = {\r\n    /**\r\n     * Converts expression of the form <i>leftop^rightop</i> into <i>Math.pow(leftop,rightop)</i>.\r\n     * @param {String} te Expression of the form <i>leftop^rightop</i>\r\n     * @returns {String} Converted expression.\r\n     */\r\n    replacePow: function (te) {\r\n        var count, pos, c, previousIndex, leftop, rightop, pre, p, left, i, right, expr;\r\n\r\n        // delete all whitespace immediately before and after all ^ operators\r\n        te = te.replace(/(\\s*)\\^(\\s*)/g, \"^\");\r\n\r\n        //  Loop over all ^ operators\r\n        i = te.indexOf(\"^\");\r\n        previousIndex = -1;\r\n\r\n        while (i >= 0 && i < te.length - 1) {\r\n            if (previousIndex === i) {\r\n                throw new Error(\"JSXGraph: Error while parsing expression '\" + te + \"'\");\r\n            }\r\n            previousIndex = i;\r\n\r\n            // left and right are the substrings before, resp. after the ^ character\r\n            left = te.slice(0, i);\r\n            right = te.slice(i + 1);\r\n\r\n            // If there is a \")\" immediately before the ^ operator, it can be the end of a\r\n            // (i) term in parenthesis\r\n            // (ii) function call\r\n            // (iii) method  call\r\n            // In either case, first the corresponding opening parenthesis is searched.\r\n            // This is the case, when count==0\r\n            if (left.charAt(left.length - 1) === \")\") {\r\n                count = 1;\r\n                pos = left.length - 2;\r\n\r\n                while (pos >= 0 && count > 0) {\r\n                    c = left.charAt(pos);\r\n                    if (c === \")\") {\r\n                        count++;\r\n                    } else if (c === \"(\") {\r\n                        count -= 1;\r\n                    }\r\n                    pos -= 1;\r\n                }\r\n\r\n                if (count === 0) {\r\n                    // Now, we have found the opning parenthesis and we have to look\r\n                    // if it is (i), or (ii), (iii).\r\n                    leftop = \"\";\r\n                    // Search for F or p.M before (...)^\r\n                    pre = left.substring(0, pos + 1);\r\n                    p = pos;\r\n                    while (p >= 0 && pre.slice(p, p + 1).match(/([\\w.]+)/)) {\r\n                        leftop = RegExp.$1 + leftop;\r\n                        p -= 1;\r\n                    }\r\n                    leftop += left.substring(pos + 1, left.length);\r\n                    leftop = leftop.replace(/([()+*%^\\-/\\][])/g, \"\\\\$1\");\r\n                } else {\r\n                    throw new Error(\"JSXGraph: Missing '(' in expression\");\r\n                }\r\n            } else {\r\n                // Otherwise, the operand has to be a constant (or variable).\r\n                leftop = \"[\\\\w\\\\.]+\"; // former: \\\\w\\\\.\r\n            }\r\n\r\n            // To the right of the ^ operator there also may be a function or method call\r\n            // or a term in parenthesis. Alos, ere we search for the closing\r\n            // parenthesis.\r\n            if (right.match(/^([\\w.]*\\()/)) {\r\n                count = 1;\r\n                pos = RegExp.$1.length;\r\n\r\n                while (pos < right.length && count > 0) {\r\n                    c = right.charAt(pos);\r\n\r\n                    if (c === \")\") {\r\n                        count -= 1;\r\n                    } else if (c === \"(\") {\r\n                        count += 1;\r\n                    }\r\n                    pos += 1;\r\n                }\r\n\r\n                if (count === 0) {\r\n                    rightop = right.substring(0, pos);\r\n                    rightop = rightop.replace(/([()+*%^\\-/[\\]])/g, \"\\\\$1\");\r\n                } else {\r\n                    throw new Error(\"JSXGraph: Missing ')' in expression\");\r\n                }\r\n            } else {\r\n                // Otherwise, the operand has to be a constant (or variable).\r\n                rightop = \"[\\\\w\\\\.]+\";\r\n            }\r\n            // Now, we have the two operands and replace ^ by JXG.Math.pow\r\n            expr = new RegExp(\"(\" + leftop + \")\\\\^(\" + rightop + \")\");\r\n            //te = te.replace(expr, 'JXG.Math.pow($1,$2)');\r\n            te = te.replace(expr, \"pow($1,$2)\");\r\n            i = te.indexOf(\"^\");\r\n        }\r\n\r\n        return te;\r\n    },\r\n\r\n    /**\r\n     * Converts expression of the form <i>If(a,b,c)</i> into <i>(a)?(b):(c)/i>.\r\n     * @param {String} te Expression of the form <i>If(a,b,c)</i>\r\n     * @returns {String} Converted expression.\r\n     */\r\n    replaceIf: function (te) {\r\n        var left,\r\n            right,\r\n            i,\r\n            pos,\r\n            count,\r\n            k1,\r\n            k2,\r\n            c,\r\n            meat,\r\n            s = \"\",\r\n            first = null,\r\n            second = null,\r\n            third = null;\r\n\r\n        i = te.indexOf(\"If(\");\r\n        if (i < 0) {\r\n            return te;\r\n        }\r\n\r\n        // \"\" means not defined. Here, we replace it by 0\r\n        te = te.replace(/\"\"/g, '0');\r\n        while (i >= 0) {\r\n            left = te.slice(0, i);\r\n            right = te.slice(i + 3);\r\n\r\n            // Search the end of the If() command and take out the meat\r\n            count = 1;\r\n            pos = 0;\r\n            k1 = -1;\r\n            k2 = -1;\r\n\r\n            while (pos < right.length && count > 0) {\r\n                c = right.charAt(pos);\r\n\r\n                if (c === \")\") {\r\n                    count -= 1;\r\n                } else if (c === \"(\") {\r\n                    count += 1;\r\n                } else if (c === \",\" && count === 1) {\r\n                    if (k1 < 0) {\r\n                        // first komma\r\n                        k1 = pos;\r\n                    } else {\r\n                        // second komma\r\n                        k2 = pos;\r\n                    }\r\n                }\r\n                pos += 1;\r\n            }\r\n            meat = right.slice(0, pos - 1);\r\n            right = right.slice(pos);\r\n\r\n            // Test the two kommas\r\n            if (k1 < 0) {\r\n                // , missing\r\n                return \"\";\r\n            }\r\n\r\n            if (k2 < 0) {\r\n                // , missing\r\n                return \"\";\r\n            }\r\n\r\n            first = meat.slice(0, k1);\r\n            second = meat.slice(k1 + 1, k2);\r\n            third = meat.slice(k2 + 1);\r\n\r\n            // Recurse\r\n            first = this.replaceIf(first);\r\n            second = this.replaceIf(second);\r\n            third = this.replaceIf(third);\r\n\r\n            s += left + \"((\" + first + \")?\" + \"(\" + second + \"):(\" + third + \"))\";\r\n            te = right;\r\n            first = null;\r\n            second = null;\r\n            i = te.indexOf(\"If(\");\r\n        }\r\n        s += right;\r\n        return s;\r\n    },\r\n\r\n    /**\r\n     * Replace an element's name in terms by an element's id.\r\n     * @param {String} term Term containing names of elements.\r\n     * @param {JXG.Board} board Reference to the board the elements are on.\r\n     * @param {Boolean} [jc=false] If true, all id's will be surrounded by <tt>$('</tt> and <tt>')</tt>.\r\n     * @returns {String} The same string with names replaced by ids.\r\n     **/\r\n    replaceNameById: function (term, board, jc) {\r\n        var end,\r\n            elName,\r\n            el,\r\n            i,\r\n            pos = 0,\r\n            funcs = [\"X\", \"Y\", \"L\", \"V\"],\r\n            printId = function (id) {\r\n                if (jc) {\r\n                    return \"$('\" + id + \"')\";\r\n                }\r\n\r\n                return id;\r\n            };\r\n\r\n        // Find X(el), Y(el), ...\r\n        // All functions declared in funcs\r\n        for (i = 0; i < funcs.length; i++) {\r\n            pos = term.indexOf(funcs[i] + \"(\");\r\n\r\n            while (pos >= 0) {\r\n                if (pos >= 0) {\r\n                    end = term.indexOf(\")\", pos + 2);\r\n                    if (end >= 0) {\r\n                        elName = term.slice(pos + 2, end);\r\n                        elName = elName.replace(/\\\\(['\"])?/g, \"$1\");\r\n                        el = board.elementsByName[elName];\r\n\r\n                        if (el) {\r\n                            term =\r\n                                term.slice(0, pos + 2) +\r\n                                (jc ? \"$('\" : \"\") +\r\n                                printId(el.id) +\r\n                                term.slice(end);\r\n                        }\r\n                    }\r\n                }\r\n                end = term.indexOf(\")\", pos + 2);\r\n                pos = term.indexOf(funcs[i] + \"(\", end);\r\n            }\r\n        }\r\n\r\n        pos = term.indexOf(\"Dist(\");\r\n        while (pos >= 0) {\r\n            if (pos >= 0) {\r\n                end = term.indexOf(\",\", pos + 5);\r\n                if (end >= 0) {\r\n                    elName = term.slice(pos + 5, end);\r\n                    elName = elName.replace(/\\\\(['\"])?/g, \"$1\");\r\n                    el = board.elementsByName[elName];\r\n\r\n                    if (el) {\r\n                        term = term.slice(0, pos + 5) + printId(el.id) + term.slice(end);\r\n                    }\r\n                }\r\n            }\r\n            end = term.indexOf(\",\", pos + 5);\r\n            pos = term.indexOf(\",\", end);\r\n            end = term.indexOf(\")\", pos + 1);\r\n\r\n            if (end >= 0) {\r\n                elName = term.slice(pos + 1, end);\r\n                elName = elName.replace(/\\\\(['\"])?/g, \"$1\");\r\n                el = board.elementsByName[elName];\r\n\r\n                if (el) {\r\n                    term = term.slice(0, pos + 1) + printId(el.id) + term.slice(end);\r\n                }\r\n            }\r\n            end = term.indexOf(\")\", pos + 1);\r\n            pos = term.indexOf(\"Dist(\", end);\r\n        }\r\n\r\n        funcs = [\"Deg\", \"Rad\"];\r\n        for (i = 0; i < funcs.length; i++) {\r\n            pos = term.indexOf(funcs[i] + \"(\");\r\n            while (pos >= 0) {\r\n                if (pos >= 0) {\r\n                    end = term.indexOf(\",\", pos + 4);\r\n                    if (end >= 0) {\r\n                        elName = term.slice(pos + 4, end);\r\n                        elName = elName.replace(/\\\\(['\"])?/g, \"$1\");\r\n                        el = board.elementsByName[elName];\r\n\r\n                        if (el) {\r\n                            term = term.slice(0, pos + 4) + printId(el.id) + term.slice(end);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                end = term.indexOf(\",\", pos + 4);\r\n                pos = term.indexOf(\",\", end);\r\n                end = term.indexOf(\",\", pos + 1);\r\n\r\n                if (end >= 0) {\r\n                    elName = term.slice(pos + 1, end);\r\n                    elName = elName.replace(/\\\\(['\"])?/g, \"$1\");\r\n                    el = board.elementsByName[elName];\r\n\r\n                    if (el) {\r\n                        term = term.slice(0, pos + 1) + printId(el.id) + term.slice(end);\r\n                    }\r\n                }\r\n\r\n                end = term.indexOf(\",\", pos + 1);\r\n                pos = term.indexOf(\",\", end);\r\n                end = term.indexOf(\")\", pos + 1);\r\n\r\n                if (end >= 0) {\r\n                    elName = term.slice(pos + 1, end);\r\n                    elName = elName.replace(/\\\\(['\"])?/g, \"$1\");\r\n                    el = board.elementsByName[elName];\r\n                    if (el) {\r\n                        term = term.slice(0, pos + 1) + printId(el.id) + term.slice(end);\r\n                    }\r\n                }\r\n\r\n                end = term.indexOf(\")\", pos + 1);\r\n                pos = term.indexOf(funcs[i] + \"(\", end);\r\n            }\r\n        }\r\n\r\n        return term;\r\n    },\r\n\r\n    /**\r\n     * Replaces element ids in terms by element this.board.objects['id'].\r\n     * @param {String} term A GEONE<sub>x</sub>T function string with JSXGraph ids in it.\r\n     * @returns {String} The input string with element ids replaced by this.board.objects[\"id\"].\r\n     **/\r\n    replaceIdByObj: function (term) {\r\n        // Search for expressions like \"X(gi23)\" or \"Y(gi23A)\" and convert them to objects['gi23'].X().\r\n        var expr = /(X|Y|L)\\(([\\w_]+)\\)/g;\r\n        term = term.replace(expr, \"$('$2').$1()\");\r\n\r\n        expr = /(V)\\(([\\w_]+)\\)/g;\r\n        term = term.replace(expr, \"$('$2').Value()\");\r\n\r\n        expr = /(Dist)\\(([\\w_]+),([\\w_]+)\\)/g;\r\n        term = term.replace(expr, \"dist($('$2'), $('$3'))\");\r\n\r\n        expr = /(Deg)\\(([\\w_]+),([ \\w[\\w_]+),([\\w_]+)\\)/g;\r\n        term = term.replace(expr, \"deg($('$2'),$('$3'),$('$4'))\");\r\n\r\n        // Search for Rad('gi23','gi24','gi25')\r\n        expr = /Rad\\(([\\w_]+),([\\w_]+),([\\w_]+)\\)/g;\r\n        term = term.replace(expr, \"rad($('$1'),$('$2'),$('$3'))\");\r\n\r\n        // it's ok, it will run through the jessiecode parser afterwards...\r\n        /*jslint regexp: true*/\r\n        expr = /N\\((.+)\\)/g;\r\n        term = term.replace(expr, \"($1)\");\r\n\r\n        return term;\r\n    },\r\n\r\n    /**\r\n     * Converts the given algebraic expression in GEONE<sub>x</sub>T syntax into an equivalent expression in JavaScript syntax.\r\n     * @param {String} term Expression in GEONExT syntax\r\n     * @param {JXG.Board} board\r\n     * @returns {String} Given expression translated to JavaScript.\r\n     */\r\n    geonext2JS: function (term, board) {\r\n        var expr,\r\n            newterm,\r\n            i,\r\n            from = [\r\n                \"Abs\",\r\n                \"ACos\",\r\n                \"ASin\",\r\n                \"ATan\",\r\n                \"Ceil\",\r\n                \"Cos\",\r\n                \"Exp\",\r\n                \"Factorial\",\r\n                \"Floor\",\r\n                \"Log\",\r\n                \"Max\",\r\n                \"Min\",\r\n                \"Random\",\r\n                \"Round\",\r\n                \"Sin\",\r\n                \"Sqrt\",\r\n                \"Tan\",\r\n                \"Trunc\"\r\n            ],\r\n            to = [\r\n                \"abs\",\r\n                \"acos\",\r\n                \"asin\",\r\n                \"atan\",\r\n                \"ceil\",\r\n                \"cos\",\r\n                \"exp\",\r\n                \"factorial\",\r\n                \"floor\",\r\n                \"log\",\r\n                \"max\",\r\n                \"min\",\r\n                \"random\",\r\n                \"round\",\r\n                \"sin\",\r\n                \"sqrt\",\r\n                \"tan\",\r\n                \"ceil\"\r\n            ];\r\n\r\n        // Hacks, to enable not well formed XML, @see JXG.GeonextReader#replaceLessThan\r\n        term = term.replace(/&lt;/g, \"<\");\r\n        term = term.replace(/&gt;/g, \">\");\r\n        term = term.replace(/&amp;/g, \"&\");\r\n\r\n        // Convert GEONExT syntax to JavaScript syntax\r\n        newterm = term;\r\n        newterm = this.replaceNameById(newterm, board);\r\n        newterm = this.replaceIf(newterm);\r\n        // Exponentiations-Problem x^y -> Math(exp(x,y).\r\n        newterm = this.replacePow(newterm);\r\n        newterm = this.replaceIdByObj(newterm);\r\n\r\n        for (i = 0; i < from.length; i++) {\r\n            // sin -> Math.sin and asin -> Math.asin\r\n            expr = new RegExp([\"(\\\\W|^)(\", from[i], \")\"].join(\"\"), 'ig');\r\n            newterm = newterm.replace(expr, [\"$1\", to[i]].join(\"\"));\r\n        }\r\n        newterm = newterm.replace(/True/g, 'true');\r\n        newterm = newterm.replace(/False/g, 'false');\r\n        newterm = newterm.replace(/fasle/g, 'false');\r\n        newterm = newterm.replace(/Pi/g, 'PI');\r\n        newterm = newterm.replace(/\"/g, \"'\");\r\n\r\n        return newterm;\r\n    },\r\n\r\n    /**\r\n     * Finds dependencies in a given term and resolves them by adding the\r\n     * dependent object to the found objects child elements.\r\n     * @param {JXG.GeometryElement} me Object depending on objects in given term.\r\n     * @param {String} term String containing dependencies for the given object.\r\n     * @param {JXG.Board} [board=me.board] Reference to a board\r\n     */\r\n    findDependencies: function (me, term, board) {\r\n        var elements, el, expr, elmask;\r\n\r\n        if (!Type.exists(board)) {\r\n            board = me.board;\r\n        }\r\n\r\n        elements = board.elementsByName;\r\n\r\n        for (el in elements) {\r\n            if (elements.hasOwnProperty(el)) {\r\n                if (el !== me.name) {\r\n                    if (elements[el].elementClass === Const.OBJECT_CLASS_TEXT) {\r\n                        if (!elements[el].evalVisProp('islabel')) {\r\n                            elmask = el.replace(/\\[/g, \"\\\\[\");\r\n                            elmask = elmask.replace(/\\]/g, \"\\\\]\");\r\n\r\n                            // Searches (A), (A,B),(A,B,C)\r\n                            expr = new RegExp(\r\n                                \"\\\\(([\\\\w\\\\[\\\\]'_ ]+,)*(\" + elmask + \")(,[\\\\w\\\\[\\\\]'_ ]+)*\\\\)\",\r\n                                \"g\"\r\n                            );\r\n\r\n                            if (term.search(expr) >= 0) {\r\n                                elements[el].addChild(me);\r\n                            }\r\n                        }\r\n                    } else {\r\n                        elmask = el.replace(/\\[/g, \"\\\\[\");\r\n                        elmask = elmask.replace(/\\]/g, \"\\\\]\");\r\n\r\n                        // Searches (A), (A,B),(A,B,C)\r\n                        expr = new RegExp(\r\n                            \"\\\\(([\\\\w\\\\[\\\\]'_ ]+,)*(\" + elmask + \")(,[\\\\w\\\\[\\\\]'_ ]+)*\\\\)\",\r\n                            \"g\"\r\n                        );\r\n\r\n                        if (term.search(expr) >= 0) {\r\n                            elements[el].addChild(me);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Converts the given algebraic expression in GEONE<sub>x</sub>T syntax into an equivalent expression in JessieCode syntax.\r\n     * @param {String} term Expression in GEONExT syntax\r\n     * @param {JXG.Board} board\r\n     * @returns {String} Given expression translated to JavaScript.\r\n     */\r\n    gxt2jc: function (term, board) {\r\n        var newterm;\r\n            // from = [\"Sqrt\"],\r\n            // to = [\"sqrt\"];\r\n\r\n        // Hacks, to enable not well formed XML, @see JXG.GeonextReader#replaceLessThan\r\n        term = term.replace(/&lt;/g, \"<\");\r\n        term = term.replace(/&gt;/g, \">\");\r\n        term = term.replace(/&amp;/g, \"&\");\r\n        newterm = term;\r\n        newterm = this.replaceNameById(newterm, board, true);\r\n        newterm = newterm.replace(/True/g, 'true');\r\n        newterm = newterm.replace(/False/g, 'false');\r\n        newterm = newterm.replace(/fasle/g, 'false');\r\n\r\n        return newterm;\r\n    }\r\n};\r\n\r\nexport default JXG.GeonextParser;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, console: true, window: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview The geometry object CoordsElement is defined in this file.\r\n * This object provides the coordinate handling of points, images and texts.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Numerics from \"../math/numerics.js\";\r\nimport Statistics from \"../math/statistics.js\";\r\nimport Coords from \"./coords.js\";\r\nimport Const from \"./constants.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * An element containing coords is a basic geometric element.\r\n * This is a parent class for points, images and texts.\r\n * It holds common methods for\r\n * all kind of coordinate elements like points, texts and images.\r\n * It can not be used directly.\r\n * @class Creates a new coords element object. It is a parent class for points, images and texts.\r\n * Do not use this constructor to create an element.\r\n *\r\n * @private\r\n * @augments JXG.GeometryElement\r\n * @param {Array} coordinates An array with the affine user coordinates of the point.\r\n * {@link JXG.Options#elements}, and - optionally - a name and an id.\r\n */\r\nJXG.CoordsElement = function (coordinates, isLabel) {\r\n    var i;\r\n\r\n    if (!Type.exists(coordinates)) {\r\n        coordinates = [1, 0, 0];\r\n    }\r\n\r\n    for (i = 0; i < coordinates.length; ++i) {\r\n        coordinates[i] = parseFloat(coordinates[i]);\r\n    }\r\n\r\n    /**\r\n     * Coordinates of the element.\r\n     * @type JXG.Coords\r\n     * @private\r\n     */\r\n    this.coords = new Coords(Const.COORDS_BY_USER, coordinates, this.board);\r\n\r\n    // initialCoords and actualCoords are needed to handle transformations\r\n    // and dragging of objects simultaneously.\r\n    // actualCoords are needed for non-points since the visible objects\r\n    // is transformed in the renderer.\r\n    // For labels and other relative texts, actualCoords is ignored, see\r\n    // board.initMoveObject\r\n    this.initialCoords = new Coords(Const.COORDS_BY_USER, coordinates, this.board);\r\n    this.actualCoords = new Coords(Const.COORDS_BY_USER, coordinates, this.board);\r\n\r\n    /**\r\n     * Relative position on a slide element (line, circle, curve) if element is a glider on this element.\r\n     * @type Number\r\n     * @private\r\n     */\r\n    this.position = null;\r\n\r\n    /**\r\n     * True if there the method this.updateConstraint() has been set. It is\r\n     * probably different from the prototype function() {return this;}.\r\n     * Used in updateCoords fo glider elements.\r\n     *\r\n     * @see JXG.CoordsElement#updateCoords\r\n     * @type Boolean\r\n     * @private\r\n     */\r\n    this.isConstrained = false;\r\n\r\n    /**\r\n     * Determines whether the element slides on a polygon if point is a glider.\r\n     * @type Boolean\r\n     * @default false\r\n     * @private\r\n     */\r\n    this.onPolygon = false;\r\n\r\n    /**\r\n     * When used as a glider this member stores the object, where to glide on.\r\n     * To set the object to glide on use the method\r\n     * {@link JXG.Point#makeGlider} and DO NOT set this property directly\r\n     * as it will break the dependency tree.\r\n     * @type JXG.GeometryElement\r\n     */\r\n    this.slideObject = null;\r\n\r\n    /**\r\n     * List of elements the element is bound to, i.e. the element glides on.\r\n     * Only the last entry is active.\r\n     * Use {@link JXG.Point#popSlideObject} to remove the currently active slideObject.\r\n     */\r\n    this.slideObjects = [];\r\n\r\n    /**\r\n     * A {@link JXG.CoordsElement#updateGlider} call is usually followed\r\n     * by a general {@link JXG.Board#update} which calls\r\n     * {@link JXG.CoordsElement#updateGliderFromParent}.\r\n     * To prevent double updates, {@link JXG.CoordsElement#needsUpdateFromParent}\r\n     * is set to false in updateGlider() and reset to true in the following call to\r\n     * {@link JXG.CoordsElement#updateGliderFromParent}\r\n     * @type Boolean\r\n     */\r\n    this.needsUpdateFromParent = true;\r\n\r\n    /**\r\n     * Stores the groups of this element in an array of Group.\r\n     * @type Array\r\n     * @see JXG.Group\r\n     * @private\r\n     */\r\n    this.groups = [];\r\n\r\n    /*\r\n     * Do we need this?\r\n     */\r\n    this.Xjc = null;\r\n    this.Yjc = null;\r\n\r\n    // documented in GeometryElement\r\n    this.methodMap = Type.deepCopy(this.methodMap, {\r\n        move: \"moveTo\",\r\n        moveTo: \"moveTo\",\r\n        moveAlong: \"moveAlong\",\r\n        visit: \"visit\",\r\n        glide: \"makeGlider\",\r\n        makeGlider: \"makeGlider\",\r\n        intersect: \"makeIntersection\",\r\n        makeIntersection: \"makeIntersection\",\r\n        X: \"X\",\r\n        Y: \"Y\",\r\n        Coords: \"Coords\",\r\n        free: \"free\",\r\n        setPosition: \"setGliderPosition\",\r\n        setGliderPosition: \"setGliderPosition\",\r\n        addConstraint: \"addConstraint\",\r\n        dist: \"Dist\",\r\n        Dist: \"Dist\",\r\n        onPolygon: \"onPolygon\",\r\n        startAnimation: \"startAnimation\",\r\n        stopAnimation: \"stopAnimation\"\r\n    });\r\n\r\n    /*\r\n     * this.element may have been set by the object constructor.\r\n     */\r\n    if (Type.exists(this.element)) {\r\n        this.addAnchor(coordinates, isLabel);\r\n    }\r\n    this.isDraggable = true;\r\n};\r\n\r\nJXG.extend(\r\n    JXG.CoordsElement.prototype,\r\n    /** @lends JXG.CoordsElement.prototype */ {\r\n        /**\r\n         * Dummy function for unconstrained points or gliders.\r\n         * @private\r\n         */\r\n        updateConstraint: function () {\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Updates the coordinates of the element.\r\n         * @private\r\n         */\r\n        updateCoords: function (fromParent) {\r\n            if (!this.needsUpdate) {\r\n                return this;\r\n            }\r\n\r\n            if (!Type.exists(fromParent)) {\r\n                fromParent = false;\r\n            }\r\n\r\n            if (this.evalVisProp('frozen') !== true) {\r\n                this.updateConstraint();\r\n            }\r\n\r\n            /*\r\n             * We need to calculate the new coordinates no matter of the elements visibility because\r\n             * a child could be visible and depend on the coordinates of the element/point (e.g. perpendicular).\r\n             *\r\n             * Check if the element is a glider and calculate new coords in dependency of this.slideObject.\r\n             * This function is called with fromParent==true in case it is a glider element for example if\r\n             * the defining elements of the line or circle have been changed.\r\n             */\r\n            if (this.type === Const.OBJECT_TYPE_GLIDER) {\r\n                if (this.isConstrained) {\r\n                    fromParent = false;\r\n                }\r\n\r\n                if (fromParent) {\r\n                    this.updateGliderFromParent();\r\n                } else {\r\n                    this.updateGlider();\r\n                }\r\n            }\r\n            this.updateTransform(fromParent);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Update of glider in case of dragging the glider or setting the postion of the glider.\r\n         * The relative position of the glider has to be updated.\r\n         *\r\n         * In case of a glider on a line:\r\n         * If the second point is an ideal point, then -1 < this.position < 1,\r\n         * this.position==+/-1 equals point2, this.position==0 equals point1\r\n         *\r\n         * If the first point is an ideal point, then 0 < this.position < 2\r\n         * this.position==0  or 2 equals point1, this.position==1 equals point2\r\n         *\r\n         * @private\r\n         */\r\n        updateGlider: function () {\r\n            var i, d, v,\r\n                p1c, p2c, poly, cc, pos,\r\n                angle, sgn, alpha, beta,\r\n                delta = 2.0 * Math.PI,\r\n                cp, c, invMat,\r\n                newCoords, newPos,\r\n                doRound = false,\r\n                ev_sw,\r\n                snappedTo, snapValues,\r\n                slide = this.slideObject,\r\n                res, cu,\r\n                slides = [],\r\n                isTransformed;\r\n\r\n            this.needsUpdateFromParent = false;\r\n            if (slide.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n                if (this.evalVisProp('isgeonext')) {\r\n                    delta = 1.0;\r\n                }\r\n                newCoords = Geometry.projectPointToCircle(this, slide, this.board);\r\n                newPos =\r\n                    Geometry.rad(\r\n                        [slide.center.X() + 1.0, slide.center.Y()],\r\n                        slide.center,\r\n                        this\r\n                    ) / delta;\r\n            } else if (slide.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                /*\r\n                 * onPolygon==true: the point is a slider on a segment and this segment is one of the\r\n                 * \"borders\" of a polygon.\r\n                 * This is a GEONExT feature.\r\n                 */\r\n                if (this.onPolygon) {\r\n                    p1c = slide.point1.coords.usrCoords;\r\n                    p2c = slide.point2.coords.usrCoords;\r\n                    i = 1;\r\n                    d = p2c[i] - p1c[i];\r\n\r\n                    if (Math.abs(d) < Mat.eps) {\r\n                        i = 2;\r\n                        d = p2c[i] - p1c[i];\r\n                    }\r\n\r\n                    cc = Geometry.projectPointToLine(this, slide, this.board);\r\n                    pos = (cc.usrCoords[i] - p1c[i]) / d;\r\n                    poly = slide.parentPolygon;\r\n\r\n                    if (pos < 0) {\r\n                        for (i = 0; i < poly.borders.length; i++) {\r\n                            if (slide === poly.borders[i]) {\r\n                                slide =\r\n                                    poly.borders[\r\n                                    (i - 1 + poly.borders.length) % poly.borders.length\r\n                                    ];\r\n                                break;\r\n                            }\r\n                        }\r\n                    } else if (pos > 1.0) {\r\n                        for (i = 0; i < poly.borders.length; i++) {\r\n                            if (slide === poly.borders[i]) {\r\n                                slide =\r\n                                    poly.borders[\r\n                                    (i + 1 + poly.borders.length) % poly.borders.length\r\n                                    ];\r\n                                break;\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    // If the slide object has changed, save the change to the glider.\r\n                    if (slide.id !== this.slideObject.id) {\r\n                        this.slideObject = slide;\r\n                    }\r\n                }\r\n\r\n                p1c = slide.point1.coords;\r\n                p2c = slide.point2.coords;\r\n\r\n                // Distance between the two defining points\r\n                d = p1c.distance(Const.COORDS_BY_USER, p2c);\r\n\r\n                // The defining points are identical\r\n                if (d < Mat.eps) {\r\n                    //this.coords.setCoordinates(Const.COORDS_BY_USER, p1c);\r\n                    newCoords = p1c;\r\n                    doRound = true;\r\n                    newPos = 0.0;\r\n                } else {\r\n                    newCoords = Geometry.projectPointToLine(this, slide, this.board);\r\n                    p1c = p1c.usrCoords.slice(0);\r\n                    p2c = p2c.usrCoords.slice(0);\r\n\r\n                    // The second point is an ideal point\r\n                    if (Math.abs(p2c[0]) < Mat.eps) {\r\n                        i = 1;\r\n                        d = p2c[i];\r\n\r\n                        if (Math.abs(d) < Mat.eps) {\r\n                            i = 2;\r\n                            d = p2c[i];\r\n                        }\r\n\r\n                        d = (newCoords.usrCoords[i] - p1c[i]) / d;\r\n                        sgn = d >= 0 ? 1 : -1;\r\n                        d = Math.abs(d);\r\n                        newPos = (sgn * d) / (d + 1);\r\n\r\n                        // The first point is an ideal point\r\n                    } else if (Math.abs(p1c[0]) < Mat.eps) {\r\n                        i = 1;\r\n                        d = p1c[i];\r\n\r\n                        if (Math.abs(d) < Mat.eps) {\r\n                            i = 2;\r\n                            d = p1c[i];\r\n                        }\r\n\r\n                        d = (newCoords.usrCoords[i] - p2c[i]) / d;\r\n\r\n                        // 1.0 - d/(1-d);\r\n                        if (d < 0.0) {\r\n                            newPos = (1 - 2.0 * d) / (1.0 - d);\r\n                        } else {\r\n                            newPos = 1 / (d + 1);\r\n                        }\r\n                    } else {\r\n                        i = 1;\r\n                        d = p2c[i] - p1c[i];\r\n\r\n                        if (Math.abs(d) < Mat.eps) {\r\n                            i = 2;\r\n                            d = p2c[i] - p1c[i];\r\n                        }\r\n                        newPos = (newCoords.usrCoords[i] - p1c[i]) / d;\r\n                    }\r\n                }\r\n\r\n                // Snap the glider to snap values.\r\n                snappedTo = this.findClosestSnapValue(newPos);\r\n                if (snappedTo !== null) {\r\n                    snapValues = this.evalVisProp('snapvalues');\r\n                    newPos = (snapValues[snappedTo] - this._smin) / (this._smax - this._smin);\r\n                    this.update(true);\r\n                } else {\r\n                    // Snap the glider point of the slider into its appropriate position\r\n                    // First, recalculate the new value of this.position\r\n                    // Second, call update(fromParent==true) to make the positioning snappier.\r\n                    ev_sw = this.evalVisProp('snapwidth');\r\n                    if (\r\n                        ev_sw > 0.0 && Math.abs(this._smax - this._smin) >= Mat.eps\r\n                    ) {\r\n                        newPos = Math.max(Math.min(newPos, 1), 0);\r\n                        // v = newPos * (this._smax - this._smin) + this._smin;\r\n                        // v = Math.round(v / ev_sw) * ev_sw;\r\n                        v = newPos * (this._smax - this._smin);\r\n                        v = Math.round(v / ev_sw) * ev_sw + this._smin;\r\n                        newPos = (v - this._smin) / (this._smax - this._smin);\r\n                        this.update(true);\r\n                    }\r\n                }\r\n\r\n                p1c = slide.point1.coords;\r\n                if (\r\n                    !slide.evalVisProp('straightfirst') &&\r\n                    Math.abs(p1c.usrCoords[0]) > Mat.eps &&\r\n                    newPos < 0\r\n                ) {\r\n                    newCoords = p1c;\r\n                    doRound = true;\r\n                    newPos = 0;\r\n                }\r\n\r\n                p2c = slide.point2.coords;\r\n                if (\r\n                    !slide.evalVisProp('straightlast') &&\r\n                    Math.abs(p2c.usrCoords[0]) > Mat.eps &&\r\n                    newPos > 1\r\n                ) {\r\n                    newCoords = p2c;\r\n                    doRound = true;\r\n                    newPos = 1;\r\n                }\r\n            } else if (slide.type === Const.OBJECT_TYPE_TURTLE) {\r\n                // In case, the point is a constrained glider.\r\n                this.updateConstraint();\r\n                res = Geometry.projectPointToTurtle(this, slide, this.board);\r\n                newCoords = res[0];\r\n                newPos = res[1]; // save position for the overwriting below\r\n            } else if (slide.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n                if (\r\n                    slide.type === Const.OBJECT_TYPE_ARC ||\r\n                    slide.type === Const.OBJECT_TYPE_SECTOR\r\n                ) {\r\n                    newCoords = Geometry.projectPointToCircle(this, slide, this.board);\r\n\r\n                    angle = Geometry.rad(slide.radiuspoint, slide.center, this);\r\n                    alpha = 0.0;\r\n                    beta = Geometry.rad(slide.radiuspoint, slide.center, slide.anglepoint);\r\n                    newPos = angle;\r\n\r\n                    ev_sw = slide.evalVisProp('selection');\r\n                    if (\r\n                        (ev_sw === \"minor\" && beta > Math.PI) ||\r\n                        (ev_sw === \"major\" && beta < Math.PI)\r\n                    ) {\r\n                        alpha = beta;\r\n                        beta = 2 * Math.PI;\r\n                    }\r\n\r\n                    // Correct the position if we are outside of the sector/arc\r\n                    if (angle < alpha || angle > beta) {\r\n                        newPos = beta;\r\n\r\n                        if (\r\n                            (angle < alpha && angle > alpha * 0.5) ||\r\n                            (angle > beta && angle > beta * 0.5 + Math.PI)\r\n                        ) {\r\n                            newPos = alpha;\r\n                        }\r\n\r\n                        this.needsUpdateFromParent = true;\r\n                        this.updateGliderFromParent();\r\n                    }\r\n\r\n                    delta = beta - alpha;\r\n                    if (this.visProp.isgeonext) {\r\n                        delta = 1.0;\r\n                    }\r\n                    if (Math.abs(delta) > Mat.eps) {\r\n                        newPos /= delta;\r\n                    }\r\n                } else {\r\n                    // In case, the point is a constrained glider.\r\n                    this.updateConstraint();\r\n\r\n                    // Handle the case if the curve comes from a transformation of a continuous curve.\r\n                    if (slide.transformations.length > 0) {\r\n                        isTransformed = false;\r\n                        // TODO this might buggy, see the recursion\r\n                        // in line.js getCurveTangentDir\r\n                        res = slide.getTransformationSource();\r\n                        if (res[0]) {\r\n                            isTransformed = res[0];\r\n                            slides.push(slide);\r\n                            slides.push(res[1]);\r\n                        }\r\n                        // Recurse\r\n                        while (res[0] && Type.exists(res[1]._transformationSource)) {\r\n                            res = res[1].getTransformationSource();\r\n                            slides.push(res[1]);\r\n                        }\r\n\r\n                        cu = this.coords.usrCoords;\r\n                        if (isTransformed) {\r\n                            for (i = 0; i < slides.length; i++) {\r\n                                slides[i].updateTransformMatrix();\r\n                                invMat = Mat.inverse(slides[i].transformMat);\r\n                                cu = Mat.matVecMult(invMat, cu);\r\n                            }\r\n                            cp = new Coords(Const.COORDS_BY_USER, cu, this.board).usrCoords;\r\n                            c = Geometry.projectCoordsToCurve(\r\n                                cp[1],\r\n                                cp[2],\r\n                                this.position || 0,\r\n                                slides[slides.length - 1],\r\n                                this.board\r\n                            );\r\n                            // projectPointCurve() already would apply the transformation.\r\n                            // Since we are projecting on the original curve, we have to do\r\n                            // the transformations \"by hand\".\r\n                            cu = c[0].usrCoords;\r\n                            for (i = slides.length - 2; i >= 0; i--) {\r\n                                cu = Mat.matVecMult(slides[i].transformMat, cu);\r\n                            }\r\n                            c[0] = new Coords(Const.COORDS_BY_USER, cu, this.board);\r\n                        } else {\r\n                            slide.updateTransformMatrix();\r\n                            invMat = Mat.inverse(slide.transformMat);\r\n                            cu = Mat.matVecMult(invMat, cu);\r\n                            cp = new Coords(Const.COORDS_BY_USER, cu, this.board).usrCoords;\r\n                            c = Geometry.projectCoordsToCurve(\r\n                                cp[1],\r\n                                cp[2],\r\n                                this.position || 0,\r\n                                slide,\r\n                                this.board\r\n                            );\r\n                        }\r\n\r\n                        newCoords = c[0];\r\n                        newPos = c[1];\r\n                    } else {\r\n                        res = Geometry.projectPointToCurve(this, slide, this.board);\r\n                        newCoords = res[0];\r\n                        newPos = res[1]; // save position for the overwriting below\r\n                    }\r\n                }\r\n            } else if (Type.isPoint(slide)) {\r\n                //this.coords.setCoordinates(Const.COORDS_BY_USER, Geometry.projectPointToPoint(this, slide, this.board).usrCoords, false);\r\n                newCoords = Geometry.projectPointToPoint(this, slide, this.board);\r\n                newPos = this.position; // save position for the overwriting below\r\n            }\r\n\r\n            this.coords.setCoordinates(Const.COORDS_BY_USER, newCoords.usrCoords, doRound);\r\n            this.position = newPos;\r\n        },\r\n\r\n        /**\r\n         * Find the closest entry in snapValues that is within snapValueDistance of pos.\r\n         *\r\n         * @param {Number} pos Value for which snapping is calculated.\r\n         * @returns {Number} Index of the value to snap to, or null.\r\n         * @private\r\n         */\r\n        findClosestSnapValue: function (pos) {\r\n            var i, d,\r\n                snapValues, snapValueDistance,\r\n                snappedTo = null;\r\n\r\n            // Snap the glider to snap values.\r\n            snapValues = this.evalVisProp('snapvalues');\r\n            snapValueDistance = this.evalVisProp('snapvaluedistance');\r\n\r\n            if (Type.isArray(snapValues) &&\r\n                Math.abs(this._smax - this._smin) >= Mat.eps &&\r\n                snapValueDistance > 0.0) {\r\n                for (i = 0; i < snapValues.length; i++) {\r\n                    d = Math.abs(pos * (this._smax - this._smin) + this._smin - snapValues[i]);\r\n                    if (d < snapValueDistance) {\r\n                        snapValueDistance = d;\r\n                        snappedTo = i;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return snappedTo;\r\n        },\r\n\r\n        /**\r\n         * Update of a glider in case a parent element has been updated. That means the\r\n         * relative position of the glider stays the same.\r\n         * @private\r\n         */\r\n        updateGliderFromParent: function () {\r\n            var p1c, p2c, r, lbda, c,\r\n                slide = this.slideObject,\r\n                slides = [],\r\n                res, i, isTransformed,\r\n                baseangle, alpha, angle, beta,\r\n                delta = 2.0 * Math.PI;\r\n\r\n            if (!this.needsUpdateFromParent) {\r\n                this.needsUpdateFromParent = true;\r\n                return;\r\n            }\r\n\r\n            if (slide.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n                r = slide.Radius();\r\n                if (this.evalVisProp('isgeonext')) {\r\n                    delta = 1.0;\r\n                }\r\n                c = [\r\n                    slide.center.X() + r * Math.cos(this.position * delta),\r\n                    slide.center.Y() + r * Math.sin(this.position * delta)\r\n                ];\r\n            } else if (slide.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                p1c = slide.point1.coords.usrCoords;\r\n                p2c = slide.point2.coords.usrCoords;\r\n\r\n                // If one of the defining points of the line does not exist,\r\n                // the glider should disappear\r\n                if (\r\n                    (p1c[0] === 0 && p1c[1] === 0 && p1c[2] === 0) ||\r\n                    (p2c[0] === 0 && p2c[1] === 0 && p2c[2] === 0)\r\n                ) {\r\n                    c = [0, 0, 0];\r\n                    // The second point is an ideal point\r\n                } else if (Math.abs(p2c[0]) < Mat.eps) {\r\n                    lbda = Math.min(Math.abs(this.position), 1 - Mat.eps);\r\n                    lbda /= 1.0 - lbda;\r\n\r\n                    if (this.position < 0) {\r\n                        lbda = -lbda;\r\n                    }\r\n\r\n                    c = [\r\n                        p1c[0] + lbda * p2c[0],\r\n                        p1c[1] + lbda * p2c[1],\r\n                        p1c[2] + lbda * p2c[2]\r\n                    ];\r\n                    // The first point is an ideal point\r\n                } else if (Math.abs(p1c[0]) < Mat.eps) {\r\n                    lbda = Math.max(this.position, Mat.eps);\r\n                    lbda = Math.min(lbda, 2 - Mat.eps);\r\n\r\n                    if (lbda > 1) {\r\n                        lbda = (lbda - 1) / (lbda - 2);\r\n                    } else {\r\n                        lbda = (1 - lbda) / lbda;\r\n                    }\r\n\r\n                    c = [\r\n                        p2c[0] + lbda * p1c[0],\r\n                        p2c[1] + lbda * p1c[1],\r\n                        p2c[2] + lbda * p1c[2]\r\n                    ];\r\n                } else {\r\n                    lbda = this.position;\r\n                    c = [\r\n                        p1c[0] + lbda * (p2c[0] - p1c[0]),\r\n                        p1c[1] + lbda * (p2c[1] - p1c[1]),\r\n                        p1c[2] + lbda * (p2c[2] - p1c[2])\r\n                    ];\r\n                }\r\n            } else if (slide.type === Const.OBJECT_TYPE_TURTLE) {\r\n                this.coords.setCoordinates(Const.COORDS_BY_USER, [\r\n                    slide.Z(this.position),\r\n                    slide.X(this.position),\r\n                    slide.Y(this.position)\r\n                ]);\r\n                // In case, the point is a constrained glider.\r\n                this.updateConstraint();\r\n                c = Geometry.projectPointToTurtle(this, slide, this.board)[0].usrCoords;\r\n            } else if (slide.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n                // Handle the case if the curve comes from a transformation of a continuous curve.\r\n                isTransformed = false;\r\n                res = slide.getTransformationSource();\r\n                if (res[0]) {\r\n                    isTransformed = res[0];\r\n                    slides.push(slide);\r\n                    slides.push(res[1]);\r\n                }\r\n                // Recurse\r\n                while (res[0] && Type.exists(res[1]._transformationSource)) {\r\n                    res = res[1].getTransformationSource();\r\n                    slides.push(res[1]);\r\n                }\r\n                if (isTransformed) {\r\n                    this.coords.setCoordinates(Const.COORDS_BY_USER, [\r\n                        slides[slides.length - 1].Z(this.position),\r\n                        slides[slides.length - 1].X(this.position),\r\n                        slides[slides.length - 1].Y(this.position)\r\n                    ]);\r\n                } else {\r\n                    this.coords.setCoordinates(Const.COORDS_BY_USER, [\r\n                        slide.Z(this.position),\r\n                        slide.X(this.position),\r\n                        slide.Y(this.position)\r\n                    ]);\r\n                }\r\n\r\n                if (\r\n                    slide.type === Const.OBJECT_TYPE_ARC ||\r\n                    slide.type === Const.OBJECT_TYPE_SECTOR\r\n                ) {\r\n                    baseangle = Geometry.rad(\r\n                        [slide.center.X() + 1, slide.center.Y()],\r\n                        slide.center,\r\n                        slide.radiuspoint\r\n                    );\r\n\r\n                    alpha = 0.0;\r\n                    beta = Geometry.rad(slide.radiuspoint, slide.center, slide.anglepoint);\r\n\r\n                    if (\r\n                        (slide.visProp.selection === \"minor\" && beta > Math.PI) ||\r\n                        (slide.visProp.selection === \"major\" && beta < Math.PI)\r\n                    ) {\r\n                        alpha = beta;\r\n                        beta = 2 * Math.PI;\r\n                    }\r\n\r\n                    delta = beta - alpha;\r\n                    if (this.evalVisProp('isgeonext')) {\r\n                        delta = 1.0;\r\n                    }\r\n                    angle = this.position * delta;\r\n\r\n                    // Correct the position if we are outside of the sector/arc\r\n                    if (angle < alpha || angle > beta) {\r\n                        angle = beta;\r\n\r\n                        if (\r\n                            (angle < alpha && angle > alpha * 0.5) ||\r\n                            (angle > beta && angle > beta * 0.5 + Math.PI)\r\n                        ) {\r\n                            angle = alpha;\r\n                        }\r\n\r\n                        this.position = angle;\r\n                        if (Math.abs(delta) > Mat.eps) {\r\n                            this.position /= delta;\r\n                        }\r\n                    }\r\n\r\n                    r = slide.Radius();\r\n                    c = [\r\n                        slide.center.X() + r * Math.cos(this.position * delta + baseangle),\r\n                        slide.center.Y() + r * Math.sin(this.position * delta + baseangle)\r\n                    ];\r\n                } else {\r\n                    // In case, the point is a constrained glider.\r\n                    this.updateConstraint();\r\n\r\n                    if (isTransformed) {\r\n                        c = Geometry.projectPointToCurve(\r\n                            this,\r\n                            slides[slides.length - 1],\r\n                            this.board\r\n                        )[0].usrCoords;\r\n                        // projectPointCurve() already would do the transformation.\r\n                        // But since we are projecting on the original curve, we have to do\r\n                        // the transformation \"by hand\".\r\n                        for (i = slides.length - 2; i >= 0; i--) {\r\n                            c = new Coords(\r\n                                Const.COORDS_BY_USER,\r\n                                Mat.matVecMult(slides[i].transformMat, c),\r\n                                this.board\r\n                            ).usrCoords;\r\n                        }\r\n                    } else {\r\n                        c = Geometry.projectPointToCurve(this, slide, this.board)[0].usrCoords;\r\n                    }\r\n                }\r\n            } else if (Type.isPoint(slide)) {\r\n                c = Geometry.projectPointToPoint(this, slide, this.board).usrCoords;\r\n            }\r\n\r\n            this.coords.setCoordinates(Const.COORDS_BY_USER, c, false);\r\n        },\r\n\r\n        updateRendererGeneric: function (rendererMethod) {\r\n            //var wasReal;\r\n\r\n            if (!this.needsUpdate || !this.board.renderer) {\r\n                return this;\r\n            }\r\n\r\n            if (this.visPropCalc.visible) {\r\n                //wasReal = this.isReal;\r\n                this.isReal = !isNaN(this.coords.usrCoords[1] + this.coords.usrCoords[2]);\r\n                //Homogeneous coords: ideal point\r\n                this.isReal =\r\n                    Math.abs(this.coords.usrCoords[0]) > Mat.eps ? this.isReal : false;\r\n\r\n                if (\r\n                    // wasReal &&\r\n                    !this.isReal\r\n                ) {\r\n                    this.updateVisibility(false);\r\n                }\r\n            }\r\n\r\n            // Call the renderer only if element is visible.\r\n            // Update the position\r\n            if (this.visPropCalc.visible) {\r\n                this.board.renderer[rendererMethod](this);\r\n            }\r\n\r\n            // Update the label if visible.\r\n            if (\r\n                this.hasLabel &&\r\n                this.visPropCalc.visible &&\r\n                this.label &&\r\n                this.label.visPropCalc.visible &&\r\n                this.isReal\r\n            ) {\r\n                this.label.update();\r\n                this.board.renderer.updateText(this.label);\r\n            }\r\n\r\n            // Update rendNode display\r\n            this.setDisplayRendNode();\r\n            // if (this.visPropCalc.visible !== this.visPropOld.visible) {\r\n            //     this.board.renderer.display(this, this.visPropCalc.visible);\r\n            //     this.visPropOld.visible = this.visPropCalc.visible;\r\n            //\r\n            //     if (this.hasLabel) {\r\n            //         this.board.renderer.display(this.label, this.label.visPropCalc.visible);\r\n            //     }\r\n            // }\r\n\r\n            this.needsUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Getter method for x, this is used by for CAS-points to access point coordinates.\r\n         * @returns {Number} User coordinate of point in x direction.\r\n         */\r\n        X: function () {\r\n            return this.coords.usrCoords[1];\r\n        },\r\n\r\n        /**\r\n         * Getter method for y, this is used by CAS-points to access point coordinates.\r\n         * @returns {Number} User coordinate of point in y direction.\r\n         */\r\n        Y: function () {\r\n            return this.coords.usrCoords[2];\r\n        },\r\n\r\n        /**\r\n         * Getter method for z, this is used by CAS-points to access point coordinates.\r\n         * @returns {Number} User coordinate of point in z direction.\r\n         */\r\n        Z: function () {\r\n            return this.coords.usrCoords[0];\r\n        },\r\n\r\n        /**\r\n         * Getter method for coordinates x, y and (optional) z.\r\n         * @param {Number|String} [digits='auto'] Truncating rule for the digits in the infobox.\r\n         * <ul>\r\n         * <li>'auto': done automatically by JXG.autoDigits()\r\n         * <li>'none': no truncation\r\n         * <li>number: truncate after \"number digits\" with JXG.toFixed()\r\n         * </ul>\r\n         * @param {Boolean} [withZ=false] If set to true the return value will be <tt>(x | y | z)</tt> instead of <tt>(x, y)</tt>.\r\n         * @returns {String} User coordinates of point.\r\n         */\r\n        Coords: function (withZ) {\r\n            if (withZ) {\r\n                return this.coords.usrCoords.slice();\r\n            }\r\n            return this.coords.usrCoords.slice(1);\r\n        },\r\n        // Coords: function (digits, withZ) {\r\n        //     var arr, sep;\r\n\r\n        //     digits = digits || 'auto';\r\n\r\n        //     if (withZ) {\r\n        //         sep = ' | ';\r\n        //     } else {\r\n        //         sep = ', ';\r\n        //     }\r\n\r\n        //     if (digits === 'none') {\r\n        //         arr = [this.X(), sep, this.Y()];\r\n        //         if (withZ) {\r\n        //             arr.push(sep, this.Z());\r\n        //         }\r\n\r\n        //     } else if (digits === 'auto') {\r\n        //         if (this.useLocale()) {\r\n        //             arr = [this.formatNumberLocale(this.X()), sep, this.formatNumberLocale(this.Y())];\r\n        //             if (withZ) {\r\n        //                 arr.push(sep, this.formatNumberLocale(this.Z()));\r\n        //             }\r\n        //         } else {\r\n        //             arr = [Type.autoDigits(this.X()), sep, Type.autoDigits(this.Y())];\r\n        //             if (withZ) {\r\n        //                 arr.push(sep, Type.autoDigits(this.Z()));\r\n        //             }\r\n        //         }\r\n\r\n        //     } else {\r\n        //         if (this.useLocale()) {\r\n        //             arr = [this.formatNumberLocale(this.X(), digits), sep, this.formatNumberLocale(this.Y(), digits)];\r\n        //             if (withZ) {\r\n        //                 arr.push(sep, this.formatNumberLocale(this.Z(), digits));\r\n        //             }\r\n        //         } else {\r\n        //             arr = [Type.toFixed(this.X(), digits), sep, Type.toFixed(this.Y(), digits)];\r\n        //             if (withZ) {\r\n        //                 arr.push(sep, Type.toFixed(this.Z(), digits));\r\n        //             }\r\n        //         }\r\n        //     }\r\n\r\n        //     return '(' + arr.join('') + ')';\r\n        // },\r\n\r\n        /**\r\n         * New evaluation of the function term.\r\n         * This is required for CAS-points: Their XTerm() method is\r\n         * overwritten in {@link JXG.CoordsElement#addConstraint}.\r\n         *\r\n         * @returns {Number} User coordinate of point in x direction.\r\n         * @private\r\n         */\r\n        XEval: function () {\r\n            return this.coords.usrCoords[1];\r\n        },\r\n\r\n        /**\r\n         * New evaluation of the function term.\r\n         * This is required for CAS-points: Their YTerm() method is overwritten\r\n         * in {@link JXG.CoordsElement#addConstraint}.\r\n         *\r\n         * @returns {Number} User coordinate of point in y direction.\r\n         * @private\r\n         */\r\n        YEval: function () {\r\n            return this.coords.usrCoords[2];\r\n        },\r\n\r\n        /**\r\n         * New evaluation of the function term.\r\n         * This is required for CAS-points: Their ZTerm() method is overwritten in\r\n         * {@link JXG.CoordsElement#addConstraint}.\r\n         *\r\n         * @returns {Number} User coordinate of point in z direction.\r\n         * @private\r\n         */\r\n        ZEval: function () {\r\n            return this.coords.usrCoords[0];\r\n        },\r\n\r\n        /**\r\n         * Getter method for the distance to a second point, this is required for CAS-elements.\r\n         * Here, function inlining seems to be worthwile (for plotting).\r\n         * @param {JXG.Point} point2 The point to which the distance shall be calculated.\r\n         * @returns {Number} Distance in user coordinate to the given point\r\n         */\r\n        Dist: function (point2) {\r\n            if (this.isReal && point2.isReal) {\r\n                return this.coords.distance(Const.COORDS_BY_USER, point2.coords);\r\n            }\r\n            return NaN;\r\n        },\r\n\r\n        /**\r\n         * Alias for {@link JXG.Element#handleSnapToGrid}\r\n         * @param {Boolean} force force snapping independent of what the snaptogrid attribute says\r\n         * @returns {JXG.CoordsElement} Reference to this element\r\n         */\r\n        snapToGrid: function (force) {\r\n            return this.handleSnapToGrid(force);\r\n        },\r\n\r\n        /**\r\n         * Let a point snap to the nearest point in distance of\r\n         * {@link JXG.Point#attractorDistance}.\r\n         * The function uses the coords object of the point as\r\n         * its actual position.\r\n         * @param {Boolean} force force snapping independent of what the snaptogrid attribute says\r\n         * @returns {JXG.CoordsElement} Reference to this element\r\n         */\r\n        handleSnapToPoints: function (force) {\r\n            var i,\r\n                pEl,\r\n                pCoords,\r\n                d = 0,\r\n                len,\r\n                dMax = Infinity,\r\n                c = null,\r\n                ev_au,\r\n                ev_ad,\r\n                ev_is2p = this.evalVisProp('ignoredsnaptopoints'),\r\n                len2,\r\n                j,\r\n                ignore = false;\r\n\r\n            len = this.board.objectsList.length;\r\n\r\n            if (ev_is2p) {\r\n                len2 = ev_is2p.length;\r\n            }\r\n\r\n            if (this.evalVisProp('snaptopoints') || force) {\r\n                ev_au = this.evalVisProp('attractorunit');\r\n                ev_ad = this.evalVisProp('attractordistance');\r\n\r\n                for (i = 0; i < len; i++) {\r\n                    pEl = this.board.objectsList[i];\r\n\r\n                    if (ev_is2p) {\r\n                        ignore = false;\r\n                        for (j = 0; j < len2; j++) {\r\n                            if (pEl === this.board.select(ev_is2p[j])) {\r\n                                ignore = true;\r\n                                break;\r\n                            }\r\n                        }\r\n                        if (ignore) {\r\n                            continue;\r\n                        }\r\n                    }\r\n\r\n                    if (Type.isPoint(pEl) && pEl !== this && pEl.visPropCalc.visible) {\r\n                        pCoords = Geometry.projectPointToPoint(this, pEl, this.board);\r\n                        if (ev_au === 'screen') {\r\n                            d = pCoords.distance(Const.COORDS_BY_SCREEN, this.coords);\r\n                        } else {\r\n                            d = pCoords.distance(Const.COORDS_BY_USER, this.coords);\r\n                        }\r\n\r\n                        if (d < ev_ad && d < dMax) {\r\n                            dMax = d;\r\n                            c = pCoords;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (c !== null) {\r\n                    this.coords.setCoordinates(Const.COORDS_BY_USER, c.usrCoords);\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Alias for {@link JXG.CoordsElement#handleSnapToPoints}.\r\n         *\r\n         * @param {Boolean} force force snapping independent of what the snaptogrid attribute says\r\n         * @returns {JXG.CoordsElement} Reference to this element\r\n         */\r\n        snapToPoints: function (force) {\r\n            return this.handleSnapToPoints(force);\r\n        },\r\n\r\n        /**\r\n         * A point can change its type from free point to glider\r\n         * and vice versa. If it is given an array of attractor elements\r\n         * (attribute attractors) and the attribute attractorDistance\r\n         * then the point will be made a glider if it less than attractorDistance\r\n         * apart from one of its attractor elements.\r\n         * If attractorDistance is equal to zero, the point stays in its\r\n         * current form.\r\n         * @returns {JXG.CoordsElement} Reference to this element\r\n         */\r\n        handleAttractors: function () {\r\n            var i,\r\n                el,\r\n                projCoords,\r\n                d = 0.0,\r\n                projection,\r\n                ev_au = this.evalVisProp('attractorunit'),\r\n                ev_ad = this.evalVisProp('attractordistance'),\r\n                ev_sd = this.evalVisProp('snatchdistance'),\r\n                ev_a = this.evalVisProp('attractors'),\r\n                len = ev_a.length;\r\n\r\n            if (ev_ad === 0.0) {\r\n                return;\r\n            }\r\n\r\n            for (i = 0; i < len; i++) {\r\n                el = this.board.select(ev_a[i]);\r\n\r\n                if (Type.exists(el) && el !== this) {\r\n                    if (Type.isPoint(el)) {\r\n                        projCoords = Geometry.projectPointToPoint(this, el, this.board);\r\n                    } else if (el.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                        projection = Geometry.projectCoordsToSegment(\r\n                            this.coords.usrCoords,\r\n                            el.point1.coords.usrCoords,\r\n                            el.point2.coords.usrCoords\r\n                        );\r\n                        if (!el.evalVisProp('straightfirst') && projection[1] < 0.0) {\r\n                            projCoords = el.point1.coords;\r\n                        } else if (\r\n                            !el.evalVisProp('straightlast') &&\r\n                            projection[1] > 1.0\r\n                        ) {\r\n                            projCoords = el.point2.coords;\r\n                        } else {\r\n                            projCoords = new Coords(\r\n                                Const.COORDS_BY_USER,\r\n                                projection[0],\r\n                                this.board\r\n                            );\r\n                        }\r\n                    } else if (el.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n                        projCoords = Geometry.projectPointToCircle(this, el, this.board);\r\n                    } else if (el.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n                        projCoords = Geometry.projectPointToCurve(this, el, this.board)[0];\r\n                    } else if (el.type === Const.OBJECT_TYPE_TURTLE) {\r\n                        projCoords = Geometry.projectPointToTurtle(this, el, this.board)[0];\r\n                    } else if (el.type === Const.OBJECT_TYPE_POLYGON) {\r\n                        projCoords = new Coords(\r\n                            Const.COORDS_BY_USER,\r\n                            Geometry.projectCoordsToPolygon(this.coords.usrCoords, el),\r\n                            this.board\r\n                        );\r\n                    }\r\n\r\n                    if (ev_au === 'screen') {\r\n                        d = projCoords.distance(Const.COORDS_BY_SCREEN, this.coords);\r\n                    } else {\r\n                        d = projCoords.distance(Const.COORDS_BY_USER, this.coords);\r\n                    }\r\n\r\n                    if (d < ev_ad) {\r\n                        if (\r\n                            !(\r\n                                this.type === Const.OBJECT_TYPE_GLIDER &&\r\n                                (el === this.slideObject ||\r\n                                    (this.slideObject &&\r\n                                        this.onPolygon &&\r\n                                        this.slideObject.parentPolygon === el))\r\n                            )\r\n                        ) {\r\n                            this.makeGlider(el);\r\n                        }\r\n                        break; // bind the point to the first attractor in its list.\r\n                    }\r\n                    if (\r\n                        d >= ev_sd &&\r\n                        (el === this.slideObject ||\r\n                            (this.slideObject &&\r\n                                this.onPolygon &&\r\n                                this.slideObject.parentPolygon === el))\r\n                    ) {\r\n                        this.popSlideObject();\r\n                    }\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Sets coordinates and calls the elements's update() method.\r\n         * @param {Number} method The type of coordinates used here.\r\n         * Possible values are {@link JXG.COORDS_BY_USER} and {@link JXG.COORDS_BY_SCREEN}.\r\n         * @param {Array} coords coordinates <tt>([z], x, y)</tt> in screen/user units\r\n         * @returns {JXG.CoordsElement} this element\r\n         */\r\n        setPositionDirectly: function (method, coords) {\r\n            var i,\r\n                c, dc, m,\r\n                oldCoords = this.coords,\r\n                newCoords;\r\n\r\n            if (this.relativeCoords) {\r\n                c = new Coords(method, coords, this.board);\r\n                if (this.evalVisProp('islabel')) {\r\n                    dc = Statistics.subtract(c.scrCoords, oldCoords.scrCoords);\r\n                    this.relativeCoords.scrCoords[1] += dc[1];\r\n                    this.relativeCoords.scrCoords[2] += dc[2];\r\n                } else {\r\n                    dc = Statistics.subtract(c.usrCoords, oldCoords.usrCoords);\r\n                    this.relativeCoords.usrCoords[1] += dc[1];\r\n                    this.relativeCoords.usrCoords[2] += dc[2];\r\n                }\r\n\r\n                return this;\r\n            }\r\n\r\n            this.coords.setCoordinates(method, coords);\r\n            this.handleSnapToGrid();\r\n            this.handleSnapToPoints();\r\n            this.handleAttractors();\r\n\r\n            // Here, we set the object's \"actualCoords\", because\r\n            // coords and initialCoords coincide since transformations\r\n            // for these elements are handled in the renderers.\r\n            this.actualCoords.setCoordinates(Const.COORDS_BY_USER, this.coords.usrCoords);\r\n\r\n            // The element's coords have been set above to the new position `coords`.\r\n            // Now, determine the preimage of `coords`, prior to all transformations.\r\n            // This is needed for free elements that have a transformation bound to it.\r\n            if (this.transformations.length > 0) {\r\n                if (method === Const.COORDS_BY_SCREEN) {\r\n                    newCoords = new Coords(method, coords, this.board).usrCoords;\r\n                } else {\r\n                    if (coords.length === 2) {\r\n                        coords = [1].concat(coords);\r\n                    }\r\n                    newCoords = coords;\r\n                }\r\n                m = [[1, 0, 0], [0, 1, 0], [0, 0, 1]];\r\n                for (i = 0; i < this.transformations.length; i++) {\r\n                    m = Mat.matMatMult(this.transformations[i].matrix, m);\r\n                }\r\n                newCoords = Mat.matVecMult(Mat.inverse(m), newCoords);\r\n\r\n                this.initialCoords.setCoordinates(Const.COORDS_BY_USER, newCoords);\r\n                if (this.elementClass !== Const.OBJECT_CLASS_POINT) {\r\n                    // This is necessary for images and texts.\r\n                    this.coords.setCoordinates(Const.COORDS_BY_USER, newCoords);\r\n                }\r\n            }\r\n            this.prepareUpdate().update();\r\n\r\n            // If the user suspends the board updates we need to recalculate the relative position of\r\n            // the point on the slide object. This is done in updateGlider() which is NOT called during the\r\n            // update process triggered by unsuspendUpdate.\r\n            if (this.board.isSuspendedUpdate && this.type === Const.OBJECT_TYPE_GLIDER) {\r\n                this.updateGlider();\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Translates the point by <tt>tv = (x, y)</tt>.\r\n         * @param {Number} method The type of coordinates used here.\r\n         * Possible values are {@link JXG.COORDS_BY_USER} and {@link JXG.COORDS_BY_SCREEN}.\r\n         * @param {Array} tv (x, y)\r\n         * @returns {JXG.CoordsElement}\r\n         */\r\n        setPositionByTransform: function (method, tv) {\r\n            var t;\r\n\r\n            tv = new Coords(method, tv, this.board);\r\n            t = this.board.create(\"transform\", tv.usrCoords.slice(1), {\r\n                type: \"translate\"\r\n            });\r\n\r\n            if (\r\n                this.transformations.length > 0 &&\r\n                this.transformations[this.transformations.length - 1].isNumericMatrix\r\n            ) {\r\n                this.transformations[this.transformations.length - 1].melt(t);\r\n            } else {\r\n                this.addTransform(this, t);\r\n            }\r\n\r\n            this.prepareUpdate().update();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Sets coordinates and calls the element's update() method.\r\n         * @param {Number} method The type of coordinates used here.\r\n         * Possible values are {@link JXG.COORDS_BY_USER} and {@link JXG.COORDS_BY_SCREEN}.\r\n         * @param {Array} coords coordinates in screen/user units\r\n         * @returns {JXG.CoordsElement}\r\n         */\r\n        setPosition: function (method, coords) {\r\n            return this.setPositionDirectly(method, coords);\r\n        },\r\n\r\n        /**\r\n         * Sets the position of a glider relative to the defining elements\r\n         * of the {@link JXG.Point#slideObject}.\r\n         * @param {Number} x\r\n         * @returns {JXG.Point} Reference to the point element.\r\n         */\r\n        setGliderPosition: function (x) {\r\n            if (this.type === Const.OBJECT_TYPE_GLIDER) {\r\n                this.position = x;\r\n                this.board.update();\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Convert the point to glider and update the construction.\r\n         * To move the point visual onto the glider, a call of board update is necessary.\r\n         * @param {String|Object} slide The object the point will be bound to.\r\n         */\r\n        makeGlider: function (slide) {\r\n            var slideobj = this.board.select(slide),\r\n                onPolygon = false,\r\n                min, i, dist;\r\n\r\n            if (slideobj.type === Const.OBJECT_TYPE_POLYGON) {\r\n                // Search for the closest edge of the polygon.\r\n                min = Number.MAX_VALUE;\r\n                for (i = 0; i < slideobj.borders.length; i++) {\r\n                    dist = JXG.Math.Geometry.distPointLine(\r\n                        this.coords.usrCoords,\r\n                        slideobj.borders[i].stdform\r\n                    );\r\n                    if (dist < min) {\r\n                        min = dist;\r\n                        slide = slideobj.borders[i];\r\n                    }\r\n                }\r\n                slideobj = this.board.select(slide);\r\n                onPolygon = true;\r\n            }\r\n\r\n            /* Gliders on Ticks are forbidden */\r\n            if (!Type.exists(slideobj)) {\r\n                throw new Error(\"JSXGraph: slide object undefined.\");\r\n            } else if (slideobj.type === Const.OBJECT_TYPE_TICKS) {\r\n                throw new Error(\"JSXGraph: gliders on ticks are not possible.\");\r\n            }\r\n\r\n            this.slideObject = this.board.select(slide);\r\n            this.slideObjects.push(this.slideObject);\r\n            this.addParents(slide);\r\n\r\n            this.type = Const.OBJECT_TYPE_GLIDER;\r\n            this.elType = 'glider';\r\n            this.visProp.snapwidth = -1; // By default, deactivate snapWidth\r\n            this.slideObject.addChild(this);\r\n            this.isDraggable = true;\r\n            this.onPolygon = onPolygon;\r\n\r\n            this.generatePolynomial = function () {\r\n                return this.slideObject.generatePolynomial(this);\r\n            };\r\n\r\n            // Determine the initial value of this.position\r\n            this.updateGlider();\r\n            this.needsUpdateFromParent = true;\r\n            this.updateGliderFromParent();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Remove the last slideObject. If there are more than one elements the point is bound to,\r\n         * the second last element is the new active slideObject.\r\n         */\r\n        popSlideObject: function () {\r\n            if (this.slideObjects.length > 0) {\r\n                this.slideObjects.pop();\r\n\r\n                // It may not be sufficient to remove the point from\r\n                // the list of childElement. For complex dependencies\r\n                // one may have to go to the list of ancestor and descendants.  A.W.\r\n                // Yes indeed, see #51 on github bug tracker\r\n                //   delete this.slideObject.childElements[this.id];\r\n                this.slideObject.removeChild(this);\r\n\r\n                if (this.slideObjects.length === 0) {\r\n                    this.type = this._org_type;\r\n                    if (this.type === Const.OBJECT_TYPE_POINT) {\r\n                        this.elType = 'point';\r\n                    } else if (this.elementClass === Const.OBJECT_CLASS_TEXT) {\r\n                        this.elType = 'text';\r\n                    } else if (this.type === Const.OBJECT_TYPE_IMAGE) {\r\n                        this.elType = 'image';\r\n                    } else if (this.type === Const.OBJECT_TYPE_FOREIGNOBJECT) {\r\n                        this.elType = 'foreignobject';\r\n                    }\r\n\r\n                    this.slideObject = null;\r\n                } else {\r\n                    this.slideObject = this.slideObjects[this.slideObjects.length - 1];\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Converts a calculated element into a free element,\r\n         * i.e. it will delete all ancestors and transformations and,\r\n         * if the element is currently a glider, will remove the slideObject reference.\r\n         */\r\n        free: function () {\r\n            var ancestorId, ancestor;\r\n            // child;\r\n\r\n            if (this.type !== Const.OBJECT_TYPE_GLIDER) {\r\n                // remove all transformations\r\n                this.transformations.length = 0;\r\n\r\n                delete this.updateConstraint;\r\n                this.isConstrained = false;\r\n                // this.updateConstraint = function () {\r\n                //     return this;\r\n                // };\r\n\r\n                if (!this.isDraggable) {\r\n                    this.isDraggable = true;\r\n\r\n                    if (this.elementClass === Const.OBJECT_CLASS_POINT) {\r\n                        this.type = Const.OBJECT_TYPE_POINT;\r\n                        this.elType = 'point';\r\n                    }\r\n\r\n                    this.XEval = function () {\r\n                        return this.coords.usrCoords[1];\r\n                    };\r\n\r\n                    this.YEval = function () {\r\n                        return this.coords.usrCoords[2];\r\n                    };\r\n\r\n                    this.ZEval = function () {\r\n                        return this.coords.usrCoords[0];\r\n                    };\r\n\r\n                    this.Xjc = null;\r\n                    this.Yjc = null;\r\n                } else {\r\n                    return;\r\n                }\r\n            }\r\n\r\n            // a free point does not depend on anything. And instead of running through tons of descendants and ancestor\r\n            // structures, where we eventually are going to visit a lot of objects twice or thrice with hard to read and\r\n            // comprehend code, just run once through all objects and delete all references to this point and its label.\r\n            for (ancestorId in this.board.objects) {\r\n                if (this.board.objects.hasOwnProperty(ancestorId)) {\r\n                    ancestor = this.board.objects[ancestorId];\r\n\r\n                    if (ancestor.descendants) {\r\n                        delete ancestor.descendants[this.id];\r\n                        delete ancestor.childElements[this.id];\r\n\r\n                        if (this.hasLabel) {\r\n                            delete ancestor.descendants[this.label.id];\r\n                            delete ancestor.childElements[this.label.id];\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // A free point does not depend on anything. Remove all ancestors.\r\n            this.ancestors = {}; // only remove the reference\r\n            this.parents = [];\r\n\r\n            // Completely remove all slideObjects of the element\r\n            this.slideObject = null;\r\n            this.slideObjects = [];\r\n            if (this.elementClass === Const.OBJECT_CLASS_POINT) {\r\n                this.type = Const.OBJECT_TYPE_POINT;\r\n                this.elType = 'point';\r\n            } else if (this.elementClass === Const.OBJECT_CLASS_TEXT) {\r\n                this.type = this._org_type;\r\n                this.elType = 'text';\r\n            } else if (this.elementClass === Const.OBJECT_CLASS_OTHER) {\r\n                this.type = this._org_type;\r\n                this.elType = 'image';\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Convert the point to CAS point and call update().\r\n         * @param {Array} terms [[zterm], xterm, yterm] defining terms for the z, x and y coordinate.\r\n         * The z-coordinate is optional and it is used for homogeneous coordinates.\r\n         * The coordinates may be either <ul>\r\n         *   <li>a JavaScript function,</li>\r\n         *   <li>a string containing GEONExT syntax. This string will be converted into a JavaScript\r\n         *     function here,</li>\r\n         *   <li>a Number</li>\r\n         *   <li>a pointer to a slider object. This will be converted into a call of the Value()-method\r\n         *     of this slider.</li>\r\n         *   </ul>\r\n         * @see JXG.GeonextParser#geonext2JS\r\n         */\r\n        addConstraint: function (terms) {\r\n            var i, v,\r\n                newfuncs = [],\r\n                what = [\"X\", \"Y\"],\r\n                makeConstFunction = function (z) {\r\n                    return function () {\r\n                        return z;\r\n                    };\r\n                },\r\n                makeSliderFunction = function (a) {\r\n                    return function () {\r\n                        return a.Value();\r\n                    };\r\n                };\r\n\r\n            if (this.elementClass === Const.OBJECT_CLASS_POINT) {\r\n                this.type = Const.OBJECT_TYPE_CAS;\r\n            }\r\n\r\n            this.isDraggable = false;\r\n\r\n            for (i = 0; i < terms.length; i++) {\r\n                v = terms[i];\r\n\r\n                if (Type.isString(v)) {\r\n                    // Convert GEONExT syntax into JavaScript syntax\r\n                    //t  = JXG.GeonextParser.geonext2JS(v, this.board);\r\n                    //newfuncs[i] = new Function('','return ' + t + ';');\r\n                    //v = GeonextParser.replaceNameById(v, this.board);\r\n                    newfuncs[i] = this.board.jc.snippet(v, true, null, true);\r\n                    this.addParentsFromJCFunctions([newfuncs[i]]);\r\n\r\n                    // Store original term as 'Xjc' or 'Yjc'\r\n                    if (terms.length === 2) {\r\n                        this[what[i] + \"jc\"] = terms[i];\r\n                    }\r\n                } else if (Type.isFunction(v)) {\r\n                    newfuncs[i] = v;\r\n                } else if (Type.isNumber(v)) {\r\n                    newfuncs[i] = makeConstFunction(v);\r\n                } else if (Type.isObject(v) && Type.isFunction(v.Value)) {\r\n                    // Slider\r\n                    newfuncs[i] = makeSliderFunction(v);\r\n                }\r\n\r\n                newfuncs[i].origin = v;\r\n            }\r\n\r\n            if (terms.length === 1) {\r\n                // Intersection function\r\n                this.updateConstraint = function () {\r\n                    var c = newfuncs[0]();\r\n\r\n                    // Array\r\n                    if (Type.isArray(c)) {\r\n                        this.coords.setCoordinates(Const.COORDS_BY_USER, c);\r\n                        // Coords object\r\n                    } else {\r\n                        this.coords = c;\r\n                    }\r\n                    return this;\r\n                };\r\n            } else if (terms.length === 2) {\r\n                // Euclidean coordinates\r\n                this.XEval = newfuncs[0];\r\n                this.YEval = newfuncs[1];\r\n                this.addParents([newfuncs[0].origin, newfuncs[1].origin]);\r\n\r\n                this.updateConstraint = function () {\r\n                    this.coords.setCoordinates(Const.COORDS_BY_USER, [\r\n                        this.XEval(),\r\n                        this.YEval()\r\n                    ]);\r\n                    return this;\r\n                };\r\n            } else {\r\n                // Homogeneous coordinates\r\n                this.ZEval = newfuncs[0];\r\n                this.XEval = newfuncs[1];\r\n                this.YEval = newfuncs[2];\r\n\r\n                this.addParents([newfuncs[0].origin, newfuncs[1].origin, newfuncs[2].origin]);\r\n\r\n                this.updateConstraint = function () {\r\n                    this.coords.setCoordinates(Const.COORDS_BY_USER, [\r\n                        this.ZEval(),\r\n                        this.XEval(),\r\n                        this.YEval()\r\n                    ]);\r\n                    return this;\r\n                };\r\n            }\r\n            this.isConstrained = true;\r\n\r\n            /**\r\n             * We have to do an update. Otherwise, elements relying on this point will receive NaN.\r\n             */\r\n            this.prepareUpdate().update();\r\n            if (!this.board.isSuspendedUpdate) {\r\n                this.updateVisibility().updateRenderer();\r\n                if (this.hasLabel) {\r\n                    this.label.fullUpdate();\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * In case there is an attribute \"anchor\", the element is bound to\r\n         * this anchor element.\r\n         * This is handled with this.relativeCoords. If the element is a label\r\n         * relativeCoords are given in scrCoords, otherwise in usrCoords.\r\n         * @param{Array} coordinates Offset from the anchor element. These are the values for this.relativeCoords.\r\n         * In case of a label, coordinates are screen coordinates. Otherwise, coordinates are user coordinates.\r\n         * @param{Boolean} isLabel Yes/no\r\n         * @private\r\n         */\r\n        addAnchor: function (coordinates, isLabel) {\r\n            if (isLabel) {\r\n                this.relativeCoords = new Coords(\r\n                    Const.COORDS_BY_SCREEN,\r\n                    coordinates.slice(0, 2),\r\n                    this.board\r\n                );\r\n            } else {\r\n                this.relativeCoords = new Coords(Const.COORDS_BY_USER, coordinates, this.board);\r\n            }\r\n            this.element.addChild(this);\r\n            if (isLabel) {\r\n                this.addParents(this.element);\r\n            }\r\n\r\n            this.XEval = function () {\r\n                var sx, coords, anchor, ev_o;\r\n\r\n                if (this.evalVisProp('islabel')) {\r\n                    ev_o = this.evalVisProp('offset');\r\n                    sx = parseFloat(ev_o[0]);\r\n                    anchor = this.element.getLabelAnchor();\r\n                    coords = new Coords(\r\n                        Const.COORDS_BY_SCREEN,\r\n                        [sx + this.relativeCoords.scrCoords[1] + anchor.scrCoords[1], 0],\r\n                        this.board\r\n                    );\r\n\r\n                    return coords.usrCoords[1];\r\n                }\r\n\r\n                anchor = this.element.getTextAnchor();\r\n                return this.relativeCoords.usrCoords[1] + anchor.usrCoords[1];\r\n            };\r\n\r\n            this.YEval = function () {\r\n                var sy, coords, anchor, ev_o;\r\n\r\n                if (this.evalVisProp('islabel')) {\r\n                    ev_o = this.evalVisProp('offset');\r\n                    sy = -parseFloat(ev_o[1]);\r\n                    anchor = this.element.getLabelAnchor();\r\n                    coords = new Coords(\r\n                        Const.COORDS_BY_SCREEN,\r\n                        [0, sy + this.relativeCoords.scrCoords[2] + anchor.scrCoords[2]],\r\n                        this.board\r\n                    );\r\n\r\n                    return coords.usrCoords[2];\r\n                }\r\n\r\n                anchor = this.element.getTextAnchor();\r\n                return this.relativeCoords.usrCoords[2] + anchor.usrCoords[2];\r\n            };\r\n\r\n            this.ZEval = Type.createFunction(1, this.board, \"\");\r\n\r\n            this.updateConstraint = function () {\r\n                this.coords.setCoordinates(Const.COORDS_BY_USER, [\r\n                    this.ZEval(),\r\n                    this.XEval(),\r\n                    this.YEval()\r\n                ]);\r\n            };\r\n            this.isConstrained = true;\r\n\r\n            this.updateConstraint();\r\n        },\r\n\r\n        /**\r\n         * Applies the transformations of the element.\r\n         * This method applies to text and images. Point transformations are handled differently.\r\n         * @param {Boolean} fromParent True if the drag comes from a child element. Unused.\r\n         * @returns {JXG.CoordsElement} Reference to itself.\r\n         */\r\n        updateTransform: function (fromParent) {\r\n            var c, i;\r\n\r\n            if (this.transformations.length === 0) {\r\n                return this;\r\n            }\r\n\r\n            // This is the case for image and text rotations\r\n            // like in smartlabels\r\n            if (this.baseElement === null) {\r\n                this.baseElement = this;\r\n            }\r\n\r\n            // This method is called for non-points only.\r\n            // Here, we set the object's \"actualCoords\", because\r\n            // coords and initialCoords coincide since transformations\r\n            // for these elements are handled in the renderers.\r\n\r\n            this.transformations[0].update();\r\n            if (this === this.baseElement) {\r\n                // Case of bindTo\r\n                c = this.transformations[0].apply(this, 'self');\r\n            } else {\r\n                c = this.transformations[0].apply(this.baseElement);\r\n            }\r\n            for (i = 1; i < this.transformations.length; i++) {\r\n                this.transformations[i].update();\r\n                c = Mat.matVecMult(this.transformations[i].matrix, c);\r\n            }\r\n            this.actualCoords.setCoordinates(Const.COORDS_BY_USER, c);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Add transformations to this element.\r\n         * @param {JXG.GeometryElement} el\r\n         * @param {JXG.Transformation|Array} transform Either one {@link JXG.Transformation}\r\n         * or an array of {@link JXG.Transformation}s.\r\n         * @returns {JXG.CoordsElement} Reference to itself.\r\n         */\r\n        addTransform: function (el, transform) {\r\n            var i,\r\n                list = Type.isArray(transform) ? transform : [transform],\r\n                len = list.length;\r\n\r\n            // There is only one baseElement possible\r\n            if (this.transformations.length === 0) {\r\n                this.baseElement = el;\r\n            }\r\n\r\n            for (i = 0; i < len; i++) {\r\n                this.transformations.push(list[i]);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Animate a point.\r\n         * @param {Number|Function} direction The direction the glider is animated. Can be +1 or -1.\r\n         * @param {Number|Function} stepCount The number of steps in which the parent element is divided.\r\n         * Must be at least 1.\r\n         * @param {Number|Function} delay Time in msec between two animation steps. Default is 250.\r\n         * @param {Number} [maxRounds=-1] The number of rounds the glider will be animated. The glider will run infinitely if\r\n         * maxRounds is negative or equal to Infinity.\r\n         * @returns {JXG.CoordsElement} Reference to itself.\r\n         *\r\n         * @name Glider#startAnimation\r\n         * @see Glider#stopAnimation\r\n         * @function\r\n         * @example\r\n         * // Divide the circle line into 6 steps and\r\n         * // visit every step 330 msec counterclockwise.\r\n         * var ci = board.create('circle', [[-1,2], [2,1]]);\r\n         * var gl = board.create('glider', [0,2, ci]);\r\n         * gl.startAnimation(-1, 6, 330);\r\n         *\r\n         * </pre><div id=\"JXG0f35a50e-e99d-11e8-a1ca-04d3b0c2aad3\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG0f35a50e-e99d-11e8-a1ca-04d3b0c2aad3',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     // Divide the circle line into 6 steps and\r\n         *     // visit every step 330 msec counterclockwise.\r\n         *     var ci = board.create('circle', [[-1,2], [2,1]]);\r\n         *     var gl = board.create('glider', [0,2, ci]);\r\n         *     gl.startAnimation(-1, 6, 330);\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         * @example\r\n         * //animate example closed curve\r\n         * var c1 = board.create('curve',[(u)=>4*Math.cos(u),(u)=>2*Math.sin(u)+2,0,2*Math.PI]);\r\n         * var p2 = board.create('glider', [c1]);\r\n         * var button1 = board.create('button', [1, 7, 'start animation',function(){p2.startAnimation(1,8)}]);\r\n         * var button2 = board.create('button', [1, 5, 'stop animation',function(){p2.stopAnimation()}]);\r\n         * </pre><div class=\"jxgbox\" id=\"JXG10e885ea-b05d-4e7d-a473-bac2554bce68\" style=\"width: 200px; height: 200px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *   var gpex4_board = JXG.JSXGraph.initBoard('JXG10e885ea-b05d-4e7d-a473-bac2554bce68', {boundingbox: [-1, 10, 10, -1], axis: true, showcopyright: false, shownavigation: false});\r\n         *   var gpex4_c1 = gpex4_board.create('curve',[(u)=>4*Math.cos(u)+4,(u)=>2*Math.sin(u)+2,0,2*Math.PI]);\r\n         *   var gpex4_p2 = gpex4_board.create('glider', [gpex4_c1]);\r\n         *   gpex4_board.create('button', [1, 7, 'start animation',function(){gpex4_p2.startAnimation(1,8)}]);\r\n         *   gpex4_board.create('button', [1, 5, 'stop animation',function(){gpex4_p2.stopAnimation()}]);\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         * // Divide the slider area into 20 steps and\r\n         * // visit every step 30 msec. Stop after 2 rounds.\r\n         * var n = board.create('slider',[[-2,4],[2,4],[1,5,100]],{name:'n'});\r\n         * n.startAnimation(1, 20, 30, 2);\r\n         *\r\n         * </pre><div id=\"JXG40ce04b8-e99c-11e8-a1ca-04d3b0c2aad3\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG40ce04b8-e99c-11e8-a1ca-04d3b0c2aad3',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     // Divide the slider area into 20 steps and\r\n         *     // visit every step 30 msec.\r\n         *     var n = board.create('slider',[[-2,4],[2,4],[1,5,100]],{name:'n'});\r\n         *     n.startAnimation(1, 20, 30, 2);\r\n         *\r\n         *     })();\r\n         * </script><pre>\r\n         *\r\n         */\r\n        startAnimation: function (direction, stepCount, delay, maxRounds) {\r\n            var dir = Type.evaluate(direction),\r\n                sc = Type.evaluate(stepCount),\r\n                that = this;\r\n\r\n            delay = Type.evaluate(delay) || 250;\r\n            maxRounds = Type.evaluate(maxRounds);\r\n            maxRounds = (maxRounds !== 'undefined') ? maxRounds : -1;\r\n\r\n            if (this.type === Const.OBJECT_TYPE_GLIDER && !Type.exists(this.intervalCode) && maxRounds !== 0) {\r\n                this.roundsCount = 0;\r\n                this.intervalCode = window.setInterval(function () {\r\n                    that._anim(dir, sc, maxRounds);\r\n                }, delay);\r\n\r\n                if (!Type.exists(this.intervalCount)) {\r\n                    this.intervalCount = 0;\r\n\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Stop animation.\r\n         * @name Glider#stopAnimation\r\n         * @see Glider#startAnimation\r\n         * @function\r\n         * @returns {JXG.CoordsElement} Reference to itself.\r\n         */\r\n        stopAnimation: function () {\r\n            if (Type.exists(this.intervalCode)) {\r\n                window.clearInterval(this.intervalCode);\r\n                delete this.intervalCode;\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Starts an animation which moves the point along a given path in given time.\r\n         * @param {Array|function} path The path the point is moved on.\r\n         * This can be either an array of arrays or containing x and y values of the points of\r\n         * the path, or an array of points, or a function taking the amount of elapsed time since the animation\r\n         * has started and returns an array containing a x and a y value or NaN.\r\n         * In case of NaN the animation stops.\r\n         * @param {Number} time The time in milliseconds in which to finish the animation\r\n         * @param {Object} [options] Optional settings for the animation.\r\n         * @param {function} [options.callback] A function that is called as soon as the animation is finished.\r\n         * @param {Boolean} [options.interpolate=true] If <tt>path</tt> is an array moveAlong()\r\n         * will interpolate the path\r\n         * using {@link JXG.Math.Numerics.Neville}. Set this flag to false if you don't want to use interpolation.\r\n         * @returns {JXG.CoordsElement} Reference to itself.\r\n         * @see JXG.CoordsElement#moveTo\r\n         * @see JXG.CoordsElement#visit\r\n         * @see JXG.CoordsElement#moveAlongES6\r\n         * @see JXG.GeometryElement#animate\r\n         */\r\n        moveAlong: function (path, time, options) {\r\n            options = options || {};\r\n\r\n            var i,\r\n                neville,\r\n                interpath = [],\r\n                p = [],\r\n                delay = this.board.attr.animationdelay,\r\n                steps = time / delay,\r\n                len,\r\n                pos,\r\n                part,\r\n                makeFakeFunction = function (i, j) {\r\n                    return function () {\r\n                        return path[i][j];\r\n                    };\r\n                };\r\n\r\n            if (Type.isArray(path)) {\r\n                len = path.length;\r\n                for (i = 0; i < len; i++) {\r\n                    if (Type.isPoint(path[i])) {\r\n                        p[i] = path[i];\r\n                    } else {\r\n                        p[i] = {\r\n                            elementClass: Const.OBJECT_CLASS_POINT,\r\n                            X: makeFakeFunction(i, 0),\r\n                            Y: makeFakeFunction(i, 1)\r\n                        };\r\n                    }\r\n                }\r\n\r\n                time = time || 0;\r\n                if (time === 0) {\r\n                    this.setPosition(Const.COORDS_BY_USER, [\r\n                        p[p.length - 1].X(),\r\n                        p[p.length - 1].Y()\r\n                    ]);\r\n                    return this.board.update(this);\r\n                }\r\n\r\n                if (!Type.exists(options.interpolate) || options.interpolate) {\r\n                    neville = Numerics.Neville(p);\r\n                    for (i = 0; i < steps; i++) {\r\n                        interpath[i] = [];\r\n                        interpath[i][0] = neville[0](((steps - i) / steps) * neville[3]());\r\n                        interpath[i][1] = neville[1](((steps - i) / steps) * neville[3]());\r\n                    }\r\n                } else {\r\n                    len = path.length - 1;\r\n                    for (i = 0; i < steps; ++i) {\r\n                        pos = Math.floor((i / steps) * len);\r\n                        part = (i / steps) * len - pos;\r\n\r\n                        interpath[i] = [];\r\n                        interpath[i][0] = (1.0 - part) * p[pos].X() + part * p[pos + 1].X();\r\n                        interpath[i][1] = (1.0 - part) * p[pos].Y() + part * p[pos + 1].Y();\r\n                    }\r\n                    interpath.push([p[len].X(), p[len].Y()]);\r\n                    interpath.reverse();\r\n                    /*\r\n                    for (i = 0; i < steps; i++) {\r\n                        interpath[i] = [];\r\n                        interpath[i][0] = path[Math.floor((steps - i) / steps * (path.length - 1))][0];\r\n                        interpath[i][1] = path[Math.floor((steps - i) / steps * (path.length - 1))][1];\r\n                    }\r\n                    */\r\n                }\r\n\r\n                this.animationPath = interpath;\r\n            } else if (Type.isFunction(path)) {\r\n                this.animationPath = path;\r\n                this.animationStart = new Date().getTime();\r\n            }\r\n\r\n            this.animationCallback = options.callback;\r\n            this.board.addAnimation(this);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Starts an animated point movement towards the given coordinates <tt>where</tt>.\r\n         * The animation is done after <tt>time</tt> milliseconds.\r\n         * If the second parameter is not given or is equal to 0, setPosition() is called, see\r\n         * {@link JXG.CoordsElement#setPosition},\r\n         * i.e. the coordinates are changed without animation.\r\n         * @param {Array} where Array containing the x and y coordinate of the target location.\r\n         * @param {Number} [time] Number of milliseconds the animation should last.\r\n         * @param {Object} [options] Optional settings for the animation\r\n         * @param {function} [options.callback] A function that is called as soon as the animation is finished.\r\n         * @param {String} [options.effect='<>'|'>'|'<'|'--'|'=='] animation effects like speed fade in and out. possible values are\r\n         * '<>' for speed increase on start and slow down at the end (default), '<' for speed up, '>' for slow down, and '--' (or '==')\r\n         * for constant speed during the whole animation.\r\n         * @returns {JXG.CoordsElement} Reference to itself.\r\n         * @see JXG.CoordsElement#setPosition\r\n         * @see JXG.CoordsElement#moveAlong\r\n         * @see JXG.CoordsElement#visit\r\n         * @see JXG.CoordsElement#moveToES6\r\n         * @see JXG.GeometryElement#animate\r\n         * @example\r\n         * // moveTo() with different easing options and callback options\r\n         * let yInit = 3\r\n         * let [A, B, C, D] = ['==', '<>', '<', '>'].map((s) => board.create('point', [4, yInit--], { name: s, label: { fontSize: 24 } }))\r\n         * let seg = board.create('segment', [A, [() => A.X(), 0]])  // shows linear\r\n         *\r\n         * let isLeftRight = true;\r\n         * let buttonMove = board.create('button', [-2, 4, 'left',\r\n         * () => {\r\n         *    isLeftRight = !isLeftRight;\r\n         *    buttonMove.rendNodeButton.innerHTML = isLeftRight ? 'left' : 'right'\r\n         *    let x = isLeftRight ? 4 : -4\r\n         *    let sym = isLeftRight ? 'triangleleft' : 'triangleright'\r\n         *\r\n         *    A.moveTo([x, 3], 1000, { callback: () => A.setAttribute({ face: sym, size: 5 }) })\r\n         *    B.moveTo([x, 2], 1000, { callback: () => B.setAttribute({ face: sym, size: 5 }), effect: \"<>\" })\r\n         *    C.moveTo([x, 1], 1000, { callback: () => C.setAttribute({ face: sym, size: 5 }), effect: \"<\" })\r\n         *    D.moveTo([x, 0], 1000, { callback: () => D.setAttribute({ face: sym, size: 5 }), effect: \">\" })\r\n         *\r\n         * }]);\r\n         *\r\n         * </pre><div id=\"JXG0f35a50e-e99d-11e8-a1ca-04d3b0c2aad4\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         * {\r\n         * let board = JXG.JSXGraph.initBoard('JXG0f35a50e-e99d-11e8-a1ca-04d3b0c2aad4')\r\n         * let yInit = 3\r\n         * let [A, B, C, D] = ['==', '<>', '<', '>'].map((s) => board.create('point', [4, yInit--], { name: s, label: { fontSize: 24 } }))\r\n         * let seg = board.create('segment', [A, [() => A.X(), 0]])  // shows linear\r\n         *\r\n         * let isLeftRight = true;\r\n         * let buttonMove = board.create('button', [-2, 4, 'left',\r\n         * () => {\r\n         *    isLeftRight = !isLeftRight;\r\n         *    buttonMove.rendNodeButton.innerHTML = isLeftRight ? 'left' : 'right'\r\n         *    let x = isLeftRight ? 4 : -4\r\n         *    let sym = isLeftRight ? 'triangleleft' : 'triangleright'\r\n         *\r\n         *    A.moveTo([x, 3], 1000, { callback: () => A.setAttribute({ face: sym, size: 5 }) })\r\n         *    B.moveTo([x, 2], 1000, { callback: () => B.setAttribute({ face: sym, size: 5 }), effect: \"<>\" })\r\n         *    C.moveTo([x, 1], 1000, { callback: () => C.setAttribute({ face: sym, size: 5 }), effect: \"<\" })\r\n         *    D.moveTo([x, 0], 1000, { callback: () => D.setAttribute({ face: sym, size: 5 }), effect: \">\" })\r\n         *\r\n         * }]);\r\n         *}\r\n         *</script><pre>\r\n         */\r\n        moveTo: function (where, time, options) {\r\n            options = options || {};\r\n            where = new Coords(Const.COORDS_BY_USER, where, this.board);\r\n\r\n            var i,\r\n                delay = this.board.attr.animationdelay,\r\n                steps = Math.ceil(time / delay),\r\n                coords = [],\r\n                X = this.coords.usrCoords[1],\r\n                Y = this.coords.usrCoords[2],\r\n                dX = where.usrCoords[1] - X,\r\n                dY = where.usrCoords[2] - Y,\r\n                /** @ignore */\r\n                stepFun = function (i) {\r\n                    var x = i / steps;  // absolute progress of the animatin\r\n\r\n                    if (options.effect) {\r\n                        if (options.effect === \"<>\") {\r\n                            return Math.pow(Math.sin((x * Math.PI) / 2), 2);\r\n                        }\r\n                        if (options.effect === \"<\") {   // cubic ease in\r\n                            return x * x * x;\r\n                        }\r\n                        if (options.effect === \">\") {   // cubic ease out\r\n                            return 1 - Math.pow(1 - x, 3);\r\n                        }\r\n                        if (options.effect === \"==\" || options.effect === \"--\") {\r\n                            return i / steps;       // linear\r\n                        }\r\n                        // throw new Error(\"Callback moveTo(): valid effects are '==', '--', '<>', '>', and '<', given is '\" + options.effect + \"'.\");\r\n                        JXG.warn(\"Callback moveTo(): valid effects are '==', '--', '<>', '>', and '<', given is '\" + options.effect + \"'. Set it to '--'\");\r\n                        options.effect = '--';\r\n                    }\r\n                    return i / steps;  // default\r\n                };\r\n\r\n            if (\r\n                !Type.exists(time) ||\r\n                time === 0 ||\r\n                Math.abs(where.usrCoords[0] - this.coords.usrCoords[0]) > Mat.eps\r\n            ) {\r\n                this.setPosition(Const.COORDS_BY_USER, where.usrCoords);\r\n                return this.board.update(this);\r\n            }\r\n\r\n            // In case there is no callback and we are already at the endpoint we can stop here\r\n            if (\r\n                !Type.exists(options.callback) &&\r\n                Math.abs(dX) < Mat.eps &&\r\n                Math.abs(dY) < Mat.eps\r\n            ) {\r\n                return this;\r\n            }\r\n\r\n            for (i = steps; i >= 0; i--) {\r\n                coords[steps - i] = [\r\n                    where.usrCoords[0],\r\n                    X + dX * stepFun(i),\r\n                    Y + dY * stepFun(i)\r\n                ];\r\n            }\r\n\r\n            this.animationPath = coords;\r\n            this.animationCallback = options.callback;\r\n            this.board.addAnimation(this);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Starts an animated point movement towards the given coordinates <tt>where</tt>. After arriving at\r\n         * <tt>where</tt> the point moves back to where it started. The animation is done after <tt>time</tt>\r\n         * milliseconds.\r\n         * @param {Array} where Array containing the x and y coordinate of the target location.\r\n         * @param {Number} time Number of milliseconds the animation should last.\r\n         * @param {Object} [options] Optional settings for the animation\r\n         * @param {function} [options.callback] A function that is called as soon as the animation is finished.\r\n         * @param {String} [options.effect='<>'|'>'|'<'|'=='|'--'] animation effects like speed fade in and out. possible values are\r\n         * '<>' for speed increase on start and slow down at the end (default), '<' for speed up, '>' for slow down, and '--' (or '==')\r\n         * for constant speed during the whole animation.\r\n         * @param {Number} [options.repeat=1] How often this animation should be repeated.\r\n         * @returns {JXG.CoordsElement} Reference to itself.\r\n         * @see JXG.CoordsElement#moveAlong\r\n         * @see JXG.CoordsElement#moveTo\r\n         * @see JXG.CoordsElement#visitES6\r\n         * @see JXG.GeometryElement#animate\r\n         * @example\r\n         * // visit() with different easing options\r\n         * let yInit = 3\r\n         * let [A, B, C, D] = ['==', '<>', '<', '>'].map((s) => board.create('point', [4, yInit--], { name: s, label: { fontSize: 24 } }))\r\n         * let seg = board.create('segment', [A, [() => A.X(), 0]])  // shows linear\r\n         *\r\n         *let isLeftRight = true;\r\n         *let buttonVisit = board.create('button', [0, 4, 'visit',\r\n         *    () => {\r\n         *        let x = isLeftRight ? 4 : -4\r\n         *\r\n         *        A.visit([-x, 3], 4000, { effect: \"==\", repeat: 2 })  // linear\r\n         *        B.visit([-x, 2], 4000, { effect: \"<>\", repeat: 2 })\r\n         *        C.visit([-x, 1], 4000, { effect: \"<\", repeat: 2 })\r\n         *        D.visit([-x, 0], 4000, { effect: \">\", repeat: 2 })\r\n         *    }])\r\n         *\r\n         * </pre><div id=\"JXG0f35a50e-e99d-11e8-a1ca-04d3b0c2aad5\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         * {\r\n         *  let board = JXG.JSXGraph.initBoard('JXG0f35a50e-e99d-11e8-a1ca-04d3b0c2aad5')\r\n         * let yInit = 3\r\n         * let [A, B, C, D] = ['==', '<>', '<', '>'].map((s) => board.create('point', [4, yInit--], { name: s, label: { fontSize: 24 } }))\r\n         * let seg = board.create('segment', [A, [() => A.X(), 0]])  // shows linear\r\n         *\r\n         * let isLeftRight = true;\r\n         * let buttonVisit = board.create('button', [0, 4, 'visit',\r\n         *    () => {\r\n         *        let x = isLeftRight ? 4 : -4\r\n         *\r\n         *        A.visit([-x, 3], 4000, { effect: \"==\", repeat: 2 })  // linear\r\n         *        B.visit([-x, 2], 4000, { effect: \"<>\", repeat: 2 })\r\n         *        C.visit([-x, 1], 4000, { effect: \"<\", repeat: 2 })\r\n         *        D.visit([-x, 0], 4000, { effect: \">\", repeat: 2 })\r\n         *    }])\r\n         *   }\r\n         * </script><pre>\r\n         *\r\n         */\r\n        visit: function (where, time, options) {\r\n            where = new Coords(Const.COORDS_BY_USER, where, this.board);\r\n\r\n            var i,\r\n                j,\r\n                steps,\r\n                delay = this.board.attr.animationdelay,\r\n                coords = [],\r\n                X = this.coords.usrCoords[1],\r\n                Y = this.coords.usrCoords[2],\r\n                dX = where.usrCoords[1] - X,\r\n                dY = where.usrCoords[2] - Y,\r\n                /** @ignore */\r\n                stepFun = function (i) {\r\n                    var x = i < steps / 2 ? (2 * i) / steps : (2 * (steps - i)) / steps;\r\n\r\n                    if (options.effect) {\r\n                        if (options.effect === \"<>\") {        // slow at beginning and end\r\n                            return Math.pow(Math.sin((x * Math.PI) / 2), 2);\r\n                        }\r\n                        if (options.effect === \"<\") {   // cubic ease in\r\n                            return x * x * x;\r\n                        }\r\n                        if (options.effect === \">\") {   // cubic ease out\r\n                            return 1 - Math.pow(1 - x, 3);\r\n                        }\r\n                        if (options.effect === \"==\" || options.effect === \"--\") {\r\n                            return x;       // linear\r\n                        }\r\n                        // throw new Error(\"Callback visit(): valid effects are '==', '--', '<>', '>', and '<', given is '\" + options.effect + \"'.\");\r\n                        JXG.warn(\"Callback visit(): valid effects are '==', '--', '<>', '>', and '<', given is '\" + options.effect + \"'. Set it to '--'\");\r\n                        options.effect = '--';\r\n                    }\r\n                    return x;\r\n                };\r\n\r\n            // support legacy interface where the third parameter was the number of repeats\r\n            if (Type.isNumber(options)) {\r\n                options = { repeat: options };\r\n            } else {\r\n                options = options || {};\r\n                if (!Type.exists(options.repeat)) {\r\n                    options.repeat = 1;\r\n                }\r\n            }\r\n\r\n            steps = Math.ceil(time / (delay * options.repeat));\r\n\r\n            for (j = 0; j < options.repeat; j++) {\r\n                for (i = steps; i >= 0; i--) {\r\n                    coords[j * (steps + 1) + steps - i] = [\r\n                        where.usrCoords[0],\r\n                        X + dX * stepFun(i),\r\n                        Y + dY * stepFun(i)\r\n                    ];\r\n                }\r\n            }\r\n            this.animationPath = coords;\r\n            this.animationCallback = options.callback;\r\n            this.board.addAnimation(this);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * ES6 version of {@link JXG.CoordsElement#moveAlong} using a promise.\r\n         *\r\n         * @param {Array} where Array containing the x and y coordinate of the target location.\r\n         * @param {Number} [time] Number of milliseconds the animation should last.\r\n         * @param {Object} [options] Optional settings for the animation\r\n         * @returns Promise\r\n         * @see JXG.CoordsElement#moveAlong\r\n         * @example\r\n         * var A = board.create('point', [4, 4]);\r\n         * A.moveAlongES6([[3, -2], [4, 0], [3, 1], [4, 4]], 2000)\r\n         *     .then(() => A.moveToES6([-3, -3], 1000));\r\n         *\r\n         * </pre><div id=\"JXGa45032e5-a517-4f1d-868a-65d698d344cf\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGa45032e5-a517-4f1d-868a-65d698d344cf',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var A = board.create('point', [4, 4]);\r\n         *     A.moveAlongES6([[3, -2], [4, 0], [3, 1], [4, 4]], 2000)\r\n         *         .then(() => A.moveToES6([-3, -3], 1000));\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        moveAlongES6: function (path, time, options) {\r\n            return new Promise((resolve, reject) => {\r\n                if (Type.exists(options) && Type.exists(options.callback)) {\r\n                    options.callback = resolve;\r\n                } else {\r\n                    options = {\r\n                        callback: resolve\r\n                    };\r\n                }\r\n                this.moveAlong(path, time, options);\r\n            });\r\n        },\r\n\r\n        /**\r\n         * ES6 version of {@link JXG.CoordsElement#moveTo} using a promise.\r\n         *\r\n         * @param {Array} where Array containing the x and y coordinate of the target location.\r\n         * @param {Number} [time] Number of milliseconds the animation should last.\r\n         * @param {Object} [options] Optional settings for the animation\r\n         * @returns Promise\r\n         * @see JXG.CoordsElement#moveTo\r\n         *\r\n         * @example\r\n         * var A = board.create('point', [4, 4]);\r\n         * A.moveToES6([-3, 3], 1000)\r\n         *     .then(() => A.moveToES6([-3, -3], 1000))\r\n         *     .then(() => A.moveToES6([3, -3], 1000))\r\n         *     .then(() => A.moveToES6([3, -3], 1000));\r\n         *\r\n         * </pre><div id=\"JXGabdc7771-34f0-4655-bb7b-fc329e773b89\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGabdc7771-34f0-4655-bb7b-fc329e773b89',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var A = board.create('point', [4, 4]);\r\n         *     A.moveToES6([-3, 3], 1000)\r\n         *         .then(() => A.moveToES6([-3, -3], 1000))\r\n         *         .then(() => A.moveToES6([3, -3], 1000))\r\n         *         .then(() => A.moveToES6([3, -3], 1000));\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         *         var A = board.create('point', [4, 4]);\r\n         *         A.moveToES6([-3, 3], 1000)\r\n         *             .then(function() {\r\n         *                 return A.moveToES6([-3, -3], 1000);\r\n         *             }).then(function() {\r\n         *                 return A.moveToES6([ 3, -3], 1000);\r\n         *             }).then(function() {\r\n         *                 return A.moveToES6([ 3, -3], 1000);\r\n         *             }).then(function() {\r\n         *                 return A.moveAlongES6([[3, -2], [4, 0], [3, 1], [4, 4]], 5000);\r\n         *             }).then(function() {\r\n         *                 return A.visitES6([-4, -4], 3000);\r\n         *             });\r\n         *\r\n         * </pre><div id=\"JXGa9439ce5-516d-4dba-9233-2a4ad9589995\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGa9439ce5-516d-4dba-9233-2a4ad9589995',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *             var A = board.create('point', [4, 4]);\r\n         *             A.moveToES6([-3, 3], 1000)\r\n         *                 .then(function() {\r\n         *                     return A.moveToES6([-3, -3], 1000);\r\n         *                 }).then(function() {\r\n         *                     return A.moveToES6([ 3, -3], 1000);\r\n         *                 }).then(function() {\r\n         *                     return A.moveToES6([ 3, -3], 1000);\r\n         *                 }).then(function() {\r\n         *                     return A.moveAlongES6([[3, -2], [4, 0], [3, 1], [4, 4]], 5000);\r\n         *                 }).then(function() {\r\n         *                     return A.visitES6([-4, -4], 3000);\r\n         *                 });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        moveToES6: function (where, time, options) {\r\n            return new Promise((resolve, reject) => {\r\n                if (Type.exists(options) && Type.exists(options.callback)) {\r\n                    options.callback = resolve;\r\n                } else {\r\n                    options = {\r\n                        callback: resolve\r\n                    };\r\n                }\r\n                this.moveTo(where, time, options);\r\n            });\r\n        },\r\n\r\n        /**\r\n         * ES6 version of {@link JXG.CoordsElement#moveVisit} using a promise.\r\n         *\r\n         * @param {Array} where Array containing the x and y coordinate of the target location.\r\n         * @param {Number} [time] Number of milliseconds the animation should last.\r\n         * @param {Object} [options] Optional settings for the animation\r\n         * @returns Promise\r\n         * @see JXG.CoordsElement#visit\r\n         * @example\r\n         * var A = board.create('point', [4, 4]);\r\n         * A.visitES6([-4, -4], 3000)\r\n         *     .then(() => A.moveToES6([-3, 3], 1000));\r\n         *\r\n         * </pre><div id=\"JXG640f1fd2-05ec-46cb-b977-36d96648ce41\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG640f1fd2-05ec-46cb-b977-36d96648ce41',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var A = board.create('point', [4, 4]);\r\n         *     A.visitES6([-4, -4], 3000)\r\n         *         .then(() => A.moveToES6([-3, 3], 1000));\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        visitES6: function (where, time, options) {\r\n            return new Promise((resolve, reject) => {\r\n                if (Type.exists(options) && Type.exists(options.callback)) {\r\n                    options.callback = resolve;\r\n                } else {\r\n                    options = {\r\n                        callback: resolve\r\n                    };\r\n                }\r\n                this.visit(where, time, options);\r\n            });\r\n        },\r\n\r\n        /**\r\n         * Animates a glider. Is called by the browser after startAnimation is called.\r\n         * @param {Number} direction The direction the glider is animated.\r\n         * @param {Number} stepCount The number of steps in which the parent element is divided.\r\n         * Must be at least 1.\r\n         * @param {Number} [maxRounds=-1] The number of rounds the glider will be animated. The glider will run infinitely if\r\n         * maxRounds is negative or equal to Infinity.\r\n         * @see JXG.CoordsElement#startAnimation\r\n         * @see JXG.CoordsElement#stopAnimation\r\n         * @private\r\n         * @returns {JXG.CoordsElement} Reference to itself.\r\n         */\r\n        _anim: function (direction, stepCount, maxRounds) {\r\n            var dX, dY, alpha, startPoint, newX, radius, sp1c, sp2c, res;\r\n\r\n            this.intervalCount += 1;\r\n            if (this.intervalCount > stepCount) {\r\n                this.intervalCount = 0;\r\n\r\n                this.roundsCount += 1;\r\n                if (maxRounds > 0 && this.roundsCount >= maxRounds) {\r\n                    this.roundsCount = 0;\r\n                    return this.stopAnimation();\r\n                }\r\n            }\r\n\r\n            if (this.slideObject.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                sp1c = this.slideObject.point1.coords.scrCoords;\r\n                sp2c = this.slideObject.point2.coords.scrCoords;\r\n\r\n                dX = Math.round(((sp2c[1] - sp1c[1]) * this.intervalCount) / stepCount);\r\n                dY = Math.round(((sp2c[2] - sp1c[2]) * this.intervalCount) / stepCount);\r\n                if (direction > 0) {\r\n                    startPoint = this.slideObject.point1;\r\n                } else {\r\n                    startPoint = this.slideObject.point2;\r\n                    dX *= -1;\r\n                    dY *= -1;\r\n                }\r\n\r\n                this.coords.setCoordinates(Const.COORDS_BY_SCREEN, [\r\n                    startPoint.coords.scrCoords[1] + dX,\r\n                    startPoint.coords.scrCoords[2] + dY\r\n                ]);\r\n            } else if (this.slideObject.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n                if (direction > 0) {\r\n                    newX = (this.slideObject.maxX() - this.slideObject.minX()) * this.intervalCount / stepCount + this.slideObject.minX();\r\n                } else {\r\n                    newX = -(this.slideObject.maxX() - this.slideObject.minX()) * this.intervalCount / stepCount + this.slideObject.maxX();\r\n                }\r\n                this.coords.setCoordinates(Const.COORDS_BY_USER, [this.slideObject.X(newX), this.slideObject.Y(newX)]);\r\n\r\n                res = Geometry.projectPointToCurve(this, this.slideObject, this.board);\r\n                this.coords = res[0];\r\n                this.position = res[1];\r\n            } else if (this.slideObject.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n                alpha = 2 * Math.PI;\r\n                if (direction < 0) {\r\n                    alpha *= this.intervalCount / stepCount;\r\n                } else {\r\n                    alpha *= (stepCount - this.intervalCount) / stepCount;\r\n                }\r\n                radius = this.slideObject.Radius();\r\n\r\n                this.coords.setCoordinates(Const.COORDS_BY_USER, [\r\n                    this.slideObject.center.coords.usrCoords[1] + radius * Math.cos(alpha),\r\n                    this.slideObject.center.coords.usrCoords[2] + radius * Math.sin(alpha)\r\n                ]);\r\n            }\r\n\r\n            this.board.update(this);\r\n            return this;\r\n        },\r\n\r\n        // documented in GeometryElement\r\n        getTextAnchor: function () {\r\n            return this.coords;\r\n        },\r\n\r\n        // documented in GeometryElement\r\n        getLabelAnchor: function () {\r\n            return this.coords;\r\n        },\r\n\r\n        // documented in element.js\r\n        getParents: function () {\r\n            var p = [this.Z(), this.X(), this.Y()];\r\n\r\n            if (this.parents.length !== 0) {\r\n                p = this.parents;\r\n            }\r\n\r\n            if (this.type === Const.OBJECT_TYPE_GLIDER) {\r\n                p = [this.X(), this.Y(), this.slideObject.id];\r\n            }\r\n\r\n            return p;\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * Generic method to create point, text or image.\r\n * Determines the type of the construction, i.e. free, or constrained by function,\r\n * transformation or of glider type.\r\n * @param{Object} Callback Object type, e.g. JXG.Point, JXG.Text or JXG.Image\r\n * @param{Object} board Link to the board object\r\n * @param{Array} coords Array with coordinates. This may be: array of numbers, function\r\n * returning an array of numbers, array of functions returning a number, object and transformation.\r\n * If the attribute \"slideObject\" exists, a glider element is constructed.\r\n * @param{Object} attr Attributes object\r\n * @param{Object} arg1 Optional argument 1: in case of text this is the text content,\r\n * in case of an image this is the url.\r\n * @param{Array} arg2 Optional argument 2: in case of image this is an array containing the size of\r\n * the image.\r\n * @returns{Object} returns the created object or false.\r\n */\r\nJXG.CoordsElement.create = function (Callback, board, coords, attr, arg1, arg2) {\r\n    var el,\r\n        isConstrained = false,\r\n        i;\r\n\r\n    for (i = 0; i < coords.length; i++) {\r\n        if (Type.isFunction(coords[i]) || Type.isString(coords[i])) {\r\n            isConstrained = true;\r\n        }\r\n    }\r\n\r\n    if (!isConstrained) {\r\n        if (Type.isNumber(coords[0]) && Type.isNumber(coords[1])) {\r\n            el = new Callback(board, coords, attr, arg1, arg2);\r\n\r\n            if (Type.exists(attr.slideobject)) {\r\n                el.makeGlider(attr.slideobject);\r\n            } else {\r\n                // Free element\r\n                el.baseElement = el;\r\n            }\r\n            el.isDraggable = true;\r\n        } else if (Type.isObject(coords[0]) && Type.isTransformationOrArray(coords[1])) {\r\n            // Transformation\r\n            // TODO less general specification of isObject\r\n            el = new Callback(board, [0, 0], attr, arg1, arg2);\r\n            el.addTransform(coords[0], coords[1]);\r\n            el.isDraggable = false;\r\n        } else {\r\n            return false;\r\n        }\r\n    } else {\r\n        el = new Callback(board, [0, 0], attr, arg1, arg2);\r\n        el.addConstraint(coords);\r\n    }\r\n\r\n    el.handleSnapToGrid();\r\n    el.handleSnapToPoints();\r\n    el.handleAttractors();\r\n\r\n    el.addParents(coords);\r\n    return el;\r\n};\r\n\r\nexport default JXG.CoordsElement;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Andreas Walter,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, window: true, document: true, navigator: true, module: true, global: true, self: true, require: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview The functions in this file help with the detection of the environment JSXGraph runs in. We can distinguish\r\n * between node.js, windows 8 app and browser, what rendering techniques are supported and (most of the time) if the device\r\n * the browser runs on is a tablet/cell or a desktop computer.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"./type.js\";\r\n\r\nJXG.extendConstants(\r\n    JXG,\r\n    /** @lends JXG */ {\r\n        // /**\r\n        //  * Determines the property that stores the relevant information in the event object.\r\n        //  * @type String\r\n        //  * @default 'touches'\r\n        //  * @private\r\n        //  */\r\n        // touchProperty: \"touches\"\r\n    }\r\n);\r\n\r\nJXG.extend(\r\n    JXG,\r\n    /** @lends JXG */ {\r\n        /**\r\n         * Determines whether evt is a touch event.\r\n         * @param evt {Event}\r\n         * @returns {Boolean}\r\n         */\r\n        isTouchEvent: function (evt) {\r\n            return JXG.exists(evt['touches']); // Old iOS touch events\r\n        },\r\n\r\n        /**\r\n         * Determines whether evt is a pointer event.\r\n         * @param evt {Event}\r\n         * @returns {Boolean}\r\n         */\r\n        isPointerEvent: function (evt) {\r\n            return JXG.exists(evt.pointerId);\r\n        },\r\n\r\n        /**\r\n         * Determines whether evt is neither a touch event nor a pointer event.\r\n         * @param evt {Event}\r\n         * @returns {Boolean}\r\n         */\r\n        isMouseEvent: function (evt) {\r\n            return !JXG.isTouchEvent(evt) && !JXG.isPointerEvent(evt);\r\n        },\r\n\r\n        /**\r\n         * Determines the number of touch points in a touch event.\r\n         * For other events, -1 is returned.\r\n         * @param evt {Event}\r\n         * @returns {Number}\r\n         */\r\n        getNumberOfTouchPoints: function (evt) {\r\n            var n = -1;\r\n\r\n            if (JXG.isTouchEvent(evt)) {\r\n                n = evt['touches'].length;\r\n            }\r\n\r\n            return n;\r\n        },\r\n\r\n        /**\r\n         * Checks whether an mouse, pointer or touch event evt is the first event of a multitouch event.\r\n         * Attention: When two or more pointer device types are being used concurrently,\r\n         *            it is only checked whether the passed event is the first one of its type!\r\n         * @param evt {Event}\r\n         * @returns {boolean}\r\n         */\r\n        isFirstTouch: function (evt) {\r\n            var touchPoints = JXG.getNumberOfTouchPoints(evt);\r\n\r\n            if (JXG.isPointerEvent(evt)) {\r\n                return evt.isPrimary;\r\n            }\r\n\r\n            return touchPoints === 1;\r\n        },\r\n\r\n        /**\r\n         * A document/window environment is available.\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        isBrowser: Type.exists(window) && Type.exists(document) &&\r\n            typeof window === \"object\" && typeof document === \"object\",\r\n\r\n        /**\r\n         * Features of ECMAScript 6+ are available.\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        supportsES6: function () {\r\n            // var testMap;\r\n            /* jshint ignore:start */\r\n            try {\r\n                // This would kill the old uglifyjs: testMap = (a = 0) => a;\r\n                new Function(\"(a = 0) => a\");\r\n                return true;\r\n            } catch (err) {\r\n                return false;\r\n            }\r\n            /* jshint ignore:end */\r\n        },\r\n\r\n        /**\r\n         * Detect browser support for VML.\r\n         * @returns {Boolean} True, if the browser supports VML.\r\n         */\r\n        supportsVML: function () {\r\n            // From stackoverflow.com\r\n            return this.isBrowser && !!document.namespaces;\r\n        },\r\n\r\n        /**\r\n         * Detect browser support for SVG.\r\n         * @returns {Boolean} True, if the browser supports SVG.\r\n         */\r\n        supportsSVG: function () {\r\n            var svgSupport;\r\n            if (!this.isBrowser) {\r\n                return false;\r\n            }\r\n            svgSupport = !!document.createElementNS && !!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect;\r\n            return svgSupport;\r\n        },\r\n\r\n        /**\r\n         * Detect browser support for Canvas.\r\n         * @returns {Boolean} True, if the browser supports HTML canvas.\r\n         */\r\n        supportsCanvas: function () {\r\n            var hasCanvas = false;\r\n\r\n            // if (this.isNode()) {\r\n            //     try {\r\n            //         // c = typeof module === \"object\" ? module.require('canvas') : $__canvas;\r\n            //         c = typeof module === \"object\" ? module.require('canvas') : import('canvas');\r\n            //         hasCanvas = !!c;\r\n            //     } catch (err) {}\r\n            // }\r\n\r\n            if (this.isNode()) {\r\n                //try {\r\n                //    JXG.createCanvas(500, 500);\r\n                    hasCanvas = true;\r\n                // } catch (err) {\r\n                //     throw new Error('JXG.createCanvas not available.\\n' +\r\n                //         'Install the npm package `canvas`\\n' +\r\n                //         'and call:\\n' +\r\n                //         '    import { createCanvas } from 'canvas.js'\\n' +\r\n                //         '    JXG.createCanvas = createCanvas;\\n');\r\n                // }\r\n            }\r\n\r\n            return (\r\n                hasCanvas || (this.isBrowser && !!document.createElement('canvas').getContext)\r\n            );\r\n        },\r\n\r\n        /**\r\n         * True, if run inside a node.js environment.\r\n         * @returns {Boolean}\r\n         */\r\n        isNode: function () {\r\n            // This is not a 100% sure but should be valid in most cases\r\n            // We are not inside a browser\r\n            /* eslint-disable no-undef */\r\n            return (\r\n                !this.isBrowser &&\r\n                (typeof process !== 'undefined') &&\r\n                (process.release.name.search(/node|io.js/) !== -1)\r\n            /* eslint-enable no-undef */\r\n\r\n                // there is a module object (plain node, no requirejs)\r\n                // ((typeof module === \"object\" && !!module.exports) ||\r\n                //     // there is a global object and requirejs is loaded\r\n                //     (typeof global === \"object\" &&\r\n                //         global.requirejsVars &&\r\n                //         !global.requirejsVars.isBrowser)\r\n                // )\r\n            );\r\n        },\r\n\r\n        /**\r\n         * True if run inside a webworker environment.\r\n         * @returns {Boolean}\r\n         */\r\n        isWebWorker: function () {\r\n            return (\r\n                !this.isBrowser &&\r\n                typeof self === \"object\" &&\r\n                typeof self.postMessage === \"function\"\r\n            );\r\n        },\r\n\r\n        /**\r\n         * Checks if the environments supports the W3C Pointer Events API {@link https://www.w3.org/TR/pointerevents/}\r\n         * @returns {Boolean}\r\n         */\r\n        supportsPointerEvents: function () {\r\n            return !!(\r\n                (\r\n                    this.isBrowser &&\r\n                    window.navigator &&\r\n                    (window.PointerEvent || // Chrome/Edge/IE11+\r\n                        window.navigator.pointerEnabled || // IE11+\r\n                        window.navigator.msPointerEnabled)\r\n                ) // IE10-\r\n            );\r\n        },\r\n\r\n        /**\r\n         * Determine if the current browser supports touch events\r\n         * @returns {Boolean} True, if the browser supports touch events.\r\n         */\r\n        isTouchDevice: function () {\r\n            return this.isBrowser && window.ontouchstart !== undefined;\r\n        },\r\n\r\n        /**\r\n         * Detects if the user is using an Android powered device.\r\n         * @returns {Boolean}\r\n         * @deprecated\r\n         */\r\n        isAndroid: function () {\r\n            return (\r\n                Type.exists(navigator) &&\r\n                navigator.userAgent.toLowerCase().indexOf('android') > -1\r\n            );\r\n        },\r\n\r\n        /**\r\n         * Detects if the user is using the default Webkit browser on an Android powered device.\r\n         * @returns {Boolean}\r\n         * @deprecated\r\n         */\r\n        isWebkitAndroid: function () {\r\n            return this.isAndroid() && navigator.userAgent.indexOf(\" AppleWebKit/\") > -1;\r\n        },\r\n\r\n        /**\r\n         * Detects if the user is using a Apple iPad / iPhone.\r\n         * @returns {Boolean}\r\n         * @deprecated\r\n         */\r\n        isApple: function () {\r\n            return (\r\n                Type.exists(navigator) &&\r\n                (navigator.userAgent.indexOf('iPad') > -1 ||\r\n                    navigator.userAgent.indexOf('iPhone') > -1)\r\n            );\r\n        },\r\n\r\n        /**\r\n         * Detects if the user is using Safari on an Apple device.\r\n         * See https://evilmartians.com/chronicles/how-to-detect-safari-and-ios-versions-with-ease (2025)\r\n         * @returns {Boolean}\r\n         * @deprecated\r\n         */\r\n        isWebkitApple: function () {\r\n            var is = ('GestureEvent' in window) && // Desktop and mobile\r\n                    (\r\n                        ('ongesturechange' in window) || // mobile webkit browsers and webview iOS\r\n                        (window !== undefined && // Desktop Safari\r\n                         'safari' in window &&\r\n                         'pushNotification' in window.safari)\r\n                    );\r\n            return is;\r\n\r\n            // return (\r\n            //     this.isApple() && navigator.userAgent.search(/Mobile\\/[0-9A-Za-z.]*Safari/) > -1\r\n            // );\r\n        },\r\n\r\n        /**\r\n         * Returns true if the run inside a Windows 8 \"Metro\" App.\r\n         * @returns {Boolean}\r\n         * @deprecated\r\n         */\r\n        isMetroApp: function () {\r\n            return (\r\n                typeof window === \"object\" &&\r\n                window.clientInformation &&\r\n                window.clientInformation.appVersion &&\r\n                window.clientInformation.appVersion.indexOf('MSAppHost') > -1\r\n            );\r\n        },\r\n\r\n        /**\r\n         * Detects if the user is using a Mozilla browser\r\n         * @returns {Boolean}\r\n         * @deprecated\r\n         */\r\n        isMozilla: function () {\r\n            return (\r\n                Type.exists(navigator) &&\r\n                navigator.userAgent.toLowerCase().indexOf('mozilla') > -1 &&\r\n                navigator.userAgent.toLowerCase().indexOf('apple') === -1\r\n            );\r\n        },\r\n\r\n        /**\r\n         * Detects if the user is using a firefoxOS powered device.\r\n         * @returns {Boolean}\r\n         * @deprecated\r\n         */\r\n        isFirefoxOS: function () {\r\n            return (\r\n                Type.exists(navigator) &&\r\n                navigator.userAgent.toLowerCase().indexOf('android') === -1 &&\r\n                navigator.userAgent.toLowerCase().indexOf('apple') === -1 &&\r\n                navigator.userAgent.toLowerCase().indexOf('mobile') > -1 &&\r\n                navigator.userAgent.toLowerCase().indexOf('mozilla') > -1\r\n            );\r\n        },\r\n\r\n        /**\r\n         * Detects if the user is using a desktop device, see <a href=\"https://stackoverflow.com/a/61073480\">https://stackoverflow.com/a/61073480</a>.\r\n         * @returns {boolean}\r\n         *\r\n         * @deprecated\r\n         */\r\n        isDesktop: function () {\r\n            return true;\r\n            // console.log(\"isDesktop\", screen.orientation);\r\n            // const navigatorAgent =\r\n            //     navigator.userAgent || navigator.vendor || window.opera;\r\n            // return !(\r\n            //     /(android|bb\\d+|meego).+mobile|avantgo|bada\\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\/|plucker|pocket|psp|series([46])0|symbian|treo|up\\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(\r\n            //         navigatorAgent\r\n            //     ) ||\r\n            //     /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br([ev])w|bumb|bw-([nu])|c55\\/|capi|ccwa|cdm-|cell|chtm|cldc|cmd-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc-s|devi|dica|dmob|do([cp])o|ds(12|-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly([-_])|g1 u|g560|gene|gf-5|g-mo|go(\\.w|od)|gr(ad|un)|haie|hcit|hd-([mpt])|hei-|hi(pt|ta)|hp( i|ip)|hs-c|ht(c([- _agpst])|tp)|hu(aw|tc)|i-(20|go|ma)|i230|iac([ \\-/])|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja([tv])a|jbro|jemu|jigs|kddi|keji|kgt([ /])|klon|kpt |kwc-|kyo([ck])|le(no|xi)|lg( g|\\/([klu])|50|54|-[a-w])|libw|lynx|m1-w|m3ga|m50\\/|ma(te|ui|xo)|mc(01|21|ca)|m-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t([- ov])|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30([02])|n50([025])|n7(0([01])|10)|ne(([cm])-|on|tf|wf|wg|wt)|nok([6i])|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan([adt])|pdxg|pg(13|-([1-8]|c))|phil|pire|pl(ay|uc)|pn-2|po(ck|rt|se)|prox|psio|pt-g|qa-a|qc(07|12|21|32|60|-[2-7]|i-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h-|oo|p-)|sdk\\/|se(c([-01])|47|mc|nd|ri)|sgh-|shar|sie([-m])|sk-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h-|v-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl-|tdg-|tel([im])|tim-|t-mo|to(pl|sh)|ts(70|m-|m3|m5)|tx-9|up(\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c([- ])|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas-|your|zeto|zte-/i.test(\r\n            //         navigatorAgent.substr(0, 4)\r\n            //     )\r\n            // );\r\n        },\r\n\r\n        /**\r\n         * Detects if the user is using a mobile device, see <a href=\"https://stackoverflow.com/questions/25542814/html5-detecting-if-youre-on-mobile-or-pc-with-javascript\">https://stackoverflow.com/questions/25542814/html5-detecting-if-youre-on-mobile-or-pc-with-javascript</a>.\r\n         * @returns {boolean}\r\n         *\r\n         * @deprecated\r\n         *\r\n         */\r\n        isMobile: function () {\r\n            return true;\r\n            // return Type.exists(navigator) && /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);\r\n        },\r\n\r\n        /**\r\n         * Internet Explorer version. Works only for IE > 4.\r\n         * @type Number\r\n         * @deprecated\r\n         */\r\n        ieVersion: (function () {\r\n            var div,\r\n                all,\r\n                v = 3;\r\n\r\n            if (document === null || typeof document !== 'object') {\r\n                return 0;\r\n            }\r\n\r\n            div = document.createElement('div');\r\n            all = div.getElementsByTagName('i');\r\n\r\n            do {\r\n                div.innerHTML = \"<!--[if gt IE \" + (++v) + \"]><\" + \"i><\" + \"/i><![endif]-->\";\r\n            } while (all[0]);\r\n\r\n            return v > 4 ? v : undefined;\r\n        })(),\r\n\r\n        /**\r\n         * Reads the width and height of an HTML element.\r\n         * @param {String|Object} elementId id of or reference to an HTML DOM node.\r\n         * @returns {Object} An object with the two properties width and height.\r\n         */\r\n        getDimensions: function (elementId, doc) {\r\n            var element,\r\n                display,\r\n                els,\r\n                originalVisibility,\r\n                originalPosition,\r\n                originalDisplay,\r\n                originalWidth,\r\n                originalHeight,\r\n                style,\r\n                pixelDimRegExp = /\\d+(\\.\\d*)?px/;\r\n\r\n            if (!this.isBrowser || elementId === null) {\r\n                return {\r\n                    width: 500,\r\n                    height: 500\r\n                };\r\n            }\r\n\r\n            doc = doc || document;\r\n            // Borrowed from prototype.js\r\n            element = (Type.isString(elementId)) ? doc.getElementById(elementId) : elementId;\r\n            if (!Type.exists(element)) {\r\n                throw new Error(\r\n                    \"\\nJSXGraph: HTML container element '\" + elementId + \"' not found.\"\r\n                );\r\n            }\r\n\r\n            display = element.style.display;\r\n\r\n            // Work around a bug in Safari\r\n            if (display !== \"none\" && display !== null) {\r\n                if (element.clientWidth > 0 && element.clientHeight > 0) {\r\n                    return { width: element.clientWidth, height: element.clientHeight };\r\n                }\r\n\r\n                // A parent might be set to display:none; try reading them from styles\r\n                style = window.getComputedStyle ? window.getComputedStyle(element) : element.style;\r\n                return {\r\n                    width: pixelDimRegExp.test(style.width) ? parseFloat(style.width) : 0,\r\n                    height: pixelDimRegExp.test(style.height) ? parseFloat(style.height) : 0\r\n                };\r\n            }\r\n\r\n            // All *Width and *Height properties give 0 on elements with display set to none,\r\n            // hence we show the element temporarily\r\n            els = element.style;\r\n\r\n            // save style\r\n            originalVisibility = els.visibility;\r\n            originalPosition = els.position;\r\n            originalDisplay = els.display;\r\n\r\n            // show element\r\n            els.visibility = 'hidden';\r\n            els.position = 'absolute';\r\n            els.display = 'block';\r\n\r\n            // read the dimension\r\n            originalWidth = element.clientWidth;\r\n            originalHeight = element.clientHeight;\r\n\r\n            // restore original css values\r\n            els.display = originalDisplay;\r\n            els.position = originalPosition;\r\n            els.visibility = originalVisibility;\r\n\r\n            return {\r\n                width: originalWidth,\r\n                height: originalHeight\r\n            };\r\n        },\r\n\r\n        /**\r\n         * Adds an event listener to a DOM element.\r\n         * @param {Object} obj Reference to a DOM node.\r\n         * @param {String} type The event to catch, without leading 'on', e.g. 'mousemove' instead of 'onmousemove'.\r\n         * @param {Function} fn The function to call when the event is triggered.\r\n         * @param {Object} owner The scope in which the event trigger is called.\r\n         * @param {Object|Boolean} [options=false] This parameter is passed as the third parameter to the method addEventListener. Depending on the data type it is either\r\n         * an options object or the useCapture Boolean.\r\n         *\r\n         */\r\n        addEvent: function (obj, type, fn, owner, options) {\r\n            var el = function () {\r\n                return fn.apply(owner, arguments);\r\n            };\r\n\r\n            el.origin = fn;\r\n            // Check if owner is a board\r\n            if (typeof owner === 'object' && Type.exists(owner.BOARD_MODE_NONE)) {\r\n                owner['x_internal' + type] = owner['x_internal' + type] || [];\r\n                owner['x_internal' + type].push(el);\r\n            }\r\n\r\n            // Non-IE browser\r\n            if (Type.exists(obj) && Type.exists(obj.addEventListener)) {\r\n                options = options || false;  // options or useCapture\r\n                obj.addEventListener(type, el, options);\r\n            }\r\n\r\n            // IE\r\n            if (Type.exists(obj) && Type.exists(obj.attachEvent)) {\r\n                obj.attachEvent(\"on\" + type, el);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Removes an event listener from a DOM element.\r\n         * @param {Object} obj Reference to a DOM node.\r\n         * @param {String} type The event to catch, without leading 'on', e.g. 'mousemove' instead of 'onmousemove'.\r\n         * @param {Function} fn The function to call when the event is triggered.\r\n         * @param {Object} owner The scope in which the event trigger is called.\r\n         */\r\n        removeEvent: function (obj, type, fn, owner) {\r\n            var i;\r\n\r\n            if (!Type.exists(owner)) {\r\n                JXG.debug(\"no such owner\");\r\n                return;\r\n            }\r\n\r\n            if (!Type.exists(owner[\"x_internal\" + type])) {\r\n                JXG.debug(\"removeEvent: no such type: \" + type);\r\n                return;\r\n            }\r\n\r\n            if (!Type.isArray(owner[\"x_internal\" + type])) {\r\n                JXG.debug(\"owner[x_internal + \" + type + \"] is not an array\");\r\n                return;\r\n            }\r\n\r\n            i = Type.indexOf(owner[\"x_internal\" + type], fn, 'origin');\r\n\r\n            if (i === -1) {\r\n                JXG.debug(\"removeEvent: no such event function in internal list: \" + fn);\r\n                return;\r\n            }\r\n\r\n            try {\r\n                // Non-IE browser\r\n                if (Type.exists(obj) && Type.exists(obj.removeEventListener)) {\r\n                    obj.removeEventListener(type, owner[\"x_internal\" + type][i], false);\r\n                }\r\n\r\n                // IE\r\n                if (Type.exists(obj) && Type.exists(obj.detachEvent)) {\r\n                    obj.detachEvent(\"on\" + type, owner[\"x_internal\" + type][i]);\r\n                }\r\n            } catch (e) {\r\n                JXG.debug(\"removeEvent: event not registered in browser: (\" + type + \" -- \" + fn + \")\");\r\n            }\r\n\r\n            owner[\"x_internal\" + type].splice(i, 1);\r\n        },\r\n\r\n        /**\r\n         * Removes all events of the given type from a given DOM node; Use with caution and do not use it on a container div\r\n         * of a {@link JXG.Board} because this might corrupt the event handling system.\r\n         * @param {Object} obj Reference to a DOM node.\r\n         * @param {String} type The event to catch, without leading 'on', e.g. 'mousemove' instead of 'onmousemove'.\r\n         * @param {Object} owner The scope in which the event trigger is called.\r\n         */\r\n        removeAllEvents: function (obj, type, owner) {\r\n            var i, len;\r\n            if (owner[\"x_internal\" + type]) {\r\n                len = owner[\"x_internal\" + type].length;\r\n\r\n                for (i = len - 1; i >= 0; i--) {\r\n                    JXG.removeEvent(obj, type, owner[\"x_internal\" + type][i].origin, owner);\r\n                }\r\n\r\n                if (owner[\"x_internal\" + type].length > 0) {\r\n                    JXG.debug(\"removeAllEvents: Not all events could be removed.\");\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Cross browser mouse / pointer / touch coordinates retrieval relative to the documents's top left corner.\r\n         * This method might be a bit outdated today, since pointer events and clientX/Y are omnipresent.\r\n         *\r\n         * @param {Object} [e] The browsers event object. If omitted, <tt>window.event</tt> will be used.\r\n         * @param {Number} [index] If <tt>e</tt> is a touch event, this provides the index of the touch coordinates, i.e. it determines which finger.\r\n         * @param {Object} [doc] The document object.\r\n         * @returns {Array} Contains the position as x,y-coordinates in the first resp. second component.\r\n         */\r\n        getPosition: function (e, index, doc) {\r\n            var i,\r\n                len,\r\n                evtTouches,\r\n                posx = 0,\r\n                posy = 0;\r\n\r\n            if (!e) {\r\n                e = window.event;\r\n            }\r\n\r\n            doc = doc || document;\r\n            evtTouches = e['touches']; // iOS touch events\r\n\r\n            // touchend events have their position in \"changedTouches\"\r\n            if (Type.exists(evtTouches) && evtTouches.length === 0) {\r\n                evtTouches = e.changedTouches;\r\n            }\r\n\r\n            if (Type.exists(index) && Type.exists(evtTouches)) {\r\n                if (index === -1) {\r\n                    len = evtTouches.length;\r\n\r\n                    for (i = 0; i < len; i++) {\r\n                        if (evtTouches[i]) {\r\n                            e = evtTouches[i];\r\n                            break;\r\n                        }\r\n                    }\r\n                } else {\r\n                    e = evtTouches[index];\r\n                }\r\n            }\r\n\r\n            // Scrolling is ignored.\r\n            // e.clientX is supported since IE6\r\n            if (e.clientX) {\r\n                posx = e.clientX;\r\n                posy = e.clientY;\r\n            }\r\n\r\n            return [posx, posy];\r\n        },\r\n\r\n        /**\r\n         * Calculates recursively the offset of the DOM element in which the board is stored.\r\n         * @param {Object} obj A DOM element\r\n         * @returns {Array} An array with the elements left and top offset.\r\n         */\r\n        getOffset: function (obj) {\r\n            var cPos,\r\n                o = obj,\r\n                o2 = obj,\r\n                l = o.offsetLeft - o.scrollLeft,\r\n                t = o.offsetTop - o.scrollTop;\r\n\r\n            cPos = this.getCSSTransform([l, t], o);\r\n            l = cPos[0];\r\n            t = cPos[1];\r\n\r\n            /*\r\n             * In Mozilla and Webkit: offsetParent seems to jump at least to the next iframe,\r\n             * if not to the body. In IE and if we are in an position:absolute environment\r\n             * offsetParent walks up the DOM hierarchy.\r\n             * In order to walk up the DOM hierarchy also in Mozilla and Webkit\r\n             * we need the parentNode steps.\r\n             */\r\n            o = o.offsetParent;\r\n            while (o) {\r\n                l += o.offsetLeft;\r\n                t += o.offsetTop;\r\n\r\n                if (o.offsetParent) {\r\n                    l += o.clientLeft - o.scrollLeft;\r\n                    t += o.clientTop - o.scrollTop;\r\n                }\r\n\r\n                cPos = this.getCSSTransform([l, t], o);\r\n                l = cPos[0];\r\n                t = cPos[1];\r\n\r\n                o2 = o2.parentNode;\r\n\r\n                while (o2 !== o) {\r\n                    l += o2.clientLeft - o2.scrollLeft;\r\n                    t += o2.clientTop - o2.scrollTop;\r\n\r\n                    cPos = this.getCSSTransform([l, t], o2);\r\n                    l = cPos[0];\r\n                    t = cPos[1];\r\n\r\n                    o2 = o2.parentNode;\r\n                }\r\n                o = o.offsetParent;\r\n            }\r\n\r\n            return [l, t];\r\n        },\r\n\r\n        /**\r\n         * Access CSS style sheets.\r\n         * @param {Object} obj A DOM element\r\n         * @param {String} stylename The CSS property to read.\r\n         * @returns The value of the CSS property and <tt>undefined</tt> if it is not set.\r\n         */\r\n        getStyle: function (obj, stylename) {\r\n            var r,\r\n                doc = obj.ownerDocument;\r\n\r\n            // Non-IE\r\n            if (doc.defaultView && doc.defaultView.getComputedStyle) {\r\n                r = doc.defaultView.getComputedStyle(obj, null).getPropertyValue(stylename);\r\n                // IE\r\n            } else if (obj.currentStyle && JXG.ieVersion >= 9) {\r\n                r = obj.currentStyle[stylename];\r\n            } else {\r\n                if (obj.style) {\r\n                    // make stylename lower camelcase\r\n                    stylename = stylename.replace(/-([a-z]|[0-9])/gi, function (all, letter) {\r\n                        return letter.toUpperCase();\r\n                    });\r\n                    r = obj.style[stylename];\r\n                }\r\n            }\r\n\r\n            return r;\r\n        },\r\n\r\n        /**\r\n         * Reads css style sheets of a given element. This method is a getStyle wrapper and\r\n         * defaults the read value to <tt>0</tt> if it can't be parsed as an integer value.\r\n         * @param {DOMElement} el\r\n         * @param {string} css\r\n         * @returns {number}\r\n         */\r\n        getProp: function (el, css) {\r\n            var n = parseInt(this.getStyle(el, css), 10);\r\n            return isNaN(n) ? 0 : n;\r\n        },\r\n\r\n        /**\r\n         * Correct position of upper left corner in case of\r\n         * a CSS transformation. Here, only translations are\r\n         * extracted. All scaling transformations are corrected\r\n         * in {@link JXG.Board#getMousePosition}.\r\n         * @param {Array} cPos Previously determined position\r\n         * @param {Object} obj A DOM element\r\n         * @returns {Array} The corrected position.\r\n         */\r\n        getCSSTransform: function (cPos, obj) {\r\n            var i,\r\n                j,\r\n                str,\r\n                arrStr,\r\n                start,\r\n                len,\r\n                len2,\r\n                arr,\r\n                t = [\r\n                    \"transform\",\r\n                    \"webkitTransform\",\r\n                    \"MozTransform\",\r\n                    \"msTransform\",\r\n                    \"oTransform\"\r\n                ];\r\n\r\n            // Take the first transformation matrix\r\n            len = t.length;\r\n\r\n            for (i = 0, str = \"\"; i < len; i++) {\r\n                if (Type.exists(obj.style[t[i]])) {\r\n                    str = obj.style[t[i]];\r\n                    break;\r\n                }\r\n            }\r\n\r\n            /**\r\n             * Extract the coordinates and apply the transformation\r\n             * to cPos\r\n             */\r\n            if (str !== \"\") {\r\n                start = str.indexOf(\"(\");\r\n\r\n                if (start > 0) {\r\n                    len = str.length;\r\n                    arrStr = str.substring(start + 1, len - 1);\r\n                    arr = arrStr.split(\",\");\r\n\r\n                    for (j = 0, len2 = arr.length; j < len2; j++) {\r\n                        arr[j] = parseFloat(arr[j]);\r\n                    }\r\n\r\n                    if (str.indexOf('matrix') === 0) {\r\n                        cPos[0] += arr[4];\r\n                        cPos[1] += arr[5];\r\n                    } else if (str.indexOf('translateX') === 0) {\r\n                        cPos[0] += arr[0];\r\n                    } else if (str.indexOf('translateY') === 0) {\r\n                        cPos[1] += arr[0];\r\n                    } else if (str.indexOf('translate') === 0) {\r\n                        cPos[0] += arr[0];\r\n                        cPos[1] += arr[1];\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Zoom is used by reveal.js\r\n            if (Type.exists(obj.style.zoom)) {\r\n                str = obj.style.zoom;\r\n                if (str !== \"\") {\r\n                    cPos[0] *= parseFloat(str);\r\n                    cPos[1] *= parseFloat(str);\r\n                }\r\n            }\r\n\r\n            return cPos;\r\n        },\r\n\r\n        /**\r\n         * Scaling CSS transformations applied to the div element containing the JSXGraph constructions\r\n         * are determined. In IE prior to 9, 'rotate', 'skew', 'skewX', 'skewY' are not supported.\r\n         * @returns {Array} 3x3 transformation matrix without translation part. See {@link JXG.Board#updateCSSTransforms}.\r\n         */\r\n        getCSSTransformMatrix: function (obj) {\r\n            var i, j, str, arrstr, arr,\r\n                start, len, len2, st,\r\n                doc = obj.ownerDocument,\r\n                t = [\r\n                    \"transform\",\r\n                    \"webkitTransform\",\r\n                    \"MozTransform\",\r\n                    \"msTransform\",\r\n                    \"oTransform\"\r\n                ],\r\n                mat = [\r\n                    [1, 0, 0],\r\n                    [0, 1, 0],\r\n                    [0, 0, 1]\r\n                ];\r\n\r\n            // This should work on all browsers except IE 6-8\r\n            if (doc.defaultView && doc.defaultView.getComputedStyle) {\r\n                st = doc.defaultView.getComputedStyle(obj, null);\r\n                str =\r\n                    st.getPropertyValue(\"-webkit-transform\") ||\r\n                    st.getPropertyValue(\"-moz-transform\") ||\r\n                    st.getPropertyValue(\"-ms-transform\") ||\r\n                    st.getPropertyValue(\"-o-transform\") ||\r\n                    st.getPropertyValue('transform');\r\n            } else {\r\n                // Take the first transformation matrix\r\n                len = t.length;\r\n                for (i = 0, str = \"\"; i < len; i++) {\r\n                    if (Type.exists(obj.style[t[i]])) {\r\n                        str = obj.style[t[i]];\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Convert and reorder the matrix for JSXGraph\r\n            if (str !== \"\") {\r\n                start = str.indexOf(\"(\");\r\n\r\n                if (start > 0) {\r\n                    len = str.length;\r\n                    arrstr = str.substring(start + 1, len - 1);\r\n                    arr = arrstr.split(\",\");\r\n\r\n                    for (j = 0, len2 = arr.length; j < len2; j++) {\r\n                        arr[j] = parseFloat(arr[j]);\r\n                    }\r\n\r\n                    if (str.indexOf('matrix') === 0) {\r\n                        mat = [\r\n                            [1, 0, 0],\r\n                            [0, arr[0], arr[1]],\r\n                            [0, arr[2], arr[3]]\r\n                        ];\r\n                    } else if (str.indexOf('scaleX') === 0) {\r\n                        mat[1][1] = arr[0];\r\n                    } else if (str.indexOf('scaleY') === 0) {\r\n                        mat[2][2] = arr[0];\r\n                    } else if (str.indexOf('scale') === 0) {\r\n                        mat[1][1] = arr[0];\r\n                        mat[2][2] = arr[1];\r\n                    }\r\n                }\r\n            }\r\n\r\n            // CSS style zoom is used by reveal.js\r\n            // Recursively search for zoom style entries.\r\n            // This is necessary for reveal.js on webkit.\r\n            // It fails if the user does zooming\r\n            if (Type.exists(obj.style.zoom)) {\r\n                str = obj.style.zoom;\r\n                if (str !== \"\") {\r\n                    mat[1][1] *= parseFloat(str);\r\n                    mat[2][2] *= parseFloat(str);\r\n                }\r\n            }\r\n\r\n            return mat;\r\n        },\r\n\r\n        /**\r\n         * Process data in timed chunks. Data which takes long to process, either because it is such\r\n         * a huge amount of data or the processing takes some time, causes warnings in browsers about\r\n         * irresponsive scripts. To prevent these warnings, the processing is split into smaller pieces\r\n         * called chunks which will be processed in serial order.\r\n         * Copyright 2009 Nicholas C. Zakas. All rights reserved. MIT Licensed\r\n         * @param {Array} items to do\r\n         * @param {Function} process Function that is applied for every array item\r\n         * @param {Object} context The scope of function process\r\n         * @param {Function} callback This function is called after the last array element has been processed.\r\n         */\r\n        timedChunk: function (items, process, context, callback) {\r\n            //create a clone of the original\r\n            var todo = items.slice(),\r\n                timerFun = function () {\r\n                    var start = +new Date();\r\n\r\n                    do {\r\n                        process.call(context, todo.shift());\r\n                    } while (todo.length > 0 && +new Date() - start < 300);\r\n\r\n                    if (todo.length > 0) {\r\n                        window.setTimeout(timerFun, 1);\r\n                    } else {\r\n                        callback(items);\r\n                    }\r\n                };\r\n\r\n            window.setTimeout(timerFun, 1);\r\n        },\r\n\r\n        /**\r\n         * Scale and vertically shift a DOM element (usually a JSXGraph div)\r\n         * inside of a parent DOM\r\n         * element which is set to fullscreen.\r\n         * This is realized with a CSS transformation.\r\n         *\r\n         * @param  {String} wrap_id  id of the parent DOM element which is in fullscreen mode\r\n         * @param  {String} inner_id id of the DOM element which is scaled and shifted\r\n         * @param  {Object} doc      document object or shadow root\r\n         * @param  {Number} scale    Relative size of the JSXGraph board in the fullscreen window.\r\n         *\r\n         * @private\r\n         * @see JXG.Board#toFullscreen\r\n         * @see JXG.Board#fullscreenListener\r\n         *\r\n         */\r\n        scaleJSXGraphDiv: function (wrap_id, inner_id, doc, scale) {\r\n            var w, h, b,\r\n                wi, hi,\r\n                wo, ho, inner,\r\n                scale_l, vshift_l,\r\n                f = scale,\r\n                ratio,\r\n                pseudo_keys = [\r\n                    \":fullscreen\",\r\n                    \":-webkit-full-screen\",\r\n                    \":-moz-full-screen\",\r\n                    \":-ms-fullscreen\"\r\n                ],\r\n                len_pseudo = pseudo_keys.length,\r\n                i;\r\n\r\n            b = doc.getElementById(wrap_id).getBoundingClientRect();\r\n            h = b.height;\r\n            w = b.width;\r\n\r\n            inner = doc.getElementById(inner_id);\r\n            wo = inner._cssFullscreenStore.w;\r\n            ho = inner._cssFullscreenStore.h;\r\n            ratio = ho / wo;\r\n\r\n            // Scale the div such that fits into the fullscreen.\r\n            if (wo > w * f) {\r\n                wo = w * f;\r\n                ho = wo * ratio;\r\n            }\r\n            if (ho > h * f) {\r\n                ho = h * f;\r\n                wo = ho / ratio;\r\n            }\r\n\r\n            wi = wo;\r\n            hi = ho;\r\n            // Compare the code in this.setBoundingBox()\r\n            if (ratio > 1) {\r\n                // h > w\r\n                if (ratio < h / w) {\r\n                    scale_l =  w * f / wo;\r\n                } else {\r\n                    scale_l =  h * f / ho;\r\n                }\r\n            } else {\r\n                // h <= w\r\n                if (ratio < h / w) {\r\n                    scale_l = w * f / wo;\r\n                } else {\r\n                    scale_l = h * f / ho;\r\n                }\r\n            }\r\n            vshift_l = (h - hi) * 0.5;\r\n\r\n            // Set a CSS properties to center the JSXGraph div horizontally and vertically\r\n            // at the first position of the fullscreen pseudo classes.\r\n            for (i = 0; i < len_pseudo; i++) {\r\n                try {\r\n                    inner.style.width = wi + 'px !important';\r\n                    inner.style.height = hi + 'px !important';\r\n                    inner.style.margin = '0 auto';\r\n                    // Add the transform to a possibly already existing transform\r\n                    inner.style.transform = inner._cssFullscreenStore.transform +\r\n                        ' matrix(' + scale_l + ',0,0,' + scale_l + ',0,' + vshift_l + ')';\r\n                    break;\r\n                } catch (err) {\r\n                    JXG.debug(\"JXG.scaleJSXGraphDiv:\\n\" + err);\r\n                }\r\n            }\r\n            if (i === len_pseudo) {\r\n                JXG.debug(\"JXG.scaleJSXGraphDiv: Could not set any CSS property.\");\r\n            }\r\n        }\r\n\r\n    }\r\n);\r\n\r\nexport default JXG;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true, unparam: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"./constants.js\";\r\nimport Coords from \"./coords.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Statistics from \"../math/statistics.js\";\r\nimport Options from \"../options.js\";\r\nimport EventEmitter from \"../utils/event.js\";\r\nimport Color from \"../utils/color.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Constructs a new GeometryElement object.\r\n * @class This is the parent class for all geometry elements like points, circles, lines, curves...\r\n * @constructor\r\n * @param {JXG.Board} board Reference to the board the element is constructed on.\r\n * @param {Object} attributes Hash of attributes and their values.\r\n * @param {Number} type Element type (a <tt>JXG.OBJECT_TYPE_</tt> value).\r\n * @param {Number} oclass The element's class (a <tt>JXG.OBJECT_CLASS_</tt> value).\r\n * @borrows JXG.EventEmitter#on as this.on\r\n * @borrows JXG.EventEmitter#off as this.off\r\n * @borrows JXG.EventEmitter#triggerEventHandlers as this.triggerEventHandlers\r\n * @borrows JXG.EventEmitter#eventHandlers as this.eventHandlers\r\n */\r\nJXG.GeometryElement = function (board, attributes, type, oclass) {\r\n    var name, key, attr;\r\n\r\n    /**\r\n     * Controls if updates are necessary\r\n     * @type Boolean\r\n     * @default true\r\n     */\r\n    this.needsUpdate = true;\r\n\r\n    /**\r\n     * Controls if this element can be dragged. In GEONExT only\r\n     * free points and gliders can be dragged.\r\n     * @type Boolean\r\n     * @default false\r\n     */\r\n    this.isDraggable = false;\r\n\r\n    /**\r\n     * If element is in two dimensional real space this is true, else false.\r\n     * @type Boolean\r\n     * @default true\r\n     */\r\n    this.isReal = true;\r\n\r\n    /**\r\n     * Stores all dependent objects to be updated when this point is moved.\r\n     * @type Object\r\n     */\r\n    this.childElements = {};\r\n\r\n    /**\r\n     * If element has a label subelement then this property will be set to true.\r\n     * @type Boolean\r\n     * @default false\r\n     */\r\n    this.hasLabel = false;\r\n\r\n    /**\r\n     * True, if the element is currently highlighted.\r\n     * @type Boolean\r\n     * @default false\r\n     */\r\n    this.highlighted = false;\r\n\r\n    /**\r\n     * Stores all Intersection Objects which in this moment are not real and\r\n     * so hide this element.\r\n     * @type Object\r\n     */\r\n    this.notExistingParents = {};\r\n\r\n    /**\r\n     * Keeps track of all objects drawn as part of the trace of the element.\r\n     * @see JXG.GeometryElement#clearTrace\r\n     * @see JXG.GeometryElement#numTraces\r\n     * @type Object\r\n     */\r\n    this.traces = {};\r\n\r\n    /**\r\n     * Counts the number of objects drawn as part of the trace of the element.\r\n     * @see JXG.GeometryElement#clearTrace\r\n     * @see JXG.GeometryElement#traces\r\n     * @type Number\r\n     */\r\n    this.numTraces = 0;\r\n\r\n    /**\r\n     * Stores the  transformations which are applied during update in an array\r\n     * @type Array\r\n     * @see JXG.Transformation\r\n     */\r\n    this.transformations = [];\r\n\r\n    /**\r\n     * @type JXG.GeometryElement\r\n     * @default null\r\n     * @private\r\n     */\r\n    this.baseElement = null;\r\n\r\n    /**\r\n     * Elements depending on this element are stored here.\r\n     * @type Object\r\n     */\r\n    this.descendants = {};\r\n\r\n    /**\r\n     * Elements on which this element depends on are stored here.\r\n     * @type Object\r\n     */\r\n    this.ancestors = {};\r\n\r\n    /**\r\n     * Ids of elements on which this element depends directly are stored here.\r\n     * @type Object\r\n     */\r\n    this.parents = [];\r\n\r\n    /**\r\n     * Stores variables for symbolic computations\r\n     * @type Object\r\n     */\r\n    this.symbolic = {};\r\n\r\n    /**\r\n     * Stores the SVG (or VML) rendering node for the element. This enables low-level\r\n     * access to SVG nodes. The properties of such an SVG node can then be changed\r\n     * by calling setAttribute(). Note that there are a few elements which consist\r\n     * of more than one SVG nodes:\r\n     * <ul>\r\n     * <li> Elements with arrow tail or head: rendNodeTriangleStart, rendNodeTriangleEnd\r\n     * <li> SVG (or VML) texts: rendNodeText\r\n     * <li> Button: rendNodeForm, rendNodeButton, rendNodeTag\r\n     * <li> Checkbox: rendNodeForm, rendNodeCheckbox, rendNodeLabel, rendNodeTag\r\n     * <li> Input: rendNodeForm, rendNodeInput, rendNodeLabel, rendNodeTag\r\n     * </ul>\r\n     *\r\n     * Here is are two examples: The first example shows how to access the SVG node,\r\n     * the second example demonstrates how to change SVG attributes.\r\n     * @example\r\n     *     var p1 = board.create('point', [0, 0]);\r\n     *     console.log(p1.rendNode);\r\n     *     // returns the full SVG node details of the point p1, something like:\r\n     *     // &lt;ellipse id='box_jxgBoard1P6' stroke='#ff0000' stroke-opacity='1' stroke-width='2px'\r\n     *     //   fill='#ff0000' fill-opacity='1' cx='250' cy='250' rx='4' ry='4'\r\n     *     //   style='position: absolute;'&gt;\r\n     *     // &lt;/ellipse&gt;\r\n     *\r\n     * @example\r\n     *     var s = board.create('segment', [p1, p2], {strokeWidth: 60});\r\n     *     s.rendNode.setAttribute('stroke-linecap', 'round');\r\n     *\r\n     * @type Object\r\n     */\r\n    this.rendNode = null;\r\n\r\n    /**\r\n     * The string used with {@link JXG.Board#create}\r\n     * @type String\r\n     */\r\n    this.elType = \"\";\r\n\r\n    /**\r\n     * The element is saved with an explicit entry in the file (<tt>true</tt>) or implicitly\r\n     * via a composition.\r\n     * @type Boolean\r\n     * @default true\r\n     */\r\n    this.dump = true;\r\n\r\n    /**\r\n     * Subs contains the subelements, created during the create method.\r\n     * @type Object\r\n     */\r\n    this.subs = {};\r\n\r\n    /**\r\n     * Inherits contains the subelements, which may have an attribute\r\n     * (in particular the attribute 'visible') having value 'inherit'.\r\n     * @type Object\r\n     */\r\n    this.inherits = [];\r\n\r\n    /**\r\n     * The position of this element inside the {@link JXG.Board#objectsList}.\r\n     * @type Number\r\n     * @default -1\r\n     * @private\r\n     */\r\n    this._pos = -1;\r\n\r\n    /**\r\n     * [c, b0, b1, a, k, r, q0, q1]\r\n     *\r\n     * See\r\n     * A.E. Middleditch, T.W. Stacey, and S.B. Tor:\r\n     * \"Intersection Algorithms for Lines and Circles\",\r\n     * ACM Transactions on Graphics, Vol. 8, 1, 1989, pp 25-40.\r\n     *\r\n     * The meaning of the parameters is:\r\n     * Circle: points p=[p0, p1] on the circle fulfill\r\n     *  a&lt;p, p&gt; + &lt;b, p&gt; + c = 0\r\n     * For convenience we also store\r\n     *  r: radius\r\n     *  k: discriminant = sqrt(&lt;b,b&gt;-4ac)\r\n     *  q=[q0, q1] center\r\n     *\r\n     * Points have radius = 0.\r\n     * Lines have radius = infinity.\r\n     * b: normalized vector, representing the direction of the line.\r\n     *\r\n     * Should be put into Coords, when all elements possess Coords.\r\n     * @type Array\r\n     * @default [1, 0, 0, 0, 1, 1, 0, 0]\r\n     */\r\n    this.stdform = [1, 0, 0, 0, 1, 1, 0, 0];\r\n\r\n    /**\r\n     * The methodMap determines which methods can be called from within JessieCode and under which name it\r\n     * can be used. The map is saved in an object, the name of a property is the name of the method used in JessieCode,\r\n     * the value of a property is the name of the method in JavaScript.\r\n     * @type Object\r\n     */\r\n    this.methodMap = {\r\n        setLabel: \"setLabel\",\r\n        label: \"label\",\r\n        setName: \"setName\",\r\n        getName: \"getName\",\r\n        Name: \"getName\",\r\n        addTransform: \"addTransform\",\r\n        setProperty: \"setAttribute\",\r\n        setAttribute: \"setAttribute\",\r\n        addChild: \"addChild\",\r\n        animate: \"animate\",\r\n        on: \"on\",\r\n        off: \"off\",\r\n        trigger: \"trigger\",\r\n        addTicks: \"addTicks\",\r\n        removeTicks: \"removeTicks\",\r\n        removeAllTicks: \"removeAllTicks\",\r\n        Bounds: \"bounds\"\r\n    };\r\n\r\n    /**\r\n     * Quadratic form representation of circles (and conics)\r\n     * @type Array\r\n     * @default [[1,0,0],[0,1,0],[0,0,1]]\r\n     */\r\n    this.quadraticform = [\r\n        [1, 0, 0],\r\n        [0, 1, 0],\r\n        [0, 0, 1]\r\n    ];\r\n\r\n    /**\r\n     * An associative array containing all visual properties.\r\n     * @type Object\r\n     * @default empty object\r\n     */\r\n    this.visProp = {};\r\n\r\n    /**\r\n     * An associative array containing visual properties which are calculated from\r\n     * the attribute values (i.e. visProp) and from other constraints.\r\n     * An example: if an intersection point does not have real coordinates,\r\n     * visPropCalc.visible is set to false.\r\n     * Additionally, the user can control visibility with the attribute \"visible\",\r\n     * even by supplying a functions as value.\r\n     *\r\n     * @type Object\r\n     * @default empty object\r\n     */\r\n    this.visPropCalc = {\r\n        visible: false\r\n    };\r\n\r\n    EventEmitter.eventify(this);\r\n\r\n    /**\r\n     * Is the mouse over this element?\r\n     * @type Boolean\r\n     * @default false\r\n     */\r\n    this.mouseover = false;\r\n\r\n    /**\r\n     * Time stamp containing the last time this element has been dragged.\r\n     * @type Date\r\n     * @default creation time\r\n     */\r\n    this.lastDragTime = new Date();\r\n\r\n    this.view = null;\r\n\r\n    if (arguments.length > 0) {\r\n        /**\r\n         * Reference to the board associated with the element.\r\n         * @type JXG.Board\r\n         */\r\n        this.board = board;\r\n\r\n        /**\r\n         * Type of the element.\r\n         * @constant\r\n         * @type Number\r\n         */\r\n        this.type = type;\r\n\r\n        /**\r\n         * Original type of the element at construction time. Used for removing glider property.\r\n         * @constant\r\n         * @type Number\r\n         */\r\n        this._org_type = type;\r\n\r\n        /**\r\n         * The element's class.\r\n         * @constant\r\n         * @type Number\r\n         */\r\n        this.elementClass = oclass || Const.OBJECT_CLASS_OTHER;\r\n\r\n        /**\r\n         * Unique identifier for the element. Equivalent to id-attribute of renderer element.\r\n         * @type String\r\n         */\r\n        this.id = attributes.id;\r\n\r\n        name = attributes.name;\r\n        /* If name is not set or null or even undefined, generate an unique name for this object */\r\n        if (!Type.exists(name)) {\r\n            name = this.board.generateName(this);\r\n        }\r\n\r\n        if (name !== \"\") {\r\n            this.board.elementsByName[name] = this;\r\n        }\r\n\r\n        /**\r\n         * Not necessarily unique name for the element.\r\n         * @type String\r\n         * @default Name generated by {@link JXG.Board#generateName}.\r\n         * @see JXG.Board#generateName\r\n         */\r\n        this.name = name;\r\n\r\n        this.needsRegularUpdate = attributes.needsregularupdate;\r\n\r\n        // create this.visPropOld and set default values\r\n        Type.clearVisPropOld(this);\r\n\r\n        attr = this.resolveShortcuts(attributes);\r\n        for (key in attr) {\r\n            if (attr.hasOwnProperty(key)) {\r\n                this._set(key, attr[key]);\r\n            }\r\n        }\r\n\r\n        this.visProp.draft = attr.draft && attr.draft.draft;\r\n        //this.visProp.gradientangle = '270';\r\n        // this.visProp.gradientsecondopacity = this.evalVisProp('fillopacity');\r\n        //this.visProp.gradientpositionx = 0.5;\r\n        //this.visProp.gradientpositiony = 0.5;\r\n    }\r\n};\r\n\r\nJXG.extend(\r\n    JXG.GeometryElement.prototype,\r\n    /** @lends JXG.GeometryElement.prototype */ {\r\n        /**\r\n         * Add an element as a child to the current element. Can be used to model dependencies between geometry elements.\r\n         * @param {JXG.GeometryElement} obj The dependent object.\r\n         */\r\n        addChild: function (obj) {\r\n            var el, el2;\r\n\r\n            this.childElements[obj.id] = obj;\r\n            this.addDescendants(obj);  // TODO TomBerend removed this. Check if it is possible.\r\n            obj.ancestors[this.id] = this;\r\n\r\n            for (el in this.descendants) {\r\n                if (this.descendants.hasOwnProperty(el)) {\r\n                    this.descendants[el].ancestors[this.id] = this;\r\n\r\n                    for (el2 in this.ancestors) {\r\n                        if (this.ancestors.hasOwnProperty(el2)) {\r\n                            this.descendants[el].ancestors[this.ancestors[el2].id] =\r\n                                this.ancestors[el2];\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            for (el in this.ancestors) {\r\n                if (this.ancestors.hasOwnProperty(el)) {\r\n                    for (el2 in this.descendants) {\r\n                        if (this.descendants.hasOwnProperty(el2)) {\r\n                            this.ancestors[el].descendants[this.descendants[el2].id] =\r\n                                this.descendants[el2];\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @param {JXG.GeometryElement} obj The element that is to be added to the descendants list.\r\n         * @private\r\n         * @return this\r\n        */\r\n        // Adds the given object to the descendants list of this object and all its child objects.\r\n        addDescendants: function (obj) {\r\n            var el;\r\n\r\n            this.descendants[obj.id] = obj;\r\n            for (el in obj.childElements) {\r\n                if (obj.childElements.hasOwnProperty(el)) {\r\n                    this.addDescendants(obj.childElements[el]);\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Adds ids of elements to the array this.parents. This method needs to be called if some dependencies\r\n         * can not be detected automatically by JSXGraph. For example if a function graph is given by a function\r\n         * which refers to coordinates of a point, calling addParents() is necessary.\r\n         *\r\n         * @param {Array} parents Array of elements or ids of elements.\r\n         * Alternatively, one can give a list of objects as parameters.\r\n         * @returns {JXG.Object} reference to the object itself.\r\n         *\r\n         * @example\r\n         * // Movable function graph\r\n         * var A = board.create('point', [1, 0], {name:'A'}),\r\n         *     B = board.create('point', [3, 1], {name:'B'}),\r\n         *     f = board.create('functiongraph', function(x) {\r\n         *          var ax = A.X(),\r\n         *              ay = A.Y(),\r\n         *              bx = B.X(),\r\n         *              by = B.Y(),\r\n         *              a = (by - ay) / ( (bx - ax) * (bx - ax) );\r\n         *           return a * (x - ax) * (x - ax) + ay;\r\n         *      }, {fixed: false});\r\n         * f.addParents([A, B]);\r\n         * </pre><div class=\"jxgbox\" id=\"JXG7c91d4d2-986c-4378-8135-24505027f251\" style=\"width: 400px; height: 400px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         * (function() {\r\n         *   var board = JXG.JSXGraph.initBoard('JXG7c91d4d2-986c-4378-8135-24505027f251', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n         *   var A = board.create('point', [1, 0], {name:'A'}),\r\n         *       B = board.create('point', [3, 1], {name:'B'}),\r\n         *       f = board.create('functiongraph', function(x) {\r\n         *            var ax = A.X(),\r\n         *                ay = A.Y(),\r\n         *                bx = B.X(),\r\n         *                by = B.Y(),\r\n         *                a = (by - ay) / ( (bx - ax) * (bx - ax) );\r\n         *             return a * (x - ax) * (x - ax) + ay;\r\n         *        }, {fixed: false});\r\n         *   f.addParents([A, B]);\r\n         * })();\r\n         * </script><pre>\r\n         *\r\n         **/\r\n        addParents: function (parents) {\r\n            var i, len, par;\r\n\r\n            if (Type.isArray(parents)) {\r\n                par = parents;\r\n            } else {\r\n                par = arguments;\r\n            }\r\n\r\n            len = par.length;\r\n            for (i = 0; i < len; ++i) {\r\n                if (!Type.exists(par[i])) {\r\n                    continue;\r\n                }\r\n                if (Type.isId(this.board, par[i])) {\r\n                    this.parents.push(par[i]);\r\n                } else if (Type.exists(par[i].id)) {\r\n                    this.parents.push(par[i].id);\r\n                }\r\n            }\r\n            this.parents = Type.uniqueArray(this.parents);\r\n        },\r\n\r\n        /**\r\n         * Sets ids of elements to the array this.parents.\r\n         * First, this.parents is cleared. See {@link JXG.GeometryElement#addParents}.\r\n         * @param {Array} parents Array of elements or ids of elements.\r\n         * Alternatively, one can give a list of objects as parameters.\r\n         * @returns {JXG.Object} reference to the object itself.\r\n         **/\r\n        setParents: function (parents) {\r\n            this.parents = [];\r\n            this.addParents(parents);\r\n        },\r\n\r\n        /**\r\n         * Add dependence on elements in JessieCode functions.\r\n         * @param {Array} function_array Array of functions containing potential properties \"deps\" with\r\n         * elements the function depends on.\r\n         * @returns {JXG.Object} reference to the object itself\r\n         * @private\r\n         */\r\n        addParentsFromJCFunctions: function (function_array) {\r\n            var i, e, obj;\r\n            for (i = 0; i < function_array.length; i++) {\r\n                for (e in function_array[i].deps) {\r\n                    obj = function_array[i].deps[e];\r\n                    // this.addParents(obj);\r\n                    obj.addChild(this);\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Remove an element as a child from the current element.\r\n         * @param {JXG.GeometryElement} obj The dependent object.\r\n         * @returns {JXG.Object} reference to the object itself\r\n         */\r\n        removeChild: function (obj) {\r\n            //var el, el2;\r\n\r\n            delete this.childElements[obj.id];\r\n            this.removeDescendants(obj);\r\n            delete obj.ancestors[this.id];\r\n\r\n            /*\r\n             // I do not know if these addDescendants stuff has to be adapted to removeChild. A.W.\r\n            for (el in this.descendants) {\r\n                if (this.descendants.hasOwnProperty(el)) {\r\n                    delete this.descendants[el].ancestors[this.id];\r\n\r\n                    for (el2 in this.ancestors) {\r\n                        if (this.ancestors.hasOwnProperty(el2)) {\r\n                            this.descendants[el].ancestors[this.ancestors[el2].id] = this.ancestors[el2];\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            for (el in this.ancestors) {\r\n                if (this.ancestors.hasOwnProperty(el)) {\r\n                    for (el2 in this.descendants) {\r\n                        if (this.descendants.hasOwnProperty(el2)) {\r\n                            this.ancestors[el].descendants[this.descendants[el2].id] = this.descendants[el2];\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            */\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Removes the given object from the descendants list of this object and all its child objects.\r\n         * @param {JXG.GeometryElement} obj The element that is to be removed from the descendants list.\r\n         * @private\r\n         * @returns {JXG.Object} reference to the object itself\r\n         */\r\n        removeDescendants: function (obj) {\r\n            var el;\r\n\r\n            delete this.descendants[obj.id];\r\n            for (el in obj.childElements) {\r\n                if (obj.childElements.hasOwnProperty(el)) {\r\n                    this.removeDescendants(obj.childElements[el]);\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Counts the direct children of an object without counting labels.\r\n         * @private\r\n         * @returns {number} Number of children\r\n         */\r\n        countChildren: function () {\r\n            var prop,\r\n                d,\r\n                s = 0;\r\n\r\n            d = this.childElements;\r\n            for (prop in d) {\r\n                if (d.hasOwnProperty(prop) && prop.indexOf('Label') < 0) {\r\n                    s++;\r\n                }\r\n            }\r\n            return s;\r\n        },\r\n\r\n        /**\r\n         * Returns the elements name. Used in JessieCode.\r\n         * @returns {String}\r\n         */\r\n        getName: function () {\r\n            return this.name;\r\n        },\r\n\r\n        /**\r\n         * Add transformations to this element.\r\n         * @param {JXG.Transformation|Array} transform Either one {@link JXG.Transformation}\r\n         * or an array of {@link JXG.Transformation}s.\r\n         * @returns {JXG.GeometryElement} Reference to the element.\r\n         */\r\n        addTransform: function (transform) {\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Decides whether an element can be dragged. This is used in\r\n         * {@link JXG.GeometryElement#setPositionDirectly} methods\r\n         * where all parent elements are checked if they may be dragged, too.\r\n         * @private\r\n         * @returns {boolean}\r\n         */\r\n        draggable: function () {\r\n            return (\r\n                this.isDraggable &&\r\n                !this.evalVisProp('fixed') &&\r\n                // !this.visProp.frozen &&\r\n                this.type !== Const.OBJECT_TYPE_GLIDER\r\n            );\r\n        },\r\n\r\n        /**\r\n         * Translates the object by <tt>(x, y)</tt>. In case the element is defined by points, the defining points are\r\n         * translated, e.g. a circle constructed by a center point and a point on the circle line.\r\n         * @param {Number} method The type of coordinates used here.\r\n         * Possible values are {@link JXG.COORDS_BY_USER} and {@link JXG.COORDS_BY_SCREEN}.\r\n         * @param {Array} coords array of translation vector.\r\n         * @returns {JXG.GeometryElement} Reference to the element object.\r\n         *\r\n         * @see JXG.GeometryElement3D#setPosition2D\r\n         */\r\n        setPosition: function (method, coords) {\r\n            var parents = [],\r\n                el,\r\n                i, len, t;\r\n\r\n            if (!Type.exists(this.parents)) {\r\n                return this;\r\n            }\r\n\r\n            len = this.parents.length;\r\n            for (i = 0; i < len; ++i) {\r\n                el = this.board.select(this.parents[i]);\r\n                if (Type.isPoint(el)) {\r\n                    if (!el.draggable()) {\r\n                        return this;\r\n                    }\r\n                    parents.push(el);\r\n                }\r\n            }\r\n\r\n            if (coords.length === 3) {\r\n                coords = coords.slice(1);\r\n            }\r\n\r\n            t = this.board.create(\"transform\", coords, { type: \"translate\" });\r\n\r\n            // We distinguish two cases:\r\n            // 1) elements which depend on free elements, i.e. arcs and sectors\r\n            // 2) other elements\r\n            //\r\n            // In the first case we simply transform the parents elements\r\n            // In the second case we add a transform to the element.\r\n            //\r\n            len = parents.length;\r\n            if (len > 0) {\r\n                t.applyOnce(parents);\r\n\r\n                // Handle dragging of a 3D element\r\n                if (Type.exists(this.view) && this.view.elType === 'view3d') {\r\n                    for (i = 0; i < this.parents.length; ++i) {\r\n                        // Search for the parent 3D element\r\n                        el = this.view.select(this.parents[i]);\r\n                        if (Type.exists(el.setPosition2D)) {\r\n                            el.setPosition2D(t);\r\n                        }\r\n                    }\r\n                }\r\n\r\n            } else {\r\n                if (\r\n                    this.transformations.length > 0 &&\r\n                    this.transformations[this.transformations.length - 1].isNumericMatrix\r\n                ) {\r\n                    this.transformations[this.transformations.length - 1].melt(t);\r\n                } else {\r\n                    this.addTransform(t);\r\n                }\r\n            }\r\n\r\n            /*\r\n             * If - against the default configuration - defining gliders are marked as\r\n             * draggable, then their position has to be updated now.\r\n             */\r\n            for (i = 0; i < len; ++i) {\r\n                if (parents[i].type === Const.OBJECT_TYPE_GLIDER) {\r\n                    parents[i].updateGlider();\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Moves an element by the difference of two coordinates.\r\n         * @param {Number} method The type of coordinates used here.\r\n         * Possible values are {@link JXG.COORDS_BY_USER} and {@link JXG.COORDS_BY_SCREEN}.\r\n         * @param {Array} coords coordinates in screen/user units\r\n         * @param {Array} oldcoords previous coordinates in screen/user units\r\n         * @returns {JXG.GeometryElement} this element\r\n         */\r\n        setPositionDirectly: function (method, coords, oldcoords) {\r\n            var c = new Coords(method, coords, this.board, false),\r\n                oldc = new Coords(method, oldcoords, this.board, false),\r\n                dc = Statistics.subtract(c.usrCoords, oldc.usrCoords);\r\n\r\n            this.setPosition(Const.COORDS_BY_USER, dc);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Array of strings containing the polynomials defining the element.\r\n         * Used for determining geometric loci the groebner way.\r\n         * @returns {Array} An array containing polynomials describing the locus of the current object.\r\n         * @public\r\n         */\r\n        generatePolynomial: function () {\r\n            return [];\r\n        },\r\n\r\n        /**\r\n         * Animates properties for that object like stroke or fill color, opacity and maybe\r\n         * even more later.\r\n         * @param {Object} hash Object containing properties with target values for the animation.\r\n         * @param {number} time Number of milliseconds to complete the animation.\r\n         * @param {Object} [options] Optional settings for the animation:<ul><li>callback: A function that is called as soon as the animation is finished.</li></ul>\r\n         * @returns {JXG.GeometryElement} A reference to the object\r\n         */\r\n        animate: function (hash, time, options) {\r\n            options = options || {};\r\n            var r,\r\n                p,\r\n                i,\r\n                delay = this.board.attr.animationdelay,\r\n                steps = Math.ceil(time / delay),\r\n                self = this,\r\n                animateColor = function (startRGB, endRGB, property) {\r\n                    var hsv1, hsv2, sh, ss, sv;\r\n                    hsv1 = Color.rgb2hsv(startRGB);\r\n                    hsv2 = Color.rgb2hsv(endRGB);\r\n\r\n                    sh = (hsv2[0] - hsv1[0]) / steps;\r\n                    ss = (hsv2[1] - hsv1[1]) / steps;\r\n                    sv = (hsv2[2] - hsv1[2]) / steps;\r\n                    self.animationData[property] = [];\r\n\r\n                    for (i = 0; i < steps; i++) {\r\n                        self.animationData[property][steps - i - 1] = Color.hsv2rgb(\r\n                            hsv1[0] + (i + 1) * sh,\r\n                            hsv1[1] + (i + 1) * ss,\r\n                            hsv1[2] + (i + 1) * sv\r\n                        );\r\n                    }\r\n                },\r\n                animateFloat = function (start, end, property, round) {\r\n                    var tmp, s;\r\n\r\n                    start = parseFloat(start);\r\n                    end = parseFloat(end);\r\n\r\n                    // we can't animate without having valid numbers.\r\n                    // And parseFloat returns NaN if the given string doesn't contain\r\n                    // a valid float number.\r\n                    if (isNaN(start) || isNaN(end)) {\r\n                        return;\r\n                    }\r\n\r\n                    s = (end - start) / steps;\r\n                    self.animationData[property] = [];\r\n\r\n                    for (i = 0; i < steps; i++) {\r\n                        tmp = start + (i + 1) * s;\r\n                        self.animationData[property][steps - i - 1] = round\r\n                            ? Math.floor(tmp)\r\n                            : tmp;\r\n                    }\r\n                };\r\n\r\n            this.animationData = {};\r\n\r\n            for (r in hash) {\r\n                if (hash.hasOwnProperty(r)) {\r\n                    p = r.toLowerCase();\r\n\r\n                    switch (p) {\r\n                        case \"strokecolor\":\r\n                        case \"fillcolor\":\r\n                            animateColor(this.visProp[p], hash[r], p);\r\n                            break;\r\n                        case \"size\":\r\n                            if (!Type.isPoint(this)) {\r\n                                break;\r\n                            }\r\n                            animateFloat(this.visProp[p], hash[r], p, true);\r\n                            break;\r\n                        case \"strokeopacity\":\r\n                        case \"strokewidth\":\r\n                        case \"fillopacity\":\r\n                            animateFloat(this.visProp[p], hash[r], p, false);\r\n                            break;\r\n                    }\r\n                }\r\n            }\r\n\r\n            this.animationCallback = options.callback;\r\n            this.board.addAnimation(this);\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * General update method. Should be overwritten by the element itself.\r\n         * Can be used sometimes to commit changes to the object.\r\n         * @return {JXG.GeometryElement} Reference to the element\r\n         */\r\n        update: function () {\r\n            if (this.evalVisProp('trace')) {\r\n                this.cloneToBackground();\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Provide updateRenderer method.\r\n         * @return {JXG.GeometryElement} Reference to the element\r\n         * @private\r\n         */\r\n        updateRenderer: function () {\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Run through the full update chain of an element.\r\n         * @param  {Boolean} visible Set visibility in case the elements attribute value is 'inherit'. null is allowed.\r\n         * @return {JXG.GeometryElement} Reference to the element\r\n         * @private\r\n         */\r\n        fullUpdate: function (visible) {\r\n            return this.prepareUpdate().update().updateVisibility(visible).updateRenderer();\r\n        },\r\n\r\n        /**\r\n         * Show the element or hide it. If hidden, it will still exist but not be\r\n         * visible on the board.\r\n         * <p>\r\n         * Sets also the display of the inherits elements. These can be\r\n         * JSXGraph elements or arrays of JSXGraph elements.\r\n         * However, deeper nesting than this is not supported.\r\n         *\r\n         * @param  {Boolean} val true: show the element, false: hide the element\r\n         * @return {JXG.GeometryElement} Reference to the element\r\n         * @private\r\n         */\r\n        setDisplayRendNode: function (val) {\r\n            var i, len, s, len_s, obj;\r\n\r\n            if (val === undefined) {\r\n                val = this.visPropCalc.visible;\r\n            }\r\n\r\n            if (val === this.visPropOld.visible) {\r\n                return this;\r\n            }\r\n\r\n            // Set display of the element itself\r\n            this.board.renderer.display(this, val);\r\n\r\n            // Set the visibility of elements which inherit the attribute 'visible'\r\n            len = this.inherits.length;\r\n            for (s = 0; s < len; s++) {\r\n                obj = this.inherits[s];\r\n                if (Type.isArray(obj)) {\r\n                    len_s = obj.length;\r\n                    for (i = 0; i < len_s; i++) {\r\n                        if (\r\n                            Type.exists(obj[i]) &&\r\n                            Type.exists(obj[i].rendNode) &&\r\n                            obj[i].evalVisProp('visible') === 'inherit'\r\n                        ) {\r\n                            obj[i].setDisplayRendNode(val);\r\n                        }\r\n                    }\r\n                } else {\r\n                    if (\r\n                        Type.exists(obj) &&\r\n                        Type.exists(obj.rendNode) &&\r\n                        obj.evalVisProp('visible') === 'inherit'\r\n                    ) {\r\n                        obj.setDisplayRendNode(val);\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Set the visibility of the label if it inherits the attribute 'visible'\r\n            if (this.hasLabel && Type.exists(this.label) && Type.exists(this.label.rendNode)) {\r\n                if (this.label.evalVisProp('visible') === 'inherit') {\r\n                    this.label.setDisplayRendNode(val);\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Hide the element. It will still exist but not be visible on the board.\r\n         * Alias for \"element.setAttribute({visible: false});\"\r\n         * @return {JXG.GeometryElement} Reference to the element\r\n         */\r\n        hide: function () {\r\n            this.setAttribute({ visible: false });\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Hide the element. It will still exist but not be visible on the board.\r\n         * Alias for {@link JXG.GeometryElement#hide}\r\n         * @returns {JXG.GeometryElement} Reference to the element\r\n         */\r\n        hideElement: function () {\r\n            this.hide();\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Make the element visible.\r\n         * Alias for \"element.setAttribute({visible: true});\"\r\n         * @return {JXG.GeometryElement} Reference to the element\r\n         */\r\n        show: function () {\r\n            this.setAttribute({ visible: true });\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Make the element visible.\r\n         * Alias for {@link JXG.GeometryElement#show}\r\n         * @returns {JXG.GeometryElement} Reference to the element\r\n         */\r\n        showElement: function () {\r\n            this.show();\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the visibility of an element. The visibility is influenced by\r\n         * (listed in ascending priority):\r\n         * <ol>\r\n         * <li> The value of the element's attribute 'visible'\r\n         * <li> The visibility of a parent element. (Example: label)\r\n         * This overrules the value of the element's attribute value only if\r\n         * this attribute value of the element is 'inherit'.\r\n         * <li> being inside of the canvas\r\n         * </ol>\r\n         * <p>\r\n         * This method is called three times for most elements:\r\n         * <ol>\r\n         * <li> between {@link JXG.GeometryElement#update}\r\n         * and {@link JXG.GeometryElement#updateRenderer}. In case the value is 'inherit', nothing is done.\r\n         * <li> Recursively, called by itself for child elements. Here, 'inherit' is overruled by the parent's value.\r\n         * <li> In {@link JXG.GeometryElement#updateRenderer}, if the element is outside of the canvas.\r\n         * </ol>\r\n         *\r\n         * @param  {Boolean} parent_val Visibility of the parent element.\r\n         * @return {JXG.GeometryElement} Reference to the element.\r\n         * @private\r\n         */\r\n        updateVisibility: function (parent_val) {\r\n            var i, len, s, len_s, obj, val;\r\n\r\n            if (this.needsUpdate) {\r\n                if (Type.exists(this.view) && this.view.evalVisProp('visible') === false) {\r\n                    // Handle hiding of view3d\r\n                    this.visPropCalc.visible = false;\r\n\r\n                } else {\r\n                    // Handle the element\r\n                    if (parent_val !== undefined) {\r\n                        this.visPropCalc.visible = parent_val;\r\n                    } else {\r\n                        val = this.evalVisProp('visible');\r\n\r\n                        // infobox uses hiddenByParent\r\n                        if (Type.exists(this.hiddenByParent) && this.hiddenByParent) {\r\n                            val = false;\r\n                        }\r\n                        if (val !== 'inherit') {\r\n                            this.visPropCalc.visible = val;\r\n                        }\r\n                    }\r\n\r\n                    // Handle elements which inherit the visibility\r\n                    len = this.inherits.length;\r\n                    for (s = 0; s < len; s++) {\r\n                        obj = this.inherits[s];\r\n                        if (Type.isArray(obj)) {\r\n                            len_s = obj.length;\r\n                            for (i = 0; i < len_s; i++) {\r\n                                if (\r\n                                    Type.exists(obj[i]) /*&& Type.exists(obj[i].rendNode)*/ &&\r\n                                    obj[i].evalVisProp('visible') === 'inherit'\r\n                                ) {\r\n                                    obj[i]\r\n                                        .prepareUpdate()\r\n                                        .updateVisibility(this.visPropCalc.visible);\r\n                                }\r\n                            }\r\n                        } else {\r\n                            if (\r\n                                Type.exists(obj) /*&& Type.exists(obj.rendNode)*/ &&\r\n                                obj.evalVisProp('visible') === 'inherit'\r\n                            ) {\r\n                                obj.prepareUpdate().updateVisibility(this.visPropCalc.visible);\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // Handle the label if it inherits the visibility\r\n                if (\r\n                    Type.exists(this.label) &&\r\n                    Type.exists(this.label.visProp) &&\r\n                    this.label.evalVisProp('visible')\r\n                ) {\r\n                    this.label.prepareUpdate().updateVisibility(this.visPropCalc.visible);\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Sets the value of attribute <tt>key</tt> to <tt>value</tt>.\r\n         * Here, mainly hex strings for rga(a) colors are parsed and values of type object get a special treatment.\r\n         * Other values are just set to the key.\r\n         *\r\n         * @param {String} key The attribute's name.\r\n         * @param value The new value\r\n         * @private\r\n         */\r\n        _set: function (key, value) {\r\n            var el;\r\n\r\n            key = key.toLocaleLowerCase();\r\n\r\n            // Search for entries in visProp with \"color\" as part of the key name\r\n            // and containing a RGBA string\r\n            if (\r\n                this.visProp.hasOwnProperty(key) &&\r\n                key.indexOf('color') >= 0 &&\r\n                Type.isString(value) &&\r\n                value.length === 9 &&\r\n                value.charAt(0) === \"#\"\r\n            ) {\r\n                value = Color.rgba2rgbo(value);\r\n                this.visProp[key] = value[0];\r\n                // Previously: *=. But then, we can only decrease opacity.\r\n                this.visProp[key.replace(\"color\", 'opacity')] = value[1];\r\n            } else {\r\n                if (\r\n                    value !== null &&\r\n                    Type.isObject(value) &&\r\n                    !Type.exists(value.id) &&\r\n                    !Type.exists(value.name)\r\n                ) {\r\n                    // value is of type {prop: val, prop: val,...}\r\n                    // Convert these attributes to lowercase, too\r\n                    this.visProp[key] = {};\r\n                    for (el in value) {\r\n                        if (value.hasOwnProperty(el)) {\r\n                            this.visProp[key][el.toLocaleLowerCase()] = value[el];\r\n                        }\r\n                    }\r\n                } else {\r\n                    this.visProp[key] = value;\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Resolves attribute shortcuts like <tt>color</tt> and expands them, e.g. <tt>strokeColor</tt> and <tt>fillColor</tt>.\r\n         * Writes the expanded attributes back to the given <tt>attributes</tt>.\r\n         * @param {Object} attributes object\r\n         * @returns {Object} The given attributes object with shortcuts expanded.\r\n         * @private\r\n         */\r\n        resolveShortcuts: function (attributes) {\r\n            var key, i, j,\r\n                subattr = [\"traceattributes\", \"traceAttributes\"];\r\n\r\n            for (key in Options.shortcuts) {\r\n                if (Options.shortcuts.hasOwnProperty(key)) {\r\n                    if (Type.exists(attributes[key])) {\r\n                        for (i = 0; i < Options.shortcuts[key].length; i++) {\r\n                            if (!Type.exists(attributes[Options.shortcuts[key][i]])) {\r\n                                attributes[Options.shortcuts[key][i]] = attributes[key];\r\n                            }\r\n                        }\r\n                    }\r\n                    for (j = 0; j < subattr.length; j++) {\r\n                        if (Type.isObject(attributes[subattr[j]])) {\r\n                            attributes[subattr[j]] = this.resolveShortcuts(attributes[subattr[j]]);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            return attributes;\r\n        },\r\n\r\n        /**\r\n         * Sets a label and its text\r\n         * If label doesn't exist, it creates one\r\n         * @param {String} str\r\n         */\r\n        setLabel: function (str) {\r\n            if (!this.hasLabel) {\r\n                this.setAttribute({ withlabel: true });\r\n            }\r\n            this.setLabelText(str);\r\n        },\r\n\r\n        /**\r\n         * Updates the element's label text, strips all html.\r\n         * @param {String} str\r\n         */\r\n        setLabelText: function (str) {\r\n            if (Type.exists(this.label)) {\r\n                str = str.replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\r\n                this.label.setText(str);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Updates the element's label text and the element's attribute \"name\", strips all html.\r\n         * @param {String} str\r\n         */\r\n        setName: function (str) {\r\n            str = str.replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\r\n            if (this.elType !== 'slider') {\r\n                this.setLabelText(str);\r\n            }\r\n            this.setAttribute({ name: str });\r\n        },\r\n\r\n        /**\r\n         * Deprecated alias for {@link JXG.GeometryElement#setAttribute}.\r\n         * @deprecated Use {@link JXG.GeometryElement#setAttribute}.\r\n         */\r\n        setProperty: function () {\r\n            JXG.deprecated(\"setProperty()\", \"setAttribute()\");\r\n            this.setAttribute.apply(this, arguments);\r\n        },\r\n\r\n        /**\r\n         * Sets an arbitrary number of attributes. This method has one or more\r\n         * parameters of the following types:\r\n         * <ul>\r\n         * <li> object: {key1:value1,key2:value2,...}\r\n         * <li> string: 'key:value'\r\n         * <li> array: ['key', value]\r\n         * </ul>\r\n         * @param {Object} attributes An object with attributes.\r\n         * @returns {JXG.GeometryElement} A reference to the element.\r\n         *\r\n         * @function\r\n         * @example\r\n         * // Set attribute directly on creation of an element using the attributes object parameter\r\n         * var board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-1, 5, 5, 1]};\r\n         * var p = board.create('point', [2, 2], {visible: false});\r\n         *\r\n         * // Now make this point visible and fixed:\r\n         * p.setAttribute({\r\n         *     fixed: true,\r\n         *     visible: true\r\n         * });\r\n         */\r\n        setAttribute: function (attr) {\r\n            var i, j, le, key, value, arg,\r\n                opacity, pair, oldvalue,\r\n                attributes = {};\r\n\r\n            // Normalize the user input\r\n            for (i = 0; i < arguments.length; i++) {\r\n                arg = arguments[i];\r\n                if (Type.isString(arg)) {\r\n                    // pairRaw is string of the form 'key:value'\r\n                    pair = arg.split(\":\");\r\n                    attributes[Type.trim(pair[0])] = Type.trim(pair[1]);\r\n                } else if (!Type.isArray(arg)) {\r\n                    // pairRaw consists of objects of the form {key1:value1,key2:value2,...}\r\n                    JXG.extend(attributes, arg);\r\n                } else {\r\n                    // pairRaw consists of array [key,value]\r\n                    attributes[arg[0]] = arg[1];\r\n                }\r\n            }\r\n\r\n            // Handle shortcuts\r\n            attributes = this.resolveShortcuts(attributes);\r\n\r\n            for (i in attributes) {\r\n                if (attributes.hasOwnProperty(i)) {\r\n                    key = i.replace(/\\s+/g, \"\").toLowerCase();\r\n                    value = attributes[i];\r\n\r\n                    // This handles the subobjects, if the key:value pairs are contained in an object.\r\n                    // Example:\r\n                    // ticks.setAttribute({\r\n                    //      strokeColor: 'blue',\r\n                    //      label: {\r\n                    //          visible: false\r\n                    //      }\r\n                    // })\r\n                    // Now, only the supplied label attributes are overwritten.\r\n                    // Otherwise, the value of label would be {visible:false} only.\r\n                    if (Type.isObject(value) && Type.exists(this.visProp[key])) {\r\n                        // this.visProp[key] = Type.merge(this.visProp[key], value);\r\n                        if (!Type.isObject(this.visProp[key]) && value !== null && Type.isObject(value)) {\r\n                            // Handle cases like key=firstarrow and\r\n                            // firstarrow==false and value = { type:1 }.\r\n                            // That is a primitive type is replaced by an object.\r\n                            this.visProp[key] = {};\r\n                        }\r\n                        Type.mergeAttr(this.visProp[key], value);\r\n\r\n                        // First, handle the special case\r\n                        // ticks.setAttribute({label: {anchorX: \"right\", ..., visible: true});\r\n                        if (this.type === Const.OBJECT_TYPE_TICKS && Type.exists(this.labels)) {\r\n                            le = this.labels.length;\r\n                            for (j = 0; j < le; j++) {\r\n                                this.labels[j].setAttribute(value);\r\n                            }\r\n                        } else if (Type.exists(this[key])) {\r\n                            // Attribute looks like: point1: {...}\r\n                            // Handle this in the sub-element: this.point1.setAttribute({...})\r\n                            if (Type.isArray(this[key])) {\r\n                                for (j = 0; j < this[key].length; j++) {\r\n                                    this[key][j].setAttribute(value);\r\n                                }\r\n                            } else {\r\n                                this[key].setAttribute(value);\r\n                            }\r\n                        } else {\r\n                            // Cases like firstarrow: {...}\r\n                            oldvalue = null;\r\n                            this.triggerEventHandlers([\"attribute:\" + key], [oldvalue, value, this]);\r\n                        }\r\n                        continue;\r\n                    }\r\n\r\n                    oldvalue = this.visProp[key];\r\n                    switch (key) {\r\n                        case \"checked\":\r\n                            // checkbox Is not available on initial call.\r\n                            if (Type.exists(this.rendNodeTag)) {\r\n                                this.rendNodeCheckbox.checked = !!value;\r\n                            }\r\n                            break;\r\n                        case \"disabled\":\r\n                            // button, checkbox, input. Is not available on initial call.\r\n                            if (Type.exists(this.rendNodeTag)) {\r\n                                this.rendNodeTag.disabled = !!value;\r\n                            }\r\n                            break;\r\n                        case \"face\":\r\n                            if (Type.isPoint(this)) {\r\n                                this.visProp.face = value;\r\n                                this.board.renderer.changePointStyle(this);\r\n                            }\r\n                            break;\r\n                        case \"generatelabelvalue\":\r\n                            if (\r\n                                this.type === Const.OBJECT_TYPE_TICKS &&\r\n                                Type.isFunction(value)\r\n                            ) {\r\n                                this.generateLabelValue = value;\r\n                            }\r\n                            break;\r\n                        case \"gradient\":\r\n                            this.visProp.gradient = value;\r\n                            this.board.renderer.setGradient(this);\r\n                            break;\r\n                        case \"gradientsecondcolor\":\r\n                            value = Color.rgba2rgbo(value);\r\n                            this.visProp.gradientsecondcolor = value[0];\r\n                            this.visProp.gradientsecondopacity = value[1];\r\n                            this.board.renderer.updateGradient(this);\r\n                            break;\r\n                        case \"gradientsecondopacity\":\r\n                            this.visProp.gradientsecondopacity = value;\r\n                            this.board.renderer.updateGradient(this);\r\n                            break;\r\n                        case \"infoboxtext\":\r\n                            if (Type.isString(value)) {\r\n                                this.infoboxText = value;\r\n                            } else {\r\n                                this.infoboxText = false;\r\n                            }\r\n                            break;\r\n                        case \"labelcolor\":\r\n                            value = Color.rgba2rgbo(value);\r\n                            opacity = value[1];\r\n                            value = value[0];\r\n                            if (opacity === 0) {\r\n                                if (Type.exists(this.label) && this.hasLabel) {\r\n                                    this.label.hideElement();\r\n                                }\r\n                            }\r\n                            if (Type.exists(this.label) && this.hasLabel) {\r\n                                this.label.visProp.strokecolor = value;\r\n                                this.board.renderer.setObjectStrokeColor(\r\n                                    this.label,\r\n                                    value,\r\n                                    opacity\r\n                                );\r\n                            }\r\n                            if (this.elementClass === Const.OBJECT_CLASS_TEXT) {\r\n                                this.visProp.strokecolor = value;\r\n                                this.visProp.strokeopacity = opacity;\r\n                                this.board.renderer.setObjectStrokeColor(this, value, opacity);\r\n                            }\r\n                            break;\r\n                        case \"layer\":\r\n                            this.board.renderer.setLayer(this, this.eval(value));\r\n                            this._set(key, value);\r\n                            break;\r\n                        case \"maxlength\":\r\n                            // input. Is not available on initial call.\r\n                            if (Type.exists(this.rendNodeTag)) {\r\n                                this.rendNodeTag.maxlength = !!value;\r\n                            }\r\n                            break;\r\n                        case \"name\":\r\n                            oldvalue = this.name;\r\n                            delete this.board.elementsByName[this.name];\r\n                            this.name = value;\r\n                            this.board.elementsByName[this.name] = this;\r\n                            break;\r\n                        case \"needsregularupdate\":\r\n                            this.needsRegularUpdate = !(value === \"false\" || value === false);\r\n                            this.board.renderer.setBuffering(\r\n                                this,\r\n                                this.needsRegularUpdate ? \"auto\" : \"static\"\r\n                            );\r\n                            break;\r\n                        case \"onpolygon\":\r\n                            if (this.type === Const.OBJECT_TYPE_GLIDER) {\r\n                                this.onPolygon = !!value;\r\n                            }\r\n                            break;\r\n                        case \"radius\":\r\n                            if (\r\n                                this.type === Const.OBJECT_TYPE_ANGLE ||\r\n                                this.type === Const.OBJECT_TYPE_SECTOR\r\n                            ) {\r\n                                this.setRadius(value);\r\n                            }\r\n                            break;\r\n                        case \"rotate\":\r\n                            if (\r\n                                (this.elementClass === Const.OBJECT_CLASS_TEXT &&\r\n                                    this.evalVisProp('display') === 'internal') ||\r\n                                this.type === Const.OBJECT_TYPE_IMAGE\r\n                            ) {\r\n                                this.addRotation(value);\r\n                            }\r\n                            break;\r\n                        case \"tabindex\":\r\n                            if (Type.exists(this.rendNode)) {\r\n                                this.rendNode.setAttribute(\"tabindex\", value);\r\n                                this._set(key, value);\r\n                            }\r\n                            break;\r\n                        // case \"ticksdistance\":\r\n                        //     if (this.type === Const.OBJECT_TYPE_TICKS && Type.isNumber(value)) {\r\n                        //         this.ticksFunction = this.makeTicksFunction(value);\r\n                        //     }\r\n                        //     break;\r\n                        case \"trace\":\r\n                            if (value === \"false\" || value === false) {\r\n                                this.clearTrace();\r\n                                this.visProp.trace = false;\r\n                            } else if (value === 'pause') {\r\n                                this.visProp.trace = false;\r\n                            } else {\r\n                                this.visProp.trace = true;\r\n                            }\r\n                            break;\r\n                        case \"visible\":\r\n                            if (value === 'false') {\r\n                                this.visProp.visible = false;\r\n                            } else if (value === 'true') {\r\n                                this.visProp.visible = true;\r\n                            } else {\r\n                                this.visProp.visible = value;\r\n                            }\r\n\r\n                            this.setDisplayRendNode(this.evalVisProp('visible'));\r\n                            if (\r\n                                this.evalVisProp('visible') &&\r\n                                Type.exists(this.updateSize)\r\n                            ) {\r\n                                this.updateSize();\r\n                            }\r\n\r\n                            break;\r\n                        case \"withlabel\":\r\n                            this.visProp.withlabel = value;\r\n                            if (!this.evalVisProp('withlabel')) {\r\n                                if (this.label && this.hasLabel) {\r\n                                    //this.label.hideElement();\r\n                                    this.label.setAttribute({ visible: false });\r\n                                }\r\n                            } else {\r\n                                if (!this.label) {\r\n                                    this.createLabel();\r\n                                }\r\n                                //this.label.showElement();\r\n                                this.label.setAttribute({ visible: 'inherit' });\r\n                                //this.label.setDisplayRendNode(this.evalVisProp('visible'));\r\n                            }\r\n                            this.hasLabel = value;\r\n                            break;\r\n                        case \"straightfirst\":\r\n                        case \"straightlast\":\r\n                            this._set(key, value);\r\n                            for (j in this.childElements) {\r\n                                if (this.childElements.hasOwnProperty(j) && this.childElements[j].elType === 'glider') {\r\n                                    this.childElements[j].fullUpdate();\r\n                                }\r\n                            }\r\n                            break;\r\n                        default:\r\n                            if (Type.exists(this.visProp[key]) &&\r\n                                (!JXG.Validator[key] ||                                   // No validator for this key => OK\r\n                                    (JXG.Validator[key] && JXG.Validator[key](value)) ||  // Value passes the validator => OK\r\n                                    (JXG.Validator[key] &&                                // Value is function, function value passes the validator => OK\r\n                                        Type.isFunction(value) && JXG.Validator[key](value(this))\r\n                                    )\r\n                                )\r\n                            ) {\r\n                                value = (value.toLowerCase && value.toLowerCase() === 'false')\r\n                                            ? false\r\n                                            : value;\r\n                                this._set(key, value);\r\n                            } else {\r\n                                if (!(key in Options.shortcuts)) {\r\n                                    JXG.warn(\"attribute '\" + key + \"' does not accept type '\" + (typeof value) + \"' of value \" + value + '.');\r\n                                }\r\n                            }\r\n                            break;\r\n                    }\r\n                    this.triggerEventHandlers([\"attribute:\" + key], [oldvalue, value, this]);\r\n                }\r\n            }\r\n\r\n            this.triggerEventHandlers([\"attribute\"], [attributes, this]);\r\n\r\n            if (!this.evalVisProp('needsregularupdate')) {\r\n                this.board.fullUpdate();\r\n            } else {\r\n                this.board.update(this);\r\n            }\r\n            if (this.elementClass === Const.OBJECT_CLASS_TEXT) {\r\n                this.updateSize();\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Deprecated alias for {@link JXG.GeometryElement#getAttribute}.\r\n         * @deprecated Use {@link JXG.GeometryElement#getAttribute}.\r\n         */\r\n        getProperty: function () {\r\n            JXG.deprecated(\"getProperty()\", \"getAttribute()\");\r\n            this.getProperty.apply(this, arguments);\r\n        },\r\n\r\n        /**\r\n         * Get the value of the property <tt>key</tt>.\r\n         * @param {String} key The name of the property you are looking for\r\n         * @returns The value of the property\r\n         */\r\n        getAttribute: function (key) {\r\n            var result;\r\n            key = key.toLowerCase();\r\n\r\n            switch (key) {\r\n                case \"needsregularupdate\":\r\n                    result = this.needsRegularUpdate;\r\n                    break;\r\n                case \"labelcolor\":\r\n                    result = this.label.visProp.strokecolor;\r\n                    break;\r\n                case \"infoboxtext\":\r\n                    result = this.infoboxText;\r\n                    break;\r\n                case \"withlabel\":\r\n                    result = this.hasLabel;\r\n                    break;\r\n                default:\r\n                    result = this.visProp[key];\r\n                    break;\r\n            }\r\n\r\n            return result;\r\n        },\r\n\r\n        /**\r\n         * Get value of an attribute. If the value that attribute is a function, call the function and return its value.\r\n         * In that case, the function is called with the GeometryElement as (only) parameter. For label elements (i.e.\r\n         * if the attribute \"islabel\" is true), the anchor element is supplied. The label element can be accessed as\r\n         * sub-object \"label\".\r\n         * If the attribute does not exist, undefined will be returned.\r\n         *\r\n         * @param {String} key Attribute key\r\n         * @returns {String|Number|Boolean} value of attribute \"key\" (evaluated in case of a function) or undefined\r\n         *\r\n         * @see GeometryElement#eval\r\n         * @see JXG#evaluate\r\n         */\r\n        evalVisProp: function (key) {\r\n            var val, arr, i, le,\r\n                e, o, found;\r\n\r\n            key = key.toLowerCase();\r\n            if (key.indexOf('.') === -1) {\r\n                // e.g. 'visible'\r\n                val = this.visProp[key];\r\n            } else {\r\n                // e.g. label.visible\r\n                arr = key.split('.');\r\n                le = arr.length;\r\n                val = this.visProp;\r\n                for (i = 0; i < le; i++) {\r\n                    if (Type.exists(val)) {\r\n                        val = val[arr[i]];\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (JXG.isFunction(val)) {\r\n                // For labels supply the anchor element as parameter.\r\n                if (this.visProp.islabel === true && Type.exists(this.visProp.anchor)) {\r\n                    // 3D: supply the 3D element\r\n                    if (this.visProp.anchor.visProp.element3d !== null) {\r\n                        return val(this.visProp.anchor.visProp.element3d);\r\n                    }\r\n                    // 2D: supply the 2D element\r\n                    return val(this.visProp.anchor);\r\n                }\r\n                // For 2D elements representing 3D elements, return the 3D element.\r\n                if (JXG.exists(this.visProp.element3d)) {\r\n                    return val(this.visProp.element3d);\r\n                }\r\n                // In all other cases, return the element itself\r\n                return val(this);\r\n            }\r\n            // val is not of type function\r\n\r\n            if (val === 'inherit') {\r\n                for (e in this.descendants) {\r\n                    if (this.descendants.hasOwnProperty(e)) {\r\n                        o = this.descendants[e];\r\n                        // Check if this is in inherits of one of its descendant\r\n                        found = false;\r\n                        le = o.inherits.length;\r\n                        for (i = 0; i < le; i++) {\r\n                            if (this.id === o.inherits[i].id) {\r\n                                found = true;\r\n                                break;\r\n                            }\r\n                        }\r\n                        if (found) {\r\n                            val = o.evalVisProp(key);\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            return val;\r\n        },\r\n\r\n        /**\r\n         * Get value of a parameter. If the parameter is a function, call the function and return its value.\r\n         * In that case, the function is called with the GeometryElement as (only) parameter. For label elements (i.e.\r\n         * if the attribute \"islabel\" is true), the anchor element is supplied. The label of an element can be accessed as\r\n         * sub-object \"label\" then.\r\n         *\r\n         * @param {String|Number|Function|Object} val If not a function, it will be returned as is. If function it will be evaluated, where the GeometryElement is\r\n         * supplied as the (only) parameter of that function.\r\n         * @returns {String|Number|Object}\r\n         *\r\n         * @see GeometryElement#evalVisProp\r\n         * @see JXG#evaluate\r\n         */\r\n        eval: function(val) {\r\n            if (JXG.isFunction(val)) {\r\n                // For labels supply the anchor element as parameter.\r\n                if (this.visProp.islabel === true && Type.exists(this.visProp.anchor)) {\r\n                    // 3D: supply the 3D element\r\n                    if (this.visProp.anchor.visProp.element3d !== null) {\r\n                        return val(this.visProp.anchor.visProp.element3d);\r\n                    }\r\n                    // 2D: supply the 2D element\r\n                    return val(this.visProp.anchor);\r\n                }\r\n                // For 2D elements representing 3D elements, return the 3D element.\r\n                if (this.visProp.element3d !== null) {\r\n                    return val(this.visProp.element3d);\r\n                }\r\n                // In all other cases, return the element itself\r\n                return val(this);\r\n            }\r\n            // val is not of type function\r\n            return val;\r\n        },\r\n\r\n        /**\r\n         * Set the dash style of an object. See {@link JXG.GeometryElement#dash}\r\n         * for a list of available dash styles.\r\n         * You should use {@link JXG.GeometryElement#setAttribute} instead of this method.\r\n         *\r\n         * @param {number} dash Indicates the new dash style\r\n         * @private\r\n         */\r\n        setDash: function (dash) {\r\n            this.setAttribute({ dash: dash });\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Notify all child elements for updates.\r\n         * @private\r\n         */\r\n        prepareUpdate: function () {\r\n            this.needsUpdate = true;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Removes the element from the construction.  This only removes the SVG or VML node of the element and its label (if available) from\r\n         * the renderer, to remove the element completely you should use {@link JXG.Board#removeObject}.\r\n         */\r\n        remove: function () {\r\n            // this.board.renderer.remove(this.board.renderer.getElementById(this.id));\r\n            this.board.renderer.remove(this.rendNode);\r\n\r\n            if (this.hasLabel) {\r\n                this.board.renderer.remove(this.board.renderer.getElementById(this.label.id));\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Returns the coords object where a text that is bound to the element shall be drawn.\r\n         * Differs in some cases from the values that getLabelAnchor returns.\r\n         * @returns {JXG.Coords} JXG.Coords Place where the text shall be drawn.\r\n         * @see JXG.GeometryElement#getLabelAnchor\r\n         */\r\n        getTextAnchor: function () {\r\n            return new Coords(Const.COORDS_BY_USER, [0, 0], this.board);\r\n        },\r\n\r\n        /**\r\n         * Returns the coords object where the label of the element shall be drawn.\r\n         * Differs in some cases from the values that getTextAnchor returns.\r\n         * @returns {JXG.Coords} JXG.Coords Place where the text shall be drawn.\r\n         * @see JXG.GeometryElement#getTextAnchor\r\n         */\r\n        getLabelAnchor: function () {\r\n            return new Coords(Const.COORDS_BY_USER, [0, 0], this.board);\r\n        },\r\n\r\n        /**\r\n         * Determines whether the element has arrows at start or end of the arc.\r\n         * If it is set to be a \"typical\" vector, ie lastArrow == true,\r\n         * then the element.type is set to VECTOR.\r\n         * @param {Boolean} firstArrow True if there is an arrow at the start of the arc, false otherwise.\r\n         * @param {Boolean} lastArrow True if there is an arrow at the end of the arc, false otherwise.\r\n         */\r\n        setArrow: function (firstArrow, lastArrow) {\r\n            this.visProp.firstarrow = firstArrow;\r\n            this.visProp.lastarrow = lastArrow;\r\n            if (lastArrow) {\r\n                this.type = Const.OBJECT_TYPE_VECTOR;\r\n                this.elType = 'arrow';\r\n            }\r\n\r\n            this.prepareUpdate().update().updateVisibility().updateRenderer();\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Creates a gradient nodes in the renderer.\r\n         * @see JXG.SVGRenderer#setGradient\r\n         * @private\r\n         */\r\n        createGradient: function () {\r\n            var ev_g = this.evalVisProp('gradient');\r\n            if (ev_g === \"linear\" || ev_g === 'radial') {\r\n                this.board.renderer.setGradient(this);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Creates a label element for this geometry element.\r\n         * @see JXG.GeometryElement#addLabelToElement\r\n         */\r\n        createLabel: function () {\r\n            var attr,\r\n                that = this;\r\n\r\n            // this is a dirty hack to resolve the text-dependency. If there is no text element available,\r\n            // just don't create a label. This method is usually not called by a user, so we won't throw\r\n            // an exception here and simply output a warning via JXG.debug.\r\n            if (JXG.elements.text) {\r\n                attr = Type.deepCopy(this.visProp.label, null);\r\n                attr.id = this.id + 'Label';\r\n                attr.isLabel = true;\r\n                attr.anchor = this;\r\n                attr.priv = this.visProp.priv;\r\n\r\n                if (this.visProp.withlabel) {\r\n                    this.label = JXG.elements.text(\r\n                        this.board,\r\n                        [\r\n                            0,\r\n                            0,\r\n                            function () {\r\n                                if (Type.isFunction(that.name)) {\r\n                                    return that.name(that);\r\n                                }\r\n                                return that.name;\r\n                            }\r\n                        ],\r\n                        attr\r\n                    );\r\n                    this.label.needsUpdate = true;\r\n                    this.label.dump = false;\r\n                    this.label.fullUpdate();\r\n\r\n                    this.hasLabel = true;\r\n                }\r\n            } else {\r\n                JXG.debug(\r\n                    \"JSXGraph: Can't create label: text element is not available. Make sure you include base/text\"\r\n                );\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Highlights the element.\r\n         * @private\r\n         * @param {Boolean} [force=false] Force the highlighting\r\n         * @returns {JXG.Board}\r\n         */\r\n        highlight: function (force) {\r\n            force = Type.def(force, false);\r\n            // I know, we have the JXG.Board.highlightedObjects AND JXG.GeometryElement.highlighted and YES we need both.\r\n            // Board.highlightedObjects is for the internal highlighting and GeometryElement.highlighted is for user highlighting\r\n            // initiated by the user, e.g. through custom DOM events. We can't just pick one because this would break user\r\n            // defined highlighting in many ways:\r\n            //  * if overriding the highlight() methods the user had to handle the highlightedObjects stuff, otherwise he'd break\r\n            //    everything (e.g. the pie chart example https://jsxgraph.org/wiki/index.php/Pie_chart (not exactly\r\n            //    user defined but for this type of chart the highlight method was overridden and not adjusted to the changes in here)\r\n            //    where it just kept highlighting until the radius of the pie was far beyond infinity...\r\n            //  * user defined highlighting would get pointless, everytime the user highlights something using .highlight(), it would get\r\n            //    dehighlighted immediately, because highlight puts the element into highlightedObjects and from there it gets dehighlighted\r\n            //    through dehighlightAll.\r\n\r\n            // highlight only if not highlighted\r\n            if (this.evalVisProp('highlight') && (!this.highlighted || force)) {\r\n                this.highlighted = true;\r\n                this.board.highlightedObjects[this.id] = this;\r\n                this.board.renderer.highlight(this);\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Uses the \"normal\" properties of the element.\r\n         * @returns {JXG.Board}\r\n         */\r\n        noHighlight: function () {\r\n            // see comment in JXG.GeometryElement.highlight()\r\n\r\n            // dehighlight only if not highlighted\r\n            if (this.highlighted) {\r\n                this.highlighted = false;\r\n                delete this.board.highlightedObjects[this.id];\r\n                this.board.renderer.noHighlight(this);\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Removes all objects generated by the trace function.\r\n         */\r\n        clearTrace: function () {\r\n            var obj;\r\n\r\n            for (obj in this.traces) {\r\n                if (this.traces.hasOwnProperty(obj)) {\r\n                    this.board.renderer.remove(this.traces[obj]);\r\n                }\r\n            }\r\n\r\n            this.numTraces = 0;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Copy the element to background. This is used for tracing elements.\r\n         * @returns {JXG.GeometryElement} A reference to the element\r\n         */\r\n        cloneToBackground: function () {\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Dimensions of the smallest rectangle enclosing the element.\r\n         * @returns {Array} The coordinates of the enclosing rectangle in a format\r\n         * like the bounding box in {@link JXG.Board#setBoundingBox}.\r\n         *\r\n         * @returns {Array} similar to {@link JXG.Board#setBoundingBox}.\r\n         */\r\n        bounds: function () {\r\n            return [0, 0, 0, 0];\r\n        },\r\n\r\n        /**\r\n         * Normalize the element's standard form.\r\n         * @private\r\n         */\r\n        normalize: function () {\r\n            this.stdform = Mat.normalize(this.stdform);\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * EXPERIMENTAL. Generate JSON object code of visProp and other properties.\r\n         * @type String\r\n         * @private\r\n         * @ignore\r\n         * @deprecated\r\n         * @returns JSON string containing element's properties.\r\n         */\r\n        toJSON: function () {\r\n            var vis,\r\n                key,\r\n                json = ['{\"name\":', this.name];\r\n\r\n            json.push(\", \" + '\"id\":' + this.id);\r\n\r\n            vis = [];\r\n            for (key in this.visProp) {\r\n                if (this.visProp.hasOwnProperty(key)) {\r\n                    if (Type.exists(this.visProp[key])) {\r\n                        vis.push('\"' + key + '\":' + this.visProp[key]);\r\n                    }\r\n                }\r\n            }\r\n            json.push(', \"visProp\":{' + vis.toString() + \"}\");\r\n            json.push(\"}\");\r\n\r\n            return json.join(\"\");\r\n        },\r\n\r\n        /**\r\n         * Rotate texts or images by a given degree.\r\n         * @param {number} angle The degree of the rotation (90 means vertical text).\r\n         * @see JXG.GeometryElement#rotate\r\n         */\r\n        addRotation: function (angle) {\r\n            var tOffInv,\r\n                tOff,\r\n                tS,\r\n                tSInv,\r\n                tRot,\r\n                that = this;\r\n\r\n            if (\r\n                (this.elementClass === Const.OBJECT_CLASS_TEXT ||\r\n                    this.type === Const.OBJECT_TYPE_IMAGE) &&\r\n                angle !== 0\r\n            ) {\r\n                tOffInv = this.board.create(\r\n                    \"transform\",\r\n                    [\r\n                        function () {\r\n                            return -that.X();\r\n                        },\r\n                        function () {\r\n                            return -that.Y();\r\n                        }\r\n                    ],\r\n                    { type: \"translate\" }\r\n                );\r\n\r\n                tOff = this.board.create(\r\n                    \"transform\",\r\n                    [\r\n                        function () {\r\n                            return that.X();\r\n                        },\r\n                        function () {\r\n                            return that.Y();\r\n                        }\r\n                    ],\r\n                    { type: \"translate\" }\r\n                );\r\n\r\n                tS = this.board.create(\r\n                    \"transform\",\r\n                    [\r\n                        function () {\r\n                            return that.board.unitX / that.board.unitY;\r\n                        },\r\n                        function () {\r\n                            return 1;\r\n                        }\r\n                    ],\r\n                    { type: \"scale\" }\r\n                );\r\n\r\n                tSInv = this.board.create(\r\n                    \"transform\",\r\n                    [\r\n                        function () {\r\n                            return that.board.unitY / that.board.unitX;\r\n                        },\r\n                        function () {\r\n                            return 1;\r\n                        }\r\n                    ],\r\n                    { type: \"scale\" }\r\n                );\r\n\r\n                tRot = this.board.create(\r\n                    \"transform\",\r\n                    [\r\n                        function () {\r\n                            return (that.eval(angle) * Math.PI) / 180;\r\n                        }\r\n                    ],\r\n                    { type: \"rotate\" }\r\n                );\r\n\r\n                tOffInv.bindTo(this);\r\n                tS.bindTo(this);\r\n                tRot.bindTo(this);\r\n                tSInv.bindTo(this);\r\n                tOff.bindTo(this);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the highlightStrokeColor of an element\r\n         * @ignore\r\n         * @name JXG.GeometryElement#highlightStrokeColorMethod\r\n         * @param {String} sColor String which determines the stroke color of an object when its highlighted.\r\n         * @see JXG.GeometryElement#highlightStrokeColor\r\n         * @deprecated Use {@link JXG.GeometryElement#setAttribute}\r\n         */\r\n        highlightStrokeColor: function (sColor) {\r\n            JXG.deprecated(\"highlightStrokeColor()\", \"setAttribute()\");\r\n            this.setAttribute({ highlightStrokeColor: sColor });\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the strokeColor of an element\r\n         * @ignore\r\n         * @name JXG.GeometryElement#strokeColorMethod\r\n         * @param {String} sColor String which determines the stroke color of an object.\r\n         * @see JXG.GeometryElement#strokeColor\r\n         * @deprecated Use {@link JXG.GeometryElement#setAttribute}\r\n         */\r\n        strokeColor: function (sColor) {\r\n            JXG.deprecated(\"strokeColor()\", \"setAttribute()\");\r\n            this.setAttribute({ strokeColor: sColor });\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the strokeWidth of an element\r\n         * @ignore\r\n         * @name JXG.GeometryElement#strokeWidthMethod\r\n         * @param {Number} width Integer which determines the stroke width of an outline.\r\n         * @see JXG.GeometryElement#strokeWidth\r\n         * @deprecated Use {@link JXG.GeometryElement#setAttribute}\r\n         */\r\n        strokeWidth: function (width) {\r\n            JXG.deprecated(\"strokeWidth()\", \"setAttribute()\");\r\n            this.setAttribute({ strokeWidth: width });\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the fillColor of an element\r\n         * @ignore\r\n         * @name JXG.GeometryElement#fillColorMethod\r\n         * @param {String} fColor String which determines the fill color of an object.\r\n         * @see JXG.GeometryElement#fillColor\r\n         * @deprecated Use {@link JXG.GeometryElement#setAttribute}\r\n         */\r\n        fillColor: function (fColor) {\r\n            JXG.deprecated(\"fillColor()\", \"setAttribute()\");\r\n            this.setAttribute({ fillColor: fColor });\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the highlightFillColor of an element\r\n         * @ignore\r\n         * @name JXG.GeometryElement#highlightFillColorMethod\r\n         * @param {String} fColor String which determines the fill color of an object when its highlighted.\r\n         * @see JXG.GeometryElement#highlightFillColor\r\n         * @deprecated Use {@link JXG.GeometryElement#setAttribute}\r\n         */\r\n        highlightFillColor: function (fColor) {\r\n            JXG.deprecated(\"highlightFillColor()\", \"setAttribute()\");\r\n            this.setAttribute({ highlightFillColor: fColor });\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the labelColor of an element\r\n         * @ignore\r\n         * @param {String} lColor String which determines the text color of an object's label.\r\n         * @see JXG.GeometryElement#labelColor\r\n         * @deprecated Use {@link JXG.GeometryElement#setAttribute}\r\n         */\r\n        labelColor: function (lColor) {\r\n            JXG.deprecated(\"labelColor()\", \"setAttribute()\");\r\n            this.setAttribute({ labelColor: lColor });\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the dash type of an element\r\n         * @ignore\r\n         * @name JXG.GeometryElement#dashMethod\r\n         * @param {Number} d Integer which determines the way of dashing an element's outline.\r\n         * @see JXG.GeometryElement#dash\r\n         * @deprecated Use {@link JXG.GeometryElement#setAttribute}\r\n         */\r\n        dash: function (d) {\r\n            JXG.deprecated(\"dash()\", \"setAttribute()\");\r\n            this.setAttribute({ dash: d });\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the visibility of an element\r\n         * @ignore\r\n         * @name JXG.GeometryElement#visibleMethod\r\n         * @param {Boolean} v Boolean which determines whether the element is drawn.\r\n         * @see JXG.GeometryElement#visible\r\n         * @deprecated Use {@link JXG.GeometryElement#setAttribute}\r\n         */\r\n        visible: function (v) {\r\n            JXG.deprecated(\"visible()\", \"setAttribute()\");\r\n            this.setAttribute({ visible: v });\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the shadow of an element\r\n         * @ignore\r\n         * @name JXG.GeometryElement#shadowMethod\r\n         * @param {Boolean} s Boolean which determines whether the element has a shadow or not.\r\n         * @see JXG.GeometryElement#shadow\r\n         * @deprecated Use {@link JXG.GeometryElement#setAttribute}\r\n         */\r\n        shadow: function (s) {\r\n            JXG.deprecated(\"shadow()\", \"setAttribute()\");\r\n            this.setAttribute({ shadow: s });\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * The type of the element as used in {@link JXG.Board#create}.\r\n         * @returns {String}\r\n         */\r\n        getType: function () {\r\n            return this.elType;\r\n        },\r\n\r\n        /**\r\n         * List of the element ids resp. values used as parents in {@link JXG.Board#create}.\r\n         * @returns {Array}\r\n         */\r\n        getParents: function () {\r\n            return Type.isArray(this.parents) ? this.parents : [];\r\n        },\r\n\r\n        /**\r\n         * @ignore\r\n         * Snaps the element to the grid. Only works for points, lines and circles. Points will snap to the grid\r\n         * as defined in their properties {@link JXG.Point#snapSizeX} and {@link JXG.Point#snapSizeY}. Lines and circles\r\n         * will snap their parent points to the grid, if they have {@link JXG.Point#snapToGrid} set to true.\r\n         * @private\r\n         * @returns {JXG.GeometryElement} Reference to the element.\r\n         */\r\n        snapToGrid: function () {\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Snaps the element to points. Only works for points. Points will snap to the next point\r\n         * as defined in their properties {@link JXG.Point#attractorDistance} and {@link JXG.Point#attractorUnit}.\r\n         * Lines and circles\r\n         * will snap their parent points to points.\r\n         * @private\r\n         * @returns {JXG.GeometryElement} Reference to the element.\r\n         */\r\n        snapToPoints: function () {\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Retrieve a copy of the current visProp.\r\n         * @returns {Object}\r\n         */\r\n        getAttributes: function () {\r\n            var attributes = Type.deepCopy(this.visProp),\r\n                /*\r\n                cleanThis = ['attractors', 'snatchdistance', 'traceattributes', 'frozen',\r\n                    'shadow', 'gradientangle', 'gradientsecondopacity', 'gradientpositionx', 'gradientpositiony',\r\n                    'needsregularupdate', 'zoom', 'layer', 'offset'],\r\n                */\r\n                cleanThis = [],\r\n                i,\r\n                len = cleanThis.length;\r\n\r\n            attributes.id = this.id;\r\n            attributes.name = this.name;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                delete attributes[cleanThis[i]];\r\n            }\r\n\r\n            return attributes;\r\n        },\r\n\r\n        /**\r\n         * Checks whether (x,y) is near the element.\r\n         * @param {Number} x Coordinate in x direction, screen coordinates.\r\n         * @param {Number} y Coordinate in y direction, screen coordinates.\r\n         * @returns {Boolean} True if (x,y) is near the element, False otherwise.\r\n         */\r\n        hasPoint: function (x, y) {\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Adds ticks to this line or curve. Ticks can be added to a curve or any kind of line: line, arrow, and axis.\r\n         * @param {JXG.Ticks} ticks Reference to a ticks object which is describing the ticks (color, distance, how many, etc.).\r\n         * @returns {String} Id of the ticks object.\r\n         */\r\n        addTicks: function (ticks) {\r\n            if (ticks.id === \"\" || !Type.exists(ticks.id)) {\r\n                ticks.id = this.id + \"_ticks_\" + (this.ticks.length + 1);\r\n            }\r\n\r\n            this.board.renderer.drawTicks(ticks);\r\n            this.ticks.push(ticks);\r\n\r\n            return ticks.id;\r\n        },\r\n\r\n        /**\r\n         * Removes all ticks from a line or curve.\r\n         */\r\n        removeAllTicks: function () {\r\n            var t;\r\n            if (Type.exists(this.ticks)) {\r\n                for (t = this.ticks.length - 1; t >= 0; t--) {\r\n                    this.removeTicks(this.ticks[t]);\r\n                }\r\n                this.ticks = [];\r\n                this.board.update();\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Removes ticks identified by parameter named tick from this line or curve.\r\n         * @param {JXG.Ticks} tick Reference to tick object to remove.\r\n         */\r\n        removeTicks: function (tick) {\r\n            var t, j;\r\n\r\n            if (Type.exists(this.defaultTicks) && this.defaultTicks === tick) {\r\n                this.defaultTicks = null;\r\n            }\r\n\r\n            if (Type.exists(this.ticks)) {\r\n                for (t = this.ticks.length - 1; t >= 0; t--) {\r\n                    if (this.ticks[t] === tick) {\r\n                        this.board.removeObject(this.ticks[t]);\r\n\r\n                        if (this.ticks[t].ticks) {\r\n                            for (j = 0; j < this.ticks[t].ticks.length; j++) {\r\n                                if (Type.exists(this.ticks[t].labels[j])) {\r\n                                    this.board.removeObject(this.ticks[t].labels[j]);\r\n                                }\r\n                            }\r\n                        }\r\n\r\n                        delete this.ticks[t];\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Determine values of snapSizeX and snapSizeY. If the attributes\r\n         * snapSizex and snapSizeY are greater than zero, these values are taken.\r\n         * Otherwise, determine the distance between major ticks of the\r\n         * default axes.\r\n         * @returns {Array} containing the snap sizes for x and y direction.\r\n         * @private\r\n         */\r\n        getSnapSizes: function () {\r\n            var sX, sY, ticks;\r\n\r\n            sX = this.evalVisProp('snapsizex');\r\n            sY = this.evalVisProp('snapsizey');\r\n\r\n            if (sX <= 0 && this.board.defaultAxes && this.board.defaultAxes.x.defaultTicks) {\r\n                ticks = this.board.defaultAxes.x.defaultTicks;\r\n                sX = ticks.ticksDelta * (ticks.evalVisProp('minorticks') + 1);\r\n            }\r\n\r\n            if (sY <= 0 && this.board.defaultAxes && this.board.defaultAxes.y.defaultTicks) {\r\n                ticks = this.board.defaultAxes.y.defaultTicks;\r\n                sY = ticks.ticksDelta * (ticks.evalVisProp('minorticks') + 1);\r\n            }\r\n\r\n            return [sX, sY];\r\n        },\r\n\r\n        /**\r\n         * Move an element to its nearest grid point.\r\n         * The function uses the coords object of the element as\r\n         * its actual position. If there is no coords object or if the object is fixed, nothing is done.\r\n         * @param {Boolean} force force snapping independent from what the snaptogrid attribute says\r\n         * @param {Boolean} fromParent True if the drag comes from a child element. This is the case if a line\r\n         *    through two points is dragged. In this case we do not try to force the points to stay inside of\r\n         *    the visible board, but the distance between the two points stays constant.\r\n         * @returns {JXG.GeometryElement} Reference to this element\r\n         */\r\n        handleSnapToGrid: function (force, fromParent) {\r\n            var x, y, rx, ry, rcoords,\r\n                mi, ma,\r\n                boardBB, res, sX, sY,\r\n                needsSnapToGrid = false,\r\n                attractToGrid = this.evalVisProp('attracttogrid'),\r\n                ev_au = this.evalVisProp('attractorunit'),\r\n                ev_ad = this.evalVisProp('attractordistance');\r\n\r\n            if (!Type.exists(this.coords) || this.evalVisProp('fixed')) {\r\n                return this;\r\n            }\r\n\r\n            needsSnapToGrid =\r\n                this.evalVisProp('snaptogrid') || attractToGrid || force === true;\r\n\r\n            if (needsSnapToGrid) {\r\n                x = this.coords.usrCoords[1];\r\n                y = this.coords.usrCoords[2];\r\n                res = this.getSnapSizes();\r\n                sX = res[0];\r\n                sY = res[1];\r\n\r\n                // If no valid snap sizes are available, don't change the coords.\r\n                if (sX > 0 && sY > 0) {\r\n                    boardBB = this.board.getBoundingBox();\r\n                    rx = Math.round(x / sX) * sX;\r\n                    ry = Math.round(y / sY) * sY;\r\n\r\n                    rcoords = new JXG.Coords(Const.COORDS_BY_USER, [rx, ry], this.board);\r\n                    if (\r\n                        !attractToGrid ||\r\n                        rcoords.distance(\r\n                            ev_au === \"screen\" ? Const.COORDS_BY_SCREEN : Const.COORDS_BY_USER,\r\n                            this.coords\r\n                        ) < ev_ad\r\n                    ) {\r\n                        x = rx;\r\n                        y = ry;\r\n                        // Checking whether x and y are still within boundingBox.\r\n                        // If not, adjust them to remain within the board.\r\n                        // Otherwise a point may become invisible.\r\n                        if (!fromParent) {\r\n                            mi = Math.min(boardBB[0], boardBB[2]);\r\n                            ma = Math.max(boardBB[0], boardBB[2]);\r\n                            if (x < mi && x > mi - sX) {\r\n                                x += sX;\r\n                            } else if (x > ma && x < ma + sX) {\r\n                                x -= sX;\r\n                            }\r\n\r\n                            mi = Math.min(boardBB[1], boardBB[3]);\r\n                            ma = Math.max(boardBB[1], boardBB[3]);\r\n                            if (y < mi && y > mi - sY) {\r\n                                y += sY;\r\n                            } else if (y > ma && y < ma + sY) {\r\n                                y -= sY;\r\n                            }\r\n                        }\r\n                        this.coords.setCoordinates(Const.COORDS_BY_USER, [x, y]);\r\n                    }\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        getBoundingBox: function () {\r\n            var i, le, v,\r\n                x, y, r,\r\n                bb = [Infinity, Infinity, -Infinity, -Infinity];\r\n\r\n            if (this.type === Const.OBJECT_TYPE_POLYGON) {\r\n                le = this.vertices.length - 1;\r\n                if (le <= 0) {\r\n                    return bb;\r\n                }\r\n                for (i = 0; i < le; i++) {\r\n                    v = this.vertices[i].X();\r\n                    bb[0] = v < bb[0] ? v : bb[0];\r\n                    bb[2] = v > bb[2] ? v : bb[2];\r\n                    v = this.vertices[i].Y();\r\n                    bb[1] = v < bb[1] ? v : bb[1];\r\n                    bb[3] = v > bb[3] ? v : bb[3];\r\n                }\r\n            } else if (this.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n                x = this.center.X();\r\n                y = this.center.Y();\r\n                bb = [x - this.radius, y + this.radius, x + this.radius, y - this.radius];\r\n            } else if (this.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n                le = this.points.length;\r\n                if (le === 0) {\r\n                    return bb;\r\n                }\r\n                for (i = 0; i < le; i++) {\r\n                    v = this.points[i].usrCoords[1];\r\n                    bb[0] = v < bb[0] ? v : bb[0];\r\n                    bb[2] = v > bb[2] ? v : bb[2];\r\n                    v = this.points[i].usrCoords[2];\r\n                    bb[1] = v < bb[1] ? v : bb[1];\r\n                    bb[3] = v > bb[3] ? v : bb[3];\r\n                }\r\n            } else if (this.elementClass === Const.OBJECT_CLASS_POINT) {\r\n                x = this.X();\r\n                y = this.Y();\r\n                r = this.evalVisProp('size');\r\n                bb = [x - r / this.board.unitX, y - r / this.board.unitY, x + r / this.board.unitX, y + r / this.board.unitY];\r\n            } else if (this.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                v = this.point1.coords.usrCoords[1];\r\n                bb[0] = v < bb[0] ? v : bb[0];\r\n                bb[2] = v > bb[2] ? v : bb[2];\r\n                v = this.point1.coords.usrCoords[2];\r\n                bb[1] = v < bb[1] ? v : bb[1];\r\n                bb[3] = v > bb[3] ? v : bb[3];\r\n\r\n                v = this.point2.coords.usrCoords[1];\r\n                bb[0] = v < bb[0] ? v : bb[0];\r\n                bb[2] = v > bb[2] ? v : bb[2];\r\n                v = this.point2.coords.usrCoords[2];\r\n                bb[1] = v < bb[1] ? v : bb[1];\r\n                bb[3] = v > bb[3] ? v : bb[3];\r\n            }\r\n\r\n            return bb;\r\n        },\r\n\r\n        /**\r\n         * Alias of {@link JXG.EventEmitter.on}.\r\n         *\r\n         * @name addEvent\r\n         * @memberof JXG.GeometryElement\r\n         * @function\r\n         */\r\n        addEvent: JXG.shortcut(JXG.GeometryElement.prototype, 'on'),\r\n\r\n        /**\r\n         * Alias of {@link JXG.EventEmitter.off}.\r\n         *\r\n         * @name removeEvent\r\n         * @memberof JXG.GeometryElement\r\n         * @function\r\n         */\r\n        removeEvent: JXG.shortcut(JXG.GeometryElement.prototype, 'off'),\r\n\r\n        /**\r\n         * Format a number according to the locale set in the attribute \"intl\".\r\n         * If in the options of the intl-attribute \"maximumFractionDigits\" is not set,\r\n         * the optional parameter digits is used instead.\r\n         * See <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat\">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat</a>\r\n         * for more  information about internationalization.\r\n         *\r\n         * @param {Number} value Number to be formatted\r\n         * @param {Number} [digits=undefined] Optional number of digits\r\n         * @returns {String|Number} string containing the formatted number according to the locale\r\n         * or the number itself of the formatting is not possible.\r\n         */\r\n        formatNumberLocale: function (value, digits) {\r\n            var loc, opt, key,\r\n                optCalc = {},\r\n                // These options are case sensitive:\r\n                translate = {\r\n                    maximumfractiondigits: 'maximumFractionDigits',\r\n                    minimumfractiondigits: 'minimumFractionDigits',\r\n                    compactdisplay: 'compactDisplay',\r\n                    currencydisplay: 'currencyDisplay',\r\n                    currencysign: 'currencySign',\r\n                    localematcher: 'localeMatcher',\r\n                    numberingsystem: 'numberingSystem',\r\n                    signdisplay: 'signDisplay',\r\n                    unitdisplay: 'unitDisplay',\r\n                    usegrouping: 'useGrouping',\r\n                    roundingmode: 'roundingMode',\r\n                    roundingpriority: 'roundingPriority',\r\n                    roundingincrement: 'roundingIncrement',\r\n                    trailingzerodisplay: 'trailingZeroDisplay',\r\n                    minimumintegerdigits: 'minimumIntegerDigits',\r\n                    minimumsignificantdigits: 'minimumSignificantDigits',\r\n                    maximumsignificantdigits: 'maximumSignificantDigits'\r\n                };\r\n\r\n            if (Type.exists(Intl) &&\r\n                this.useLocale()) {\r\n\r\n                loc = this.evalVisProp('intl.locale') ||\r\n                    this.eval(this.board.attr.intl.locale);\r\n                opt = this.evalVisProp('intl.options') || {};\r\n\r\n                // Transfer back to camel case if necessary and evaluate\r\n                for (key in opt) {\r\n                    if (opt.hasOwnProperty(key)) {\r\n                        if (translate.hasOwnProperty(key)) {\r\n                            optCalc[translate[key]] = this.eval(opt[key]);\r\n                        } else {\r\n                            optCalc[key] = this.eval(opt[key]);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // If maximumfractiondigits is not set,\r\n                // the value of the attribute \"digits\" is taken instead.\r\n                key = 'maximumfractiondigits';\r\n                if (!Type.exists(opt[key])) {\r\n                    optCalc[translate[key]] = digits;\r\n\r\n                    // key = 'minimumfractiondigits';\r\n                    // if (!this.eval(opt[key]) || this.eval(opt[key]) > digits) {\r\n                    //     optCalc[translate[key]] = digits;\r\n                    // }\r\n                }\r\n\r\n                return Intl.NumberFormat(loc, optCalc).format(value);\r\n            }\r\n\r\n            return value;\r\n        },\r\n\r\n        /**\r\n         * Checks if locale is enabled in the attribute. This may be in the attributes of the board,\r\n         * or in the attributes of the text. The latter has higher priority. The board attribute is taken if\r\n         * attribute \"intl.enabled\" of the text element is set to 'inherit'.\r\n         *\r\n         * @returns {Boolean} if locale can be used for number formatting.\r\n         */\r\n        useLocale: function () {\r\n            var val;\r\n\r\n            // Check if element supports intl\r\n            if (!Type.exists(this.visProp.intl) ||\r\n                !Type.exists(this.visProp.intl.enabled)) {\r\n                return false;\r\n            }\r\n\r\n            // Check if intl is supported explicitly enabled for this element\r\n            val = this.evalVisProp('intl.enabled');\r\n\r\n            if (val === true) {\r\n                return true;\r\n            }\r\n\r\n            // Check intl attribute of the board\r\n            if (val === 'inherit') {\r\n                if (this.eval(this.board.attr.intl.enabled) === true) {\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        /* **************************\r\n         *     EVENT DEFINITION\r\n         * for documentation purposes\r\n         * ************************** */\r\n\r\n        //region Event handler documentation\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user is hovering over an element.\r\n         * @name JXG.GeometryElement#over\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__over: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user puts the mouse over an element.\r\n         * @name JXG.GeometryElement#mouseover\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__mouseover: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user is leaving an element.\r\n         * @name JXG.GeometryElement#out\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__out: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user puts the mouse away from an element.\r\n         * @name JXG.GeometryElement#mouseout\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__mouseout: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user is moving over an element.\r\n         * @name JXG.GeometryElement#move\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__move: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user is moving the mouse over an element.\r\n         * @name JXG.GeometryElement#mousemove\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__mousemove: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user drags an element.\r\n         * @name JXG.GeometryElement#drag\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__drag: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user drags the element with a mouse.\r\n         * @name JXG.GeometryElement#mousedrag\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__mousedrag: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user drags the element with a pen.\r\n         * @name JXG.GeometryElement#pendrag\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__pendrag: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user drags the element on a touch device.\r\n         * @name JXG.GeometryElement#touchdrag\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__touchdrag: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user drags the element by pressing arrow keys\r\n         * on the keyboard.\r\n         * @name JXG.GeometryElement#keydrag\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__keydrag: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user starts to touch or click an element.\r\n         * @name JXG.GeometryElement#down\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__down: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user starts to click an element.\r\n         * @name JXG.GeometryElement#mousedown\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__mousedown: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user taps an element with the pen.\r\n         * @name JXG.GeometryElement#pendown\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__pendown: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user starts to touch an element.\r\n         * @name JXG.GeometryElement#touchdown\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__touchdown: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user clicks on an element.\r\n         * @name JXG.Board#click\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__click: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user double clicks on an element.\r\n         * This event works on desktop browser, but is undefined\r\n         * on mobile browsers.\r\n         * @name JXG.Board#dblclick\r\n         * @param {Event} e The browser's event object.\r\n         * @see JXG.Board#clickDelay\r\n         * @see JXG.Board#dblClickSuppressClick\r\n         */\r\n        __evt__dblclick: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user clicks on an element with a mouse device.\r\n         * @name JXG.Board#mouseclick\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__mouseclick: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user double clicks on an element with a mouse device.\r\n         * @name JXG.Board#mousedblclick\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__mousedblclick: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user clicks on an element with a pointer device.\r\n         * @name JXG.Board#pointerclick\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__pointerclick: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user double clicks on an element with a pointer device.\r\n         * This event works on desktop browser, but is undefined\r\n         * on mobile browsers.\r\n         * @name JXG.Board#pointerdblclick\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__pointerdblclick: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user stops to touch or click an element.\r\n         * @name JXG.GeometryElement#up\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__up: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user releases the mousebutton over an element.\r\n         * @name JXG.GeometryElement#mouseup\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__mouseup: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user lifts the pen over an element.\r\n         * @name JXG.GeometryElement#penup\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__penup: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user stops touching an element.\r\n         * @name JXG.GeometryElement#touchup\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__touchup: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Notify every time an attribute is changed.\r\n         * @name JXG.GeometryElement#attribute\r\n         * @param {Object} o A list of changed attributes and their new value.\r\n         * @param {Object} el Reference to the element\r\n         */\r\n        __evt__attribute: function (o, el) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This is a generic event handler. It exists for every possible attribute that can be set for\r\n         * any element, e.g. if you want to be notified everytime an element's strokecolor is changed, is the event\r\n         * <tt>attribute:strokecolor</tt>.\r\n         * @name JXG.GeometryElement#attribute:key\r\n         * @param val The old value.\r\n         * @param nval The new value\r\n         * @param {Object} el Reference to the element\r\n         */\r\n        __evt__attribute_: function (val, nval, el) { },\r\n\r\n        /**\r\n         * @ignore\r\n         */\r\n        __evt: function () { }\r\n        //endregion\r\n    }\r\n);\r\n\r\nexport default JXG.GeometryElement;\r\n// const GeometryElement = JXG.GeometryElement;\r\n// export { GeometryElement as default,  GeometryElement };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n/*eslint no-loss-of-precision: off */\r\n\r\n/**\r\n * @fileoverview In this file the namespace Math.Numerics is defined, which holds numerical\r\n * algorithms for solving linear equations etc.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Env from \"../utils/env.js\";\r\nimport Mat from \"./math.js\";\r\n\r\n// Predefined butcher tableaus for the common Runge-Kutta method (fourth order), Heun method (second order), and Euler method (first order).\r\nvar predefinedButcher = {\r\n    rk4: {\r\n        s: 4,\r\n        A: [\r\n            [0, 0, 0, 0],\r\n            [0.5, 0, 0, 0],\r\n            [0, 0.5, 0, 0],\r\n            [0, 0, 1, 0]\r\n        ],\r\n        b: [1.0 / 6.0, 1.0 / 3.0, 1.0 / 3.0, 1.0 / 6.0],\r\n        c: [0, 0.5, 0.5, 1]\r\n    },\r\n    heun: {\r\n        s: 2,\r\n        A: [\r\n            [0, 0],\r\n            [1, 0]\r\n        ],\r\n        b: [0.5, 0.5],\r\n        c: [0, 1]\r\n    },\r\n    euler: {\r\n        s: 1,\r\n        A: [[0]],\r\n        b: [1],\r\n        c: [0]\r\n    }\r\n};\r\n\r\n/**\r\n * The JXG.Math.Numerics namespace holds numerical algorithms, constants, and variables.\r\n * @name JXG.Math.Numerics\r\n * @exports Mat.Numerics as JXG.Math.Numerics\r\n * @namespace\r\n */\r\nMat.Numerics = {\r\n    //JXG.extend(Mat.Numerics, /** @lends JXG.Math.Numerics */ {\r\n    /**\r\n     * Solves a system of linear equations given by A and b using the Gauss-Jordan-elimination.\r\n     * The algorithm runs in-place. I.e. the entries of A and b are changed.\r\n     * @param {Array} A Square matrix represented by an array of rows, containing the coefficients of the lineare equation system.\r\n     * @param {Array} b A vector containing the linear equation system's right hand side.\r\n     * @throws {Error} If a non-square-matrix is given or if b has not the right length or A's rank is not full.\r\n     * @returns {Array} A vector that solves the linear equation system.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    Gauss: function (A, b) {\r\n        var i,\r\n            j,\r\n            k,\r\n            // copy the matrix to prevent changes in the original\r\n            Acopy,\r\n            // solution vector, to prevent changing b\r\n            x,\r\n            eps = Mat.eps,\r\n            // number of columns of A\r\n            n = A.length > 0 ? A[0].length : 0;\r\n\r\n        if (n !== b.length || n !== A.length) {\r\n            throw new Error(\r\n                \"JXG.Math.Numerics.Gauss: Dimensions don't match. A must be a square matrix and b must be of the same length as A.\"\r\n            );\r\n        }\r\n\r\n        // initialize solution vector\r\n        Acopy = [];\r\n        x = b.slice(0, n);\r\n\r\n        for (i = 0; i < n; i++) {\r\n            Acopy[i] = A[i].slice(0, n);\r\n        }\r\n\r\n        // Gauss-Jordan-elimination\r\n        for (j = 0; j < n; j++) {\r\n            for (i = n - 1; i > j; i--) {\r\n                // Is the element which is to eliminate greater than zero?\r\n                if (Math.abs(Acopy[i][j]) > eps) {\r\n                    // Equals pivot element zero?\r\n                    if (Math.abs(Acopy[j][j]) < eps) {\r\n                        // At least numerically, so we have to exchange the rows\r\n                        Type.swap(Acopy, i, j);\r\n                        Type.swap(x, i, j);\r\n                    } else {\r\n                        // Saves the L matrix of the LR-decomposition. unnecessary.\r\n                        Acopy[i][j] /= Acopy[j][j];\r\n                        // Transform right-hand-side b\r\n                        x[i] -= Acopy[i][j] * x[j];\r\n\r\n                        // subtract the multiple of A[i][j] / A[j][j] of the j-th row from the i-th.\r\n                        for (k = j + 1; k < n; k++) {\r\n                            Acopy[i][k] -= Acopy[i][j] * Acopy[j][k];\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // The absolute values of all coefficients below the j-th row in the j-th column are smaller than JXG.Math.eps.\r\n            if (Math.abs(Acopy[j][j]) < eps) {\r\n                throw new Error(\r\n                    \"JXG.Math.Numerics.Gauss(): The given matrix seems to be singular.\"\r\n                );\r\n            }\r\n        }\r\n\r\n        this.backwardSolve(Acopy, x, true);\r\n\r\n        return x;\r\n    },\r\n\r\n    /**\r\n     * Solves a system of linear equations given by the right triangular matrix R and vector b.\r\n     * @param {Array} R Right triangular matrix represented by an array of rows. All entries a_(i,j) with i &lt; j are ignored.\r\n     * @param {Array} b Right hand side of the linear equation system.\r\n     * @param {Boolean} [canModify=false] If true, the right hand side vector is allowed to be changed by this method.\r\n     * @returns {Array} An array representing a vector that solves the system of linear equations.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    backwardSolve: function (R, b, canModify) {\r\n        var x, m, n, i, j;\r\n\r\n        if (canModify) {\r\n            x = b;\r\n        } else {\r\n            x = b.slice(0, b.length);\r\n        }\r\n\r\n        // m: number of rows of R\r\n        // n: number of columns of R\r\n        m = R.length;\r\n        n = R.length > 0 ? R[0].length : 0;\r\n\r\n        for (i = m - 1; i >= 0; i--) {\r\n            for (j = n - 1; j > i; j--) {\r\n                x[i] -= R[i][j] * x[j];\r\n            }\r\n            x[i] /= R[i][i];\r\n        }\r\n\r\n        return x;\r\n    },\r\n\r\n    /**\r\n     *  Gauss-Bareiss algorithm to compute the\r\n     *  determinant of matrix without fractions.\r\n     *  See Henri Cohen, \"A Course in Computational\r\n     *  Algebraic Number Theory (Graduate texts\r\n     *  in mathematics; 138)\", Springer-Verlag,\r\n     *  ISBN 3-540-55640-0 / 0-387-55640-0\r\n     *  Third, Corrected Printing 1996\r\n     *  \"Algorithm 2.2.6\", pg. 52-53\r\n     *\r\n     * @param {Array} mat Matrix\r\n     * @returns Number\r\n     * @private\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    gaussBareiss: function (mat) {\r\n        var k, c, s,\r\n            i, j, p,\r\n            n, M, t,\r\n            eps = Mat.eps;\r\n\r\n        n = mat.length;\r\n\r\n        if (n <= 0) {\r\n            return 0;\r\n        }\r\n\r\n        if (mat[0].length < n) {\r\n            n = mat[0].length;\r\n        }\r\n\r\n        // Copy the input matrix to M\r\n        M = [];\r\n\r\n        for (i = 0; i < n; i++) {\r\n            M[i] = mat[i].slice(0, n);\r\n        }\r\n\r\n        c = 1;\r\n        s = 1;\r\n\r\n        for (k = 0; k < n - 1; k++) {\r\n            p = M[k][k];\r\n\r\n            // Pivot step\r\n            if (Math.abs(p) < eps) {\r\n                for (i = k + 1; i < n; i++) {\r\n                    if (Math.abs(M[i][k]) >= eps) {\r\n                        break;\r\n                    }\r\n                }\r\n\r\n                // No nonzero entry found in column k -> det(M) = 0\r\n                if (i === n) {\r\n                    return 0.0;\r\n                }\r\n\r\n                // swap row i and k partially\r\n                for (j = k; j < n; j++) {\r\n                    t = M[i][j];\r\n                    M[i][j] = M[k][j];\r\n                    M[k][j] = t;\r\n                }\r\n                s = -s;\r\n                p = M[k][k];\r\n            }\r\n\r\n            // Main step\r\n            for (i = k + 1; i < n; i++) {\r\n                for (j = k + 1; j < n; j++) {\r\n                    t = p * M[i][j] - M[i][k] * M[k][j];\r\n                    M[i][j] = t / c;\r\n                }\r\n            }\r\n\r\n            c = p;\r\n        }\r\n\r\n        return s * M[n - 1][n - 1];\r\n    },\r\n\r\n    /**\r\n     * Computes the determinant of a square nxn matrix with the\r\n     * Gauss-Bareiss algorithm.\r\n     * @param {Array} mat Matrix.\r\n     * @returns {Number} The determinant pf the matrix mat.\r\n     *                   The empty matrix returns 0.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    det: function (mat) {\r\n        var n = mat.length;\r\n\r\n        if (n === 2 && mat[0].length === 2) {\r\n            return mat[0][0] * mat[1][1] - mat[1][0] * mat[0][1];\r\n        }\r\n\r\n        return this.gaussBareiss(mat);\r\n    },\r\n\r\n    /**\r\n     * Compute the Eigenvalues and Eigenvectors of a symmetric 3x3 matrix with the Jacobi method\r\n     * Adaption of a FORTRAN program by Ed Wilson, Dec. 25, 1990\r\n     * @param {Array} Ain A symmetric 3x3 matrix.\r\n     * @returns {Array} [A,V] the matrices A and V. The diagonal of A contains the Eigenvalues, V contains the Eigenvectors.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    Jacobi: function (Ain) {\r\n        var i,\r\n            j,\r\n            k,\r\n            aa,\r\n            si,\r\n            co,\r\n            tt,\r\n            ssum,\r\n            amax,\r\n            eps = Mat.eps * Mat.eps,\r\n            sum = 0.0,\r\n            n = Ain.length,\r\n            V = [\r\n                [0, 0, 0],\r\n                [0, 0, 0],\r\n                [0, 0, 0]\r\n            ],\r\n            A = [\r\n                [0, 0, 0],\r\n                [0, 0, 0],\r\n                [0, 0, 0]\r\n            ],\r\n            nloops = 0;\r\n\r\n        // Initialization. Set initial Eigenvectors.\r\n        for (i = 0; i < n; i++) {\r\n            for (j = 0; j < n; j++) {\r\n                V[i][j] = 0.0;\r\n                A[i][j] = Ain[i][j];\r\n                sum += Math.abs(A[i][j]);\r\n            }\r\n            V[i][i] = 1.0;\r\n        }\r\n\r\n        // Trivial problems\r\n        if (n === 1) {\r\n            return [A, V];\r\n        }\r\n\r\n        if (sum <= 0.0) {\r\n            return [A, V];\r\n        }\r\n\r\n        sum /= n * n;\r\n\r\n        // Reduce matrix to diagonal\r\n        do {\r\n            ssum = 0.0;\r\n            amax = 0.0;\r\n            for (j = 1; j < n; j++) {\r\n                for (i = 0; i < j; i++) {\r\n                    // Check if A[i][j] is to be reduced\r\n                    aa = Math.abs(A[i][j]);\r\n\r\n                    if (aa > amax) {\r\n                        amax = aa;\r\n                    }\r\n\r\n                    ssum += aa;\r\n\r\n                    if (aa >= eps) {\r\n                        // calculate rotation angle\r\n                        aa = Math.atan2(2.0 * A[i][j], A[i][i] - A[j][j]) * 0.5;\r\n                        si = Math.sin(aa);\r\n                        co = Math.cos(aa);\r\n\r\n                        // Modify 'i' and 'j' columns\r\n                        for (k = 0; k < n; k++) {\r\n                            tt = A[k][i];\r\n                            A[k][i] = co * tt + si * A[k][j];\r\n                            A[k][j] = -si * tt + co * A[k][j];\r\n                            tt = V[k][i];\r\n                            V[k][i] = co * tt + si * V[k][j];\r\n                            V[k][j] = -si * tt + co * V[k][j];\r\n                        }\r\n\r\n                        // Modify diagonal terms\r\n                        A[i][i] = co * A[i][i] + si * A[j][i];\r\n                        A[j][j] = -si * A[i][j] + co * A[j][j];\r\n                        A[i][j] = 0.0;\r\n\r\n                        // Make 'A' matrix symmetrical\r\n                        for (k = 0; k < n; k++) {\r\n                            A[i][k] = A[k][i];\r\n                            A[j][k] = A[k][j];\r\n                        }\r\n                        // A[i][j] made zero by rotation\r\n                    }\r\n                }\r\n            }\r\n            nloops += 1;\r\n        } while (Math.abs(ssum) / sum > eps && nloops < 2000);\r\n\r\n        return [A, V];\r\n    },\r\n\r\n    /**\r\n     * Calculates the integral of function f over interval using Newton-Cotes-algorithm.\r\n     * @param {Array} interval The integration interval, e.g. [0, 3].\r\n     * @param {function} f A function which takes one argument of type number and returns a number.\r\n     * @param {Object} [config] The algorithm setup. Accepted properties are number_of_nodes of type number and integration_type\r\n     * with value being either 'trapez', 'simpson', or 'milne'.\r\n     * @param {Number} [config.number_of_nodes=28]\r\n     * @param {String} [config.integration_type='milne'] Possible values are 'milne', 'simpson', 'trapez'\r\n     * @returns {Number} Integral value of f over interval\r\n     * @throws {Error} If config.number_of_nodes doesn't match config.integration_type an exception is thrown. If you want to use\r\n     * simpson rule respectively milne rule config.number_of_nodes must be dividable by 2 respectively 4.\r\n     * @example\r\n     * function f(x) {\r\n     *   return x*x;\r\n     * }\r\n     *\r\n     * // calculates integral of <tt>f</tt> from 0 to 2.\r\n     * var area1 = JXG.Math.Numerics.NewtonCotes([0, 2], f);\r\n     *\r\n     * // the same with an anonymous function\r\n     * var area2 = JXG.Math.Numerics.NewtonCotes([0, 2], function (x) { return x*x; });\r\n     *\r\n     * // use trapez rule with 16 nodes\r\n     * var area3 = JXG.Math.Numerics.NewtonCotes([0, 2], f,\r\n     *                                   {number_of_nodes: 16, integration_type: 'trapez'});\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    NewtonCotes: function (interval, f, config) {\r\n        var evaluation_point,\r\n            i,\r\n            number_of_intervals,\r\n            integral_value = 0.0,\r\n            number_of_nodes =\r\n                config && Type.isNumber(config.number_of_nodes) ? config.number_of_nodes : 28,\r\n            available_types = { trapez: true, simpson: true, milne: true },\r\n            integration_type =\r\n                config &&\r\n                    config.integration_type &&\r\n                    available_types.hasOwnProperty(config.integration_type) &&\r\n                    available_types[config.integration_type]\r\n                    ? config.integration_type\r\n                    : \"milne\",\r\n            step_size = (interval[1] - interval[0]) / number_of_nodes;\r\n\r\n        switch (integration_type) {\r\n            case \"trapez\":\r\n                integral_value = (f(interval[0]) + f(interval[1])) * 0.5;\r\n                evaluation_point = interval[0];\r\n\r\n                for (i = 0; i < number_of_nodes - 1; i++) {\r\n                    evaluation_point += step_size;\r\n                    integral_value += f(evaluation_point);\r\n                }\r\n\r\n                integral_value *= step_size;\r\n                break;\r\n            case \"simpson\":\r\n                if (number_of_nodes % 2 > 0) {\r\n                    throw new Error(\r\n                        \"JSXGraph:  INT_SIMPSON requires config.number_of_nodes dividable by 2.\"\r\n                    );\r\n                }\r\n\r\n                number_of_intervals = number_of_nodes / 2.0;\r\n                integral_value = f(interval[0]) + f(interval[1]);\r\n                evaluation_point = interval[0];\r\n\r\n                for (i = 0; i < number_of_intervals - 1; i++) {\r\n                    evaluation_point += 2.0 * step_size;\r\n                    integral_value += 2.0 * f(evaluation_point);\r\n                }\r\n\r\n                evaluation_point = interval[0] - step_size;\r\n\r\n                for (i = 0; i < number_of_intervals; i++) {\r\n                    evaluation_point += 2.0 * step_size;\r\n                    integral_value += 4.0 * f(evaluation_point);\r\n                }\r\n\r\n                integral_value *= step_size / 3.0;\r\n                break;\r\n            default:\r\n                if (number_of_nodes % 4 > 0) {\r\n                    throw new Error(\r\n                        \"JSXGraph: Error in INT_MILNE: config.number_of_nodes must be a multiple of 4\"\r\n                    );\r\n                }\r\n\r\n                number_of_intervals = number_of_nodes * 0.25;\r\n                integral_value = 7.0 * (f(interval[0]) + f(interval[1]));\r\n                evaluation_point = interval[0];\r\n\r\n                for (i = 0; i < number_of_intervals - 1; i++) {\r\n                    evaluation_point += 4.0 * step_size;\r\n                    integral_value += 14.0 * f(evaluation_point);\r\n                }\r\n\r\n                evaluation_point = interval[0] - 3.0 * step_size;\r\n\r\n                for (i = 0; i < number_of_intervals; i++) {\r\n                    evaluation_point += 4.0 * step_size;\r\n                    integral_value +=\r\n                        32.0 * (f(evaluation_point) + f(evaluation_point + 2 * step_size));\r\n                }\r\n\r\n                evaluation_point = interval[0] - 2.0 * step_size;\r\n\r\n                for (i = 0; i < number_of_intervals; i++) {\r\n                    evaluation_point += 4.0 * step_size;\r\n                    integral_value += 12.0 * f(evaluation_point);\r\n                }\r\n\r\n                integral_value *= (2.0 * step_size) / 45.0;\r\n        }\r\n        return integral_value;\r\n    },\r\n\r\n    /**\r\n     * Calculates the integral of function f over interval using Romberg iteration.\r\n     * @param {Array} interval The integration interval, e.g. [0, 3].\r\n     * @param {function} f A function which takes one argument of type number and returns a number.\r\n     * @param {Object} [config] The algorithm setup. Accepted properties are max_iterations of type number and precision eps.\r\n     * @param {Number} [config.max_iterations=20]\r\n     * @param {Number} [config.eps=0.0000001]\r\n     * @returns {Number} Integral value of f over interval\r\n     * @example\r\n     * function f(x) {\r\n     *   return x*x;\r\n     * }\r\n     *\r\n     * // calculates integral of <tt>f</tt> from 0 to 2.\r\n     * var area1 = JXG.Math.Numerics.Romberg([0, 2], f);\r\n     *\r\n     * // the same with an anonymous function\r\n     * var area2 = JXG.Math.Numerics.Romberg([0, 2], function (x) { return x*x; });\r\n     *\r\n     * // use trapez rule with maximum of 16 iterations or stop if the precision 0.0001 has been reached.\r\n     * var area3 = JXG.Math.Numerics.Romberg([0, 2], f,\r\n     *                                   {max_iterations: 16, eps: 0.0001});\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    Romberg: function (interval, f, config) {\r\n        var a,\r\n            b,\r\n            h,\r\n            s,\r\n            n,\r\n            k,\r\n            i,\r\n            q,\r\n            p = [],\r\n            integral = 0.0,\r\n            last = Infinity,\r\n            m = config && Type.isNumber(config.max_iterations) ? config.max_iterations : 20,\r\n            eps = config && Type.isNumber(config.eps) ? config.eps : config.eps || 0.0000001;\r\n\r\n        a = interval[0];\r\n        b = interval[1];\r\n        h = b - a;\r\n        n = 1;\r\n\r\n        p[0] = 0.5 * h * (f(a) + f(b));\r\n\r\n        for (k = 0; k < m; ++k) {\r\n            s = 0;\r\n            h *= 0.5;\r\n            n *= 2;\r\n            q = 1;\r\n\r\n            for (i = 1; i < n; i += 2) {\r\n                s += f(a + i * h);\r\n            }\r\n\r\n            p[k + 1] = 0.5 * p[k] + s * h;\r\n\r\n            integral = p[k + 1];\r\n            for (i = k - 1; i >= 0; --i) {\r\n                q *= 4;\r\n                p[i] = p[i + 1] + (p[i + 1] - p[i]) / (q - 1.0);\r\n                integral = p[i];\r\n            }\r\n\r\n            if (Math.abs(integral - last) < eps * Math.abs(integral)) {\r\n                break;\r\n            }\r\n            last = integral;\r\n        }\r\n\r\n        return integral;\r\n    },\r\n\r\n    /**\r\n     * Calculates the integral of function f over interval using Gauss-Legendre quadrature.\r\n     * @param {Array} interval The integration interval, e.g. [0, 3].\r\n     * @param {function} f A function which takes one argument of type number and returns a number.\r\n     * @param {Object} [config] The algorithm setup. Accepted property is the order n of type number. n is allowed to take\r\n     * values between 2 and 18, default value is 12.\r\n     * @param {Number} [config.n=16]\r\n     * @returns {Number} Integral value of f over interval\r\n     * @example\r\n     * function f(x) {\r\n     *   return x*x;\r\n     * }\r\n     *\r\n     * // calculates integral of <tt>f</tt> from 0 to 2.\r\n     * var area1 = JXG.Math.Numerics.GaussLegendre([0, 2], f);\r\n     *\r\n     * // the same with an anonymous function\r\n     * var area2 = JXG.Math.Numerics.GaussLegendre([0, 2], function (x) { return x*x; });\r\n     *\r\n     * // use 16 point Gauss-Legendre rule.\r\n     * var area3 = JXG.Math.Numerics.GaussLegendre([0, 2], f,\r\n     *                                   {n: 16});\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    GaussLegendre: function (interval, f, config) {\r\n        var a,\r\n            b,\r\n            i,\r\n            m,\r\n            xp,\r\n            xm,\r\n            result = 0.0,\r\n            table_xi = [],\r\n            table_w = [],\r\n            xi,\r\n            w,\r\n            n = config && Type.isNumber(config.n) ? config.n : 12;\r\n\r\n        if (n > 18) {\r\n            n = 18;\r\n        }\r\n\r\n        /* n = 2 */\r\n        table_xi[2] = [0.5773502691896257645091488];\r\n        table_w[2] = [1.0];\r\n\r\n        /* n = 4 */\r\n        table_xi[4] = [0.3399810435848562648026658, 0.8611363115940525752239465];\r\n        table_w[4] = [0.6521451548625461426269361, 0.3478548451374538573730639];\r\n\r\n        /* n = 6 */\r\n        table_xi[6] = [\r\n            0.2386191860831969086305017, 0.6612093864662645136613996,\r\n            0.9324695142031520278123016\r\n        ];\r\n        table_w[6] = [\r\n            0.4679139345726910473898703, 0.3607615730481386075698335,\r\n            0.1713244923791703450402961\r\n        ];\r\n\r\n        /* n = 8 */\r\n        table_xi[8] = [\r\n            0.1834346424956498049394761, 0.525532409916328985817739,\r\n            0.7966664774136267395915539, 0.9602898564975362316835609\r\n        ];\r\n        table_w[8] = [\r\n            0.3626837833783619829651504, 0.3137066458778872873379622,\r\n            0.222381034453374470544356, 0.1012285362903762591525314\r\n        ];\r\n\r\n        /* n = 10 */\r\n        table_xi[10] = [\r\n            0.148874338981631210884826, 0.4333953941292471907992659,\r\n            0.6794095682990244062343274, 0.8650633666889845107320967, 0.973906528517171720077964\r\n        ];\r\n        table_w[10] = [\r\n            0.295524224714752870173893, 0.2692667193099963550912269,\r\n            0.2190863625159820439955349, 0.1494513491505805931457763,\r\n            0.0666713443086881375935688\r\n        ];\r\n\r\n        /* n = 12 */\r\n        table_xi[12] = [\r\n            0.1252334085114689154724414, 0.3678314989981801937526915,\r\n            0.5873179542866174472967024, 0.7699026741943046870368938,\r\n            0.9041172563704748566784659, 0.9815606342467192506905491\r\n        ];\r\n        table_w[12] = [\r\n            0.2491470458134027850005624, 0.2334925365383548087608499,\r\n            0.2031674267230659217490645, 0.1600783285433462263346525,\r\n            0.1069393259953184309602547, 0.047175336386511827194616\r\n        ];\r\n\r\n        /* n = 14 */\r\n        table_xi[14] = [\r\n            0.1080549487073436620662447, 0.3191123689278897604356718,\r\n            0.5152486363581540919652907, 0.6872929048116854701480198,\r\n            0.8272013150697649931897947, 0.9284348836635735173363911,\r\n            0.9862838086968123388415973\r\n        ];\r\n        table_w[14] = [\r\n            0.2152638534631577901958764, 0.2051984637212956039659241,\r\n            0.1855383974779378137417166, 0.1572031671581935345696019,\r\n            0.1215185706879031846894148, 0.0801580871597602098056333,\r\n            0.0351194603317518630318329\r\n        ];\r\n\r\n        /* n = 16 */\r\n        table_xi[16] = [\r\n            0.0950125098376374401853193, 0.2816035507792589132304605,\r\n            0.4580167776572273863424194, 0.6178762444026437484466718,\r\n            0.7554044083550030338951012, 0.8656312023878317438804679,\r\n            0.9445750230732325760779884, 0.9894009349916499325961542\r\n        ];\r\n        table_w[16] = [\r\n            0.1894506104550684962853967, 0.1826034150449235888667637,\r\n            0.1691565193950025381893121, 0.1495959888165767320815017,\r\n            0.1246289712555338720524763, 0.0951585116824927848099251,\r\n            0.0622535239386478928628438, 0.0271524594117540948517806\r\n        ];\r\n\r\n        /* n = 18 */\r\n        table_xi[18] = [\r\n            0.0847750130417353012422619, 0.2518862256915055095889729,\r\n            0.4117511614628426460359318, 0.5597708310739475346078715,\r\n            0.6916870430603532078748911, 0.8037049589725231156824175,\r\n            0.8926024664975557392060606, 0.9558239495713977551811959, 0.991565168420930946730016\r\n        ];\r\n        table_w[18] = [\r\n            0.1691423829631435918406565, 0.1642764837458327229860538,\r\n            0.154684675126265244925418, 0.1406429146706506512047313,\r\n            0.1225552067114784601845191, 0.100942044106287165562814,\r\n            0.0764257302548890565291297, 0.0497145488949697964533349,\r\n            0.0216160135264833103133427\r\n        ];\r\n\r\n        /* n = 3 */\r\n        table_xi[3] = [0.0, 0.7745966692414833770358531];\r\n        table_w[3] = [0.8888888888888888888888889, 0.5555555555555555555555556];\r\n\r\n        /* n = 5 */\r\n        table_xi[5] = [0.0, 0.5384693101056830910363144, 0.9061798459386639927976269];\r\n        table_w[5] = [\r\n            0.5688888888888888888888889, 0.4786286704993664680412915, 0.236926885056189087514264\r\n        ];\r\n\r\n        /* n = 7 */\r\n        table_xi[7] = [\r\n            0.0, 0.4058451513773971669066064, 0.7415311855993944398638648,\r\n            0.9491079123427585245261897\r\n        ];\r\n        table_w[7] = [\r\n            0.417959183673469387755102, 0.3818300505051189449503698,\r\n            0.2797053914892766679014678, 0.1294849661688696932706114\r\n        ];\r\n\r\n        /* n = 9 */\r\n        table_xi[9] = [\r\n            0.0, 0.324253423403808929038538, 0.613371432700590397308702,\r\n            0.8360311073266357942994298, 0.9681602395076260898355762\r\n        ];\r\n        table_w[9] = [\r\n            0.3302393550012597631645251, 0.3123470770400028400686304,\r\n            0.2606106964029354623187429, 0.180648160694857404058472, 0.0812743883615744119718922\r\n        ];\r\n\r\n        /* n = 11 */\r\n        table_xi[11] = [\r\n            0.0, 0.269543155952344972331532, 0.5190961292068118159257257,\r\n            0.7301520055740493240934163, 0.8870625997680952990751578, 0.978228658146056992803938\r\n        ];\r\n        table_w[11] = [\r\n            0.2729250867779006307144835, 0.2628045445102466621806889,\r\n            0.2331937645919904799185237, 0.1862902109277342514260976,\r\n            0.1255803694649046246346943, 0.0556685671161736664827537\r\n        ];\r\n\r\n        /* n = 13 */\r\n        table_xi[13] = [\r\n            0.0, 0.2304583159551347940655281, 0.4484927510364468528779129,\r\n            0.6423493394403402206439846, 0.8015780907333099127942065,\r\n            0.9175983992229779652065478, 0.9841830547185881494728294\r\n        ];\r\n        table_w[13] = [\r\n            0.2325515532308739101945895, 0.2262831802628972384120902,\r\n            0.2078160475368885023125232, 0.1781459807619457382800467,\r\n            0.1388735102197872384636018, 0.0921214998377284479144218,\r\n            0.0404840047653158795200216\r\n        ];\r\n\r\n        /* n = 15 */\r\n        table_xi[15] = [\r\n            0.0, 0.2011940939974345223006283, 0.3941513470775633698972074,\r\n            0.5709721726085388475372267, 0.7244177313601700474161861,\r\n            0.8482065834104272162006483, 0.9372733924007059043077589,\r\n            0.9879925180204854284895657\r\n        ];\r\n        table_w[15] = [\r\n            0.2025782419255612728806202, 0.1984314853271115764561183,\r\n            0.1861610000155622110268006, 0.1662692058169939335532009,\r\n            0.1395706779261543144478048, 0.1071592204671719350118695,\r\n            0.0703660474881081247092674, 0.0307532419961172683546284\r\n        ];\r\n\r\n        /* n = 17 */\r\n        table_xi[17] = [\r\n            0.0, 0.1784841814958478558506775, 0.3512317634538763152971855,\r\n            0.5126905370864769678862466, 0.6576711592166907658503022,\r\n            0.7815140038968014069252301, 0.8802391537269859021229557,\r\n            0.950675521768767761222717, 0.990575475314417335675434\r\n        ];\r\n        table_w[17] = [\r\n            0.1794464703562065254582656, 0.176562705366992646325271,\r\n            0.1680041021564500445099707, 0.1540457610768102880814316, 0.13513636846852547328632,\r\n            0.1118838471934039710947884, 0.0850361483171791808835354,\r\n            0.0554595293739872011294402, 0.02414830286854793196011\r\n        ];\r\n\r\n        a = interval[0];\r\n        b = interval[1];\r\n\r\n        //m = Math.ceil(n * 0.5);\r\n        m = (n + 1) >> 1;\r\n\r\n        xi = table_xi[n];\r\n        w = table_w[n];\r\n\r\n        xm = 0.5 * (b - a);\r\n        xp = 0.5 * (b + a);\r\n\r\n        if (n & (1 === 1)) {\r\n            // n odd\r\n            result = w[0] * f(xp);\r\n            for (i = 1; i < m; ++i) {\r\n                result += w[i] * (f(xp + xm * xi[i]) + f(xp - xm * xi[i]));\r\n            }\r\n        } else {\r\n            // n even\r\n            result = 0.0;\r\n            for (i = 0; i < m; ++i) {\r\n                result += w[i] * (f(xp + xm * xi[i]) + f(xp - xm * xi[i]));\r\n            }\r\n        }\r\n\r\n        return xm * result;\r\n    },\r\n\r\n    /**\r\n     * Scale error in Gauss Kronrod quadrature.\r\n     * Internal method used in {@link JXG.Math.Numerics._gaussKronrod}.\r\n     * @private\r\n     */\r\n    _rescale_error: function (err, result_abs, result_asc) {\r\n        var scale,\r\n            min_err,\r\n            DBL_MIN = 2.2250738585072014e-308,\r\n            DBL_EPS = 2.2204460492503131e-16;\r\n\r\n        err = Math.abs(err);\r\n        if (result_asc !== 0 && err !== 0) {\r\n            scale = Math.pow((200 * err) / result_asc, 1.5);\r\n\r\n            if (scale < 1.0) {\r\n                err = result_asc * scale;\r\n            } else {\r\n                err = result_asc;\r\n            }\r\n        }\r\n        if (result_abs > DBL_MIN / (50 * DBL_EPS)) {\r\n            min_err = 50 * DBL_EPS * result_abs;\r\n\r\n            if (min_err > err) {\r\n                err = min_err;\r\n            }\r\n        }\r\n\r\n        return err;\r\n    },\r\n\r\n    /**\r\n     * Generic Gauss-Kronrod quadrature algorithm.\r\n     * Internal method used in {@link JXG.Math.Numerics.GaussKronrod15},\r\n     * {@link JXG.Math.Numerics.GaussKronrod21},\r\n     * {@link JXG.Math.Numerics.GaussKronrod31}.\r\n     * Taken from QUADPACK.\r\n     *\r\n     * @param {Array} interval The integration interval, e.g. [0, 3].\r\n     * @param {function} f A function which takes one argument of type number and returns a number.\r\n     * @param {Number} n order of approximation. Actually, n is the length of the array xgk. For example, for the 15-point Kronrod rule, n is equal to 8.\r\n     * @param {Array} xgk Kronrod quadrature abscissae\r\n     * @param {Array} wg Weights of the Gauss rule\r\n     * @param {Array} wgk Weights of the Kronrod rule\r\n     * @param {Object} resultObj Object returning resultObj.abserr, resultObj.resabs, resultObj.resasc.\r\n     * See the library QUADPACK for an explanation.\r\n     *\r\n     * @returns {Number} Integral value of f over interval\r\n     *\r\n     * @private\r\n     */\r\n    _gaussKronrod: function (interval, f, n, xgk, wg, wgk, resultObj) {\r\n        var a = interval[0],\r\n            b = interval[1],\r\n            up,\r\n            result,\r\n            center = 0.5 * (a + b),\r\n            half_length = 0.5 * (b - a),\r\n            abs_half_length = Math.abs(half_length),\r\n            f_center = f(center),\r\n            result_gauss = 0.0,\r\n            result_kronrod = f_center * wgk[n - 1],\r\n            result_abs = Math.abs(result_kronrod),\r\n            result_asc = 0.0,\r\n            mean = 0.0,\r\n            err = 0.0,\r\n            j, jtw, jtwm1,\r\n            abscissa,\r\n            fval1, fval2, fsum,\r\n            fv1 = [],\r\n            fv2 = [];\r\n\r\n        if (n % 2 === 0) {\r\n            result_gauss = f_center * wg[n / 2 - 1];\r\n        }\r\n\r\n        up = Math.floor((n - 1) / 2);\r\n        for (j = 0; j < up; j++) {\r\n            jtw = j * 2 + 1; // in original fortran j=1,2,3 jtw=2,4,6\r\n            abscissa = half_length * xgk[jtw];\r\n            fval1 = f(center - abscissa);\r\n            fval2 = f(center + abscissa);\r\n            fsum = fval1 + fval2;\r\n            fv1[jtw] = fval1;\r\n            fv2[jtw] = fval2;\r\n            result_gauss += wg[j] * fsum;\r\n            result_kronrod += wgk[jtw] * fsum;\r\n            result_abs += wgk[jtw] * (Math.abs(fval1) + Math.abs(fval2));\r\n        }\r\n\r\n        up = Math.floor(n / 2);\r\n        for (j = 0; j < up; j++) {\r\n            jtwm1 = j * 2;\r\n            abscissa = half_length * xgk[jtwm1];\r\n            fval1 = f(center - abscissa);\r\n            fval2 = f(center + abscissa);\r\n            fv1[jtwm1] = fval1;\r\n            fv2[jtwm1] = fval2;\r\n            result_kronrod += wgk[jtwm1] * (fval1 + fval2);\r\n            result_abs += wgk[jtwm1] * (Math.abs(fval1) + Math.abs(fval2));\r\n        }\r\n\r\n        mean = result_kronrod * 0.5;\r\n        result_asc = wgk[n - 1] * Math.abs(f_center - mean);\r\n\r\n        for (j = 0; j < n - 1; j++) {\r\n            result_asc += wgk[j] * (Math.abs(fv1[j] - mean) + Math.abs(fv2[j] - mean));\r\n        }\r\n\r\n        // scale by the width of the integration region\r\n        err = (result_kronrod - result_gauss) * half_length;\r\n\r\n        result_kronrod *= half_length;\r\n        result_abs *= abs_half_length;\r\n        result_asc *= abs_half_length;\r\n        result = result_kronrod;\r\n\r\n        resultObj.abserr = this._rescale_error(err, result_abs, result_asc);\r\n        resultObj.resabs = result_abs;\r\n        resultObj.resasc = result_asc;\r\n\r\n        return result;\r\n    },\r\n\r\n    /**\r\n     * 15-point Gauss-Kronrod quadrature algorithm, see the library QUADPACK\r\n     * @param {Array} interval The integration interval, e.g. [0, 3].\r\n     * @param {function} f A function which takes one argument of type number and returns a number.\r\n     * @param {Object} resultObj Object returning resultObj.abserr, resultObj.resabs, resultObj.resasc. See the library\r\n     *  QUADPACK for an explanation.\r\n     *\r\n     * @returns {Number} Integral value of f over interval\r\n     *\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    GaussKronrod15: function (interval, f, resultObj) {\r\n        /* Gauss quadrature weights and kronrod quadrature abscissae and\r\n                weights as evaluated with 80 decimal digit arithmetic by\r\n                L. W. Fullerton, Bell Labs, Nov. 1981. */\r\n\r\n        var xgk =\r\n            /* abscissae of the 15-point kronrod rule */\r\n            [\r\n                0.991455371120812639206854697526329, 0.949107912342758524526189684047851,\r\n                0.864864423359769072789712788640926, 0.741531185599394439863864773280788,\r\n                0.58608723546769113029414483825873, 0.405845151377397166906606412076961,\r\n                0.207784955007898467600689403773245, 0.0\r\n            ],\r\n            /* xgk[1], xgk[3], ... abscissae of the 7-point gauss rule.\r\n                xgk[0], xgk[2], ... abscissae to optimally extend the 7-point gauss rule */\r\n\r\n            wg =\r\n                /* weights of the 7-point gauss rule */\r\n                [\r\n                    0.129484966168869693270611432679082, 0.27970539148927666790146777142378,\r\n                    0.381830050505118944950369775488975, 0.417959183673469387755102040816327\r\n                ],\r\n            wgk =\r\n                /* weights of the 15-point kronrod rule */\r\n                [\r\n                    0.02293532201052922496373200805897, 0.063092092629978553290700663189204,\r\n                    0.104790010322250183839876322541518, 0.140653259715525918745189590510238,\r\n                    0.16900472663926790282658342659855, 0.190350578064785409913256402421014,\r\n                    0.204432940075298892414161999234649, 0.209482141084727828012999174891714\r\n                ];\r\n\r\n        return this._gaussKronrod(interval, f, 8, xgk, wg, wgk, resultObj);\r\n    },\r\n\r\n    /**\r\n     * 21 point Gauss-Kronrod quadrature algorithm, see the library QUADPACK\r\n     * @param {Array} interval The integration interval, e.g. [0, 3].\r\n     * @param {function} f A function which takes one argument of type number and returns a number.\r\n     * @param {Object} resultObj Object returning resultObj.abserr, resultObj.resabs, resultObj.resasc. See the library\r\n     *  QUADPACK for an explanation.\r\n     *\r\n     * @returns {Number} Integral value of f over interval\r\n     *\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    GaussKronrod21: function (interval, f, resultObj) {\r\n        /* Gauss quadrature weights and kronrod quadrature abscissae and\r\n                weights as evaluated with 80 decimal digit arithmetic by\r\n                L. W. Fullerton, Bell Labs, Nov. 1981. */\r\n\r\n        var xgk =\r\n            /* abscissae of the 21-point kronrod rule */\r\n            [\r\n                0.995657163025808080735527280689003, 0.973906528517171720077964012084452,\r\n                0.930157491355708226001207180059508, 0.865063366688984510732096688423493,\r\n                0.780817726586416897063717578345042, 0.679409568299024406234327365114874,\r\n                0.562757134668604683339000099272694, 0.433395394129247190799265943165784,\r\n                0.294392862701460198131126603103866, 0.14887433898163121088482600112972, 0.0\r\n            ],\r\n            /* xgk[1], xgk[3], ... abscissae of the 10-point gauss rule.\r\n                xgk[0], xgk[2], ... abscissae to optimally extend the 10-point gauss rule */\r\n            wg =\r\n                /* weights of the 10-point gauss rule */\r\n                [\r\n                    0.066671344308688137593568809893332, 0.149451349150580593145776339657697,\r\n                    0.219086362515982043995534934228163, 0.269266719309996355091226921569469,\r\n                    0.295524224714752870173892994651338\r\n                ],\r\n            wgk =\r\n                /* weights of the 21-point kronrod rule */\r\n                [\r\n                    0.011694638867371874278064396062192, 0.03255816230796472747881897245939,\r\n                    0.05475589657435199603138130024458, 0.07503967481091995276704314091619,\r\n                    0.093125454583697605535065465083366, 0.109387158802297641899210590325805,\r\n                    0.123491976262065851077958109831074, 0.134709217311473325928054001771707,\r\n                    0.142775938577060080797094273138717, 0.147739104901338491374841515972068,\r\n                    0.149445554002916905664936468389821\r\n                ];\r\n\r\n        return this._gaussKronrod(interval, f, 11, xgk, wg, wgk, resultObj);\r\n    },\r\n\r\n    /**\r\n     * 31 point Gauss-Kronrod quadrature algorithm, see the library QUADPACK\r\n     * @param {Array} interval The integration interval, e.g. [0, 3].\r\n     * @param {function} f A function which takes one argument of type number and returns a number.\r\n     * @param {Object} resultObj Object returning resultObj.abserr, resultObj.resabs, resultObj.resasc. See the library\r\n     *  QUADPACK for an explanation.\r\n     *\r\n     * @returns {Number} Integral value of f over interval\r\n     *\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    GaussKronrod31: function (interval, f, resultObj) {\r\n        /* Gauss quadrature weights and kronrod quadrature abscissae and\r\n                weights as evaluated with 80 decimal digit arithmetic by\r\n                L. W. Fullerton, Bell Labs, Nov. 1981. */\r\n\r\n        var xgk =\r\n            /* abscissae of the 21-point kronrod rule */\r\n            [\r\n                0.998002298693397060285172840152271, 0.987992518020485428489565718586613,\r\n                0.967739075679139134257347978784337, 0.937273392400705904307758947710209,\r\n                0.897264532344081900882509656454496, 0.848206583410427216200648320774217,\r\n                0.790418501442465932967649294817947, 0.724417731360170047416186054613938,\r\n                0.650996741297416970533735895313275, 0.570972172608538847537226737253911,\r\n                0.485081863640239680693655740232351, 0.394151347077563369897207370981045,\r\n                0.299180007153168812166780024266389, 0.201194093997434522300628303394596,\r\n                0.101142066918717499027074231447392, 0.0\r\n            ],\r\n            /* xgk[1], xgk[3], ... abscissae of the 10-point gauss rule.\r\n                xgk[0], xgk[2], ... abscissae to optimally extend the 10-point gauss rule */\r\n            wg =\r\n                /* weights of the 10-point gauss rule */\r\n                [\r\n                    0.030753241996117268354628393577204, 0.070366047488108124709267416450667,\r\n                    0.107159220467171935011869546685869, 0.139570677926154314447804794511028,\r\n                    0.166269205816993933553200860481209, 0.186161000015562211026800561866423,\r\n                    0.198431485327111576456118326443839, 0.202578241925561272880620199967519\r\n                ],\r\n            wgk =\r\n                /* weights of the 21-point kronrod rule */\r\n                [\r\n                    0.005377479872923348987792051430128, 0.015007947329316122538374763075807,\r\n                    0.025460847326715320186874001019653, 0.03534636079137584622203794847836,\r\n                    0.04458975132476487660822729937328, 0.05348152469092808726534314723943,\r\n                    0.062009567800670640285139230960803, 0.069854121318728258709520077099147,\r\n                    0.076849680757720378894432777482659, 0.083080502823133021038289247286104,\r\n                    0.088564443056211770647275443693774, 0.093126598170825321225486872747346,\r\n                    0.096642726983623678505179907627589, 0.099173598721791959332393173484603,\r\n                    0.10076984552387559504494666261757, 0.101330007014791549017374792767493\r\n                ];\r\n\r\n        return this._gaussKronrod(interval, f, 16, xgk, wg, wgk, resultObj);\r\n    },\r\n\r\n    /**\r\n     * Generate workspace object for {@link JXG.Math.Numerics.Qag}.\r\n     * @param {Array} interval The integration interval, e.g. [0, 3].\r\n     * @param {Number} n Max. limit\r\n     * @returns {Object} Workspace object\r\n     *\r\n     * @private\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    _workspace: function (interval, n) {\r\n        return {\r\n            limit: n,\r\n            size: 0,\r\n            nrmax: 0,\r\n            i: 0,\r\n            alist: [interval[0]],\r\n            blist: [interval[1]],\r\n            rlist: [0.0],\r\n            elist: [0.0],\r\n            order: [0],\r\n            level: [0],\r\n\r\n            qpsrt: function () {\r\n                var last = this.size - 1,\r\n                    limit = this.limit,\r\n                    errmax,\r\n                    errmin,\r\n                    i,\r\n                    k,\r\n                    top,\r\n                    i_nrmax = this.nrmax,\r\n                    i_maxerr = this.order[i_nrmax];\r\n\r\n                /* Check whether the list contains more than two error estimates */\r\n                if (last < 2) {\r\n                    this.order[0] = 0;\r\n                    this.order[1] = 1;\r\n                    this.i = i_maxerr;\r\n                    return;\r\n                }\r\n\r\n                errmax = this.elist[i_maxerr];\r\n\r\n                /* This part of the routine is only executed if, due to a difficult\r\n                        integrand, subdivision increased the error estimate. In the normal\r\n                        case the insert procedure should start after the nrmax-th largest\r\n                        error estimate. */\r\n                while (i_nrmax > 0 && errmax > this.elist[this.order[i_nrmax - 1]]) {\r\n                    this.order[i_nrmax] = this.order[i_nrmax - 1];\r\n                    i_nrmax--;\r\n                }\r\n\r\n                /* Compute the number of elements in the list to be maintained in\r\n                        descending order. This number depends on the number of\r\n                        subdivisions still allowed. */\r\n                if (last < limit / 2 + 2) {\r\n                    top = last;\r\n                } else {\r\n                    top = limit - last + 1;\r\n                }\r\n\r\n                /* Insert errmax by traversing the list top-down, starting\r\n                        comparison from the element elist(order(i_nrmax+1)). */\r\n                i = i_nrmax + 1;\r\n\r\n                /* The order of the tests in the following line is important to\r\n                        prevent a segmentation fault */\r\n                while (i < top && errmax < this.elist[this.order[i]]) {\r\n                    this.order[i - 1] = this.order[i];\r\n                    i++;\r\n                }\r\n\r\n                this.order[i - 1] = i_maxerr;\r\n\r\n                /* Insert errmin by traversing the list bottom-up */\r\n                errmin = this.elist[last];\r\n                k = top - 1;\r\n\r\n                while (k > i - 2 && errmin >= this.elist[this.order[k]]) {\r\n                    this.order[k + 1] = this.order[k];\r\n                    k--;\r\n                }\r\n\r\n                this.order[k + 1] = last;\r\n\r\n                /* Set i_max and e_max */\r\n                i_maxerr = this.order[i_nrmax];\r\n                this.i = i_maxerr;\r\n                this.nrmax = i_nrmax;\r\n            },\r\n\r\n            set_initial_result: function (result, error) {\r\n                this.size = 1;\r\n                this.rlist[0] = result;\r\n                this.elist[0] = error;\r\n            },\r\n\r\n            update: function (a1, b1, area1, error1, a2, b2, area2, error2) {\r\n                var i_max = this.i,\r\n                    i_new = this.size,\r\n                    new_level = this.level[this.i] + 1;\r\n\r\n                /* append the newly-created intervals to the list */\r\n\r\n                if (error2 > error1) {\r\n                    this.alist[i_max] = a2; /* blist[maxerr] is already == b2 */\r\n                    this.rlist[i_max] = area2;\r\n                    this.elist[i_max] = error2;\r\n                    this.level[i_max] = new_level;\r\n\r\n                    this.alist[i_new] = a1;\r\n                    this.blist[i_new] = b1;\r\n                    this.rlist[i_new] = area1;\r\n                    this.elist[i_new] = error1;\r\n                    this.level[i_new] = new_level;\r\n                } else {\r\n                    this.blist[i_max] = b1; /* alist[maxerr] is already == a1 */\r\n                    this.rlist[i_max] = area1;\r\n                    this.elist[i_max] = error1;\r\n                    this.level[i_max] = new_level;\r\n\r\n                    this.alist[i_new] = a2;\r\n                    this.blist[i_new] = b2;\r\n                    this.rlist[i_new] = area2;\r\n                    this.elist[i_new] = error2;\r\n                    this.level[i_new] = new_level;\r\n                }\r\n\r\n                this.size++;\r\n\r\n                if (new_level > this.maximum_level) {\r\n                    this.maximum_level = new_level;\r\n                }\r\n\r\n                this.qpsrt();\r\n            },\r\n\r\n            retrieve: function () {\r\n                var i = this.i;\r\n                return {\r\n                    a: this.alist[i],\r\n                    b: this.blist[i],\r\n                    r: this.rlist[i],\r\n                    e: this.elist[i]\r\n                };\r\n            },\r\n\r\n            sum_results: function () {\r\n                var nn = this.size,\r\n                    k,\r\n                    result_sum = 0.0;\r\n\r\n                for (k = 0; k < nn; k++) {\r\n                    result_sum += this.rlist[k];\r\n                }\r\n\r\n                return result_sum;\r\n            },\r\n\r\n            subinterval_too_small: function (a1, a2, b2) {\r\n                var e = 2.2204460492503131e-16,\r\n                    u = 2.2250738585072014e-308,\r\n                    tmp = (1 + 100 * e) * (Math.abs(a2) + 1000 * u);\r\n\r\n                return Math.abs(a1) <= tmp && Math.abs(b2) <= tmp;\r\n            }\r\n        };\r\n    },\r\n\r\n    /**\r\n     * Quadrature algorithm qag from QUADPACK.\r\n     * Internal method used in {@link JXG.Math.Numerics.GaussKronrod15},\r\n     * {@link JXG.Math.Numerics.GaussKronrod21},\r\n     * {@link JXG.Math.Numerics.GaussKronrod31}.\r\n     *\r\n     * @param {Array} interval The integration interval, e.g. [0, 3].\r\n     * @param {function} f A function which takes one argument of type number and returns a number.\r\n     * @param {Object} [config] The algorithm setup. Accepted propert are max. recursion limit of type number,\r\n     * and epsrel and epsabs, the relative and absolute required precision of type number. Further,\r\n     * q the internal quadrature sub-algorithm of type function.\r\n     * @param {Number} [config.limit=15]\r\n     * @param {Number} [config.epsrel=0.0000001]\r\n     * @param {Number} [config.epsabs=0.0000001]\r\n     * @param {Number} [config.q=JXG.Math.Numerics.GaussKronrod15]\r\n     * @returns {Number} Integral value of f over interval\r\n     *\r\n     * @example\r\n     * function f(x) {\r\n     *   return x*x;\r\n     * }\r\n     *\r\n     * // calculates integral of <tt>f</tt> from 0 to 2.\r\n     * var area1 = JXG.Math.Numerics.Qag([0, 2], f);\r\n     *\r\n     * // the same with an anonymous function\r\n     * var area2 = JXG.Math.Numerics.Qag([0, 2], function (x) { return x*x; });\r\n     *\r\n     * // use JXG.Math.Numerics.GaussKronrod31 rule as sub-algorithm.\r\n     * var area3 = JXG.Math.Numerics.Quag([0, 2], f,\r\n     *                                   {q: JXG.Math.Numerics.GaussKronrod31});\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    Qag: function (interval, f, config) {\r\n        var DBL_EPS = 2.2204460492503131e-16,\r\n            ws = this._workspace(interval, 1000),\r\n            limit = config && Type.isNumber(config.limit) ? config.limit : 15,\r\n            epsrel = config && Type.isNumber(config.epsrel) ? config.epsrel : 0.0000001,\r\n            epsabs = config && Type.isNumber(config.epsabs) ? config.epsabs : 0.0000001,\r\n            q = config && Type.isFunction(config.q) ? config.q : this.GaussKronrod15,\r\n            resultObj = {},\r\n            area,\r\n            errsum,\r\n            result0,\r\n            abserr0,\r\n            resabs0,\r\n            resasc0,\r\n            result,\r\n            tolerance,\r\n            iteration = 0,\r\n            roundoff_type1 = 0,\r\n            roundoff_type2 = 0,\r\n            error_type = 0,\r\n            round_off,\r\n            a1,\r\n            b1,\r\n            a2,\r\n            b2,\r\n            a_i,\r\n            b_i,\r\n            r_i,\r\n            e_i,\r\n            area1 = 0,\r\n            area2 = 0,\r\n            area12 = 0,\r\n            error1 = 0,\r\n            error2 = 0,\r\n            error12 = 0,\r\n            resasc1,\r\n            resasc2,\r\n            // resabs1, resabs2,\r\n            wsObj,\r\n            delta;\r\n\r\n        if (limit > ws.limit) {\r\n            JXG.warn(\"iteration limit exceeds available workspace\");\r\n        }\r\n        if (epsabs <= 0 && (epsrel < 50 * Mat.eps || epsrel < 0.5e-28)) {\r\n            JXG.warn(\"tolerance cannot be acheived with given epsabs and epsrel\");\r\n        }\r\n\r\n        result0 = q.apply(this, [interval, f, resultObj]);\r\n        abserr0 = resultObj.abserr;\r\n        resabs0 = resultObj.resabs;\r\n        resasc0 = resultObj.resasc;\r\n\r\n        ws.set_initial_result(result0, abserr0);\r\n        tolerance = Math.max(epsabs, epsrel * Math.abs(result0));\r\n        round_off = 50 * DBL_EPS * resabs0;\r\n\r\n        if (abserr0 <= round_off && abserr0 > tolerance) {\r\n            result = result0;\r\n            // abserr = abserr0;\r\n\r\n            JXG.warn(\"cannot reach tolerance because of roundoff error on first attempt\");\r\n            return -Infinity;\r\n        }\r\n\r\n        if ((abserr0 <= tolerance && abserr0 !== resasc0) || abserr0 === 0.0) {\r\n            result = result0;\r\n            // abserr = abserr0;\r\n\r\n            return result;\r\n        }\r\n\r\n        if (limit === 1) {\r\n            result = result0;\r\n            // abserr = abserr0;\r\n\r\n            JXG.warn(\"a maximum of one iteration was insufficient\");\r\n            return -Infinity;\r\n        }\r\n\r\n        area = result0;\r\n        errsum = abserr0;\r\n        iteration = 1;\r\n\r\n        do {\r\n            area1 = 0;\r\n            area2 = 0;\r\n            area12 = 0;\r\n            error1 = 0;\r\n            error2 = 0;\r\n            error12 = 0;\r\n\r\n            /* Bisect the subinterval with the largest error estimate */\r\n            wsObj = ws.retrieve();\r\n            a_i = wsObj.a;\r\n            b_i = wsObj.b;\r\n            r_i = wsObj.r;\r\n            e_i = wsObj.e;\r\n\r\n            a1 = a_i;\r\n            b1 = 0.5 * (a_i + b_i);\r\n            a2 = b1;\r\n            b2 = b_i;\r\n\r\n            area1 = q.apply(this, [[a1, b1], f, resultObj]);\r\n            error1 = resultObj.abserr;\r\n            // resabs1 = resultObj.resabs;\r\n            resasc1 = resultObj.resasc;\r\n\r\n            area2 = q.apply(this, [[a2, b2], f, resultObj]);\r\n            error2 = resultObj.abserr;\r\n            // resabs2 = resultObj.resabs;\r\n            resasc2 = resultObj.resasc;\r\n\r\n            area12 = area1 + area2;\r\n            error12 = error1 + error2;\r\n\r\n            errsum += error12 - e_i;\r\n            area += area12 - r_i;\r\n\r\n            if (resasc1 !== error1 && resasc2 !== error2) {\r\n                delta = r_i - area12;\r\n                if (Math.abs(delta) <= 1.0e-5 * Math.abs(area12) && error12 >= 0.99 * e_i) {\r\n                    roundoff_type1++;\r\n                }\r\n                if (iteration >= 10 && error12 > e_i) {\r\n                    roundoff_type2++;\r\n                }\r\n            }\r\n\r\n            tolerance = Math.max(epsabs, epsrel * Math.abs(area));\r\n\r\n            if (errsum > tolerance) {\r\n                if (roundoff_type1 >= 6 || roundoff_type2 >= 20) {\r\n                    error_type = 2; /* round off error */\r\n                }\r\n\r\n                /* set error flag in the case of bad integrand behaviour at\r\n                    a point of the integration range */\r\n\r\n                if (ws.subinterval_too_small(a1, a2, b2)) {\r\n                    error_type = 3;\r\n                }\r\n            }\r\n\r\n            ws.update(a1, b1, area1, error1, a2, b2, area2, error2);\r\n            wsObj = ws.retrieve();\r\n            a_i = wsObj.a_i;\r\n            b_i = wsObj.b_i;\r\n            r_i = wsObj.r_i;\r\n            e_i = wsObj.e_i;\r\n\r\n            iteration++;\r\n        } while (iteration < limit && !error_type && errsum > tolerance);\r\n\r\n        result = ws.sum_results();\r\n        // abserr = errsum;\r\n        /*\r\n  if (errsum <= tolerance)\r\n    {\r\n      return GSL_SUCCESS;\r\n    }\r\n  else if (error_type == 2)\r\n    {\r\n      GSL_ERROR (\"roundoff error prevents tolerance from being achieved\",\r\n                 GSL_EROUND);\r\n    }\r\n  else if (error_type == 3)\r\n    {\r\n      GSL_ERROR (\"bad integrand behavior found in the integration interval\",\r\n                 GSL_ESING);\r\n    }\r\n  else if (iteration == limit)\r\n    {\r\n      GSL_ERROR (\"maximum number of subdivisions reached\", GSL_EMAXITER);\r\n    }\r\n  else\r\n    {\r\n      GSL_ERROR (\"could not integrate function\", GSL_EFAILED);\r\n    }\r\n*/\r\n\r\n        return result;\r\n    },\r\n\r\n    /**\r\n     * Integral of function f over interval.\r\n     * @param {Array} interval The integration interval, e.g. [0, 3].\r\n     * @param {function} f A function which takes one argument of type number and returns a number.\r\n     * @returns {Number} The value of the integral of f over interval\r\n     * @see JXG.Math.Numerics.NewtonCotes\r\n     * @see JXG.Math.Numerics.Romberg\r\n     * @see JXG.Math.Numerics.Qag\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    I: function (interval, f) {\r\n        // return this.NewtonCotes(interval, f, {number_of_nodes: 16, integration_type: 'milne'});\r\n        // return this.Romberg(interval, f, {max_iterations: 20, eps: 0.0000001});\r\n        return this.Qag(interval, f, {\r\n            q: this.GaussKronrod15,\r\n            limit: 15,\r\n            epsrel: 0.0000001,\r\n            epsabs: 0.0000001\r\n        });\r\n    },\r\n\r\n    /**\r\n     * Newton's method to find roots of a funtion in one variable.\r\n     * @param {function} f We search for a solution of f(x)=0.\r\n     * @param {Number} x initial guess for the root, i.e. start value.\r\n     * @param {Object} context optional object that is treated as \"this\" in the function body. This is useful if\r\n     * the function is a method of an object and contains a reference to its parent object via \"this\".\r\n     * @returns {Number} A root of the function f.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    Newton: function (f, x, context) {\r\n        var df,\r\n            i = 0,\r\n            h = Mat.eps,\r\n            newf = f.apply(context, [x]);\r\n        // nfev = 1;\r\n\r\n        // For compatibility\r\n        if (Type.isArray(x)) {\r\n            x = x[0];\r\n        }\r\n\r\n        while (i < 50 && Math.abs(newf) > h) {\r\n            df = this.D(f, context)(x);\r\n            // nfev += 2;\r\n\r\n            if (Math.abs(df) > h) {\r\n                x -= newf / df;\r\n            } else {\r\n                x += Math.random() * 0.2 - 1.0;\r\n            }\r\n\r\n            newf = f.apply(context, [x]);\r\n            // nfev += 1;\r\n            i += 1;\r\n        }\r\n\r\n        return x;\r\n    },\r\n\r\n    /**\r\n     * Abstract method to find roots of univariate functions, which - for the time being -\r\n     * is an alias for {@link JXG.Math.Numerics.chandrupatla}.\r\n     * @param {function} f We search for a solution of f(x)=0.\r\n     * @param {Number|Array} x initial guess for the root, i.e. starting value, or start interval enclosing the root.\r\n     * If x is an interval [a,b], it is required that f(a)f(b) <= 0, otherwise the minimum of f in [a, b] will be returned.\r\n     * If x is a number, the algorithms tries to enclose the root by an interval [a, b] containing x and the root and\r\n     * f(a)f(b) <= 0. If this fails, the algorithm falls back to Newton's method.\r\n     *\r\n     * @param {Object} context optional object that is treated as \"this\" in the function body. This is useful if\r\n     * the function is a method of an object and contains a reference to its parent object via \"this\".\r\n     * @returns {Number} A root of the function f.\r\n     *\r\n     * @see JXG.Math.Numerics.chandrupatla\r\n     * @see JXG.Math.Numerics.fzero\r\n     * @see JXG.Math.Numerics.polzeros\r\n     * @see JXG.Math.Numerics.Newton\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    root: function (f, x, context) {\r\n        //return this.fzero(f, x, context);\r\n        return this.chandrupatla(f, x, context);\r\n    },\r\n\r\n    /**\r\n     * Compute an intersection of the curves c1 and c2\r\n     * with a generalized Newton method (Newton-Raphson).\r\n     * We want to find values t1, t2 such that\r\n     * c1(t1) = c2(t2), i.e.\r\n     * <br>\r\n     * (c1_x(t1) - c2_x(t2), c1_y(t1) - c2_y(t2)) = (0, 0).\r\n     * <p>\r\n     * We set\r\n     * (e, f) := (c1_x(t1) - c2_x(t2), c1_y(t1) - c2_y(t2))\r\n     * <p>\r\n     * The Jacobian J is defined by\r\n     * <pre>\r\n     * J = (a, b)\r\n     *     (c, d)\r\n     * </pre>\r\n     * where\r\n     * <ul>\r\n     * <li> a = c1_x'(t1)\r\n     * <li> b = -c2_x'(t2)\r\n     * <li> c = c1_y'(t1)\r\n     * <li> d = -c2_y'(t2)\r\n     * </ul>\r\n     * The inverse J^(-1) of J is equal to\r\n     * <pre>\r\n     *  (d, -b) / (ad - bc)\r\n     *  (-c, a) / (ad - bc)\r\n     * </pre>\r\n     *\r\n     * Then, (t1new, t2new) := (t1,t2) - J^(-1)*(e,f).\r\n     * <p>\r\n     *\r\n     * @param {JXG.Curve} c1 Curve, Line or Circle\r\n     * @param {JXG.Curve} c2 Curve, Line or Circle\r\n     * @param {Number} t1ini start value for t1\r\n     * @param {Number} t2ini start value for t2\r\n     * @returns {JXG.Coords} intersection point\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    generalizedNewton: function (c1, c2, t1ini, t2ini) {\r\n        var t1, t2,\r\n            a, b, c, d, e, f,\r\n            disc,\r\n            F,\r\n            D00, D01, D10, D11,\r\n            count = 0;\r\n\r\n        // if (this.generalizedNewton.t1memo) {\r\n        //     t1 = this.generalizedNewton.t1memo;\r\n        //     t2 = this.generalizedNewton.t2memo;\r\n        // } else {\r\n        t1 = t1ini;\r\n        t2 = t2ini;\r\n        // }\r\n\r\n        e = c1.X(t1) - c2.X(t2);\r\n        f = c1.Y(t1) - c2.Y(t2);\r\n        F = e * e + f * f;\r\n\r\n        D00 = this.D(c1.X, c1);\r\n        D01 = this.D(c2.X, c2);\r\n        D10 = this.D(c1.Y, c1);\r\n        D11 = this.D(c2.Y, c2);\r\n\r\n        while (F > Mat.eps && count < 10) {\r\n            a = D00(t1);\r\n            b = -D01(t2);\r\n            c = D10(t1);\r\n            d = -D11(t2);\r\n            disc = a * d - b * c;\r\n            t1 -= (d * e - b * f) / disc;\r\n            t2 -= (a * f - c * e) / disc;\r\n            e = c1.X(t1) - c2.X(t2);\r\n            f = c1.Y(t1) - c2.Y(t2);\r\n            F = e * e + f * f;\r\n            count += 1;\r\n        }\r\n\r\n        // this.generalizedNewton.t1memo = t1;\r\n        // this.generalizedNewton.t2memo = t2;\r\n\r\n        if (Math.abs(t1) < Math.abs(t2)) {\r\n            return [c1.X(t1), c1.Y(t1)];\r\n        }\r\n\r\n        return [c2.X(t2), c2.Y(t2)];\r\n    },\r\n\r\n    /**\r\n     * Apply damped Newton-Raphson algorithm to determine the intersection\r\n     * between the curve elements c1 and c2. Transformations of the curves\r\n     * are already taken into regard.\r\n     * <p>\r\n     * We use a very high accuracy: Mat.eps**3\r\n     *\r\n     * @deprecated\r\n     * @param {JXG.Curve} c1 Curve, Line or Circle\r\n     * @param {JXG.Curve} c2 Curve, Line or Circle\r\n     * @param {Number} t1ini Start value for curve c1\r\n     * @param {Number} t2ini Start value for curve c2\r\n     * @param {Number} gamma Damping factor, should be in the open interval (0, 1)\r\n     * @param {Number} eps Stop if function value is smaller than eps\r\n     * @returns {Array} [t1, t2, F2], where t1 and t2 are the parameters of the intersection for both curves, F2 is ||c1[t1]-c2[t2]||**2.\r\n     */\r\n    generalizedDampedNewtonCurves: function (c1, c2, t1ini, t2ini, gamma, eps) {\r\n        var t1, t2,\r\n            a, b, c, d, e, f,\r\n            disc,\r\n            F2,\r\n            f1, f2,\r\n            D, Dt,\r\n            max_it = 40,\r\n            count = 0;\r\n\r\n        t1 = t1ini;\r\n        t2 = t2ini;\r\n\r\n        f1 = c1.Ft(t1);\r\n        f2 = c2.Ft(t2);\r\n        e = f1[1] - f2[1];\r\n        f = f1[2] - f2[2];\r\n        F2 = e * e + f * f;\r\n\r\n        D = function(t1, t2) {\r\n            var h = Mat.eps,\r\n                f1_1 = c1.Ft(t1 - h),\r\n                f1_2 = c1.Ft(t1 + h),\r\n                f2_1 = c2.Ft(t2 - h),\r\n                f2_2 = c2.Ft(t2 + h);\r\n            return [\r\n                [ (f1_2[1] - f1_1[1]) / (2 * h),\r\n                 -(f2_2[1] - f2_1[1]) / (2 * h)],\r\n                [ (f1_2[2] - f1_1[2]) / (2 * h),\r\n                 -(f2_2[2] - f2_1[2]) / (2 * h)]\r\n            ];\r\n        };\r\n\r\n        while (F2 > eps && count < max_it) {\r\n            Dt = D(t1, t2);\r\n            a = Dt[0][0];\r\n            b = Dt[0][1];\r\n            c = Dt[1][0];\r\n            d = Dt[1][1];\r\n\r\n            disc = a * d - b * c;\r\n            t1 -= gamma * (d * e - b * f) / disc;\r\n            t2 -= gamma * (a * f - c * e) / disc;\r\n            f1 = c1.Ft(t1);\r\n            f2 = c2.Ft(t2);\r\n\r\n            e = f1[1] - f2[1];\r\n            f = f1[2] - f2[2];\r\n            F2 = e * e + f * f;\r\n            count += 1;\r\n        }\r\n\r\n        return [t1, t2, F2];\r\n    },\r\n\r\n    /**\r\n     * Apply the damped Newton-Raphson algorithm to determine to find a root of a\r\n     * function F: R^n to R^n.\r\n     *\r\n     * @param {Function} F Function with n parameters, returns a vactor of length n.\r\n     * @param {Function} D Function returning the Jacobian matrix (n \\times n) of F\r\n     * @param {Number} n\r\n     * @param {Array} t_ini Array of length n, containing start values\r\n     * @param {Number} gamma Damping factor should be between 0 and 1. If equal to 1,\r\n     * the algorithm is Newton-Raphson.\r\n     * @param {Number} eps The algorithm stops if the square norm of the root is less than this eps\r\n     * or if the maximum number of steps is reached.\r\n     * @param {Number} [max_steps=40] maximum number of steps\r\n     * @returns {Array} [t, F2] array of length, containing t, the approximation of the root (array of length n),\r\n     * and the square norm of F(t).\r\n     */\r\n    generalizedDampedNewton: function (F, D, n, t_ini, gamma, eps, max_steps) {\r\n        var i,\r\n            t = [],\r\n            a, b, c, d, e, f,\r\n            disc,\r\n            Ft, Dt,\r\n            F2, vec,\r\n            count = 0;\r\n\r\n        max_steps = max_steps || 40;\r\n\r\n        t = t_ini.slice(0, n);\r\n        Ft = F(t, n);\r\n\r\n        if (n === 2) {\r\n            // Special case n = 2\r\n            Ft = F(t, n);\r\n            e = Ft[0];\r\n            f = Ft[1];\r\n            F2 = e * e + f * f;\r\n\r\n            while (F2 > eps && count < max_steps) {\r\n                Dt = D(t, n);\r\n\r\n                a = Dt[0][0];\r\n                b = Dt[0][1];\r\n                c = Dt[1][0];\r\n                d = Dt[1][1];\r\n\r\n                disc = a * d - b * c;\r\n                t[0] -= gamma * (d * e - b * f) / disc;\r\n                t[1] -= gamma * (a * f - c * e) / disc;\r\n\r\n                Ft = F(t, n);\r\n                e = Ft[0];\r\n                f = Ft[1];\r\n                F2 = e * e + f * f;\r\n\r\n                count += 1;\r\n            }\r\n\r\n            return [t, F2];\r\n        } else {\r\n            // General case, arbitrary n\r\n            Ft = F(t, n);\r\n            F2 = Mat.innerProduct(Ft, Ft, n);\r\n\r\n            while (F2 > eps && count < max_steps) {\r\n                Dt = Mat.inverse(D(t, n));\r\n\r\n                vec = Mat.matVecMult(Dt, Ft);\r\n                for (i = 0; i < n; i++) {\r\n                    t[i] -= gamma * vec[i];\r\n                }\r\n\r\n                Ft = F(t, n);\r\n                F2 = Mat.innerProduct(Ft, Ft, n);\r\n\r\n                count += 1;\r\n            }\r\n\r\n            return [t, F2];\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Returns the Lagrange polynomials for curves with equidistant nodes, see\r\n     * Jean-Paul Berrut, Lloyd N. Trefethen: Barycentric Lagrange Interpolation,\r\n     * SIAM Review, Vol 46, No 3, (2004) 501-517.\r\n     * The graph of the parametric curve [x(t),y(t)] runs through the given points.\r\n     * @param {Array} p Array of JXG.Points\r\n     * @returns {Array} An array consisting of two functions x(t), y(t) which define a parametric curve\r\n     * f(t) = (x(t), y(t)), a number x1 (which equals 0) and a function x2 defining the curve's domain.\r\n     * That means the curve is defined between x1 and x2(). x2 returns the (length of array p minus one).\r\n     * @memberof JXG.Math.Numerics\r\n     *\r\n     * @example\r\n     * var p = [];\r\n     *\r\n     * p[0] = board.create('point', [0, -2], {size:2, name: 'C(a)'});\r\n     * p[1] = board.create('point', [-1.5, 5], {size:2, name: ''});\r\n     * p[2] = board.create('point', [1, 4], {size:2, name: ''});\r\n     * p[3] = board.create('point', [3, 3], {size:2, name: 'C(b)'});\r\n     *\r\n     * // Curve\r\n     * var fg = JXG.Math.Numerics.Neville(p);\r\n     * var graph = board.create('curve', fg, {strokeWidth:3, strokeOpacity:0.5});\r\n     *\r\n     * </pre><div id=\"JXG88a8b3a8-6561-44f5-a678-76bca13fd484\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXG88a8b3a8-6561-44f5-a678-76bca13fd484',\r\n     *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n     *     var p = [];\r\n     *\r\n     *     p[0] = board.create('point', [0, -2], {size:2, name: 'C(a)'});\r\n     *     p[1] = board.create('point', [-1.5, 5], {size:2, name: ''});\r\n     *     p[2] = board.create('point', [1, 4], {size:2, name: ''});\r\n     *     p[3] = board.create('point', [3, 3], {size:2, name: 'C(b)'});\r\n     *\r\n     *     // Curve\r\n     *     var fg = JXG.Math.Numerics.Neville(p);\r\n     *     var graph = board.create('curve', fg, {strokeWidth:3, strokeOpacity:0.5});\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     */\r\n    Neville: function (p) {\r\n        var w = [],\r\n            /** @ignore */\r\n            makeFct = function (fun) {\r\n                return function (t, suspendedUpdate) {\r\n                    var i,\r\n                        d,\r\n                        s,\r\n                        bin = Mat.binomial,\r\n                        len = p.length,\r\n                        len1 = len - 1,\r\n                        num = 0.0,\r\n                        denom = 0.0;\r\n\r\n                    if (!suspendedUpdate) {\r\n                        s = 1;\r\n                        for (i = 0; i < len; i++) {\r\n                            w[i] = bin(len1, i) * s;\r\n                            s *= -1;\r\n                        }\r\n                    }\r\n\r\n                    d = t;\r\n\r\n                    for (i = 0; i < len; i++) {\r\n                        if (d === 0) {\r\n                            return p[i][fun]();\r\n                        }\r\n                        s = w[i] / d;\r\n                        d -= 1;\r\n                        num += p[i][fun]() * s;\r\n                        denom += s;\r\n                    }\r\n                    return num / denom;\r\n                };\r\n            },\r\n            xfct = makeFct('X'),\r\n            yfct = makeFct('Y');\r\n\r\n        return [\r\n            xfct,\r\n            yfct,\r\n            0,\r\n            function () {\r\n                return p.length - 1;\r\n            }\r\n        ];\r\n    },\r\n\r\n    /**\r\n     * Calculates second derivatives at the given knots.\r\n     * @param {Array} x x values of knots\r\n     * @param {Array} y y values of knots\r\n     * @returns {Array} Second derivatives of the interpolated function at the knots.\r\n     * @see JXG.Math.Numerics.splineEval\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    splineDef: function (x, y) {\r\n        var pair,\r\n            i,\r\n            l,\r\n            n = Math.min(x.length, y.length),\r\n            diag = [],\r\n            z = [],\r\n            data = [],\r\n            dx = [],\r\n            delta = [],\r\n            F = [];\r\n\r\n        if (n === 2) {\r\n            return [0, 0];\r\n        }\r\n\r\n        for (i = 0; i < n; i++) {\r\n            pair = { X: x[i], Y: y[i] };\r\n            data.push(pair);\r\n        }\r\n        data.sort(function (a, b) {\r\n            return a.X - b.X;\r\n        });\r\n        for (i = 0; i < n; i++) {\r\n            x[i] = data[i].X;\r\n            y[i] = data[i].Y;\r\n        }\r\n\r\n        for (i = 0; i < n - 1; i++) {\r\n            dx.push(x[i + 1] - x[i]);\r\n        }\r\n        for (i = 0; i < n - 2; i++) {\r\n            delta.push(\r\n                (6 * (y[i + 2] - y[i + 1])) / dx[i + 1] - (6 * (y[i + 1] - y[i])) / dx[i]\r\n            );\r\n        }\r\n\r\n        // ForwardSolve\r\n        diag.push(2 * (dx[0] + dx[1]));\r\n        z.push(delta[0]);\r\n\r\n        for (i = 0; i < n - 3; i++) {\r\n            l = dx[i + 1] / diag[i];\r\n            diag.push(2 * (dx[i + 1] + dx[i + 2]) - l * dx[i + 1]);\r\n            z.push(delta[i + 1] - l * z[i]);\r\n        }\r\n\r\n        // BackwardSolve\r\n        F[n - 3] = z[n - 3] / diag[n - 3];\r\n        for (i = n - 4; i >= 0; i--) {\r\n            F[i] = (z[i] - dx[i + 1] * F[i + 1]) / diag[i];\r\n        }\r\n\r\n        // Generate f''-Vector\r\n        for (i = n - 3; i >= 0; i--) {\r\n            F[i + 1] = F[i];\r\n        }\r\n\r\n        // natural cubic spline\r\n        F[0] = 0;\r\n        F[n - 1] = 0;\r\n\r\n        return F;\r\n    },\r\n\r\n    /**\r\n     * Evaluate points on spline.\r\n     * @param {Number|Array} x0 A single float value or an array of values to evaluate\r\n     * @param {Array} x x values of knots\r\n     * @param {Array} y y values of knots\r\n     * @param {Array} F Second derivatives at knots, calculated by {@link JXG.Math.Numerics.splineDef}\r\n     * @see JXG.Math.Numerics.splineDef\r\n     * @returns {Number|Array} A single value or an array, depending on what is given as x0.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    splineEval: function (x0, x, y, F) {\r\n        var i,\r\n            j,\r\n            a,\r\n            b,\r\n            c,\r\n            d,\r\n            x_,\r\n            n = Math.min(x.length, y.length),\r\n            l = 1,\r\n            asArray = false,\r\n            y0 = [];\r\n\r\n        // number of points to be evaluated\r\n        if (Type.isArray(x0)) {\r\n            l = x0.length;\r\n            asArray = true;\r\n        } else {\r\n            x0 = [x0];\r\n        }\r\n\r\n        for (i = 0; i < l; i++) {\r\n            // is x0 in defining interval?\r\n            if (x0[i] < x[0] || x[i] > x[n - 1]) {\r\n                return NaN;\r\n            }\r\n\r\n            // determine part of spline in which x0 lies\r\n            for (j = 1; j < n; j++) {\r\n                if (x0[i] <= x[j]) {\r\n                    break;\r\n                }\r\n            }\r\n\r\n            j -= 1;\r\n\r\n            // we're now in the j-th partial interval, i.e. x[j] < x0[i] <= x[j+1];\r\n            // determine the coefficients of the polynomial in this interval\r\n            a = y[j];\r\n            b =\r\n                (y[j + 1] - y[j]) / (x[j + 1] - x[j]) -\r\n                ((x[j + 1] - x[j]) / 6) * (F[j + 1] + 2 * F[j]);\r\n            c = F[j] / 2;\r\n            d = (F[j + 1] - F[j]) / (6 * (x[j + 1] - x[j]));\r\n            // evaluate x0[i]\r\n            x_ = x0[i] - x[j];\r\n            //y0.push(a + b*x_ + c*x_*x_ + d*x_*x_*x_);\r\n            y0.push(a + (b + (c + d * x_) * x_) * x_);\r\n        }\r\n\r\n        if (asArray) {\r\n            return y0;\r\n        }\r\n\r\n        return y0[0];\r\n    },\r\n\r\n    /**\r\n     * Generate a string containing the function term of a polynomial.\r\n     * @param {Array} coeffs Coefficients of the polynomial. The position i belongs to x^i.\r\n     * @param {Number} deg Degree of the polynomial\r\n     * @param {String} varname Name of the variable (usually 'x')\r\n     * @param {Number} prec Precision\r\n     * @returns {String} A string containing the function term of the polynomial.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    generatePolynomialTerm: function (coeffs, deg, varname, prec) {\r\n        var i,\r\n            t = [];\r\n\r\n        for (i = deg; i >= 0; i--) {\r\n            Type.concat(t, [\"(\", coeffs[i].toPrecision(prec), \")\"]);\r\n\r\n            if (i > 1) {\r\n                Type.concat(t, [\"*\", varname, \"<sup>\", i, \"<\", \"/sup> + \"]);\r\n            } else if (i === 1) {\r\n                Type.concat(t, [\"*\", varname, \" + \"]);\r\n            }\r\n        }\r\n\r\n        return t.join(\"\");\r\n    },\r\n\r\n    /**\r\n     * Computes the polynomial through a given set of coordinates in Lagrange form.\r\n     * Returns the Lagrange polynomials, see\r\n     * Jean-Paul Berrut, Lloyd N. Trefethen: Barycentric Lagrange Interpolation,\r\n     * SIAM Review, Vol 46, No 3, (2004) 501-517.\r\n     * <p>\r\n     * It possesses the method getTerm() which returns the string containing the function term of the polynomial and\r\n     * the method getCoefficients() which returns an array containing the coefficients of the polynomial.\r\n     * @param {Array} p Array of JXG.Points\r\n     * @returns {function} A function of one parameter which returns the value of the polynomial, whose graph runs through the given points.\r\n     * @memberof JXG.Math.Numerics\r\n     *\r\n     * @example\r\n     * var p = [];\r\n     * p[0] = board.create('point', [-1,2], {size:4});\r\n     * p[1] = board.create('point', [0,3], {size:4});\r\n     * p[2] = board.create('point', [1,1], {size:4});\r\n     * p[3] = board.create('point', [3,-1], {size:4});\r\n     * var f = JXG.Math.Numerics.lagrangePolynomial(p);\r\n     * var graph = board.create('functiongraph', [f,-10, 10], {strokeWidth:3});\r\n     *\r\n     * </pre><div id=\"JXGc058aa6b-74d4-41e1-af94-df06169a2d89\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXGc058aa6b-74d4-41e1-af94-df06169a2d89',\r\n     *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n     *     var p = [];\r\n     *     p[0] = board.create('point', [-1,2], {size:4});\r\n     *     p[1] = board.create('point', [0,3], {size:4});\r\n     *     p[2] = board.create('point', [1,1], {size:4});\r\n     *     p[3] = board.create('point', [3,-1], {size:4});\r\n     *     var f = JXG.Math.Numerics.lagrangePolynomial(p);\r\n     *     var graph = board.create('functiongraph', [f,-10, 10], {strokeWidth:3});\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     * @example\r\n     * var points = [];\r\n     * points[0] = board.create('point', [-1,2], {size:4});\r\n     * points[1] = board.create('point', [0, 0], {size:4});\r\n     * points[2] = board.create('point', [2, 1], {size:4});\r\n     *\r\n     * var f = JXG.Math.Numerics.lagrangePolynomial(points);\r\n     * var graph = board.create('functiongraph', [f,-10, 10], {strokeWidth:3});\r\n     * var txt = board.create('text', [-3, -4,  () => f.getTerm(2, 't', ' * ')], {fontSize: 16});\r\n     * var txt2 = board.create('text', [-3, -6,  () => f.getCoefficients()], {fontSize: 12});\r\n     *\r\n     * </pre><div id=\"JXG73fdaf12-e257-4374-b488-ae063e4eecbb\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXG73fdaf12-e257-4374-b488-ae063e4eecbb',\r\n     *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n     *     var points = [];\r\n     *     points[0] = board.create('point', [-1,2], {size:4});\r\n     *     points[1] = board.create('point', [0, 0], {size:4});\r\n     *     points[2] = board.create('point', [2, 1], {size:4});\r\n     *\r\n     *     var f = JXG.Math.Numerics.lagrangePolynomial(points);\r\n     *     var graph = board.create('functiongraph', [f,-10, 10], {strokeWidth:3});\r\n     *     var txt = board.create('text', [-3, -4,  () => f.getTerm(2, 't', ' * ')], {fontSize: 16});\r\n     *     var txt2 = board.create('text', [-3, -6,  () => f.getCoefficients()], {fontSize: 12});\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     */\r\n    lagrangePolynomial: function (p) {\r\n        var w = [],\r\n            that = this,\r\n            /** @ignore */\r\n            fct = function (x, suspendedUpdate) {\r\n                var i, // j,\r\n                    k,\r\n                    xi,\r\n                    s, //M,\r\n                    len = p.length,\r\n                    num = 0,\r\n                    denom = 0;\r\n\r\n                if (!suspendedUpdate) {\r\n                    for (i = 0; i < len; i++) {\r\n                        w[i] = 1.0;\r\n                        xi = p[i].X();\r\n\r\n                        for (k = 0; k < len; k++) {\r\n                            if (k !== i) {\r\n                                w[i] *= xi - p[k].X();\r\n                            }\r\n                        }\r\n\r\n                        w[i] = 1 / w[i];\r\n                    }\r\n\r\n                    // M = [];\r\n                    // for (k = 0; k < len; k++) {\r\n                    //     M.push([1]);\r\n                    // }\r\n                }\r\n\r\n                for (i = 0; i < len; i++) {\r\n                    xi = p[i].X();\r\n\r\n                    if (x === xi) {\r\n                        return p[i].Y();\r\n                    }\r\n\r\n                    s = w[i] / (x - xi);\r\n                    denom += s;\r\n                    num += s * p[i].Y();\r\n                }\r\n\r\n                return num / denom;\r\n            };\r\n\r\n        /**\r\n         * Get the term of the Lagrange polynomial as string.\r\n         * Calls {@link JXG.Math.Numerics#lagrangePolynomialTerm}.\r\n         *\r\n         * @name JXG.Math.Numerics.lagrangePolynomial#getTerm\r\n         * @param {Number} digits Number of digits of the coefficients\r\n         * @param {String} param Variable name\r\n         * @param {String} dot Dot symbol\r\n         * @returns {String} containing the term of Lagrange polynomial as string.\r\n         * @see JXG.Math.Numerics.lagrangePolynomialTerm\r\n         * @example\r\n         * var points = [];\r\n         * points[0] = board.create('point', [-1,2], {size:4});\r\n         * points[1] = board.create('point', [0, 0], {size:4});\r\n         * points[2] = board.create('point', [2, 1], {size:4});\r\n         *\r\n         * var f = JXG.Math.Numerics.lagrangePolynomial(points);\r\n         * var graph = board.create('functiongraph', [f,-10, 10], {strokeWidth:3});\r\n         * var txt = board.create('text', [-3, -4,  () => f.getTerm(2, 't', ' * ')], {fontSize: 16});\r\n         *\r\n         * </pre><div id=\"JXG73fdaf12-e257-4374-b488-ae063e4eeccf\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG73fdaf12-e257-4374-b488-ae063e4eeccf',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var points = [];\r\n         *     points[0] = board.create('point', [-1,2], {size:4});\r\n         *     points[1] = board.create('point', [0, 0], {size:4});\r\n         *     points[2] = board.create('point', [2, 1], {size:4});\r\n         *\r\n         *     var f = JXG.Math.Numerics.lagrangePolynomial(points);\r\n         *     var graph = board.create('functiongraph', [f,-10, 10], {strokeWidth:3});\r\n         *     var txt = board.create('text', [-3, -4,  () => f.getTerm(2, 't', ' * ')], {fontSize: 16});\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        fct.getTerm = function (digits, param, dot) {\r\n            return that.lagrangePolynomialTerm(p, digits, param, dot)();\r\n        };\r\n\r\n        /**\r\n         * Get the coefficients of the Lagrange polynomial as array. The leading\r\n         * coefficient is at position 0.\r\n         * Calls {@link JXG.Math.Numerics#lagrangePolynomialCoefficients}.\r\n         *\r\n         * @name JXG.Math.Numerics.lagrangePolynomial#getCoefficients\r\n         * @returns {Array} containing the coefficients of the Lagrange polynomial.\r\n         * @see JXG.Math.Numerics.lagrangePolynomial.getTerm\r\n         * @see JXG.Math.Numerics.lagrangePolynomialTerm\r\n         * @see JXG.Math.Numerics.lagrangePolynomialCoefficients\r\n         * @example\r\n         * var points = [];\r\n         * points[0] = board.create('point', [-1,2], {size:4});\r\n         * points[1] = board.create('point', [0, 0], {size:4});\r\n         * points[2] = board.create('point', [2, 1], {size:4});\r\n         *\r\n         * var f = JXG.Math.Numerics.lagrangePolynomial(points);\r\n         * var graph = board.create('functiongraph', [f,-10, 10], {strokeWidth:3});\r\n         * var txt = board.create('text', [1, -4,  () => f.getCoefficients()], {fontSize: 10});\r\n         *\r\n         * </pre><div id=\"JXG52a883a5-2e0c-4caf-8f84-8650c173c365\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG52a883a5-2e0c-4caf-8f84-8650c173c365',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var points = [];\r\n         *     points[0] = board.create('point', [-1,2], {size:4});\r\n         *     points[1] = board.create('point', [0, 0], {size:4});\r\n         *     points[2] = board.create('point', [2, 1], {size:4});\r\n         *\r\n         *     var f = JXG.Math.Numerics.lagrangePolynomial(points);\r\n         *     var graph = board.create('functiongraph', [f,-10, 10], {strokeWidth:3});\r\n         *     var txt = board.create('text', [1, -4,  () => f.getCoefficients()], {fontSize: 10});\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        fct.getCoefficients = function () {\r\n            return that.lagrangePolynomialCoefficients(p)();\r\n        };\r\n\r\n        return fct;\r\n    },\r\n\r\n    /**\r\n     * Determine the Lagrange polynomial through an array of points and\r\n     * return the term of the polynomial as string.\r\n     *\r\n     * @param {Array} points Array of JXG.Points\r\n     * @param {Number} digits Number of decimal digits of the coefficients\r\n     * @param {String} param Name of the parameter. Default: 'x'.\r\n     * @param {String} dot Multiplication symbol. Default: ' * '.\r\n     * @returns {Function} returning the Lagrange polynomial term through\r\n     *    the supplied points as string\r\n     * @memberof JXG.Math.Numerics\r\n     *\r\n     * @example\r\n     * var points = [];\r\n     * points[0] = board.create('point', [-1,2], {size:4});\r\n     * points[1] = board.create('point', [0, 0], {size:4});\r\n     * points[2] = board.create('point', [2, 1], {size:4});\r\n     *\r\n     * var f = JXG.Math.Numerics.lagrangePolynomial(points);\r\n     * var graph = board.create('functiongraph', [f,-10, 10], {strokeWidth:3});\r\n     *\r\n     * var f_txt = JXG.Math.Numerics.lagrangePolynomialTerm(points, 2, 't', ' * ');\r\n     * var txt = board.create('text', [-3, -4, f_txt], {fontSize: 16});\r\n     *\r\n     * </pre><div id=\"JXGd45e9e96-7526-486d-aa43-e1178d5f2baa\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXGd45e9e96-7526-486d-aa43-e1178d5f2baa',\r\n     *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n     *     var points = [];\r\n     *     points[0] = board.create('point', [-1,2], {size:4});\r\n     *     points[1] = board.create('point', [0, 0], {size:4});\r\n     *     points[2] = board.create('point', [2, 1], {size:4});\r\n     *\r\n     *     var f = JXG.Math.Numerics.lagrangePolynomial(points);\r\n     *     var graph = board.create('functiongraph', [f,-10, 10], {strokeWidth:3});\r\n     *\r\n     *     var f_txt = JXG.Math.Numerics.lagrangePolynomialTerm(points, 2, 't', ' * ');\r\n     *     var txt = board.create('text', [-3, -4, f_txt], {fontSize: 16});\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     */\r\n    lagrangePolynomialTerm: function (points, digits, param, dot) {\r\n        var that = this;\r\n\r\n        return function () {\r\n            var len = points.length,\r\n                coeffs = [],\r\n                isLeading = true,\r\n                n, t, j, c;\r\n\r\n            param = param || 'x';\r\n            if (dot === undefined) {\r\n                dot = \" * \";\r\n            }\r\n\r\n            n = len - 1; // (Max) degree of the polynomial\r\n            coeffs = that.lagrangePolynomialCoefficients(points)();\r\n\r\n            t = \"\";\r\n            for (j = 0; j < coeffs.length; j++) {\r\n                c = coeffs[j];\r\n                if (Math.abs(c) < Mat.eps) {\r\n                    continue;\r\n                }\r\n                if (JXG.exists(digits)) {\r\n                    c = Env._round10(c, -digits);\r\n                }\r\n                if (isLeading) {\r\n                    t += c > 0 ? c : \"-\" + -c;\r\n                    isLeading = false;\r\n                } else {\r\n                    t += c > 0 ? \" + \" + c : \" - \" + -c;\r\n                }\r\n\r\n                if (n - j > 1) {\r\n                    t += dot + param + \"^\" + (n - j);\r\n                } else if (n - j === 1) {\r\n                    t += dot + param;\r\n                }\r\n            }\r\n            return t; // board.jc.manipulate('f = map(x) -> ' + t + ';');\r\n        };\r\n    },\r\n\r\n    /**\r\n     * Determine the Lagrange polynomial through an array of points and\r\n     * return the coefficients of the polynomial as array.\r\n     * The leading coefficient is at position 0.\r\n     *\r\n     * @param {Array} points Array of JXG.Points\r\n     * @returns {Function} returning the coefficients of the Lagrange polynomial through\r\n     *    the supplied points.\r\n     * @memberof JXG.Math.Numerics\r\n     *\r\n     * @example\r\n     * var points = [];\r\n     * points[0] = board.create('point', [-1,2], {size:4});\r\n     * points[1] = board.create('point', [0, 0], {size:4});\r\n     * points[2] = board.create('point', [2, 1], {size:4});\r\n     *\r\n     * var f = JXG.Math.Numerics.lagrangePolynomial(points);\r\n     * var graph = board.create('functiongraph', [f,-10, 10], {strokeWidth:3});\r\n     *\r\n     * var f_arr = JXG.Math.Numerics.lagrangePolynomialCoefficients(points);\r\n     * var txt = board.create('text', [1, -4, f_arr], {fontSize: 10});\r\n     *\r\n     * </pre><div id=\"JXG1778f0d1-a420-473f-99e8-1755ef4be97e\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXG1778f0d1-a420-473f-99e8-1755ef4be97e',\r\n     *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n     *     var points = [];\r\n     *     points[0] = board.create('point', [-1,2], {size:4});\r\n     *     points[1] = board.create('point', [0, 0], {size:4});\r\n     *     points[2] = board.create('point', [2, 1], {size:4});\r\n     *\r\n     *     var f = JXG.Math.Numerics.lagrangePolynomial(points);\r\n     *     var graph = board.create('functiongraph', [f,-10, 10], {strokeWidth:3});\r\n     *\r\n     *     var f_arr = JXG.Math.Numerics.lagrangePolynomialCoefficients(points);\r\n     *     var txt = board.create('text', [1, -4, f_arr], {fontSize: 10});\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     */\r\n    lagrangePolynomialCoefficients: function (points) {\r\n        return function () {\r\n            var len = points.length,\r\n                zeroes = [],\r\n                coeffs = [],\r\n                coeffs_sum = [],\r\n                i, j, c, p;\r\n\r\n            // n = len - 1; // (Max) degree of the polynomial\r\n            for (j = 0; j < len; j++) {\r\n                coeffs_sum[j] = 0;\r\n            }\r\n\r\n            for (i = 0; i < len; i++) {\r\n                c = points[i].Y();\r\n                p = points[i].X();\r\n                zeroes = [];\r\n                for (j = 0; j < len; j++) {\r\n                    if (j !== i) {\r\n                        c /= p - points[j].X();\r\n                        zeroes.push(points[j].X());\r\n                    }\r\n                }\r\n                coeffs = [1].concat(Mat.Vieta(zeroes));\r\n                for (j = 0; j < coeffs.length; j++) {\r\n                    coeffs_sum[j] += (j % 2 === 1 ? -1 : 1) * coeffs[j] * c;\r\n                }\r\n            }\r\n\r\n            return coeffs_sum;\r\n        };\r\n    },\r\n\r\n    /**\r\n     * Determine the coefficients of a cardinal spline polynom, See\r\n     * https://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections\r\n     * @param  {Number} x1 point 1\r\n     * @param  {Number} x2 point 2\r\n     * @param  {Number} t1 tangent slope 1\r\n     * @param  {Number} t2 tangent slope 2\r\n     * @return {Array}    coefficents array c for the polynomial t maps to\r\n     * c[0] + c[1]*t + c[2]*t*t + c[3]*t*t*t\r\n     */\r\n    _initCubicPoly: function (x1, x2, t1, t2) {\r\n        return [x1, t1, -3 * x1 + 3 * x2 - 2 * t1 - t2, 2 * x1 - 2 * x2 + t1 + t2];\r\n    },\r\n\r\n    /**\r\n     * Computes the cubic cardinal spline curve through a given set of points. The curve\r\n     * is uniformly parametrized.\r\n     * Two artificial control points at the beginning and the end are added.\r\n     *\r\n     * The implementation (especially the centripetal parametrization) is from\r\n     * https://stackoverflow.com/questions/9489736/catmull-rom-curve-with-no-cusps-and-no-self-intersections .\r\n     * @param {Array} points Array consisting of JXG.Points.\r\n     * @param {Number|Function} tau The tension parameter, either a constant number or a function returning a number. This number is between 0 and 1.\r\n     * tau=1/2 give Catmull-Rom splines.\r\n     * @param {String} type (Optional) parameter which allows to choose between \"uniform\" (default) and\r\n     * \"centripetal\" parameterization. Thus the two possible values are \"uniform\" or \"centripetal\".\r\n     * @returns {Array} An Array consisting of four components: Two functions each of one parameter t\r\n     * which return the x resp. y coordinates of the Catmull-Rom-spline curve in t, a zero value,\r\n     * and a function simply returning the length of the points array\r\n     * minus three.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    CardinalSpline: function (points, tau_param, type) {\r\n        var p,\r\n            coeffs = [],\r\n            makeFct,\r\n            tau, _tau,\r\n            that = this;\r\n\r\n        if (Type.isFunction(tau_param)) {\r\n            _tau = tau_param;\r\n        } else {\r\n            _tau = function () {\r\n                return tau_param;\r\n            };\r\n        }\r\n\r\n        if (type === undefined) {\r\n            type = 'uniform';\r\n        }\r\n\r\n        /** @ignore */\r\n        makeFct = function (which) {\r\n            return function (t, suspendedUpdate) {\r\n                var s,\r\n                    c,\r\n                    // control point at the beginning and at the end\r\n                    first,\r\n                    last,\r\n                    t1,\r\n                    t2,\r\n                    dt0,\r\n                    dt1,\r\n                    dt2,\r\n                    // dx, dy,\r\n                    len;\r\n\r\n                if (points.length < 2) {\r\n                    return NaN;\r\n                }\r\n\r\n                if (!suspendedUpdate) {\r\n                    tau = _tau();\r\n\r\n                    // New point list p: [first, points ..., last]\r\n                    first = {\r\n                        X: function () {\r\n                            return 2 * points[0].X() - points[1].X();\r\n                        },\r\n                        Y: function () {\r\n                            return 2 * points[0].Y() - points[1].Y();\r\n                        },\r\n                        Dist: function (p) {\r\n                            var dx = this.X() - p.X(),\r\n                                dy = this.Y() - p.Y();\r\n                            return Mat.hypot(dx, dy);\r\n                        }\r\n                    };\r\n\r\n                    last = {\r\n                        X: function () {\r\n                            return (\r\n                                2 * points[points.length - 1].X() -\r\n                                points[points.length - 2].X()\r\n                            );\r\n                        },\r\n                        Y: function () {\r\n                            return (\r\n                                2 * points[points.length - 1].Y() -\r\n                                points[points.length - 2].Y()\r\n                            );\r\n                        },\r\n                        Dist: function (p) {\r\n                            var dx = this.X() - p.X(),\r\n                                dy = this.Y() - p.Y();\r\n                            return Mat.hypot(dx, dy);\r\n                        }\r\n                    };\r\n\r\n                    p = [first].concat(points, [last]);\r\n                    len = p.length;\r\n\r\n                    coeffs[which] = [];\r\n\r\n                    for (s = 0; s < len - 3; s++) {\r\n                        if (type === 'centripetal') {\r\n                            // The order is important, since p[0].coords === undefined\r\n                            dt0 = p[s].Dist(p[s + 1]);\r\n                            dt1 = p[s + 2].Dist(p[s + 1]);\r\n                            dt2 = p[s + 3].Dist(p[s + 2]);\r\n\r\n                            dt0 = Math.sqrt(dt0);\r\n                            dt1 = Math.sqrt(dt1);\r\n                            dt2 = Math.sqrt(dt2);\r\n\r\n                            if (dt1 < Mat.eps) {\r\n                                dt1 = 1.0;\r\n                            }\r\n                            if (dt0 < Mat.eps) {\r\n                                dt0 = dt1;\r\n                            }\r\n                            if (dt2 < Mat.eps) {\r\n                                dt2 = dt1;\r\n                            }\r\n\r\n                            t1 =\r\n                                (p[s + 1][which]() - p[s][which]()) / dt0 -\r\n                                (p[s + 2][which]() - p[s][which]()) / (dt1 + dt0) +\r\n                                (p[s + 2][which]() - p[s + 1][which]()) / dt1;\r\n\r\n                            t2 =\r\n                                (p[s + 2][which]() - p[s + 1][which]()) / dt1 -\r\n                                (p[s + 3][which]() - p[s + 1][which]()) / (dt2 + dt1) +\r\n                                (p[s + 3][which]() - p[s + 2][which]()) / dt2;\r\n\r\n                            t1 *= dt1;\r\n                            t2 *= dt1;\r\n\r\n                            coeffs[which][s] = that._initCubicPoly(\r\n                                p[s + 1][which](),\r\n                                p[s + 2][which](),\r\n                                tau * t1,\r\n                                tau * t2\r\n                            );\r\n                        } else {\r\n                            coeffs[which][s] = that._initCubicPoly(\r\n                                p[s + 1][which](),\r\n                                p[s + 2][which](),\r\n                                tau * (p[s + 2][which]() - p[s][which]()),\r\n                                tau * (p[s + 3][which]() - p[s + 1][which]())\r\n                            );\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (isNaN(t)) {\r\n                    return NaN;\r\n                }\r\n\r\n                len = points.length;\r\n                // This is necessary for our advanced plotting algorithm:\r\n                if (t <= 0.0) {\r\n                    return points[0][which]();\r\n                }\r\n                if (t >= len) {\r\n                    return points[len - 1][which]();\r\n                }\r\n\r\n                s = Math.floor(t);\r\n                if (s === t) {\r\n                    return points[s][which]();\r\n                }\r\n\r\n                t -= s;\r\n                c = coeffs[which][s];\r\n                if (c === undefined) {\r\n                    return NaN;\r\n                }\r\n\r\n                return ((c[3] * t + c[2]) * t + c[1]) * t + c[0];\r\n            };\r\n        };\r\n\r\n        return [\r\n            makeFct('X'),\r\n            makeFct('Y'),\r\n            0,\r\n            function () {\r\n                return points.length - 1;\r\n            }\r\n        ];\r\n    },\r\n\r\n    /**\r\n     * Computes the cubic Catmull-Rom spline curve through a given set of points. The curve\r\n     * is uniformly parametrized. The curve is the cardinal spline curve for tau=0.5.\r\n     * Two artificial control points at the beginning and the end are added.\r\n     * @param {Array} points Array consisting of JXG.Points.\r\n     * @param {String} type (Optional) parameter which allows to choose between \"uniform\" (default) and\r\n     * \"centripetal\" parameterization. Thus the two possible values are \"uniform\" or \"centripetal\".\r\n     * @returns {Array} An Array consisting of four components: Two functions each of one parameter t\r\n     * which return the x resp. y coordinates of the Catmull-Rom-spline curve in t, a zero value, and a function simply\r\n     * returning the length of the points array minus three.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    CatmullRomSpline: function (points, type) {\r\n        return this.CardinalSpline(points, 0.5, type);\r\n    },\r\n\r\n    /**\r\n     * Computes the regression polynomial of a given degree through a given set of coordinates.\r\n     * Returns the regression polynomial function.\r\n     * @param {Number|function|Slider} degree number, function or slider.\r\n     * Either\r\n     * @param {Array} dataX Array containing either the x-coordinates of the data set or both coordinates in\r\n     * an array of {@link JXG.Point}s or {@link JXG.Coords}.\r\n     * In the latter case, the <tt>dataY</tt> parameter will be ignored.\r\n     * @param {Array} dataY Array containing the y-coordinates of the data set,\r\n     * @returns {function} A function of one parameter which returns the value of the regression polynomial of the given degree.\r\n     * It possesses the method getTerm() which returns the string containing the function term of the polynomial.\r\n     * The function returned will throw an exception, if the data set is malformed.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    regressionPolynomial: function (degree, dataX, dataY) {\r\n        var coeffs, deg, dX, dY, inputType, fct,\r\n            term = \"\";\r\n\r\n        // Slider\r\n        if (Type.isPoint(degree) && Type.isFunction(degree.Value)) {\r\n            /** @ignore */\r\n            deg = function () {\r\n                return degree.Value();\r\n            };\r\n            // function\r\n        } else if (Type.isFunction(degree)) {\r\n            deg = degree;\r\n            // number\r\n        } else if (Type.isNumber(degree)) {\r\n            /** @ignore */\r\n            deg = function () {\r\n                return degree;\r\n            };\r\n        } else {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create regressionPolynomial from degree of type'\" +\r\n                typeof degree +\r\n                \"'.\"\r\n            );\r\n        }\r\n\r\n        // Parameters degree, dataX, dataY\r\n        if (arguments.length === 3 && Type.isArray(dataX) && Type.isArray(dataY)) {\r\n            inputType = 0;\r\n            // Parameters degree, point array\r\n        } else if (\r\n            arguments.length === 2 &&\r\n            Type.isArray(dataX) &&\r\n            dataX.length > 0 &&\r\n            Type.isPoint(dataX[0])\r\n        ) {\r\n            inputType = 1;\r\n        } else if (\r\n            arguments.length === 2 &&\r\n            Type.isArray(dataX) &&\r\n            dataX.length > 0 &&\r\n            dataX[0].usrCoords &&\r\n            dataX[0].scrCoords\r\n        ) {\r\n            inputType = 2;\r\n        } else {\r\n            throw new Error(\"JSXGraph: Can't create regressionPolynomial. Wrong parameters.\");\r\n        }\r\n\r\n        /** @ignore */\r\n        fct = function (x, suspendedUpdate) {\r\n            var i, j,\r\n                M, MT, y, B, c, s, d,\r\n                // input data\r\n                len = dataX.length;\r\n\r\n            d = Math.floor(deg());\r\n\r\n            if (!suspendedUpdate) {\r\n                // point list as input\r\n                if (inputType === 1) {\r\n                    dX = [];\r\n                    dY = [];\r\n\r\n                    for (i = 0; i < len; i++) {\r\n                        dX[i] = dataX[i].X();\r\n                        dY[i] = dataX[i].Y();\r\n                    }\r\n                }\r\n\r\n                if (inputType === 2) {\r\n                    dX = [];\r\n                    dY = [];\r\n\r\n                    for (i = 0; i < len; i++) {\r\n                        dX[i] = dataX[i].usrCoords[1];\r\n                        dY[i] = dataX[i].usrCoords[2];\r\n                    }\r\n                }\r\n\r\n                // check for functions\r\n                if (inputType === 0) {\r\n                    dX = [];\r\n                    dY = [];\r\n\r\n                    for (i = 0; i < len; i++) {\r\n                        if (Type.isFunction(dataX[i])) {\r\n                            dX.push(dataX[i]());\r\n                        } else {\r\n                            dX.push(dataX[i]);\r\n                        }\r\n\r\n                        if (Type.isFunction(dataY[i])) {\r\n                            dY.push(dataY[i]());\r\n                        } else {\r\n                            dY.push(dataY[i]);\r\n                        }\r\n                    }\r\n                }\r\n\r\n                M = [];\r\n                for (j = 0; j < len; j++) {\r\n                    M.push([1]);\r\n                }\r\n                for (i = 1; i <= d; i++) {\r\n                    for (j = 0; j < len; j++) {\r\n                        M[j][i] = M[j][i - 1] * dX[j];\r\n                    }\r\n                }\r\n\r\n                y = dY;\r\n                MT = Mat.transpose(M);\r\n                B = Mat.matMatMult(MT, M);\r\n                c = Mat.matVecMult(MT, y);\r\n                coeffs = Mat.Numerics.Gauss(B, c);\r\n                term = Mat.Numerics.generatePolynomialTerm(coeffs, d, \"x\", 3);\r\n            }\r\n\r\n            // Horner's scheme to evaluate polynomial\r\n            s = coeffs[d];\r\n            for (i = d - 1; i >= 0; i--) {\r\n                s = s * x + coeffs[i];\r\n            }\r\n\r\n            return s;\r\n        };\r\n\r\n        /** @ignore */\r\n        fct.getTerm = function () {\r\n            return term;\r\n        };\r\n\r\n        return fct;\r\n    },\r\n\r\n    /**\r\n     * Computes the cubic Bezier curve through a given set of points.\r\n     * @param {Array} points Array consisting of 3*k+1 {@link JXG.Points}.\r\n     * The points at position k with k mod 3 = 0 are the data points,\r\n     * points at position k with k mod 3 = 1 or 2 are the control points.\r\n     * @returns {Array} An array consisting of two functions of one parameter t which return the\r\n     * x resp. y coordinates of the Bezier curve in t, one zero value, and a third function accepting\r\n     * no parameters and returning one third of the length of the points.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    bezier: function (points) {\r\n        var len,\r\n            flen,\r\n            /** @ignore */\r\n            makeFct = function (which) {\r\n                return function (t, suspendedUpdate) {\r\n                    var z = Math.floor(t) * 3,\r\n                        t0 = t % 1,\r\n                        t1 = 1 - t0;\r\n\r\n                    if (!suspendedUpdate) {\r\n                        flen = 3 * Math.floor((points.length - 1) / 3);\r\n                        len = Math.floor(flen / 3);\r\n                    }\r\n\r\n                    if (t < 0) {\r\n                        return points[0][which]();\r\n                    }\r\n\r\n                    if (t >= len) {\r\n                        return points[flen][which]();\r\n                    }\r\n\r\n                    if (isNaN(t)) {\r\n                        return NaN;\r\n                    }\r\n\r\n                    return (\r\n                        t1 * t1 * (t1 * points[z][which]() + 3 * t0 * points[z + 1][which]()) +\r\n                        (3 * t1 * points[z + 2][which]() + t0 * points[z + 3][which]()) *\r\n                        t0 *\r\n                        t0\r\n                    );\r\n                };\r\n            };\r\n\r\n        return [\r\n            makeFct('X'),\r\n            makeFct('Y'),\r\n            0,\r\n            function () {\r\n                return Math.floor(points.length / 3);\r\n            }\r\n        ];\r\n    },\r\n\r\n    /**\r\n     * Computes the B-spline curve of order k (order = degree+1) through a given set of points.\r\n     * @param {Array} points Array consisting of JXG.Points.\r\n     * @param {Number} order Order of the B-spline curve.\r\n     * @returns {Array} An Array consisting of four components: Two functions each of one parameter t\r\n     * which return the x resp. y coordinates of the B-spline curve in t, a zero value, and a function simply\r\n     * returning the length of the points array minus one.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    bspline: function (points, order) {\r\n        var knots,\r\n            _knotVector = function (n, k) {\r\n                var j,\r\n                    kn = [];\r\n\r\n                for (j = 0; j < n + k + 1; j++) {\r\n                    if (j < k) {\r\n                        kn[j] = 0.0;\r\n                    } else if (j <= n) {\r\n                        kn[j] = j - k + 1;\r\n                    } else {\r\n                        kn[j] = n - k + 2;\r\n                    }\r\n                }\r\n\r\n                return kn;\r\n            },\r\n            _evalBasisFuncs = function (t, kn, k, s) {\r\n                var i,\r\n                    j,\r\n                    a,\r\n                    b,\r\n                    den,\r\n                    N = [];\r\n\r\n                if (kn[s] <= t && t < kn[s + 1]) {\r\n                    N[s] = 1;\r\n                } else {\r\n                    N[s] = 0;\r\n                }\r\n\r\n                for (i = 2; i <= k; i++) {\r\n                    for (j = s - i + 1; j <= s; j++) {\r\n                        if (j <= s - i + 1 || j < 0) {\r\n                            a = 0.0;\r\n                        } else {\r\n                            a = N[j];\r\n                        }\r\n\r\n                        if (j >= s) {\r\n                            b = 0.0;\r\n                        } else {\r\n                            b = N[j + 1];\r\n                        }\r\n\r\n                        den = kn[j + i - 1] - kn[j];\r\n\r\n                        if (den === 0) {\r\n                            N[j] = 0;\r\n                        } else {\r\n                            N[j] = ((t - kn[j]) / den) * a;\r\n                        }\r\n\r\n                        den = kn[j + i] - kn[j + 1];\r\n\r\n                        if (den !== 0) {\r\n                            N[j] += ((kn[j + i] - t) / den) * b;\r\n                        }\r\n                    }\r\n                }\r\n                return N;\r\n            },\r\n            /** @ignore */\r\n            makeFct = function (which) {\r\n                return function (t, suspendedUpdate) {\r\n                    var y,\r\n                        j,\r\n                        s,\r\n                        N = [],\r\n                        len = points.length,\r\n                        n = len - 1,\r\n                        k = order;\r\n\r\n                    if (n <= 0) {\r\n                        return NaN;\r\n                    }\r\n\r\n                    if (n + 2 <= k) {\r\n                        k = n + 1;\r\n                    }\r\n\r\n                    if (t <= 0) {\r\n                        return points[0][which]();\r\n                    }\r\n\r\n                    if (t >= n - k + 2) {\r\n                        return points[n][which]();\r\n                    }\r\n\r\n                    s = Math.floor(t) + k - 1;\r\n                    knots = _knotVector(n, k);\r\n                    N = _evalBasisFuncs(t, knots, k, s);\r\n\r\n                    y = 0.0;\r\n                    for (j = s - k + 1; j <= s; j++) {\r\n                        if (j < len && j >= 0) {\r\n                            y += points[j][which]() * N[j];\r\n                        }\r\n                    }\r\n\r\n                    return y;\r\n                };\r\n            };\r\n\r\n        return [\r\n            makeFct('X'),\r\n            makeFct('Y'),\r\n            0,\r\n            function () {\r\n                return points.length - 1;\r\n            }\r\n        ];\r\n    },\r\n\r\n    /**\r\n     * Numerical (symmetric) approximation of derivative. suspendUpdate is piped through,\r\n     * see {@link JXG.Curve#updateCurve}\r\n     * and {@link JXG.Curve#hasPoint}.\r\n     * @param {function} f Function in one variable to be differentiated.\r\n     * @param {object} [obj] Optional object that is treated as \"this\" in the function body. This is useful, if the function is a\r\n     * method of an object and contains a reference to its parent object via \"this\".\r\n     * @returns {function} Derivative function of a given function f.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    D: function (f, obj) {\r\n        if (!Type.exists(obj)) {\r\n            return function (x, suspendedUpdate) {\r\n                var h = 0.00001,\r\n                    h2 = h * 2.0;\r\n\r\n                // Experiments with Richardsons rule\r\n                /*\r\n                    var phi = (f(x + h, suspendedUpdate) - f(x - h, suspendedUpdate)) / h2;\r\n                    var phi2;\r\n                    h *= 0.5;\r\n                    h2 *= 0.5;\r\n                    phi2 = (f(x + h, suspendedUpdate) - f(x - h, suspendedUpdate)) / h2;\r\n\r\n                    return phi2 + (phi2 - phi) / 3.0;\r\n                    */\r\n                return (f(x + h, suspendedUpdate) - f(x - h, suspendedUpdate)) / h2;\r\n            };\r\n        }\r\n\r\n        return function (x, suspendedUpdate) {\r\n            var h = 0.00001,\r\n                h2 = h * 2.0;\r\n\r\n            return (\r\n                (f.apply(obj, [x + h, suspendedUpdate]) -\r\n                    f.apply(obj, [x - h, suspendedUpdate])) /\r\n                h2\r\n            );\r\n        };\r\n    },\r\n\r\n    /**\r\n     * Evaluate the function term for {@link JXG.Math.Numerics.riemann}.\r\n     * @private\r\n     * @param {Number} x function argument\r\n     * @param {function} f JavaScript function returning a number\r\n     * @param {String} type Name of the Riemann sum type, e.g. 'lower'.\r\n     * @param {Number} delta Width of the bars in user coordinates\r\n     * @returns {Number} Upper (delta > 0) or lower (delta < 0) value of the bar containing x of the Riemann sum.\r\n     * @see JXG.Math.Numerics.riemann\r\n     * @private\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    _riemannValue: function (x, f, type, delta) {\r\n        var y, y1, x1, delta1;\r\n\r\n        if (delta < 0) {\r\n            // delta is negative if the lower function term is evaluated\r\n            if (type !== 'trapezoidal') {\r\n                x = x + delta;\r\n            }\r\n            delta *= -1;\r\n            if (type === 'lower') {\r\n                type = 'upper';\r\n            } else if (type === 'upper') {\r\n                type = 'lower';\r\n            }\r\n        }\r\n\r\n        delta1 = delta * 0.01; // for 'lower' and 'upper'\r\n\r\n        if (type === 'right') {\r\n            y = f(x + delta);\r\n        } else if (type === 'middle') {\r\n            y = f(x + delta * 0.5);\r\n        } else if (type === \"left\" || type === 'trapezoidal') {\r\n            y = f(x);\r\n        } else if (type === 'lower') {\r\n            y = f(x);\r\n\r\n            for (x1 = x + delta1; x1 <= x + delta; x1 += delta1) {\r\n                y1 = f(x1);\r\n\r\n                if (y1 < y) {\r\n                    y = y1;\r\n                }\r\n            }\r\n\r\n            y1 = f(x + delta);\r\n            if (y1 < y) {\r\n                y = y1;\r\n            }\r\n        } else if (type === 'upper') {\r\n            y = f(x);\r\n\r\n            for (x1 = x + delta1; x1 <= x + delta; x1 += delta1) {\r\n                y1 = f(x1);\r\n                if (y1 > y) {\r\n                    y = y1;\r\n                }\r\n            }\r\n\r\n            y1 = f(x + delta);\r\n            if (y1 > y) {\r\n                y = y1;\r\n            }\r\n        } else if (type === 'random') {\r\n            y = f(x + delta * Math.random());\r\n        } else if (type === 'simpson') {\r\n            y = (f(x) + 4 * f(x + delta * 0.5) + f(x + delta)) / 6.0;\r\n        } else {\r\n            y = f(x); // default is lower\r\n        }\r\n\r\n        return y;\r\n    },\r\n\r\n    /**\r\n     * Helper function to create curve which displays Riemann sums.\r\n     * Compute coordinates for the rectangles showing the Riemann sum.\r\n     * <p>\r\n     * In case of type \"simpson\" and \"trapezoidal\", the horizontal line approximating the function value\r\n     * is replaced by a parabola or a secant. IN case of \"simpson\",\r\n     * the parabola is approximated visually by a polygonal chain of fixed step width.\r\n     *\r\n     * @param {Function|Array} f Function or array of two functions.\r\n     * If f is a function the integral of this function is approximated by the Riemann sum.\r\n     * If f is an array consisting of two functions the area between the two functions is filled\r\n     * by the Riemann sum bars.\r\n     * @param {Number} n number of rectangles.\r\n     * @param {String} type Type of approximation. Possible values are: 'left', 'right', 'middle', 'lower', 'upper', 'random', 'simpson', or 'trapezoidal'.\r\n     * \"simpson\" is Simpson's 1/3 rule.\r\n     * @param {Number} start Left border of the approximation interval\r\n     * @param {Number} end Right border of the approximation interval\r\n     * @returns {Array} An array of two arrays containing the x and y coordinates for the rectangles showing the Riemann sum. This\r\n     * array may be used as parent array of a {@link JXG.Curve}. The third parameteris the riemann sum, i.e. the sum of the volumes of all\r\n     * rectangles.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    riemann: function (gf, n, type, start, end) {\r\n        var i, delta,\r\n            k, a, b, c, f0, f1, f2, xx, h,\r\n            steps = 30, // Constant step width for Simpson's rule\r\n            xarr = [],\r\n            yarr = [],\r\n            x = start,\r\n            sum = 0,\r\n            y, f, g;\r\n\r\n        if (Type.isArray(gf)) {\r\n            g = gf[0];\r\n            f = gf[1];\r\n        } else {\r\n            f = gf;\r\n        }\r\n\r\n        n = Math.floor(n);\r\n\r\n        if (n <= 0) {\r\n            return [xarr, yarr, sum];\r\n        }\r\n\r\n        delta = (end - start) / n;\r\n\r\n        // Horizontal lines defined by function\r\n        // Go forward\r\n        for (i = 0; i < n; i++) {\r\n            if (type === 'simpson') {\r\n                sum += this._riemannValue(x, f, type, delta) * delta;\r\n\r\n                h = delta * 0.5;\r\n                f0 = f(x);\r\n                f1 = f(x + h);\r\n                f2 = f(x + 2 * h);\r\n\r\n                a = (f2 + f0 - 2 * f1) / (h * h) * 0.5;\r\n                b = (f2 - f0) / (2 * h);\r\n                c = f1;\r\n                for (k = 0; k < steps; k++) {\r\n                    xx = k * delta / steps - h;\r\n                    xarr.push(x + xx + h);\r\n                    yarr.push(a * xx * xx + b * xx + c);\r\n                }\r\n                x += delta;\r\n                y = f2;\r\n            } else {\r\n                y = this._riemannValue(x, f, type, delta);\r\n                xarr.push(x);\r\n                yarr.push(y);\r\n\r\n                x += delta;\r\n                if (type === 'trapezoidal') {\r\n                    f2 = f(x);\r\n                    sum += (y + f2) * 0.5 * delta;\r\n                    y = f2;\r\n                } else {\r\n                    sum += y * delta;\r\n                }\r\n            }\r\n            xarr.push(x);\r\n            yarr.push(y);\r\n        }\r\n\r\n        // Horizontal lines defined by x-axis or second function\r\n        // Go backwards\r\n        for (i = 0; i < n; i++) {\r\n            if (type === \"simpson\" && g) {\r\n                sum -= this._riemannValue(x, g, type, -delta) * delta;\r\n\r\n                h = delta * 0.5;\r\n                f0 = g(x);\r\n                f1 = g(x - h);\r\n                f2 = g(x - 2 * h);\r\n\r\n                a = (f2 + f0 - 2 * f1) / (h * h) * 0.5;\r\n                b = (f2 - f0) / (2 * h);\r\n                c = f1;\r\n                for (k = 0; k < steps; k++) {\r\n                    xx = k * delta / steps - h;\r\n                    xarr.push(x - xx - h);\r\n                    yarr.push(a * xx * xx + b * xx + c);\r\n                }\r\n                x -= delta;\r\n                y = f2;\r\n            } else {\r\n                if (g) {\r\n                    y = this._riemannValue(x, g, type, -delta);\r\n                } else {\r\n                    y = 0.0;\r\n                }\r\n                xarr.push(x);\r\n                yarr.push(y);\r\n\r\n                x -= delta;\r\n                if (g) {\r\n                    if (type === 'trapezoidal') {\r\n                        f2 = g(x);\r\n                        sum -= (y + f2) * 0.5 * delta;\r\n                        y = f2;\r\n                    } else {\r\n                        sum -= y * delta;\r\n                    }\r\n                }\r\n            }\r\n            xarr.push(x);\r\n            yarr.push(y);\r\n\r\n            // Close rectangle\r\n            xarr.push(x);\r\n            if (type === 'simpson') {\r\n                yarr.push(f(x));\r\n            } else {\r\n                y = this._riemannValue(x, f, type, delta);\r\n                yarr.push(y);\r\n            }\r\n        }\r\n\r\n        return [xarr, yarr, sum];\r\n    },\r\n\r\n    /**\r\n     * Approximate the integral by Riemann sums.\r\n     * Compute the area described by the riemann sum rectangles.\r\n     *\r\n     * If there is an element of type {@link Riemannsum}, then it is more efficient\r\n     * to use the method JXG.Curve.Value() of this element instead.\r\n     *\r\n     * @param {Function_Array} f Function or array of two functions.\r\n     * If f is a function the integral of this function is approximated by the Riemann sum.\r\n     * If f is an array consisting of two functions the area between the two functions is approximated\r\n     * by the Riemann sum.\r\n     * @param {Number} n number of rectangles.\r\n     * @param {String} type Type of approximation. Possible values are: 'left', 'right', 'middle', 'lower', 'upper', 'random', 'simpson' or 'trapezoidal'.\r\n     *\r\n     * @param {Number} start Left border of the approximation interval\r\n     * @param {Number} end Right border of the approximation interval\r\n     * @returns {Number} The sum of the areas of the rectangles.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    riemannsum: function (f, n, type, start, end) {\r\n        JXG.deprecated(\"Numerics.riemannsum()\", \"Numerics.riemann()[2]\");\r\n        return this.riemann(f, n, type, start, end)[2];\r\n    },\r\n\r\n    /**\r\n     * Solve initial value problems numerically using <i>explicit</i> Runge-Kutta methods.\r\n     * See {@link https://en.wikipedia.org/wiki/Runge-Kutta_methods} for more information on the algorithm.\r\n     * @param {object|String} butcher Butcher tableau describing the Runge-Kutta method to use. This can be either a string describing\r\n     * a Runge-Kutta method with a Butcher tableau predefined in JSXGraph like 'euler', 'heun', 'rk4' or an object providing the structure\r\n     * <pre>\r\n     * {\r\n     *     s: &lt;Number&gt;,\r\n     *     A: &lt;matrix&gt;,\r\n     *     b: &lt;Array&gt;,\r\n     *     c: &lt;Array&gt;\r\n     * }\r\n     * </pre>\r\n     * which corresponds to the Butcher tableau structure\r\n     * shown here: https://en.wikipedia.org/w/index.php?title=List_of_Runge%E2%80%93Kutta_methods&oldid=357796696 .\r\n     * <i>Default</i> is 'euler'.\r\n     * @param {Array} x0 Initial value vector. Even if the problem is one-dimensional, the initial value has to be given in an array.\r\n     * @param {Array} I Interval on which to integrate.\r\n     * @param {Number} N Number of integration intervals, i.e. there are <i>N+1</i> evaluation points.\r\n     * @param {function} f Function describing the right hand side of the first order ordinary differential equation, i.e. if the ode\r\n     * is given by the equation <pre>dx/dt = f(t, x(t))</pre>. So, f has to take two parameters, a number <tt>t</tt> and a\r\n     * vector <tt>x</tt>, and has to return a vector of the same length as <tt>x</tt> has.\r\n     * @returns {Array} An array of vectors describing the solution of the ode on the given interval I.\r\n     * @example\r\n     * // A very simple autonomous system dx(t)/dt = x(t);\r\n     * var f = function(t, x) {\r\n     *     return [x[0]];\r\n     * }\r\n     *\r\n     * // Solve it with initial value x(0) = 1 on the interval [0, 2]\r\n     * // with 20 evaluation points.\r\n     * var data = JXG.Math.Numerics.rungeKutta('heun', [1], [0, 2], 20, f);\r\n     *\r\n     * // Prepare data for plotting the solution of the ode using a curve.\r\n     * var dataX = [];\r\n     * var dataY = [];\r\n     * var h = 0.1;        // (I[1] - I[0])/N  = (2-0)/20\r\n     * var i;\r\n     * for(i=0; i&lt;data.length; i++) {\r\n     *     dataX[i] = i*h;\r\n     *     dataY[i] = data[i][0];\r\n     * }\r\n     * var g = board.create('curve', [dataX, dataY], {strokeWidth:'2px'});\r\n     * </pre><div class=\"jxgbox\" id=\"JXGd2432d04-4ef7-4159-a90b-a2eb8d38c4f6\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     * var board = JXG.JSXGraph.initBoard('JXGd2432d04-4ef7-4159-a90b-a2eb8d38c4f6', {boundingbox: [-1, 5, 5, -1], axis: true, showcopyright: false, shownavigation: false});\r\n     * var f = function(t, x) {\r\n     *     // we have to copy the value.\r\n     *     // return x; would just return the reference.\r\n     *     return [x[0]];\r\n     * }\r\n     * var data = JXG.Math.Numerics.rungeKutta('heun', [1], [0, 2], 20, f);\r\n     * var dataX = [];\r\n     * var dataY = [];\r\n     * var h = 0.1;\r\n     * for(var i=0; i<data.length; i++) {\r\n     *     dataX[i] = i*h;\r\n     *     dataY[i] = data[i][0];\r\n     * }\r\n     * var g = board.create('curve', [dataX, dataY], {strokeColor:'red', strokeWidth:'2px'});\r\n     * </script><pre>\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    rungeKutta: function (butcher, x0, I, N, f) {\r\n        var e,\r\n            i, j, k, l, s,\r\n            x = [],\r\n            y = [],\r\n            h = (I[1] - I[0]) / N,\r\n            t = I[0],\r\n            dim = x0.length,\r\n            result = [],\r\n            r = 0;\r\n\r\n        if (Type.isString(butcher)) {\r\n            butcher = predefinedButcher[butcher] || predefinedButcher.euler;\r\n        }\r\n        s = butcher.s;\r\n\r\n        // Don't change x0, so copy it\r\n        x = x0.slice();\r\n\r\n        for (i = 0; i <= N; i++) {\r\n            result[r] = x.slice();\r\n\r\n            r++;\r\n            k = [];\r\n\r\n            for (j = 0; j < s; j++) {\r\n                // Init y = 0\r\n                for (e = 0; e < dim; e++) {\r\n                    y[e] = 0.0;\r\n                }\r\n\r\n                // Calculate linear combination of former k's and save it in y\r\n                for (l = 0; l < j; l++) {\r\n                    for (e = 0; e < dim; e++) {\r\n                        y[e] += butcher.A[j][l] * h * k[l][e];\r\n                    }\r\n                }\r\n\r\n                // Add x(t) to y\r\n                for (e = 0; e < dim; e++) {\r\n                    y[e] += x[e];\r\n                }\r\n\r\n                // Calculate new k and add it to the k matrix\r\n                k.push(f(t + butcher.c[j] * h, y));\r\n            }\r\n\r\n            // Init y = 0\r\n            for (e = 0; e < dim; e++) {\r\n                y[e] = 0.0;\r\n            }\r\n\r\n            for (l = 0; l < s; l++) {\r\n                for (e = 0; e < dim; e++) {\r\n                    y[e] += butcher.b[l] * k[l][e];\r\n                }\r\n            }\r\n\r\n            for (e = 0; e < dim; e++) {\r\n                x[e] = x[e] + h * y[e];\r\n            }\r\n\r\n            t += h;\r\n        }\r\n\r\n        return result;\r\n    },\r\n\r\n    /**\r\n     * Maximum number of iterations in {@link JXG.Math.Numerics.fzero} and\r\n     * {@link JXG.Math.Numerics.chandrupatla}\r\n     * @type Number\r\n     * @default 80\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    maxIterationsRoot: 80,\r\n\r\n    /**\r\n     * Maximum number of iterations in {@link JXG.Math.Numerics.fminbr}\r\n     * @type Number\r\n     * @default 500\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    maxIterationsMinimize: 500,\r\n\r\n    /**\r\n     * Given a number x_0, this function tries to find a second number x_1 such that\r\n     * the function f has opposite signs at x_0 and x_1.\r\n     * The return values have to be tested if the method succeeded.\r\n     *\r\n     * @param {Function} f Function, whose root is to be found\r\n     * @param {Number} x0 Start value\r\n     * @param {Object} [context] Parent object in case f is method of it\r\n     * @returns {Array} [x_0, f(x_0), x_1, f(x_1)] in case that x_0 <= x_1\r\n     *   or [x_1, f(x_1), x_0, f(x_0)] in case that x_1 < x_0.\r\n     *\r\n     * @see JXG.Math.Numerics.fzero\r\n     * @see JXG.Math.Numerics.chandrupatla\r\n     *\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    findBracket: function (f, x0, context) {\r\n        var a, aa, fa, blist, b, fb, u, fu, i, len;\r\n\r\n        if (Type.isArray(x0)) {\r\n            return x0;\r\n        }\r\n\r\n        a = x0;\r\n        fa = f.call(context, a);\r\n        // nfev += 1;\r\n\r\n        // Try to get b, by trying several values related to a\r\n        aa = a === 0 ? 1 : a;\r\n        blist = [\r\n            a - 0.1 * aa,\r\n            a + 0.1 * aa,\r\n            a - 1,\r\n            a + 1,\r\n            a - 0.5 * aa,\r\n            a + 0.5 * aa,\r\n            a - 0.6 * aa,\r\n            a + 0.6 * aa,\r\n            a - 1 * aa,\r\n            a + 1 * aa,\r\n            a - 2 * aa,\r\n            a + 2 * aa,\r\n            a - 5 * aa,\r\n            a + 5 * aa,\r\n            a - 10 * aa,\r\n            a + 10 * aa,\r\n            a - 50 * aa,\r\n            a + 50 * aa,\r\n            a - 100 * aa,\r\n            a + 100 * aa\r\n        ];\r\n        len = blist.length;\r\n\r\n        for (i = 0; i < len; i++) {\r\n            b = blist[i];\r\n            fb = f.call(context, b);\r\n            // nfev += 1;\r\n\r\n            if (fa * fb <= 0) {\r\n                break;\r\n            }\r\n        }\r\n        if (b < a) {\r\n            u = a;\r\n            a = b;\r\n            b = u;\r\n\r\n            fu = fa;\r\n            fa = fb;\r\n            fb = fu;\r\n        }\r\n        return [a, fa, b, fb];\r\n    },\r\n\r\n    /**\r\n     *\r\n     * Find zero of an univariate function f.\r\n     * @param {function} f Function, whose root is to be found\r\n     * @param {Array|Number} x0  Start value or start interval enclosing the root.\r\n     * If x0 is an interval [a,b], it is required that f(a)f(b) <= 0, otherwise the minimum of f in [a, b] will be returned.\r\n     * If x0 is a number, the algorithms tries to enclose the root by an interval [a, b] containing x0 and the root and\r\n     * f(a)f(b) <= 0. If this fails, the algorithm falls back to Newton's method.\r\n     * @param {Object} [context] Parent object in case f is method of it\r\n     * @returns {Number} the approximation of the root\r\n     * Algorithm:\r\n     *  Brent's root finder from\r\n     *  G.Forsythe, M.Malcolm, C.Moler, Computer methods for mathematical\r\n     *  computations. M., Mir, 1980, p.180 of the Russian edition\r\n     *  https://www.netlib.org/c/brent.shar\r\n     *\r\n     * If x0 is an array containing lower and upper bound for the zero\r\n     * algorithm 748 is applied. Otherwise, if x0 is a number,\r\n     * the algorithm tries to bracket a zero of f starting from x0.\r\n     * If this fails, we fall back to Newton's method.\r\n     *\r\n     * @see JXG.Math.Numerics.chandrupatla\r\n     * @see JXG.Math.Numerics.root\r\n     * @see JXG.Math.Numerics.findBracket\r\n     * @see JXG.Math.Numerics.Newton\r\n     * @see JXG.Math.Numerics.fminbr\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    fzero: function (f, x0, context) {\r\n        var a, b, c,\r\n            fa, fb, fc,\r\n            res, x00,\r\n            prev_step,\r\n            t1, t2,\r\n            cb,\r\n            tol_act,   // Actual tolerance\r\n            p,         // Interpolation step is calculated in the form p/q; division\r\n            q,         // operations is delayed until the last moment\r\n            new_step,  // Step at this iteration\r\n            eps = Mat.eps,\r\n            maxiter = this.maxIterationsRoot,\r\n            niter = 0;\r\n        // nfev = 0;\r\n\r\n        if (Type.isArray(x0)) {\r\n            if (x0.length < 2) {\r\n                throw new Error(\r\n                    \"JXG.Math.Numerics.fzero: length of array x0 has to be at least two.\"\r\n                );\r\n            }\r\n\r\n            x00 = this.findDomain(f, x0, context);\r\n            a = x00[0];\r\n            b = x00[1];\r\n            // a = x0[0];\r\n            // b = x0[1];\r\n\r\n            fa = f.call(context, a);\r\n            // nfev += 1;\r\n            fb = f.call(context, b);\r\n            // nfev += 1;\r\n        } else {\r\n            res = this.findBracket(f, x0, context);\r\n            a = res[0];\r\n            fa = res[1];\r\n            b = res[2];\r\n            fb = res[3];\r\n        }\r\n\r\n        if (Math.abs(fa) <= eps) {\r\n            return a;\r\n        }\r\n        if (Math.abs(fb) <= eps) {\r\n            return b;\r\n        }\r\n\r\n        if (fa * fb > 0) {\r\n            // Bracketing not successful, fall back to Newton's method or to fminbr\r\n            if (Type.isArray(x0)) {\r\n                return this.fminbr(f, [a, b], context);\r\n            }\r\n\r\n            return this.Newton(f, a, context);\r\n        }\r\n\r\n        // OK, we have enclosed a zero of f.\r\n        // Now we can start Brent's method\r\n        c = a;\r\n        fc = fa;\r\n\r\n        // Main iteration loop\r\n        while (niter < maxiter) {\r\n            // Distance from the last but one to the last approximation\r\n            prev_step = b - a;\r\n\r\n            // Swap data for b to be the best approximation\r\n            if (Math.abs(fc) < Math.abs(fb)) {\r\n                a = b;\r\n                b = c;\r\n                c = a;\r\n\r\n                fa = fb;\r\n                fb = fc;\r\n                fc = fa;\r\n            }\r\n            tol_act = 2 * eps * Math.abs(b) + eps * 0.5;\r\n            new_step = (c - b) * 0.5;\r\n\r\n            if (Math.abs(new_step) <= tol_act || Math.abs(fb) <= eps) {\r\n                //  Acceptable approx. is found\r\n                return b;\r\n            }\r\n\r\n            // Decide if the interpolation can be tried\r\n            // If prev_step was large enough and was in true direction Interpolatiom may be tried\r\n            if (Math.abs(prev_step) >= tol_act && Math.abs(fa) > Math.abs(fb)) {\r\n                cb = c - b;\r\n\r\n                // If we have only two distinct points linear interpolation can only be applied\r\n                if (a === c) {\r\n                    t1 = fb / fa;\r\n                    p = cb * t1;\r\n                    q = 1.0 - t1;\r\n                    // Quadric inverse interpolation\r\n                } else {\r\n                    q = fa / fc;\r\n                    t1 = fb / fc;\r\n                    t2 = fb / fa;\r\n\r\n                    p = t2 * (cb * q * (q - t1) - (b - a) * (t1 - 1.0));\r\n                    q = (q - 1.0) * (t1 - 1.0) * (t2 - 1.0);\r\n                }\r\n\r\n                // p was calculated with the opposite sign; make p positive\r\n                if (p > 0) {\r\n                    q = -q;\r\n                    // and assign possible minus to q\r\n                } else {\r\n                    p = -p;\r\n                }\r\n\r\n                // If b+p/q falls in [b,c] and isn't too large it is accepted\r\n                // If p/q is too large then the bissection procedure can reduce [b,c] range to more extent\r\n                if (\r\n                    p < 0.75 * cb * q - Math.abs(tol_act * q) * 0.5 &&\r\n                    p < Math.abs(prev_step * q * 0.5)\r\n                ) {\r\n                    new_step = p / q;\r\n                }\r\n            }\r\n\r\n            // Adjust the step to be not less than tolerance\r\n            if (Math.abs(new_step) < tol_act) {\r\n                new_step = new_step > 0 ? tol_act : -tol_act;\r\n            }\r\n\r\n            // Save the previous approx.\r\n            a = b;\r\n            fa = fb;\r\n            b += new_step;\r\n            fb = f.call(context, b);\r\n            // Do step to a new approxim.\r\n            // nfev += 1;\r\n\r\n            // Adjust c for it to have a sign opposite to that of b\r\n            if ((fb > 0 && fc > 0) || (fb < 0 && fc < 0)) {\r\n                c = a;\r\n                fc = fa;\r\n            }\r\n            niter++;\r\n        } // End while\r\n\r\n        return b;\r\n    },\r\n\r\n    /**\r\n     * Find zero of an univariate function f.\r\n     * @param {function} f Function, whose root is to be found\r\n     * @param {Array|Number} x0  Start value or start interval enclosing the root.\r\n     * If x0 is an interval [a,b], it is required that f(a)f(b) <= 0, otherwise the minimum of f in [a, b] will be returned.\r\n     * If x0 is a number, the algorithms tries to enclose the root by an interval [a, b] containing x0 and the root and\r\n     * f(a)f(b) <= 0. If this fails, the algorithm falls back to Newton's method.\r\n     * @param {Object} [context] Parent object in case f is method of it\r\n     * @returns {Number} the approximation of the root\r\n     * Algorithm:\r\n     * Chandrupatla's method, see\r\n     * Tirupathi R. Chandrupatla,\r\n     * \"A new hybrid quadratic/bisection algorithm for finding the zero of a nonlinear function without using derivatives\",\r\n     * Advances in Engineering Software, Volume 28, Issue 3, April 1997, Pages 145-149.\r\n     *\r\n     * If x0 is an array containing lower and upper bound for the zero\r\n     * algorithm 748 is applied. Otherwise, if x0 is a number,\r\n     * the algorithm tries to bracket a zero of f starting from x0.\r\n     * If this fails, we fall back to Newton's method.\r\n     *\r\n     * @see JXG.Math.Numerics.root\r\n     * @see JXG.Math.Numerics.fzero\r\n     * @see JXG.Math.Numerics.findBracket\r\n     * @see JXG.Math.Numerics.Newton\r\n     * @see JXG.Math.Numerics.fminbr\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    chandrupatla: function (f, x0, context) {\r\n        var a, b, fa, fb,\r\n            res,\r\n            niter = 0,\r\n            maxiter = this.maxIterationsRoot,\r\n            rand = 1 + Math.random() * 0.001,\r\n            t = 0.5 * rand,\r\n            eps = Mat.eps, // 1.e-10,\r\n            dlt = 0.00001,\r\n            x1, x2, x3, x,\r\n            f1, f2, f3, y,\r\n            xm, fm,\r\n            tol, tl,\r\n            xi, ph, fl, fh,\r\n            AL, A, B, C, D;\r\n\r\n        if (Type.isArray(x0)) {\r\n            if (x0.length < 2) {\r\n                throw new Error(\r\n                    \"JXG.Math.Numerics.fzero: length of array x0 has to be at least two.\"\r\n                );\r\n            }\r\n\r\n            a = x0[0];\r\n            fa = f.call(context, a);\r\n            // nfev += 1;\r\n            b = x0[1];\r\n            fb = f.call(context, b);\r\n            // nfev += 1;\r\n        } else {\r\n            res = this.findBracket(f, x0, context);\r\n            a = res[0];\r\n            fa = res[1];\r\n            b = res[2];\r\n            fb = res[3];\r\n        }\r\n\r\n        if (fa * fb > 0) {\r\n            // Bracketing not successful, fall back to Newton's method or to fminbr\r\n            if (Type.isArray(x0)) {\r\n                return this.fminbr(f, [a, b], context);\r\n            }\r\n\r\n            return this.Newton(f, a, context);\r\n        }\r\n\r\n        x1 = a;\r\n        x2 = b;\r\n        f1 = fa;\r\n        f2 = fb;\r\n        do {\r\n            x = x1 + t * (x2 - x1);\r\n            y = f.call(context, x);\r\n\r\n            // Arrange 2-1-3: 2-1 interval, 1 middle, 3 discarded point\r\n            if (Math.sign(y) === Math.sign(f1)) {\r\n                x3 = x1;\r\n                x1 = x;\r\n                f3 = f1;\r\n                f1 = y;\r\n            } else {\r\n                x3 = x2;\r\n                x2 = x1;\r\n                f3 = f2;\r\n                f2 = f1;\r\n            }\r\n            x1 = x;\r\n            f1 = y;\r\n\r\n            xm = x1;\r\n            fm = f1;\r\n            if (Math.abs(f2) < Math.abs(f1)) {\r\n                xm = x2;\r\n                fm = f2;\r\n            }\r\n            tol = 2 * eps * Math.abs(xm) + 0.5 * dlt;\r\n            tl = tol / Math.abs(x2 - x1);\r\n            if (tl > 0.5 || fm === 0) {\r\n                break;\r\n            }\r\n            // If inverse quadratic interpolation holds, use it\r\n            xi = (x1 - x2) / (x3 - x2);\r\n            ph = (f1 - f2) / (f3 - f2);\r\n            fl = 1 - Math.sqrt(1 - xi);\r\n            fh = Math.sqrt(xi);\r\n            if (fl < ph && ph < fh) {\r\n                AL = (x3 - x1) / (x2 - x1);\r\n                A = f1 / (f2 - f1);\r\n                B = f3 / (f2 - f3);\r\n                C = f1 / (f3 - f1);\r\n                D = f2 / (f3 - f2);\r\n                t = A * B + C * D * AL;\r\n            } else {\r\n                t = 0.5 * rand;\r\n            }\r\n            // Adjust t away from the interval boundary\r\n            if (t < tl) {\r\n                t = tl;\r\n            }\r\n            if (t > 1 - tl) {\r\n                t = 1 - tl;\r\n            }\r\n            niter++;\r\n        } while (niter <= maxiter);\r\n        // console.log(niter);\r\n\r\n        return xm;\r\n    },\r\n\r\n    /**\r\n     * Find a small enclosing interval of the domain of a function by\r\n     * tightening the input interval x0.\r\n     * <p>\r\n     * This is a helper function which is used in {@link JXG.Math.Numerics.fminbr},\r\n     * {@link JXG.Math.Numerics.fzero}, and  {@link JXG.Curve.getLabelPosition}\r\n     * to avoid search in an interval where the function is mostly undefined.\r\n     *\r\n     * @param {function} f\r\n     * @param {Array} x0 Start interval\r\n     * @param {Object} context Parent object in case f is method of it\r\n     * @param {Boolean} [outer=true] if true take a proper enclosing array. If false return the domain such that the function is defined\r\n     * at its  borders.\r\n     * @returns Array\r\n     *\r\n     * @example\r\n     * var f = (x) => Math.sqrt(x);\r\n     * console.log(JXG.Math.Numerics.findDomain(f, [-5, 5]));\r\n     *\r\n     * // Output: [ -0.00020428174445492973, 5 ]\r\n     *\r\n     * @example\r\n     * var f = (x) => Math.sqrt(x);\r\n     * console.log(JXG.Math.Numerics.findDomain(f, [-5, 5], null, false));\r\n     *\r\n     * // Output: [ 0.00020428174562965915, 5 ]\r\n     */\r\n    findDomain: function (f, x0, context, outer) {\r\n        var a, b, c, fc,\r\n            x,\r\n            gr = 1 - 1 / 1.61803398875,\r\n            eps = 0.001,\r\n            cnt,\r\n            max_cnt = 20;\r\n\r\n        if (outer === undefined) {\r\n            outer = true;\r\n        }\r\n\r\n        if (!Type.isArray(x0) || x0.length < 2) {\r\n            throw new Error(\r\n                \"JXG.Math.Numerics.findDomain: length of array x0 has to be at least two.\"\r\n            );\r\n        }\r\n\r\n        x = x0.slice();\r\n        a = x[0];\r\n        b = x[1];\r\n        fc = f.call(context, a);\r\n        if (isNaN(fc)) {\r\n            // Divide the interval with the golden ratio\r\n            // and keep a such that f(a) = NaN\r\n            cnt = 0;\r\n            while (b - a > eps && cnt < max_cnt) {\r\n                c = (b - a) * gr + a;\r\n                fc = f.call(context, c);\r\n                if (isNaN(fc)) {\r\n                    a = c;\r\n                } else {\r\n                    b = c;\r\n                }\r\n                cnt++;\r\n            }\r\n            if (outer) {\r\n                x[0] = a;\r\n            } else {\r\n                x[0] = b;\r\n            }\r\n            // x[0] = a;\r\n        }\r\n\r\n        a = x[0];\r\n        b = x[1];\r\n        fc = f.call(context, b);\r\n        if (isNaN(fc)) {\r\n            // Divide the interval with the golden ratio\r\n            // and keep b such that f(b) = NaN\r\n            cnt = 0;\r\n            while (b - a > eps && cnt < max_cnt) {\r\n                c = b - (b - a) * gr;\r\n                fc = f.call(context, c);\r\n                if (isNaN(fc)) {\r\n                    b = c;\r\n                } else {\r\n                    a = c;\r\n                }\r\n                cnt++;\r\n            }\r\n            if (outer) {\r\n                x[1] = b;\r\n            } else {\r\n                x[1] = a;\r\n            }\r\n            // x[1] = b;\r\n        }\r\n\r\n        return x;\r\n    },\r\n\r\n    /**\r\n     *\r\n     * Find minimum of an univariate function f.\r\n     * <p>\r\n     * Algorithm:\r\n     *  G.Forsythe, M.Malcolm, C.Moler, Computer methods for mathematical\r\n     *  computations. M., Mir, 1980, p.180 of the Russian edition\r\n     *\r\n     * @param {function} f Function, whose minimum is to be found\r\n     * @param {Array} x0  Start interval enclosing the minimum\r\n     * @param {Object} [context] Parent object in case f is method of it\r\n     * @returns {Number} the approximation of the minimum value position\r\n     * @memberof JXG.Math.Numerics\r\n     **/\r\n    fminbr: function (f, x0, context) {\r\n        var a, b, x, v, w,\r\n            fx, fv, fw,\r\n            x00,\r\n            range, middle_range, tol_act, new_step,\r\n            p, q, t, ft,\r\n            r = (3.0 - Math.sqrt(5.0)) * 0.5,      // Golden section ratio\r\n            tol = Mat.eps,\r\n            sqrteps = Mat.eps, // Math.sqrt(Mat.eps),\r\n            maxiter = this.maxIterationsMinimize,\r\n            niter = 0;\r\n        // nfev = 0;\r\n\r\n        if (!Type.isArray(x0) || x0.length < 2) {\r\n            throw new Error(\r\n                \"JXG.Math.Numerics.fminbr: length of array x0 has to be at least two.\"\r\n            );\r\n        }\r\n\r\n        x00 = this.findDomain(f, x0, context);\r\n        a = x00[0];\r\n        b = x00[1];\r\n        v = a + r * (b - a);\r\n        fv = f.call(context, v);\r\n\r\n        // First step - always gold section\r\n        // nfev += 1;\r\n        x = v;\r\n        w = v;\r\n        fx = fv;\r\n        fw = fv;\r\n\r\n        while (niter < maxiter) {\r\n            // Range over the interval in which we are looking for the minimum\r\n            range = b - a;\r\n            middle_range = (a + b) * 0.5;\r\n\r\n            // Actual tolerance\r\n            tol_act = sqrteps * Math.abs(x) + tol / 3.0;\r\n\r\n            if (Math.abs(x - middle_range) + range * 0.5 <= 2.0 * tol_act) {\r\n                // Acceptable approx. is found\r\n                return x;\r\n            }\r\n\r\n            // Obtain the golden section step\r\n            new_step = r * (x < middle_range ? b - x : a - x);\r\n\r\n            // Decide if the interpolation can be tried. If x and w are distinct, interpolatiom may be tried\r\n            if (Math.abs(x - w) >= tol_act) {\r\n                // Interpolation step is calculated as p/q;\r\n                // division operation is delayed until last moment\r\n                t = (x - w) * (fx - fv);\r\n                q = (x - v) * (fx - fw);\r\n                p = (x - v) * q - (x - w) * t;\r\n                q = 2 * (q - t);\r\n\r\n                if (q > 0) {\r\n                    p = -p; // q was calculated with the opposite sign; make q positive\r\n                } else {\r\n                    q = -q; // // and assign possible minus to p\r\n                }\r\n                if (\r\n                    Math.abs(p) < Math.abs(new_step * q) && // If x+p/q falls in [a,b]\r\n                    p > q * (a - x + 2 * tol_act) &&        //  not too close to a and\r\n                    p < q * (b - x - 2 * tol_act)\r\n                ) {\r\n                    // b, and isn't too large\r\n                    new_step = p / q; // it is accepted\r\n                }\r\n                // If p / q is too large then the\r\n                // golden section procedure can\r\n                // reduce [a,b] range to more\r\n                // extent\r\n            }\r\n\r\n            // Adjust the step to be not less than tolerance\r\n            if (Math.abs(new_step) < tol_act) {\r\n                if (new_step > 0) {\r\n                    new_step = tol_act;\r\n                } else {\r\n                    new_step = -tol_act;\r\n                }\r\n            }\r\n\r\n            // Obtain the next approximation to min\r\n            // and reduce the enveloping range\r\n\r\n            // Tentative point for the min\r\n            t = x + new_step;\r\n            ft = f.call(context, t);\r\n            // nfev += 1;\r\n\r\n            // t is a better approximation\r\n            if (ft <= fx) {\r\n                // Reduce the range so that t would fall within it\r\n                if (t < x) {\r\n                    b = x;\r\n                } else {\r\n                    a = x;\r\n                }\r\n\r\n                // Assign the best approx to x\r\n                v = w;\r\n                w = x;\r\n                x = t;\r\n\r\n                fv = fw;\r\n                fw = fx;\r\n                fx = ft;\r\n                // x remains the better approx\r\n            } else {\r\n                // Reduce the range enclosing x\r\n                if (t < x) {\r\n                    a = t;\r\n                } else {\r\n                    b = t;\r\n                }\r\n\r\n                if (ft <= fw || w === x) {\r\n                    v = w;\r\n                    w = t;\r\n                    fv = fw;\r\n                    fw = ft;\r\n                } else if (ft <= fv || v === x || v === w) {\r\n                    v = t;\r\n                    fv = ft;\r\n                }\r\n            }\r\n            niter += 1;\r\n        }\r\n\r\n        return x;\r\n    },\r\n\r\n    /**\r\n     * GLOMIN seeks a global minimum of a function F(X) in an interval [A,B]\r\n     * and is the adaption of the algorithm GLOMIN by Richard Brent.\r\n     *\r\n     * Here is the original documentation:\r\n     * <pre>\r\n     *\r\n     * Discussion:\r\n     *\r\n     * This function assumes that F(X) is twice continuously differentiable over [A,B]\r\n     * and that |F''(X)| <= M for all X in [A,B].\r\n     *\r\n     * Licensing:\r\n     *   This code is distributed under the GNU LGPL license.\r\n     *\r\n     * Modified:\r\n     *\r\n     *   17 April 2008\r\n     *\r\n     * Author:\r\n     *\r\n     *   Original FORTRAN77 version by Richard Brent.\r\n     *   C version by John Burkardt.\r\n     *   https://people.math.sc.edu/Burkardt/c_src/brent/brent.c\r\n     *\r\n     * Reference:\r\n     *\r\n     *   Richard Brent,\r\n     *  Algorithms for Minimization Without Derivatives,\r\n     *   Dover, 2002,\r\n     *  ISBN: 0-486-41998-3,\r\n     *   LC: QA402.5.B74.\r\n     *\r\n     * Parameters:\r\n     *\r\n     *   Input, double A, B, the endpoints of the interval.\r\n     *  It must be the case that A < B.\r\n     *\r\n     *   Input, double C, an initial guess for the global\r\n     *  minimizer.  If no good guess is known, C = A or B is acceptable.\r\n     *\r\n     *  Input, double M, the bound on the second derivative.\r\n     *\r\n     *   Input, double MACHEP, an estimate for the relative machine\r\n     *  precision.\r\n     *\r\n     *   Input, double E, a positive tolerance, a bound for the\r\n     *  absolute error in the evaluation of F(X) for any X in [A,B].\r\n     *\r\n     *   Input, double T, a positive error tolerance.\r\n     *\r\n     *    Input, double F (double x ), a user-supplied\r\n     *  function whose global minimum is being sought.\r\n     *\r\n     *   Output, double *X, the estimated value of the abscissa\r\n     *  for which F attains its global minimum value in [A,B].\r\n     *\r\n     *   Output, double GLOMIN, the value F(X).\r\n     * </pre>\r\n     *\r\n     * In JSXGraph, some parameters of the original algorithm are set to fixed values:\r\n     * <ul>\r\n     *  <li> M = 10000000.0\r\n     *  <li> C = A or B, depending if f(A) <= f(B)\r\n     *  <li> T = JXG.Math.eps\r\n     *  <li> E = JXG.Math.eps * JXG.Math.eps\r\n     *  <li> MACHEP = JXG.Math.eps * JXG.Math.eps * JXG.Math.eps\r\n     * </ul>\r\n     * @param {function} f Function, whose global minimum is to be found\r\n     * @param {Array} x0 Array of length 2 determining the interval [A, B] for which the global minimum is to be found\r\n     * @returns {Array} [x, y] x is the position of the global minimum and y = f(x).\r\n     */\r\n    glomin: function (f, x0) {\r\n        var a0, a2, a3, d0, d1, d2, h,\r\n            k, m2,\r\n            p, q, qs,\r\n            r, s, sc,\r\n            y, y0, y1, y2, y3, yb,\r\n            z0, z1, z2,\r\n            a, b, c, x,\r\n            m = 10000000.0,\r\n            t = Mat.eps, // * Mat.eps,\r\n            e = Mat.eps * Mat.eps,\r\n            machep = Mat.eps * Mat.eps * Mat.eps;\r\n\r\n        a = x0[0];\r\n        b = x0[1];\r\n        c = (f(a) < f(b)) ? a : b;\r\n\r\n        a0 = b;\r\n        x = a0;\r\n        a2 = a;\r\n        y0 = f(b);\r\n        yb = y0;\r\n        y2 = f(a);\r\n        y = y2;\r\n\r\n        if (y0 < y) {\r\n            y = y0;\r\n        } else {\r\n            x = a;\r\n        }\r\n\r\n        if (m <= 0.0 || b <= a) {\r\n            return y;\r\n        }\r\n\r\n        m2 = 0.5 * (1.0 + 16.0 * machep) * m;\r\n\r\n        if (c <= a || b <= c) {\r\n            sc = 0.5 * (a + b);\r\n        } else {\r\n            sc = c;\r\n        }\r\n\r\n        y1 = f(sc);\r\n        k = 3;\r\n        d0 = a2 - sc;\r\n        h = 9.0 / 11.0;\r\n\r\n        if (y1 < y) {\r\n            x = sc;\r\n            y = y1;\r\n        }\r\n\r\n        for (; ;) {\r\n            d1 = a2 - a0;\r\n            d2 = sc - a0;\r\n            z2 = b - a2;\r\n            z0 = y2 - y1;\r\n            z1 = y2 - y0;\r\n            r = d1 * d1 * z0 - d0 * d0 * z1;\r\n            p = r;\r\n            qs = 2.0 * (d0 * z1 - d1 * z0);\r\n            q = qs;\r\n\r\n            if (k < 1000000 || y2 <= y) {\r\n                for (; ;) {\r\n                    if (q * (r * (yb - y2) + z2 * q * ((y2 - y) + t)) <\r\n                        z2 * m2 * r * (z2 * q - r)) {\r\n\r\n                        a3 = a2 + r / q;\r\n                        y3 = f(a3);\r\n\r\n                        if (y3 < y) {\r\n                            x = a3;\r\n                            y = y3;\r\n                        }\r\n                    }\r\n                    k = ((1611 * k) % 1048576);\r\n                    q = 1.0;\r\n                    r = (b - a) * 0.00001 * k;\r\n\r\n                    if (z2 <= r) {\r\n                        break;\r\n                    }\r\n                }\r\n            } else {\r\n                k = ((1611 * k) % 1048576);\r\n                q = 1.0;\r\n                r = (b - a) * 0.00001 * k;\r\n\r\n                while (r < z2) {\r\n                    if (q * (r * (yb - y2) + z2 * q * ((y2 - y) + t)) <\r\n                        z2 * m2 * r * (z2 * q - r)) {\r\n\r\n                        a3 = a2 + r / q;\r\n                        y3 = f(a3);\r\n\r\n                        if (y3 < y) {\r\n                            x = a3;\r\n                            y = y3;\r\n                        }\r\n                    }\r\n                    k = ((1611 * k) % 1048576);\r\n                    q = 1.0;\r\n                    r = (b - a) * 0.00001 * k;\r\n                }\r\n            }\r\n\r\n            r = m2 * d0 * d1 * d2;\r\n            s = Math.sqrt(((y2 - y) + t) / m2);\r\n            h = 0.5 * (1.0 + h);\r\n            p = h * (p + 2.0 * r * s);\r\n            q = q + 0.5 * qs;\r\n            r = - 0.5 * (d0 + (z0 + 2.01 * e) / (d0 * m2));\r\n\r\n            if (r < s || d0 < 0.0) {\r\n                r = a2 + s;\r\n            } else {\r\n                r = a2 + r;\r\n            }\r\n\r\n            if (0.0 < p * q) {\r\n                a3 = a2 + p / q;\r\n            } else {\r\n                a3 = r;\r\n            }\r\n\r\n            for (; ;) {\r\n                a3 = Math.max(a3, r);\r\n\r\n                if (b <= a3) {\r\n                    a3 = b;\r\n                    y3 = yb;\r\n                } else {\r\n                    y3 = f(a3);\r\n                }\r\n\r\n                if (y3 < y) {\r\n                    x = a3;\r\n                    y = y3;\r\n                }\r\n\r\n                d0 = a3 - a2;\r\n\r\n                if (a3 <= r) {\r\n                    break;\r\n                }\r\n\r\n                p = 2.0 * (y2 - y3) / (m * d0);\r\n\r\n                if ((1.0 + 9.0 * machep) * d0 <= Math.abs(p)) {\r\n                    break;\r\n                }\r\n\r\n                if (0.5 * m2 * (d0 * d0 + p * p) <= (y2 - y) + (y3 - y) + 2.0 * t) {\r\n                    break;\r\n                }\r\n                a3 = 0.5 * (a2 + a3);\r\n                h = 0.9 * h;\r\n            }\r\n\r\n            if (b <= a3) {\r\n                break;\r\n            }\r\n\r\n            a0 = sc;\r\n            sc = a2;\r\n            a2 = a3;\r\n            y0 = y1;\r\n            y1 = y2;\r\n            y2 = y3;\r\n        }\r\n\r\n        return [x, y];\r\n    },\r\n\r\n    /**\r\n     * Determine all roots of a polynomial with real or complex coefficients by using the\r\n     * iterative method attributed to Weierstrass, Durand, Kerner, Aberth, and Ehrlich. In particular,\r\n     * the iteration method with cubic convergence is used that is usually attributed to Ehrlich-Aberth.\r\n     * <p>\r\n     * The returned roots are sorted with respect to their real values.\r\n     * <p> This method makes use of the JSXGraph classes {@link JXG.Complex} and {@link JXG.C} to handle\r\n     * complex numbers.\r\n     *\r\n     * @param {Array} a Array of coefficients of the polynomial a[0] + a[1]*x+ a[2]*x**2...\r\n     * The coefficients are of type Number or JXG.Complex.\r\n     * @param {Number} [deg] Optional degree of the polynomial. Otherwise all entries are taken, with\r\n     * leading zeros removed.\r\n     * @param {Number} [tol=Number.EPSILON] Approximation tolerance\r\n     * @param {Number} [max_it=30] Maximum number of iterations\r\n     * @param {Array} [initial_values=null] Array of initial values for the roots. If not given,\r\n     * starting values are determined by the method of Ozawa.\r\n     * @returns {Array} Array of complex numbers (of JXG.Complex) approximating the roots of the polynomial.\r\n     * @memberof JXG.Math.Numerics\r\n     * @see JXG.Complex\r\n     * @see JXG.C\r\n     *\r\n     * @example\r\n     * // Polynomial p(z) = -1 + 1z^2\r\n     * var i, roots,\r\n     *     p = [-1, 0, 1];\r\n     *\r\n     * roots = JXG.Math.Numerics.polzeros(p);\r\n     * for (i = 0; i < roots.length; i++) {\r\n     *     console.log(i, roots[i].toString());\r\n     * }\r\n     * // Output:\r\n     *   0 -1 + -3.308722450212111e-24i\r\n     *   1 1 + 0i\r\n     *\r\n     * @example\r\n     * // Polynomial p(z) = -1 + 3z - 9z^2 + z^3 - 8z^6 + 9z^7 - 9z^8 + z^9\r\n     * var i, roots,\r\n     *     p = [-1, 3, -9, 1, 0, 0, -8, 9, -9, 1];\r\n     *\r\n     * roots = JXG.Math.Numerics.polzeros(p);\r\n     * for (i = 0; i < roots.length; i++) {\r\n     *     console.log(i, roots[i].toString());\r\n     * }\r\n     * // Output:\r\n     * 0 -0.7424155888401961 + 0.4950476539211721i\r\n     * 1 -0.7424155888401961 + -0.4950476539211721i\r\n     * 2 0.16674869833354108 + 0.2980502714610669i\r\n     * 3 0.16674869833354108 + -0.29805027146106694i\r\n     * 4 0.21429002063640837 + 1.0682775088132996i\r\n     * 5 0.21429002063640842 + -1.0682775088132999i\r\n     * 6 0.861375497926218 + -0.6259177003583295i\r\n     * 7 0.8613754979262181 + 0.6259177003583295i\r\n     * 8 8.000002743888055 + -1.8367099231598242e-40i\r\n     *\r\n     */\r\n    polzeros: function (coeffs, deg, tol, max_it, initial_values) {\r\n        var i, le, off, it,\r\n            debug = false,\r\n            cc = [],\r\n            obvious = [],\r\n            roots = [],\r\n\r\n            /**\r\n             * Horner method to evaluate polynomial or the derivative thereof for complex numbers,\r\n             * i.e. coefficients and variable are complex.\r\n             * @function\r\n             * @param {Array} a Array of complex coefficients of the polynomial a[0] + a[1]*x+ a[2]*x**2...\r\n             * @param {JXG.Complex} z Value for which the polynomial will be evaluated.\r\n             * @param {Boolean} [derivative=false] If true the derivative will be evaluated.\r\n             * @ignore\r\n             */\r\n            hornerComplex = function (a, z, derivative) {\r\n                var i, s,\r\n                    n = a.length - 1;\r\n\r\n                derivative = derivative || false;\r\n                if (derivative) {\r\n                    // s = n * a_n\r\n                    s = JXG.C.mult(n, a[n]);\r\n                    for (i = n - 1; i > 0; i--) {\r\n                        // s = s * z + i * a_i\r\n                        s.mult(z);\r\n                        s.add(JXG.C.mult(a[i], i));\r\n                    }\r\n                } else {\r\n                    // s = a_n\r\n                    s = JXG.C.copy(a[n]);\r\n                    for (i = n - 1; i >= 0; i--) {\r\n                        // s = s * z + a_i\r\n                        s.mult(z);\r\n                        s.add(a[i]);\r\n                    }\r\n                }\r\n                return s;\r\n            },\r\n\r\n            /**\r\n             * Horner method to evaluate reciprocal polynomial or the derivative thereof for complex numbers,\r\n             * i.e. coefficients and variable are complex.\r\n             * @function\r\n             * @param {Array} a Array of complex coefficients of the polynomial a[0] + a[1]*x+ a[2]*x**2...\r\n             * @param {JXG.Complex} z Value for which the reciprocal polynomial will be evaluated.\r\n             * @param {Boolean} [derivative=false] If true the derivative will be evaluated.\r\n             * @ignore\r\n             */\r\n            hornerRec = function (a, x, derivative) {\r\n                var i, s,\r\n                    n = a.length - 1;\r\n\r\n                derivative = derivative || false;\r\n                if (derivative) {\r\n                    // s = n * a_0\r\n                    s = JXG.C.mult(n, a[0]);\r\n                    for (i = n - 1; i > 0; i--) {\r\n                        // s = s * x + i * a_{n-i}\r\n                        s.mult(x);\r\n                        s.add(JXG.C.mult(a[n - i], i));\r\n                    }\r\n                } else {\r\n                    // s = a_0\r\n                    s = JXG.C.copy(a[0]);\r\n                    for (i = n - 1; i >= 0; i--) {\r\n                        // s = s * x + a_{n-i}\r\n                        s.mult(x);\r\n                        s.add(a[n - i]);\r\n                    }\r\n                }\r\n                return s;\r\n            },\r\n\r\n            /**\r\n             * Horner method to evaluate real polynomial at a real value.\r\n             * @function\r\n             * @param {Array} a Array of real coefficients of the polynomial a[0] + a[1]*x+ a[2]*x**2...\r\n             * @param {Number} z Value for which the polynomial will be evaluated.\r\n             * @ignore\r\n             */\r\n            horner = function (a, x) {\r\n                var i, s,\r\n                    n = a.length - 1;\r\n\r\n                s = a[n];\r\n                for (i = n - 1; i >= 0; i--) {\r\n                    s = s * x + a[i];\r\n                }\r\n                return s;\r\n            },\r\n\r\n            /**\r\n             * Determine start values for the Aberth iteration, see\r\n             * Ozawa, \"An experimental study of the starting values\r\n             * of the Durand-Kerner-Aberth iteration\" (1995).\r\n             *\r\n             * @function\r\n             * @param {Array} a Array of complex coefficients of the polynomial a[0] + a[1]*x+ a[2]*x**2...\r\n             * @returns {Array} Array Initial values for the roots.\r\n             * @ignore\r\n             */\r\n            initial_guess = function (a) {\r\n                var i, r,\r\n                    n = a.length - 1, // degree\r\n                    alpha1 = Math.PI * 2 / n,\r\n                    alpha0 = Math.PI / n * 0.5,\r\n                    b, z,\r\n                    init = [];\r\n\r\n\r\n                // From Ozawa, \"An experimental study of the starting values\r\n                // of the Durand-Kerner-Aberth iteration\" (1995)\r\n\r\n                // b is the arithmetic mean of the roots.\r\n                // With is Vieta's formula <https://en.wikipedia.org/wiki/Vieta%27s_formulas>\r\n                //   b = -a_{n-1} / (n * a_n)\r\n                b = JXG.C.mult(-1, a[n - 1]);\r\n                b.div(JXG.C.mult(n, a[n]));\r\n\r\n                // r is the geometric mean of the deviations |b - root_i|.\r\n                // Using\r\n                //   p(z) = a_n prod(z - root_i)\r\n                // and therefore\r\n                //   |p(b)| = |a_n| prod(|b - root_i|)\r\n                // we arrive at:\r\n                //   r = |p(b)/a_n|^(1/n)\r\n                z = JXG.C.div(hornerComplex(a, b), a[n]);\r\n                r = Math.pow(JXG.C.abs(z), 1 / n);\r\n                if (r === 0) { r = 1; }\r\n\r\n                for (i = 0; i < n; i++) {\r\n                    a = new JXG.Complex(r * Math.cos(alpha1 * i + alpha0), r * Math.sin(alpha1 * i + alpha0));\r\n                    init[i] = JXG.C.add(b, a);\r\n                }\r\n\r\n                return init;\r\n            },\r\n\r\n            /**\r\n             * Ehrlich-Aberth iteration. The stopping criterion is from\r\n             * D.A. Bini, \"Numerical computation of polynomial zeros\r\n             * by means of Aberths's method\", Numerical Algorithms (1996).\r\n             *\r\n             * @function\r\n             * @param {Array} a Array of complex coefficients of the polynomial a[0] + a[1]*x+ a[2]*x**2...\r\n             * @param {Number} mu Machine precision\r\n             * @param {Number} max_it Maximum number of iterations\r\n             * @param {Array} z Initial guess for the roots. Will be changed in place.\r\n             * @returns {Number} Number of iterations\r\n             * @ignore\r\n             */\r\n            aberthIteration = function (cc, mu, max_it, z) {\r\n                var k, i, j,\r\n                    done = [],\r\n                    cr = [],\r\n                    gamma, x,\r\n                    done_sum = 0,\r\n                    num, denom, s, pp,\r\n                    n = z.length;\r\n\r\n                for (i = 0; i < n; i++) {\r\n                    done.push(false);\r\n                }\r\n                for (i = 0; i < cc.length; i++) {\r\n                    cr.push(JXG.C.abs(cc[i]) * (4 * i + 1));\r\n                }\r\n                for (k = 0; k < max_it && done_sum < n; k++) {\r\n                    for (i = 0; i < n; i++) {\r\n                        if (done[i]) {\r\n                            continue;\r\n                        }\r\n                        num = hornerComplex(cc, z[i]);\r\n                        x = JXG.C.abs(z[i]);\r\n\r\n                        // Stopping criterion by D.A. Bini\r\n                        // \"Numerical computation of polynomial zeros\r\n                        // by means of Aberths's method\", Numerical Algorithms (1996).\r\n                        //\r\n                        if (JXG.C.abs(num) < mu * horner(cr, x)) {\r\n                            done[i] = true;\r\n                            done_sum++;\r\n                            if (done_sum === n) {\r\n                                break;\r\n                            }\r\n                            continue;\r\n                        }\r\n\r\n                        // num = P(z_i) / P'(z_i)\r\n                        if (x > 1) {\r\n                            gamma = JXG.C.div(1, z[i]);\r\n                            pp = hornerRec(cc, gamma, true);\r\n                            pp.div(hornerRec(cc, gamma));\r\n                            pp.mult(gamma);\r\n                            num = JXG.C.sub(n, pp);\r\n                            num = JXG.C.div(z[i], num);\r\n                        } else {\r\n                            num.div(hornerComplex(cc, z[i], true));\r\n                        }\r\n\r\n                        // denom = sum_{i\\neq j} 1 / (z_i  - z_j)\r\n                        denom = new JXG.Complex(0);\r\n                        for (j = 0; j < n; j++) {\r\n                            if (j === i) {\r\n                                continue;\r\n                            }\r\n                            s = JXG.C.sub(z[i], z[j]);\r\n                            s = JXG.C.div(1, s);\r\n                            denom.add(s);\r\n                        }\r\n\r\n                        // num = num / 1 - num * sum_{i\\neq j} 1 / (z_i - z_j)\r\n                        denom.mult(num);\r\n                        denom = JXG.C.sub(1, denom);\r\n                        num.div(denom);\r\n                        // z_i = z_i - num\r\n                        z[i].sub(num);\r\n                    }\r\n                }\r\n\r\n                return k;\r\n            };\r\n\r\n\r\n        tol = tol || Number.EPSILON;\r\n        max_it = max_it || 30;\r\n\r\n        le = coeffs.length;\r\n        if (JXG.isNumber(deg) && deg >= 0 && deg < le - 1) {\r\n            le = deg + 1;\r\n        }\r\n\r\n        // Convert coefficient array to complex numbers\r\n        for (i = 0; i < le; i++) {\r\n            cc.push(new JXG.Complex(coeffs[i]));\r\n        }\r\n\r\n        // Search for (multiple) roots at x=0\r\n        for (i = 0; i < le; i++) {\r\n            if (cc[i].real !== 0 || cc[i].imaginary !== 0) {\r\n                off = i;\r\n                break;\r\n            }\r\n        }\r\n\r\n        // Deflate root x=0, store roots at x=0 in obvious\r\n        for (i = 0; i < off; i++) {\r\n            obvious.push(new JXG.Complex(0));\r\n        }\r\n        cc = cc.slice(off);\r\n        le = cc.length;\r\n\r\n        // Remove leading zeros from the coefficient array\r\n        for (i = le - 1; i >= 0; i--) {\r\n            if (cc[i].real !== 0 || cc[i].imaginary !== 0) {\r\n                break;\r\n            }\r\n            cc.pop();\r\n        }\r\n        le = cc.length;\r\n        if (le === 0) {\r\n            return [];\r\n        }\r\n\r\n        // From now on we can assume that the\r\n        // constant coefficient and the leading coefficient\r\n        // are not zero.\r\n        if (initial_values) {\r\n            for (i = 0; i < le - 1; i++) {\r\n                roots.push(new JXG.Complex(initial_values[i]));\r\n            }\r\n        } else {\r\n            roots = initial_guess(cc);\r\n        }\r\n        it = aberthIteration(cc, tol, max_it, roots);\r\n\r\n        // Append the roots at x=0\r\n        roots = obvious.concat(roots);\r\n\r\n        if (debug) {\r\n            console.log(\"Iterations:\", it);\r\n            console.log('Roots:');\r\n            for (i = 0; i < roots.length; i++) {\r\n                console.log(i, roots[i].toString(), JXG.C.abs(hornerComplex(cc, roots[i])));\r\n            }\r\n        }\r\n\r\n        // Sort roots according to their real part\r\n        roots.sort(function (a, b) {\r\n            if (a.real < b.real) {\r\n                return -1;\r\n            }\r\n            if (a.real > b.real) {\r\n                return 1;\r\n            }\r\n            return 0;\r\n        });\r\n\r\n        return roots;\r\n    },\r\n\r\n    /**\r\n     * Implements the Ramer-Douglas-Peucker algorithm.\r\n     * It discards points which are not necessary from the polygonal line defined by the point array\r\n     * pts. The computation is done in screen coordinates.\r\n     * Average runtime is O(nlog(n)), worst case runtime is O(n^2), where n is the number of points.\r\n     * @param {Array} pts Array of {@link JXG.Coords}\r\n     * @param {Number} eps If the absolute value of a given number <tt>x</tt> is smaller than <tt>eps</tt> it is considered to be equal <tt>0</tt>.\r\n     * @returns {Array} An array containing points which represent an apparently identical curve as the points of pts do, but contains fewer points.\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    RamerDouglasPeucker: function (pts, eps) {\r\n        var allPts = [],\r\n            newPts = [],\r\n            i, k, len,\r\n            endless = true,\r\n\r\n            /**\r\n             * findSplit() is a subroutine of {@link JXG.Math.Numerics.RamerDouglasPeucker}.\r\n             * It searches for the point between index i and j which\r\n             * has the largest distance from the line between the points i and j.\r\n             * @param {Array} pts Array of {@link JXG.Coords}\r\n             * @param {Number} i Index of a point in pts\r\n             * @param {Number} j Index of a point in pts\r\n             * @ignore\r\n             * @private\r\n             */\r\n            findSplit = function (pts, i, j) {\r\n                var d, k, ci, cj, ck,\r\n                    x0, y0, x1, y1,\r\n                    den, lbda,\r\n                    eps = Mat.eps * Mat.eps,\r\n                    huge = 10000,\r\n                    dist = 0,\r\n                    f = i;\r\n\r\n                if (j - i < 2) {\r\n                    return [-1.0, 0];\r\n                }\r\n\r\n                ci = pts[i].scrCoords;\r\n                cj = pts[j].scrCoords;\r\n\r\n                if (isNaN(ci[1]) || isNaN(ci[2])) {\r\n                    return [NaN, i];\r\n                }\r\n                if (isNaN(cj[1]) || isNaN(cj[2])) {\r\n                    return [NaN, j];\r\n                }\r\n\r\n                for (k = i + 1; k < j; k++) {\r\n                    ck = pts[k].scrCoords;\r\n                    if (isNaN(ck[1]) || isNaN(ck[2])) {\r\n                        return [NaN, k];\r\n                    }\r\n\r\n                    x0 = ck[1] - ci[1];\r\n                    y0 = ck[2] - ci[2];\r\n                    x1 = cj[1] - ci[1];\r\n                    y1 = cj[2] - ci[2];\r\n                    x0 = x0 === Infinity ? huge : x0;\r\n                    y0 = y0 === Infinity ? huge : y0;\r\n                    x1 = x1 === Infinity ? huge : x1;\r\n                    y1 = y1 === Infinity ? huge : y1;\r\n                    x0 = x0 === -Infinity ? -huge : x0;\r\n                    y0 = y0 === -Infinity ? -huge : y0;\r\n                    x1 = x1 === -Infinity ? -huge : x1;\r\n                    y1 = y1 === -Infinity ? -huge : y1;\r\n                    den = x1 * x1 + y1 * y1;\r\n\r\n                    if (den > eps) {\r\n                        lbda = (x0 * x1 + y0 * y1) / den;\r\n\r\n                        if (lbda < 0.0) {\r\n                            lbda = 0.0;\r\n                        } else if (lbda > 1.0) {\r\n                            lbda = 1.0;\r\n                        }\r\n\r\n                        x0 = x0 - lbda * x1;\r\n                        y0 = y0 - lbda * y1;\r\n                        d = x0 * x0 + y0 * y0;\r\n                    } else {\r\n                        lbda = 0.0;\r\n                        d = x0 * x0 + y0 * y0;\r\n                    }\r\n\r\n                    if (d > dist) {\r\n                        dist = d;\r\n                        f = k;\r\n                    }\r\n                }\r\n                return [Math.sqrt(dist), f];\r\n            },\r\n            /**\r\n             * RDP() is a private subroutine of {@link JXG.Math.Numerics.RamerDouglasPeucker}.\r\n             * It runs recursively through the point set and searches the\r\n             * point which has the largest distance from the line between the first point and\r\n             * the last point. If the distance from the line is greater than eps, this point is\r\n             * included in our new point set otherwise it is discarded.\r\n             * If it is taken, we recursively apply the subroutine to the point set before\r\n             * and after the chosen point.\r\n             * @param {Array} pts Array of {@link JXG.Coords}\r\n             * @param {Number} i Index of an element of pts\r\n             * @param {Number} j Index of an element of pts\r\n             * @param {Number} eps If the absolute value of a given number <tt>x</tt> is smaller than <tt>eps</tt> it is considered to be equal <tt>0</tt>.\r\n             * @param {Array} newPts Array of {@link JXG.Coords}\r\n             * @ignore\r\n             * @private\r\n             */\r\n            RDP = function (pts, i, j, eps, newPts) {\r\n                var result = findSplit(pts, i, j),\r\n                    k = result[1];\r\n\r\n                if (isNaN(result[0])) {\r\n                    RDP(pts, i, k - 1, eps, newPts);\r\n                    newPts.push(pts[k]);\r\n                    do {\r\n                        ++k;\r\n                    } while (k <= j && isNaN(pts[k].scrCoords[1] + pts[k].scrCoords[2]));\r\n                    if (k <= j) {\r\n                        newPts.push(pts[k]);\r\n                    }\r\n                    RDP(pts, k + 1, j, eps, newPts);\r\n                } else if (result[0] > eps) {\r\n                    RDP(pts, i, k, eps, newPts);\r\n                    RDP(pts, k, j, eps, newPts);\r\n                } else {\r\n                    newPts.push(pts[j]);\r\n                }\r\n            };\r\n\r\n        len = pts.length;\r\n\r\n        i = 0;\r\n        while (endless) {\r\n            // Search for the next point without NaN coordinates\r\n            while (i < len && isNaN(pts[i].scrCoords[1] + pts[i].scrCoords[2])) {\r\n                i += 1;\r\n            }\r\n            // Search for the next position of a NaN point\r\n            k = i + 1;\r\n            while (k < len && !isNaN(pts[k].scrCoords[1] + pts[k].scrCoords[2])) {\r\n                k += 1;\r\n            }\r\n            k--;\r\n\r\n            // Only proceed if something is left\r\n            if (i < len && k > i) {\r\n                newPts = [];\r\n                newPts[0] = pts[i];\r\n                RDP(pts, i, k, eps, newPts);\r\n                allPts = allPts.concat(newPts);\r\n            }\r\n            if (i >= len) {\r\n                break;\r\n            }\r\n            // Push the NaN point\r\n            if (k < len - 1) {\r\n                allPts.push(pts[k + 1]);\r\n            }\r\n            i = k + 1;\r\n        }\r\n\r\n        return allPts;\r\n    },\r\n\r\n    /**\r\n     * Old name for the implementation of the Ramer-Douglas-Peucker algorithm.\r\n     * @deprecated Use {@link JXG.Math.Numerics.RamerDouglasPeucker}\r\n     * @memberof JXG.Math.Numerics\r\n     */\r\n    RamerDouglasPeuker: function (pts, eps) {\r\n        JXG.deprecated(\"Numerics.RamerDouglasPeuker()\", \"Numerics.RamerDouglasPeucker()\");\r\n        return this.RamerDouglasPeucker(pts, eps);\r\n    },\r\n\r\n    /**\r\n     * Implements the Visvalingam-Whyatt algorithm.\r\n     * See M. Visvalingam, J. D. Whyatt:\r\n     * \"Line generalisation by repeated elimination of the smallest area\", C.I.S.R.G Discussion paper 10, July 1992\r\n     *\r\n     * The algorithm discards points which are not necessary from the polygonal line defined by the point array\r\n     * pts (consisting of type JXG.Coords).\r\n     * @param {Array} pts Array of {@link JXG.Coords}\r\n     * @param {Number} numPoints Number of remaining intermediate points. The first and the last point of the original points will\r\n     *    be taken in any case.\r\n     * @returns {Array} An array containing points which approximates the curve defined by pts.\r\n     * @memberof JXG.Math.Numerics\r\n     *\r\n     * @example\r\n     *     var i, p = [];\r\n     *     for (i = 0; i < 5; ++i) {\r\n     *         p.push(board.create('point', [Math.random() * 12 - 6, Math.random() * 12 - 6]));\r\n     *     }\r\n     *\r\n     *     // Plot a cardinal spline curve\r\n     *     var splineArr = JXG.Math.Numerics.CardinalSpline(p, 0.5);\r\n     *     var cu1 = board.create('curve', splineArr, {strokeColor: 'green'});\r\n     *\r\n     *     var c = board.create('curve', [[0],[0]], {strokeWidth: 2, strokeColor: 'black'});\r\n     *     c.updateDataArray = function() {\r\n     *         var i, len, points;\r\n     *\r\n     *         // Reduce number of intermediate points with Visvakingam-Whyatt to 6\r\n     *         points = JXG.Math.Numerics.Visvalingam(cu1.points, 6);\r\n     *         // Plot the remaining points\r\n     *         len = points.length;\r\n     *         this.dataX = [];\r\n     *         this.dataY = [];\r\n     *         for (i = 0; i < len; i++) {\r\n     *             this.dataX.push(points[i].usrCoords[1]);\r\n     *             this.dataY.push(points[i].usrCoords[2]);\r\n     *         }\r\n     *     };\r\n     *     board.update();\r\n     *\r\n     * </pre><div id=\"JXGce0cc55c-b592-11e6-8270-104a7d3be7eb\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXGce0cc55c-b592-11e6-8270-104a7d3be7eb',\r\n     *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n     *\r\n     *         var i, p = [];\r\n     *         for (i = 0; i < 5; ++i) {\r\n     *             p.push(board.create('point', [Math.random() * 12 - 6, Math.random() * 12 - 6]));\r\n     *         }\r\n     *\r\n     *         // Plot a cardinal spline curve\r\n     *         var splineArr = JXG.Math.Numerics.CardinalSpline(p, 0.5);\r\n     *         var cu1 = board.create('curve', splineArr, {strokeColor: 'green'});\r\n     *\r\n     *         var c = board.create('curve', [[0],[0]], {strokeWidth: 2, strokeColor: 'black'});\r\n     *         c.updateDataArray = function() {\r\n     *             var i, len, points;\r\n     *\r\n     *             // Reduce number of intermediate points with Visvakingam-Whyatt to 6\r\n     *             points = JXG.Math.Numerics.Visvalingam(cu1.points, 6);\r\n     *             // Plot the remaining points\r\n     *             len = points.length;\r\n     *             this.dataX = [];\r\n     *             this.dataY = [];\r\n     *             for (i = 0; i < len; i++) {\r\n     *                 this.dataX.push(points[i].usrCoords[1]);\r\n     *                 this.dataY.push(points[i].usrCoords[2]);\r\n     *             }\r\n     *         };\r\n     *         board.update();\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     */\r\n    Visvalingam: function (pts, numPoints) {\r\n        var i,\r\n            len,\r\n            vol,\r\n            lastVol,\r\n            linkedList = [],\r\n            heap = [],\r\n            points = [],\r\n            lft,\r\n            rt,\r\n            lft2,\r\n            rt2,\r\n            obj;\r\n\r\n        len = pts.length;\r\n\r\n        // At least one intermediate point is needed\r\n        if (len <= 2) {\r\n            return pts;\r\n        }\r\n\r\n        // Fill the linked list\r\n        // Add first point to the linked list\r\n        linkedList[0] = {\r\n            used: true,\r\n            lft: null,\r\n            node: null\r\n        };\r\n\r\n        // Add all intermediate points to the linked list,\r\n        // whose triangle area is nonzero.\r\n        lft = 0;\r\n        for (i = 1; i < len - 1; i++) {\r\n            vol = Math.abs(\r\n                JXG.Math.Numerics.det([\r\n                    pts[i - 1].usrCoords,\r\n                    pts[i].usrCoords,\r\n                    pts[i + 1].usrCoords\r\n                ])\r\n            );\r\n            if (!isNaN(vol)) {\r\n                obj = {\r\n                    v: vol,\r\n                    idx: i\r\n                };\r\n                heap.push(obj);\r\n                linkedList[i] = {\r\n                    used: true,\r\n                    lft: lft,\r\n                    node: obj\r\n                };\r\n                linkedList[lft].rt = i;\r\n                lft = i;\r\n            }\r\n        }\r\n\r\n        // Add last point to the linked list\r\n        linkedList[len - 1] = {\r\n            used: true,\r\n            rt: null,\r\n            lft: lft,\r\n            node: null\r\n        };\r\n        linkedList[lft].rt = len - 1;\r\n\r\n        // Remove points until only numPoints intermediate points remain\r\n        lastVol = -Infinity;\r\n        while (heap.length > numPoints) {\r\n            // Sort the heap with the updated volume values\r\n            heap.sort(function (a, b) {\r\n                // descending sort\r\n                return b.v - a.v;\r\n            });\r\n\r\n            // Remove the point with the smallest triangle\r\n            i = heap.pop().idx;\r\n            linkedList[i].used = false;\r\n            lastVol = linkedList[i].node.v;\r\n\r\n            // Update the pointers of the linked list\r\n            lft = linkedList[i].lft;\r\n            rt = linkedList[i].rt;\r\n            linkedList[lft].rt = rt;\r\n            linkedList[rt].lft = lft;\r\n\r\n            // Update the values for the volumes in the linked list\r\n            lft2 = linkedList[lft].lft;\r\n            if (lft2 !== null) {\r\n                vol = Math.abs(\r\n                    JXG.Math.Numerics.det([\r\n                        pts[lft2].usrCoords,\r\n                        pts[lft].usrCoords,\r\n                        pts[rt].usrCoords\r\n                    ])\r\n                );\r\n\r\n                linkedList[lft].node.v = vol >= lastVol ? vol : lastVol;\r\n            }\r\n            rt2 = linkedList[rt].rt;\r\n            if (rt2 !== null) {\r\n                vol = Math.abs(\r\n                    JXG.Math.Numerics.det([\r\n                        pts[lft].usrCoords,\r\n                        pts[rt].usrCoords,\r\n                        pts[rt2].usrCoords\r\n                    ])\r\n                );\r\n\r\n                linkedList[rt].node.v = vol >= lastVol ? vol : lastVol;\r\n            }\r\n        }\r\n\r\n        // Return an array with the remaining points\r\n        i = 0;\r\n        points = [pts[i]];\r\n        do {\r\n            i = linkedList[i].rt;\r\n            points.push(pts[i]);\r\n        } while (linkedList[i].rt !== null);\r\n\r\n        return points;\r\n    }\r\n};\r\n\r\nexport default Mat.Numerics;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Andreas Walter,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, html_sanitize: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview type.js contains several functions to help deal with javascript's weak types.\r\n * This file mainly consists of detector functions which verify if a variable is or is not of\r\n * a specific type and converter functions that convert variables to another type or normalize\r\n * the type of a variable.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Mat from \"../math/math.js\";\r\n\r\nJXG.extend(\r\n    JXG,\r\n    /** @lends JXG */ {\r\n        /**\r\n         * Checks if the given object is an JSXGraph board.\r\n         * @param {Object} v\r\n         * @returns {Boolean}\r\n         */\r\n        isBoard: function (v) {\r\n            return v !== null &&\r\n                typeof v === \"object\" &&\r\n                this.isNumber(v.BOARD_MODE_NONE) &&\r\n                this.isObject(v.objects) &&\r\n                this.isObject(v.jc) &&\r\n                this.isFunction(v.update) &&\r\n                !!v.containerObj &&\r\n                this.isString(v.id);\r\n        },\r\n\r\n        /**\r\n         * Checks if the given string is an id within the given board.\r\n         * @param {JXG.Board} board\r\n         * @param {String} s\r\n         * @returns {Boolean}\r\n         */\r\n        isId: function (board, s) {\r\n            return typeof s === \"string\" && !!board.objects[s];\r\n        },\r\n\r\n        /**\r\n         * Checks if the given string is a name within the given board.\r\n         * @param {JXG.Board} board\r\n         * @param {String} s\r\n         * @returns {Boolean}\r\n         */\r\n        isName: function (board, s) {\r\n            return typeof s === \"string\" && !!board.elementsByName[s];\r\n        },\r\n\r\n        /**\r\n         * Checks if the given string is a group id within the given board.\r\n         * @param {JXG.Board} board\r\n         * @param {String} s\r\n         * @returns {Boolean}\r\n         */\r\n        isGroup: function (board, s) {\r\n            return typeof s === \"string\" && !!board.groups[s];\r\n        },\r\n\r\n        /**\r\n         * Checks if the value of a given variable is of type string.\r\n         * @param v A variable of any type.\r\n         * @returns {Boolean} True, if v is of type string.\r\n         */\r\n        isString: function (v) {\r\n            return typeof v === 'string';\r\n        },\r\n\r\n        /**\r\n         * Checks if the value of a given variable is of type number.\r\n         * @param v A variable of any type.\r\n         * @param {Boolean} [acceptStringNumber=false] If set to true, the function returns true for e.g. v='3.1415'.\r\n         * @param {Boolean} [acceptNaN=true] If set to false, the function returns false for v=NaN.\r\n         * @returns {Boolean} True, if v is of type number.\r\n         */\r\n        isNumber: function (v, acceptStringNumber, acceptNaN) {\r\n            var result = (\r\n                typeof v === 'number' || Object.prototype.toString.call(v) === '[Object Number]'\r\n            );\r\n            acceptStringNumber = acceptStringNumber || false;\r\n            acceptNaN = acceptNaN === undefined ? true : acceptNaN;\r\n\r\n            if (acceptStringNumber) {\r\n                result = result || ('' + parseFloat(v)) === v;\r\n            }\r\n            if (!acceptNaN) {\r\n                result = result && !isNaN(v);\r\n            }\r\n            return result;\r\n        },\r\n\r\n        /**\r\n         * Checks if a given variable references a function.\r\n         * @param v A variable of any type.\r\n         * @returns {Boolean} True, if v is a function.\r\n         */\r\n        isFunction: function (v) {\r\n            return typeof v === 'function';\r\n        },\r\n\r\n        /**\r\n         * Checks if a given variable references an array.\r\n         * @param v A variable of any type.\r\n         * @returns {Boolean} True, if v is of type array.\r\n         */\r\n        isArray: function (v) {\r\n            var r;\r\n\r\n            // use the ES5 isArray() method and if that doesn't exist use a fallback.\r\n            if (Array.isArray) {\r\n                r = Array.isArray(v);\r\n            } else {\r\n                r =\r\n                    v !== null &&\r\n                    typeof v === \"object\" &&\r\n                    typeof v.splice === \"function\" &&\r\n                    typeof v.join === 'function';\r\n            }\r\n\r\n            return r;\r\n        },\r\n\r\n        /**\r\n         * Tests if the input variable is an Object\r\n         * @param v\r\n         */\r\n        isObject: function (v) {\r\n            return typeof v === \"object\" && !this.isArray(v);\r\n        },\r\n\r\n        /**\r\n         * Tests if the input variable is a DOM Document or DocumentFragment node\r\n         * @param v A variable of any type\r\n         */\r\n        isDocumentOrFragment: function (v) {\r\n            return this.isObject(v) && (\r\n                v.nodeType === 9 || // Node.DOCUMENT_NODE\r\n                v.nodeType === 11   // Node.DOCUMENT_FRAGMENT_NODE\r\n            );\r\n        },\r\n\r\n        /**\r\n         * Checks if a given variable is a reference of a JSXGraph Point element.\r\n         * @param v A variable of any type.\r\n         * @returns {Boolean} True, if v is of type JXG.Point.\r\n         */\r\n        isPoint: function (v) {\r\n            if (v !== null && typeof v === \"object\" && this.exists(v.elementClass)) {\r\n                return v.elementClass === Const.OBJECT_CLASS_POINT;\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Checks if a given variable is a reference of a JSXGraph Point3D element.\r\n         * @param v A variable of any type.\r\n         * @returns {Boolean} True, if v is of type JXG.Point3D.\r\n         */\r\n        isPoint3D: function (v) {\r\n            if (v !== null && typeof v === \"object\" && this.exists(v.type)) {\r\n                return v.type === Const.OBJECT_TYPE_POINT3D;\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Checks if a given variable is a reference of a JSXGraph Point element or an array of length at least two or\r\n         * a function returning an array of length two or three.\r\n         * @param {JXG.Board} board\r\n         * @param v A variable of any type.\r\n         * @returns {Boolean} True, if v is of type JXG.Point.\r\n         */\r\n        isPointType: function (board, v) {\r\n            var val, p;\r\n\r\n            if (this.isArray(v)) {\r\n                return true;\r\n            }\r\n            if (this.isFunction(v)) {\r\n                val = v();\r\n                if (this.isArray(val) && val.length > 1) {\r\n                    return true;\r\n                }\r\n            }\r\n            p = board.select(v);\r\n            return this.isPoint(p);\r\n        },\r\n\r\n        /**\r\n         * Checks if a given variable is a reference of a JSXGraph Point3D element or an array of length three\r\n         * or a function returning an array of length three.\r\n         * @param {JXG.Board} board\r\n         * @param v A variable of any type.\r\n         * @returns {Boolean} True, if v is of type JXG.Point3D or an array of length at least 3, or a function returning\r\n         * such an array.\r\n         */\r\n        isPointType3D: function (board, v) {\r\n            var val, p;\r\n\r\n            if (this.isArray(v) && v.length >= 3) {\r\n                return true;\r\n            }\r\n            if (this.isFunction(v)) {\r\n                val = v();\r\n                if (this.isArray(val) && val.length >= 3) {\r\n                    return true;\r\n                }\r\n            }\r\n            p = board.select(v);\r\n            return this.isPoint3D(p);\r\n        },\r\n\r\n        /**\r\n         * Checks if a given variable is a reference of a JSXGraph transformation element or an array\r\n         * of JSXGraph transformation elements.\r\n         * @param v A variable of any type.\r\n         * @returns {Boolean} True, if v is of type JXG.Transformation.\r\n         */\r\n        isTransformationOrArray: function (v) {\r\n            if (v !== null) {\r\n                if (this.isArray(v) && v.length > 0) {\r\n                    return this.isTransformationOrArray(v[0]);\r\n                }\r\n                if (typeof v === 'object') {\r\n                    return v.type === Const.OBJECT_TYPE_TRANSFORMATION;\r\n                }\r\n            }\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Checks if v is an empty object or empty.\r\n         * @param v {Object|Array}\r\n         * @returns {boolean} True, if v is an empty object or array.\r\n         */\r\n        isEmpty: function (v) {\r\n            return Object.keys(v).length === 0;\r\n        },\r\n\r\n        /**\r\n         * Checks if a given variable is neither undefined nor null. You should not use this together with global\r\n         * variables!\r\n         * @param v A variable of any type.\r\n         * @param {Boolean} [checkEmptyString=false] If set to true, it is also checked whether v is not equal to ''.\r\n         * @returns {Boolean} True, if v is neither undefined nor null.\r\n         */\r\n        exists: function (v, checkEmptyString) {\r\n            /* eslint-disable eqeqeq */\r\n            var result = !(v == undefined || v === null);\r\n            /* eslint-enable eqeqeq */\r\n            checkEmptyString = checkEmptyString || false;\r\n\r\n            if (checkEmptyString) {\r\n                return result && v !== \"\";\r\n            }\r\n            return result;\r\n        },\r\n        // exists: (function (undef) {\r\n        //     return function (v, checkEmptyString) {\r\n        //         var result = !(v === undef || v === null);\r\n\r\n        //         checkEmptyString = checkEmptyString || false;\r\n\r\n        //         if (checkEmptyString) {\r\n        //             return result && v !== '';\r\n        //         }\r\n        //         return result;\r\n        //     };\r\n        // }()),\r\n\r\n        /**\r\n         * Handle default parameters.\r\n         * @param v Given value\r\n         * @param d Default value\r\n         * @returns <tt>d</tt>, if <tt>v</tt> is undefined or null.\r\n         */\r\n        def: function (v, d) {\r\n            if (this.exists(v)) {\r\n                return v;\r\n            }\r\n\r\n            return d;\r\n        },\r\n\r\n        /**\r\n         * Converts a string containing either <strong>true</strong> or <strong>false</strong> into a boolean value.\r\n         * @param {String} s String containing either <strong>true</strong> or <strong>false</strong>.\r\n         * @returns {Boolean} String typed boolean value converted to boolean.\r\n         */\r\n        str2Bool: function (s) {\r\n            if (!this.exists(s)) {\r\n                return true;\r\n            }\r\n\r\n            if (typeof s === 'boolean') {\r\n                return s;\r\n            }\r\n\r\n            if (this.isString(s)) {\r\n                return s.toLowerCase() === 'true';\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Converts a given CSS style string into a JavaScript object.\r\n         * @param {String} styles String containing CSS styles.\r\n         * @returns {Object} Object containing CSS styles.\r\n         */\r\n        cssParse: function (styles) {\r\n            var str = styles;\r\n            if (!this.isString(str)) return {};\r\n\r\n            str = str.replace(/\\s*;\\s*$/g, '');\r\n            str = str.replace(/\\s*;\\s*/g, '\",\"');\r\n            str = str.replace(/\\s*:\\s*/g, '\":\"');\r\n            str = str.trim();\r\n            str = '{\"' + str + '\"}';\r\n\r\n            return JSON.parse(str);\r\n        },\r\n\r\n        /**\r\n         * Converts a given object into a CSS style string.\r\n         * @param {Object} styles Object containing CSS styles.\r\n         * @returns {String} String containing CSS styles.\r\n         */\r\n        cssStringify: function (styles) {\r\n            var str = '',\r\n                attr, val;\r\n            if (!this.isObject(styles)) return '';\r\n\r\n            for (attr in styles) {\r\n                if (!styles.hasOwnProperty(attr)) continue;\r\n                val = styles[attr];\r\n                if (!this.isString(val) && !this.isNumber(val)) continue;\r\n\r\n                str += attr + ':' + val + '; ';\r\n            }\r\n            str = str.trim();\r\n\r\n            return str;\r\n        },\r\n\r\n        /**\r\n         * Convert a String, a number or a function into a function. This method is used in Transformation.js\r\n         * @param {JXG.Board} board Reference to a JSXGraph board. It is required to resolve dependencies given\r\n         * by a JessieCode string, thus it must be a valid reference only in case one of the param\r\n         * values is of type string.\r\n         * @param {Array} param An array containing strings, numbers, or functions.\r\n         * @param {Number} n Length of <tt>param</tt>.\r\n         * @returns {Function} A function taking one parameter k which specifies the index of the param element\r\n         * to evaluate.\r\n         */\r\n        createEvalFunction: function (board, param, n) {\r\n            var f = [], func, i, e,\r\n                deps = {};\r\n\r\n            for (i = 0; i < n; i++) {\r\n                f[i] = this.createFunction(param[i], board);\r\n                for (e in f[i].deps) {\r\n                    deps[e] = f[i].deps;\r\n                }\r\n            }\r\n\r\n            func = function (k) {\r\n                return f[k]();\r\n            };\r\n            func.deps = deps;\r\n\r\n            return func;\r\n        },\r\n\r\n        /**\r\n         * Convert a String, number or function into a function.\r\n         * @param {String|Number|Function} term A variable of type string, function or number.\r\n         * @param {JXG.Board} board Reference to a JSXGraph board. It is required to resolve dependencies given\r\n         * by a JessieCode/GEONE<sub>X</sub>T string, thus it must be a valid reference only in case one of the param\r\n         * values is of type string.\r\n         * @param {String} variableName Only required if function is supplied as JessieCode string or evalGeonext is set to true.\r\n         * Describes the variable name of the variable in a JessieCode/GEONE<sub>X</sub>T string given as term.\r\n         * @param {Boolean} [evalGeonext=false] Obsolete and ignored! Set this true\r\n         * if term should be treated as a GEONE<sub>X</sub>T string.\r\n         * @returns {Function} A function evaluating the value given by term or null if term is not of type string,\r\n         * function or number.\r\n         */\r\n        createFunction: function (term, board, variableName, evalGeonext) {\r\n            var f = null;\r\n\r\n            // if ((!this.exists(evalGeonext) || evalGeonext) && this.isString(term)) {\r\n            if (this.isString(term)) {\r\n                // Convert GEONExT syntax into  JavaScript syntax\r\n                //newTerm = JXG.GeonextParser.geonext2JS(term, board);\r\n                //return new Function(variableName,'return ' + newTerm + ';');\r\n                //term = JXG.GeonextParser.replaceNameById(term, board);\r\n                //term = JXG.GeonextParser.geonext2JS(term, board);\r\n\r\n                f = board.jc.snippet(term, true, variableName, false);\r\n            } else if (this.isFunction(term)) {\r\n                f = term;\r\n                f.deps = (this.isObject(term.deps)) ? term.deps : {};\r\n            } else if (this.isNumber(term) || this.isArray(term)) {\r\n                /** @ignore */\r\n                f = function () { return term; };\r\n                f.deps = {};\r\n                // } else if (this.isString(term)) {\r\n                //     // In case of string function like fontsize\r\n                //     /** @ignore */\r\n                //     f = function () { return term; };\r\n                //     f.deps = {};\r\n            }\r\n\r\n            if (f !== null) {\r\n                f.origin = term;\r\n            }\r\n\r\n            return f;\r\n        },\r\n\r\n        /**\r\n         *  Test if the parents array contains existing points. If instead parents contains coordinate arrays or\r\n         *  function returning coordinate arrays\r\n         *  free points with these coordinates are created.\r\n         *\r\n         * @param {JXG.Board} board Board object\r\n         * @param {Array} parents Array containing parent elements for a new object. This array may contain\r\n         *    <ul>\r\n         *      <li> {@link JXG.Point} objects\r\n         *      <li> {@link JXG.GeometryElement#name} of {@link JXG.Point} objects\r\n         *      <li> {@link JXG.GeometryElement#id} of {@link JXG.Point} objects\r\n         *      <li> Coordinates of points given as array of numbers of length two or three, e.g. [2, 3].\r\n         *      <li> Coordinates of points given as array of functions of length two or three. Each function returns one coordinate, e.g.\r\n         *           [function(){ return 2; }, function(){ return 3; }]\r\n         *      <li> Function returning coordinates, e.g. function() { return [2, 3]; }\r\n         *    </ul>\r\n         *  In the last three cases a new point will be created.\r\n         * @param {String} attrClass Main attribute class of newly created points, see {@link JXG#copyAttributes}\r\n         * @param {Array} attrArray List of subtype attributes for the newly created points. The list of subtypes is mapped to the list of new points.\r\n         * @returns {Array} List of newly created {@link JXG.Point} elements or false if not all returned elements are points.\r\n         */\r\n        providePoints: function (board, parents, attributes, attrClass, attrArray) {\r\n            var i,\r\n                j,\r\n                len,\r\n                lenAttr = 0,\r\n                points = [],\r\n                attr,\r\n                val;\r\n\r\n            if (!this.isArray(parents)) {\r\n                parents = [parents];\r\n            }\r\n            len = parents.length;\r\n            if (this.exists(attrArray)) {\r\n                lenAttr = attrArray.length;\r\n            }\r\n            if (lenAttr === 0) {\r\n                attr = this.copyAttributes(attributes, board.options, attrClass);\r\n            }\r\n\r\n            for (i = 0; i < len; ++i) {\r\n                if (lenAttr > 0) {\r\n                    j = Math.min(i, lenAttr - 1);\r\n                    attr = this.copyAttributes(\r\n                        attributes,\r\n                        board.options,\r\n                        attrClass,\r\n                        attrArray[j].toLowerCase()\r\n                    );\r\n                }\r\n                if (this.isArray(parents[i]) && parents[i].length > 1) {\r\n                    points.push(board.create(\"point\", parents[i], attr));\r\n                    points[points.length - 1]._is_new = true;\r\n                } else if (this.isFunction(parents[i])) {\r\n                    val = parents[i]();\r\n                    if (this.isArray(val) && val.length > 1) {\r\n                        points.push(board.create(\"point\", [parents[i]], attr));\r\n                        points[points.length - 1]._is_new = true;\r\n                    }\r\n                } else {\r\n                    points.push(board.select(parents[i]));\r\n                }\r\n\r\n                if (!this.isPoint(points[i])) {\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            return points;\r\n        },\r\n\r\n        /**\r\n         *  Test if the parents array contains existing points. If instead parents contains coordinate arrays or\r\n         *  function returning coordinate arrays\r\n         *  free points with these coordinates are created.\r\n         *\r\n         * @param {JXG.View3D} view View3D object\r\n         * @param {Array} parents Array containing parent elements for a new object. This array may contain\r\n         *    <ul>\r\n         *      <li> {@link JXG.Point3D} objects\r\n         *      <li> {@link JXG.GeometryElement#name} of {@link JXG.Point3D} objects\r\n         *      <li> {@link JXG.GeometryElement#id} of {@link JXG.Point3D} objects\r\n         *      <li> Coordinates of 3D points given as array of numbers of length three, e.g. [2, 3, 1].\r\n         *      <li> Coordinates of 3D points given as array of functions of length three. Each function returns one coordinate, e.g.\r\n         *           [function(){ return 2; }, function(){ return 3; }, function(){ return 1; }]\r\n         *      <li> Function returning coordinates, e.g. function() { return [2, 3, 1]; }\r\n         *    </ul>\r\n         *  In the last three cases a new 3D point will be created.\r\n         * @param {String} attrClass Main attribute class of newly created 3D points, see {@link JXG#copyAttributes}\r\n         * @param {Array} attrArray List of subtype attributes for the newly created 3D points. The list of subtypes is mapped to the list of new 3D points.\r\n         * @returns {Array} List of newly created {@link JXG.Point3D} elements or false if not all returned elements are 3D points.\r\n         */\r\n        providePoints3D: function (view, parents, attributes, attrClass, attrArray) {\r\n            var i,\r\n                j,\r\n                len,\r\n                lenAttr = 0,\r\n                points = [],\r\n                attr,\r\n                val;\r\n\r\n            if (!this.isArray(parents)) {\r\n                parents = [parents];\r\n            }\r\n            len = parents.length;\r\n            if (this.exists(attrArray)) {\r\n                lenAttr = attrArray.length;\r\n            }\r\n            if (lenAttr === 0) {\r\n                attr = this.copyAttributes(attributes, view.board.options, attrClass);\r\n            }\r\n\r\n            for (i = 0; i < len; ++i) {\r\n                if (lenAttr > 0) {\r\n                    j = Math.min(i, lenAttr - 1);\r\n                    attr = this.copyAttributes(\r\n                        attributes,\r\n                        view.board.options,\r\n                        attrClass,\r\n                        attrArray[j]\r\n                    );\r\n                }\r\n\r\n                if (this.isArray(parents[i]) && parents[i].length > 0 && parents[i].every((x)=>this.isArray(x) && this.isNumber(x[0]))) {\r\n                    // Testing for array-of-arrays-of-numbers, like [[1,2,3],[2,3,4]]\r\n                    for (j = 0; j < parents[i].length; j++) {\r\n                        points.push(view.create(\"point3d\", parents[i][j], attr));;\r\n                        points[points.length - 1]._is_new = true;\r\n                    }\r\n                } else if (this.isArray(parents[i]) &&  parents[i].every((x)=> this.isNumber(x) || this.isFunction(x))) {\r\n                    // Single array [1,2,3]\r\n                    points.push(view.create(\"point3d\", parents[i], attr));\r\n                    points[points.length - 1]._is_new = true;\r\n\r\n                } else if (this.isPoint3D(parents[i])) {\r\n                    points.push(parents[i]);\r\n                } else if (this.isFunction(parents[i])) {\r\n                    val = parents[i]();\r\n                    if (this.isArray(val) && val.length > 1) {\r\n                        points.push(view.create(\"point3d\", [parents[i]], attr));\r\n                        points[points.length - 1]._is_new = true;\r\n                    }\r\n                } else {\r\n                    points.push(view.select(parents[i]));\r\n                }\r\n\r\n                if (!this.isPoint3D(points[i])) {\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            return points;\r\n        },\r\n\r\n        /**\r\n         * Generates a function which calls the function fn in the scope of owner.\r\n         * @param {Function} fn Function to call.\r\n         * @param {Object} owner Scope in which fn is executed.\r\n         * @returns {Function} A function with the same signature as fn.\r\n         */\r\n        bind: function (fn, owner) {\r\n            return function () {\r\n                return fn.apply(owner, arguments);\r\n            };\r\n        },\r\n\r\n        /**\r\n         * If <tt>val</tt> is a function, it will be evaluated without giving any parameters, else the input value\r\n         * is just returned.\r\n         * @param val Could be anything. Preferably a number or a function.\r\n         * @returns If <tt>val</tt> is a function, it is evaluated and the result is returned. Otherwise <tt>val</tt> is returned.\r\n         */\r\n        evaluate: function (val) {\r\n            if (this.isFunction(val)) {\r\n                return val();\r\n            }\r\n\r\n            return val;\r\n        },\r\n\r\n        /**\r\n         * Search an array for a given value.\r\n         * @param {Array} array\r\n         * @param value\r\n         * @param {String} [sub] Use this property if the elements of the array are objects.\r\n         * @returns {Number} The index of the first appearance of the given value, or\r\n         * <tt>-1</tt> if the value was not found.\r\n         */\r\n        indexOf: function (array, value, sub) {\r\n            var i,\r\n                s = this.exists(sub);\r\n\r\n            if (Array.indexOf && !s) {\r\n                return array.indexOf(value);\r\n            }\r\n\r\n            for (i = 0; i < array.length; i++) {\r\n                if ((s && array[i][sub] === value) || (!s && array[i] === value)) {\r\n                    return i;\r\n                }\r\n            }\r\n\r\n            return -1;\r\n        },\r\n\r\n        /**\r\n         * Eliminates duplicate entries in an array consisting of numbers and strings.\r\n         * @param {Array} a An array of numbers and/or strings.\r\n         * @returns {Array} The array with duplicate entries eliminated.\r\n         */\r\n        eliminateDuplicates: function (a) {\r\n            var i,\r\n                len = a.length,\r\n                result = [],\r\n                obj = {};\r\n\r\n            for (i = 0; i < len; i++) {\r\n                obj[a[i]] = 0;\r\n            }\r\n\r\n            for (i in obj) {\r\n                if (obj.hasOwnProperty(i)) {\r\n                    result.push(i);\r\n                }\r\n            }\r\n\r\n            return result;\r\n        },\r\n\r\n        /**\r\n         * Swaps to array elements.\r\n         * @param {Array} arr\r\n         * @param {Number} i\r\n         * @param {Number} j\r\n         * @returns {Array} Reference to the given array.\r\n         */\r\n        swap: function (arr, i, j) {\r\n            var tmp;\r\n\r\n            tmp = arr[i];\r\n            arr[i] = arr[j];\r\n            arr[j] = tmp;\r\n\r\n            return arr;\r\n        },\r\n\r\n        /**\r\n         * Generates a copy of an array and removes the duplicate entries. The original\r\n         * Array will be altered.\r\n         * @param {Array} arr\r\n         * @returns {Array}\r\n         */\r\n        uniqueArray: function (arr) {\r\n            var i,\r\n                j,\r\n                isArray,\r\n                ret = [];\r\n\r\n            if (arr.length === 0) {\r\n                return [];\r\n            }\r\n\r\n            for (i = 0; i < arr.length; i++) {\r\n                isArray = this.isArray(arr[i]);\r\n\r\n                if (!this.exists(arr[i])) {\r\n                    arr[i] = \"\";\r\n                    continue;\r\n                }\r\n                for (j = i + 1; j < arr.length; j++) {\r\n                    if (isArray && JXG.cmpArrays(arr[i], arr[j])) {\r\n                        arr[i] = [];\r\n                    } else if (!isArray && arr[i] === arr[j]) {\r\n                        arr[i] = \"\";\r\n                    }\r\n                }\r\n            }\r\n\r\n            j = 0;\r\n\r\n            for (i = 0; i < arr.length; i++) {\r\n                isArray = this.isArray(arr[i]);\r\n\r\n                if (!isArray && arr[i] !== \"\") {\r\n                    ret[j] = arr[i];\r\n                    j++;\r\n                } else if (isArray && arr[i].length !== 0) {\r\n                    ret[j] = arr[i].slice(0);\r\n                    j++;\r\n                }\r\n            }\r\n\r\n            arr = ret;\r\n            return ret;\r\n        },\r\n\r\n        toUniqueArrayFloat: function (arr, eps) {\r\n            var a,\r\n                i, le;\r\n\r\n            // if (false && Type.exists(arr.toSorted)) {\r\n            //     a = arr.toSorted(function(a, b) { return a - b; });\r\n            // } else {\r\n            // }\r\n            // Backwards compatibility\r\n            a = arr.slice();\r\n            a.sort(function (a, b) { return a - b; });\r\n            le = a.length;\r\n            for (i = le - 1; i > 0; i--) {\r\n                if (Math.abs(a[i] - a[i - 1]) < eps) {\r\n                    a.splice(i, 1);\r\n                }\r\n            }\r\n            return a;\r\n        },\r\n\r\n\r\n        /**\r\n         * Checks if an array contains an element equal to <tt>val</tt> but does not check the type!\r\n         * @param {Array} arr\r\n         * @param val\r\n         * @returns {Boolean}\r\n         */\r\n        isInArray: function (arr, val) {\r\n            return JXG.indexOf(arr, val) > -1;\r\n        },\r\n\r\n        /**\r\n         * Converts an array of {@link JXG.Coords} objects into a coordinate matrix.\r\n         * @param {Array} coords\r\n         * @param {Boolean} split\r\n         * @returns {Array}\r\n         */\r\n        coordsArrayToMatrix: function (coords, split) {\r\n            var i,\r\n                x = [],\r\n                m = [];\r\n\r\n            for (i = 0; i < coords.length; i++) {\r\n                if (split) {\r\n                    x.push(coords[i].usrCoords[1]);\r\n                    m.push(coords[i].usrCoords[2]);\r\n                } else {\r\n                    m.push([coords[i].usrCoords[1], coords[i].usrCoords[2]]);\r\n                }\r\n            }\r\n\r\n            if (split) {\r\n                m = [x, m];\r\n            }\r\n\r\n            return m;\r\n        },\r\n\r\n        /**\r\n         * Compare two arrays.\r\n         * @param {Array} a1\r\n         * @param {Array} a2\r\n         * @returns {Boolean} <tt>true</tt>, if the arrays coefficients are of same type and value.\r\n         */\r\n        cmpArrays: function (a1, a2) {\r\n            var i;\r\n\r\n            // trivial cases\r\n            if (a1 === a2) {\r\n                return true;\r\n            }\r\n\r\n            if (a1.length !== a2.length) {\r\n                return false;\r\n            }\r\n\r\n            for (i = 0; i < a1.length; i++) {\r\n                if (this.isArray(a1[i]) && this.isArray(a2[i])) {\r\n                    if (!this.cmpArrays(a1[i], a2[i])) {\r\n                        return false;\r\n                    }\r\n                } else if (a1[i] !== a2[i]) {\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            return true;\r\n        },\r\n\r\n        /**\r\n         * Removes an element from the given array\r\n         * @param {Array} ar\r\n         * @param el\r\n         * @returns {Array}\r\n         */\r\n        removeElementFromArray: function (ar, el) {\r\n            var i;\r\n\r\n            for (i = 0; i < ar.length; i++) {\r\n                if (ar[i] === el) {\r\n                    ar.splice(i, 1);\r\n                    return ar;\r\n                }\r\n            }\r\n\r\n            return ar;\r\n        },\r\n\r\n        /**\r\n         * Truncate a number <tt>n</tt> after <tt>p</tt> decimals.\r\n         * @param {Number} n\r\n         * @param {Number} p\r\n         * @returns {Number}\r\n         */\r\n        trunc: function (n, p) {\r\n            p = JXG.def(p, 0);\r\n\r\n            return this.toFixed(n, p);\r\n        },\r\n\r\n        /**\r\n         * Decimal adjustment of a number.\r\n         * From https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Math/round\r\n         *\r\n         * @param    {String}    type    The type of adjustment.\r\n         * @param    {Number}    value    The number.\r\n         * @param    {Number}    exp        The exponent (the 10 logarithm of the adjustment base).\r\n         * @returns    {Number}            The adjusted value.\r\n         *\r\n         * @private\r\n         */\r\n        _decimalAdjust: function (type, value, exp) {\r\n            // If the exp is undefined or zero...\r\n            if (exp === undefined || +exp === 0) {\r\n                return Math[type](value);\r\n            }\r\n\r\n            value = +value;\r\n            exp = +exp;\r\n            // If the value is not a number or the exp is not an integer...\r\n            if (isNaN(value) || !(typeof exp === \"number\" && exp % 1 === 0)) {\r\n                return NaN;\r\n            }\r\n\r\n            // Shift\r\n            value = value.toString().split('e');\r\n            value = Math[type](+(value[0] + \"e\" + (value[1] ? +value[1] - exp : -exp)));\r\n\r\n            // Shift back\r\n            value = value.toString().split('e');\r\n            return +(value[0] + \"e\" + (value[1] ? +value[1] + exp : exp));\r\n        },\r\n\r\n        /**\r\n         * Round a number to given number of decimal digits.\r\n         *\r\n         * Example: JXG._toFixed(3.14159, -2) gives 3.14\r\n         * @param  {Number} value Number to be rounded\r\n         * @param  {Number} exp   Number of decimal digits given as negative exponent\r\n         * @return {Number}       Rounded number.\r\n         *\r\n         * @private\r\n         */\r\n        _round10: function (value, exp) {\r\n            return this._decimalAdjust(\"round\", value, exp);\r\n        },\r\n\r\n        /**\r\n         * \"Floor\" a number to given number of decimal digits.\r\n         *\r\n         * Example: JXG._toFixed(3.14159, -2) gives 3.14\r\n         * @param  {Number} value Number to be floored\r\n         * @param  {Number} exp   Number of decimal digits given as negative exponent\r\n         * @return {Number}       \"Floored\" number.\r\n         *\r\n         * @private\r\n         */\r\n        _floor10: function (value, exp) {\r\n            return this._decimalAdjust(\"floor\", value, exp);\r\n        },\r\n\r\n        /**\r\n         * \"Ceil\" a number to given number of decimal digits.\r\n         *\r\n         * Example: JXG._toFixed(3.14159, -2) gives 3.15\r\n         * @param  {Number} value Number to be ceiled\r\n         * @param  {Number} exp   Number of decimal digits given as negative exponent\r\n         * @return {Number}       \"Ceiled\" number.\r\n         *\r\n         * @private\r\n         */\r\n        _ceil10: function (value, exp) {\r\n            return this._decimalAdjust(\"ceil\", value, exp);\r\n        },\r\n\r\n        /**\r\n         * Replacement of the default toFixed() method.\r\n         * It does a correct rounding (independent of the browser) and\r\n         * returns \"0.00\" for toFixed(-0.000001, 2) instead of \"-0.00\" which\r\n         * is returned by JavaScript's toFixed()\r\n         *\r\n         * @memberOf JXG\r\n         * @param  {Number} num    Number tp be rounded\r\n         * @param  {Number} digits Decimal digits\r\n         * @return {String}        Rounded number is returned as string\r\n         */\r\n        toFixed: function (num, digits) {\r\n            return this._round10(num, -digits).toFixed(digits);\r\n        },\r\n\r\n        /**\r\n         * Truncate a number <tt>val</tt> automatically.\r\n         * @memberOf JXG\r\n         * @param val\r\n         * @returns {Number}\r\n         */\r\n        autoDigits: function (val) {\r\n            var x = Math.abs(val),\r\n                str;\r\n\r\n            if (x >= 0.1) {\r\n                str = this.toFixed(val, 2);\r\n            } else if (x >= 0.01) {\r\n                str = this.toFixed(val, 4);\r\n            } else if (x >= 0.0001) {\r\n                str = this.toFixed(val, 6);\r\n            } else {\r\n                str = val;\r\n            }\r\n            return str;\r\n        },\r\n\r\n        /**\r\n         * Convert value v. If v has the form\r\n         * <ul>\r\n         * <li> 'x%': return floating point number x * percentOfWhat * 0.01\r\n         * <li> 'xfr': return floating point number x * percentOfWhat\r\n         * <li> 'xpx': return x * convertPx or convertPx(x) or x\r\n         * <li> x or 'x': return floating point number x\r\n         * </ul>\r\n         * @param {String|Number} v\r\n         * @param {Number} percentOfWhat\r\n         * @param {Function|Number|*} convertPx\r\n         * @returns {String|Number}\r\n         */\r\n        parseNumber: function(v, percentOfWhat, convertPx) {\r\n            var str;\r\n\r\n            if (this.isString(v) && v.indexOf('%') > -1) {\r\n                str = v.replace(/\\s+%\\s+/, '');\r\n                return parseFloat(str) * percentOfWhat * 0.01;\r\n            }\r\n            if (this.isString(v) && v.indexOf('fr') > -1) {\r\n                str = v.replace(/\\s+fr\\s+/, '');\r\n                return parseFloat(str) * percentOfWhat;\r\n            }\r\n            if (this.isString(v) && v.indexOf('px') > -1) {\r\n                str = v.replace(/\\s+px\\s+/, '');\r\n                str = parseFloat(str);\r\n                if(this.isFunction(convertPx)) {\r\n                    return convertPx(str);\r\n                } else if(this.isNumber(convertPx)) {\r\n                    return str * convertPx;\r\n                } else {\r\n                    return str;\r\n                }\r\n            }\r\n            // Number or String containing no unit\r\n            return parseFloat(v);\r\n        },\r\n\r\n        /**\r\n         * Parse a string for label positioning of the form 'left pos' or 'pos right'\r\n         * and return e.g.\r\n         * <tt>{ side: 'left', pos: 'pos' }</tt>.\r\n         * @param {String} str\r\n         * @returns {Obj}  <tt>{ side, pos }</tt>\r\n         */\r\n        parsePosition: function(str) {\r\n            var a, i,\r\n                side = '',\r\n                pos = '';\r\n\r\n            str = str.trim();\r\n            if (str !== '') {\r\n                a = str.split(/[ ,]+/);\r\n                for (i = 0; i < a.length; i++) {\r\n                    if (a[i] === 'left' || a[i] === 'right') {\r\n                        side = a[i];\r\n                    } else {\r\n                        pos = a[i];\r\n                    }\r\n                }\r\n            }\r\n\r\n            return {\r\n                side: side,\r\n                pos: pos\r\n            };\r\n        },\r\n\r\n        /**\r\n         * Extracts the keys of a given object.\r\n         * @param object The object the keys are to be extracted\r\n         * @param onlyOwn If true, hasOwnProperty() is used to verify that only keys are collected\r\n         * the object owns itself and not some other object in the prototype chain.\r\n         * @returns {Array} All keys of the given object.\r\n         */\r\n        keys: function (object, onlyOwn) {\r\n            var keys = [],\r\n                property;\r\n\r\n            // the caller decides if we use hasOwnProperty\r\n            /*jslint forin:true*/\r\n            for (property in object) {\r\n                if (onlyOwn) {\r\n                    if (object.hasOwnProperty(property)) {\r\n                        keys.push(property);\r\n                    }\r\n                } else {\r\n                    keys.push(property);\r\n                }\r\n            }\r\n            /*jslint forin:false*/\r\n\r\n            return keys;\r\n        },\r\n\r\n        /**\r\n         * This outputs an object with a base class reference to the given object. This is useful if\r\n         * you need a copy of an e.g. attributes object and want to overwrite some of the attributes\r\n         * without changing the original object.\r\n         * @param {Object} obj Object to be embedded.\r\n         * @returns {Object} An object with a base class reference to <tt>obj</tt>.\r\n         */\r\n        clone: function (obj) {\r\n            var cObj = {};\r\n\r\n            cObj.prototype = obj;\r\n\r\n            return cObj;\r\n        },\r\n\r\n        /**\r\n         * Embeds an existing object into another one just like {@link #clone} and copies the contents of the second object\r\n         * to the new one. Warning: The copied properties of obj2 are just flat copies.\r\n         * @param {Object} obj Object to be copied.\r\n         * @param {Object} obj2 Object with data that is to be copied to the new one as well.\r\n         * @returns {Object} Copy of given object including some new/overwritten data from obj2.\r\n         */\r\n        cloneAndCopy: function (obj, obj2) {\r\n            var r,\r\n                cObj = function () {\r\n                    return undefined;\r\n                };\r\n\r\n            cObj.prototype = obj;\r\n\r\n            // no hasOwnProperty on purpose\r\n            /*jslint forin:true*/\r\n            /*jshint forin:true*/\r\n\r\n            for (r in obj2) {\r\n                cObj[r] = obj2[r];\r\n            }\r\n\r\n            /*jslint forin:false*/\r\n            /*jshint forin:false*/\r\n\r\n            return cObj;\r\n        },\r\n\r\n        /**\r\n         * Recursively merges obj2 into obj1 in-place. Contrary to {@link JXG#deepCopy} this won't create a new object\r\n         * but instead will overwrite obj1.\r\n         * <p>\r\n         * In contrast to method JXG.mergeAttr, merge recurses into any kind of object, e.g. DOM object and JSXGraph objects.\r\n         * So, please be careful.\r\n         * @param {Object} obj1\r\n         * @param {Object} obj2\r\n         * @returns {Object}\r\n         * @see JXG.mergeAttr\r\n         *\r\n         * @example\r\n         * JXG.Options = JXG.merge(JXG.Options, {\r\n         *     board: {\r\n         *         showNavigation: false,\r\n         *         showInfobox: true\r\n         *     },\r\n         *     point: {\r\n         *         face: 'o',\r\n         *         size: 4,\r\n         *         fillColor: '#eeeeee',\r\n         *         highlightFillColor: '#eeeeee',\r\n         *         strokeColor: 'white',\r\n         *         highlightStrokeColor: 'white',\r\n         *         showInfobox: 'inherit'\r\n         *     }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXGc5bf0f2a-bd5a-4612-97c2-09f17b1bbc6b\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGc5bf0f2a-bd5a-4612-97c2-09f17b1bbc6b',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     JXG.Options = JXG.merge(JXG.Options, {\r\n         *         board: {\r\n         *             showNavigation: false,\r\n         *             showInfobox: true\r\n         *         },\r\n         *         point: {\r\n         *             face: 'o',\r\n         *             size: 4,\r\n         *             fillColor: '#eeeeee',\r\n         *             highlightFillColor: '#eeeeee',\r\n         *             strokeColor: 'white',\r\n         *             highlightStrokeColor: 'white',\r\n         *             showInfobox: 'inherit'\r\n         *         }\r\n         *     });\r\n         *\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         */\r\n        merge: function (obj1, obj2) {\r\n            var i, j, o, oo;\r\n\r\n            for (i in obj2) {\r\n                if (obj2.hasOwnProperty(i)) {\r\n                    o = obj2[i];\r\n                    if (this.isArray(o)) {\r\n                        if (!obj1[i]) {\r\n                            obj1[i] = [];\r\n                        }\r\n\r\n                        for (j = 0; j < o.length; j++) {\r\n                            oo = obj2[i][j];\r\n                            if (typeof obj2[i][j] === 'object') {\r\n                                obj1[i][j] = this.merge(obj1[i][j], oo);\r\n                            } else {\r\n                                obj1[i][j] = obj2[i][j];\r\n                            }\r\n                        }\r\n                    } else if (typeof o === 'object') {\r\n                        if (!obj1[i]) {\r\n                            obj1[i] = {};\r\n                        }\r\n\r\n                        obj1[i] = this.merge(obj1[i], o);\r\n                    } else {\r\n                        if (typeof obj1 === 'boolean') {\r\n                            // This is necessary in the following scenario:\r\n                            //   lastArrow == false\r\n                            // and call of\r\n                            //   setAttribute({lastArrow: {type: 7}})\r\n                            obj1 = {};\r\n                        }\r\n                        obj1[i] = o;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return obj1;\r\n        },\r\n\r\n        /**\r\n         * Creates a deep copy of an existing object, i.e. arrays or sub-objects are copied component resp.\r\n         * element-wise instead of just copying the reference. If a second object is supplied, the two objects\r\n         * are merged into one object. The properties of the second object have priority.\r\n         * @param {Object} obj This object will be copied.\r\n         * @param {Object} obj2 This object will merged into the newly created object\r\n         * @param {Boolean} [toLower=false] If true the keys are convert to lower case. This is needed for visProp, see JXG#copyAttributes\r\n         * @returns {Object} copy of obj or merge of obj and obj2.\r\n         */\r\n        deepCopy: function (obj, obj2, toLower) {\r\n            var c, i, prop, i2;\r\n\r\n            toLower = toLower || false;\r\n            if (typeof obj !== 'object' || obj === null) {\r\n                return obj;\r\n            }\r\n\r\n            // Missing hasOwnProperty is on purpose in this function\r\n            if (this.isArray(obj)) {\r\n                c = [];\r\n                for (i = 0; i < obj.length; i++) {\r\n                    prop = obj[i];\r\n                    // Attention: typeof null === 'object'\r\n                    if (prop !== null && typeof prop === 'object') {\r\n                        // We certainly do not want to recurse into a JSXGraph object.\r\n                        // This would for sure result in an infinite recursion.\r\n                        // As alternative we copy the id of the object.\r\n                        if (this.exists(prop.board)) {\r\n                            c[i] = prop.id;\r\n                        } else {\r\n                            c[i] = this.deepCopy(prop, {}, toLower);\r\n                        }\r\n                    } else {\r\n                        c[i] = prop;\r\n                    }\r\n                }\r\n            } else {\r\n                c = {};\r\n                for (i in obj) {\r\n                    if (obj.hasOwnProperty(i)) {\r\n                        i2 = toLower ? i.toLowerCase() : i;\r\n                        prop = obj[i];\r\n                        if (prop !== null && typeof prop === 'object') {\r\n                            if (this.exists(prop.board)) {\r\n                                c[i2] = prop.id;\r\n                            } else {\r\n                                c[i2] = this.deepCopy(prop, {}, toLower);\r\n                            }\r\n                        } else {\r\n                            c[i2] = prop;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                for (i in obj2) {\r\n                    if (obj2.hasOwnProperty(i)) {\r\n                        i2 = toLower ? i.toLowerCase() : i;\r\n\r\n                        prop = obj2[i];\r\n                        if (prop !== null && typeof prop === 'object') {\r\n                            if (this.isArray(prop) || !this.exists(c[i2])) {\r\n                                c[i2] = this.deepCopy(prop, {}, toLower);\r\n                            } else {\r\n                                c[i2] = this.deepCopy(c[i2], prop, toLower);\r\n                            }\r\n                        } else {\r\n                            c[i2] = prop;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            return c;\r\n        },\r\n\r\n        /**\r\n         * In-place (deep) merging of attributes. Allows attributes like `{shadow: {enabled: true...}}`\r\n         * <p>\r\n         * In contrast to method JXG.merge, mergeAttr does not recurse into DOM objects and JSXGraph objects. Instead\r\n         * handles (pointers) to these objects are used.\r\n         *\r\n         * @param {Object} attr Object with attributes - usually containing default options - that will be changed in-place.\r\n         * @param {Object} special Special option values which overwrite (recursively) the default options\r\n         * @param {Boolean} [toLower=true] If true the keys are converted to lower case.\r\n         * @param {Boolean} [ignoreUndefinedSpecials=false] If true the values in special that are undefined are not used.\r\n         *\r\n         * @see JXG.merge\r\n         *\r\n         */\r\n        mergeAttr: function (attr, special, toLower, ignoreUndefinedSpecials) {\r\n            var e, e2, o;\r\n\r\n            toLower = toLower || true;\r\n            ignoreUndefinedSpecials = ignoreUndefinedSpecials || false;\r\n\r\n            for (e in special) {\r\n                if (special.hasOwnProperty(e)) {\r\n                    e2 = (toLower) ? e.toLowerCase(): e;\r\n                    // Key already exists, but not in lower case\r\n                    if (e2 !== e && attr.hasOwnProperty(e)) {\r\n                        if (attr.hasOwnProperty(e2)) {\r\n                            // Lower case key already exists - this should not happen\r\n                            // We have to unify the two key-value pairs\r\n                            // It is not clear which has precedence.\r\n                            this.mergeAttr(attr[e2], attr[e], toLower);\r\n                        } else {\r\n                            attr[e2] = attr[e];\r\n                        }\r\n                        delete attr[e];\r\n                    }\r\n\r\n                    o = special[e];\r\n                    if (this.isObject(o) && o !== null &&\r\n                        // Do not recurse into a document object or a JSXGraph object\r\n                        !this.isDocumentOrFragment(o) && !this.exists(o.board) &&\r\n                        // Do not recurse if a string is provided as \"new String(...)\"\r\n                        typeof o.valueOf() !== 'string') {\r\n                        if (attr[e2] === undefined || attr[e2] === null || !this.isObject(attr[e2])) {\r\n                            // The last test handles the case:\r\n                            //   attr.draft = false;\r\n                            //   special.draft = { strokewidth: 4}\r\n                            attr[e2] = {};\r\n                        }\r\n                        this.mergeAttr(attr[e2], o, toLower);\r\n                    } else if(!ignoreUndefinedSpecials || this.exists(o)) {\r\n                        // Flat copy\r\n                        // This is also used in the cases\r\n                        //   attr.shadow = { enabled: true ...}\r\n                        //   special.shadow = false;\r\n                        // and\r\n                        //   special.anchor is a JSXGraph element\r\n                        attr[e2] = o;\r\n                    }\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Convert an object to a new object containing only\r\n         * lower case properties.\r\n         *\r\n         * @param {Object} obj\r\n         * @returns Object\r\n         * @example\r\n         * var attr = JXG.keysToLowerCase({radiusPoint: {visible: false}});\r\n         *\r\n         * // return {radiuspoint: {visible: false}}\r\n         */\r\n        keysToLowerCase: function (obj) {\r\n            var key, val,\r\n                keys = Object.keys(obj),\r\n                n = keys.length,\r\n                newObj = {};\r\n\r\n            if (typeof obj !== 'object') {\r\n                return obj;\r\n            }\r\n\r\n            while (n--) {\r\n                key = keys[n];\r\n                if (obj.hasOwnProperty(key)) {\r\n                    // We recurse into an object only if it is\r\n                    // neither a DOM node nor an JSXGraph object\r\n                    val = obj[key];\r\n                    if (typeof val === 'object' && val !== null &&\r\n                        !this.isArray(val) &&\r\n                        !this.exists(val.nodeType) &&\r\n                        !this.exists(val.board)) {\r\n                        newObj[key.toLowerCase()] = this.keysToLowerCase(val);\r\n                    } else {\r\n                        newObj[key.toLowerCase()] = val;\r\n                    }\r\n                }\r\n            }\r\n            return newObj;\r\n        },\r\n\r\n        /**\r\n         * Generates an attributes object that is filled with default values from the Options object\r\n         * and overwritten by the user specified attributes.\r\n         * @param {Object} attributes user specified attributes\r\n         * @param {Object} options defaults options\r\n         * @param {String} s variable number of strings, e.g. 'slider', subtype 'point1'. Must be provided in lower case!\r\n         * @returns {Object} The resulting attributes object\r\n         */\r\n        copyAttributes: function (attributes, options, s) {\r\n            var a, arg, i, len, o, isAvail,\r\n                primitives = {\r\n                    circle: 1,\r\n                    curve: 1,\r\n                    foreignobject: 1,\r\n                    image: 1,\r\n                    line: 1,\r\n                    point: 1,\r\n                    polygon: 1,\r\n                    text: 1,\r\n                    ticks: 1,\r\n                    integral: 1\r\n                };\r\n\r\n            len = arguments.length;\r\n            if (len < 3 || primitives[s]) {\r\n                // Default options from Options.elements\r\n                a = JXG.deepCopy(options.elements, null, true);\r\n            } else {\r\n                a = {};\r\n            }\r\n\r\n            // Only the layer of the main element is set.\r\n            if (len < 4 && this.exists(s) && this.exists(options.layer[s])) {\r\n                a.layer = options.layer[s];\r\n            }\r\n\r\n            // Default options from the specific element like 'line' in\r\n            //     copyAttribute(attributes, board.options, 'line')\r\n            // but also like in\r\n            //     Type.copyAttributes(attributes, board.options, 'view3d', 'az', 'slider');\r\n            o = options;\r\n            isAvail = true;\r\n            for (i = 2; i < len; i++) {\r\n                arg = arguments[i];\r\n                if (this.exists(o[arg])) {\r\n                    o = o[arg];\r\n                } else {\r\n                    isAvail = false;\r\n                    break;\r\n                }\r\n            }\r\n            if (isAvail) {\r\n                a = JXG.deepCopy(a, o, true);\r\n            }\r\n\r\n            // Merge the specific options given in the parameter 'attributes'\r\n            // into the default options.\r\n            // Additionally, we step into a sub-element of attribute like line.point1 -\r\n            // in case it is supplied as in\r\n            //     copyAttribute(attributes, board.options, 'line', 'point1')\r\n            // In this case we would merge attributes.point1 into the global line.point1 attributes.\r\n            o = (typeof attributes === 'object') ? this.keysToLowerCase(attributes) : {};\r\n            isAvail = true;\r\n            for (i = 3; i < len; i++) {\r\n                arg = arguments[i].toLowerCase();\r\n                if (this.exists(o[arg])) {\r\n                    o = o[arg];\r\n                } else {\r\n                    isAvail = false;\r\n                    break;\r\n                }\r\n            }\r\n            if (isAvail) {\r\n                this.mergeAttr(a, o, true);\r\n            }\r\n\r\n            if (arguments[2] === 'board') {\r\n                // For board attributes we are done now.\r\n                return a;\r\n            }\r\n\r\n            // Special treatment of labels\r\n            o = options;\r\n            isAvail = true;\r\n            for (i = 2; i < len; i++) {\r\n                arg = arguments[i];\r\n                if (this.exists(o[arg])) {\r\n                    o = o[arg];\r\n                } else {\r\n                    isAvail = false;\r\n                    break;\r\n                }\r\n            }\r\n            if (isAvail && this.exists(o.label)) {\r\n                a.label = JXG.deepCopy(o.label, a.label, true);\r\n            }\r\n            a.label = JXG.deepCopy(options.label, a.label, true);\r\n\r\n            return a;\r\n        },\r\n\r\n        /**\r\n         * Copy all prototype methods from object \"superObject\" to object\r\n         * \"subObject\". The constructor of superObject will be available\r\n         * in subObject as subObject.constructor[constructorName].\r\n         * @param {Object} subObj A JavaScript object which receives new methods.\r\n         * @param {Object} superObj A JavaScript object which lends its prototype methods to subObject\r\n         * @returns {String} constructorName Under this name the constructor of superObj will be available\r\n         * in subObject.\r\n         * @private\r\n         */\r\n        copyPrototypeMethods: function (subObject, superObject, constructorName) {\r\n            var key;\r\n\r\n            subObject.prototype[constructorName] = superObject.prototype.constructor;\r\n            for (key in superObject.prototype) {\r\n                if (superObject.prototype.hasOwnProperty(key)) {\r\n                    subObject.prototype[key] = superObject.prototype[key];\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Create a stripped down version of a JSXGraph element for cloning to the background.\r\n         * Used in {JXG.GeometryElement#cloneToBackground} for creating traces.\r\n         *\r\n         * @param {JXG.GeometryElement} el Element to be cloned\r\n         * @returns Object Cloned element\r\n         * @private\r\n         */\r\n        getCloneObject: function(el) {\r\n            var obj, key,\r\n                copy = {};\r\n\r\n            copy.id = el.id + \"T\" + el.numTraces;\r\n            el.numTraces += 1;\r\n\r\n            copy.coords = el.coords;\r\n            obj = this.deepCopy(el.visProp, el.visProp.traceattributes, true);\r\n            copy.visProp = {};\r\n            for (key in obj) {\r\n                if (obj.hasOwnProperty(key)) {\r\n                    if (\r\n                        key.indexOf('aria') !== 0 &&\r\n                        key.indexOf('highlight') !== 0 &&\r\n                        key.indexOf('attractor') !== 0 &&\r\n                        key !== 'label' &&\r\n                        key !== 'needsregularupdate' &&\r\n                        key !== 'infoboxdigits'\r\n                    ) {\r\n                        copy.visProp[key] = el.eval(obj[key]);\r\n                    }\r\n                }\r\n            }\r\n            copy.evalVisProp = function(val) {\r\n                return copy.visProp[val];\r\n            };\r\n            copy.eval = function(val) {\r\n                return val;\r\n            };\r\n\r\n            copy.visProp.layer = el.board.options.layer.trace;\r\n            copy.visProp.tabindex = null;\r\n            copy.visProp.highlight = false;\r\n            copy.board = el.board;\r\n            copy.elementClass = el.elementClass;\r\n\r\n            this.clearVisPropOld(copy);\r\n            copy.visPropCalc = {\r\n                visible: el.evalVisProp('visible')\r\n            };\r\n\r\n            return copy;\r\n        },\r\n\r\n        /**\r\n         * Converts a JavaScript object into a JSON string.\r\n         * @param {Object} obj A JavaScript object, functions will be ignored.\r\n         * @param {Boolean} [noquote=false] No quotes around the name of a property.\r\n         * @returns {String} The given object stored in a JSON string.\r\n         * @deprecated\r\n         */\r\n        toJSON: function (obj, noquote) {\r\n            var list, prop, i, s, val;\r\n\r\n            noquote = JXG.def(noquote, false);\r\n\r\n            // check for native JSON support:\r\n            if (JSON !== undefined && JSON.stringify && !noquote) {\r\n                try {\r\n                    s = JSON.stringify(obj);\r\n                    return s;\r\n                } catch (e) {\r\n                    // if something goes wrong, e.g. if obj contains functions we won't return\r\n                    // and use our own implementation as a fallback\r\n                }\r\n            }\r\n\r\n            switch (typeof obj) {\r\n                case \"object\":\r\n                    if (obj) {\r\n                        list = [];\r\n\r\n                        if (this.isArray(obj)) {\r\n                            for (i = 0; i < obj.length; i++) {\r\n                                list.push(JXG.toJSON(obj[i], noquote));\r\n                            }\r\n\r\n                            return \"[\" + list.join(\",\") + \"]\";\r\n                        }\r\n\r\n                        for (prop in obj) {\r\n                            if (obj.hasOwnProperty(prop)) {\r\n                                try {\r\n                                    val = JXG.toJSON(obj[prop], noquote);\r\n                                } catch (e2) {\r\n                                    val = \"\";\r\n                                }\r\n\r\n                                if (noquote) {\r\n                                    list.push(prop + \":\" + val);\r\n                                } else {\r\n                                    list.push('\"' + prop + '\":' + val);\r\n                                }\r\n                            }\r\n                        }\r\n\r\n                        return \"{\" + list.join(\",\") + \"} \";\r\n                    }\r\n                    return 'null';\r\n                case \"string\":\r\n                    return \"'\" + obj.replace(/([\"'])/g, \"\\\\$1\") + \"'\";\r\n                case \"number\":\r\n                case \"boolean\":\r\n                    return obj.toString();\r\n            }\r\n\r\n            return '0';\r\n        },\r\n\r\n        /**\r\n         * Resets visPropOld.\r\n         * @param {JXG.GeometryElement} el\r\n         * @returns {GeometryElement}\r\n         */\r\n        clearVisPropOld: function (el) {\r\n            el.visPropOld = {\r\n                cssclass: \"\",\r\n                cssdefaultstyle: \"\",\r\n                cssstyle: \"\",\r\n                fillcolor: \"\",\r\n                fillopacity: \"\",\r\n                firstarrow: false,\r\n                fontsize: -1,\r\n                lastarrow: false,\r\n                left: -100000,\r\n                linecap: \"\",\r\n                shadow: false,\r\n                strokecolor: \"\",\r\n                strokeopacity: \"\",\r\n                strokewidth: \"\",\r\n                tabindex: -100000,\r\n                transitionduration: 0,\r\n                top: -100000,\r\n                visible: null\r\n            };\r\n\r\n            return el;\r\n        },\r\n\r\n        /**\r\n         * Checks if an object contains a key, whose value equals to val.\r\n         * @param {Object} obj\r\n         * @param val\r\n         * @returns {Boolean}\r\n         */\r\n        isInObject: function (obj, val) {\r\n            var el;\r\n\r\n            for (el in obj) {\r\n                if (obj.hasOwnProperty(el)) {\r\n                    if (obj[el] === val) {\r\n                        return true;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Replaces all occurences of &amp; by &amp;amp;, &gt; by &amp;gt;, and &lt; by &amp;lt;.\r\n         * @param {String} str\r\n         * @returns {String}\r\n         */\r\n        escapeHTML: function (str) {\r\n            return str.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\r\n        },\r\n\r\n        /**\r\n         * Eliminates all substrings enclosed by &lt; and &gt; and replaces all occurences of\r\n         * &amp;amp; by &amp;, &amp;gt; by &gt;, and &amp;lt; by &lt;.\r\n         * @param {String} str\r\n         * @returns {String}\r\n         */\r\n        unescapeHTML: function (str) {\r\n            // This regex is NOT insecure. We are replacing everything found with ''\r\n            /*jslint regexp:true*/\r\n            return str\r\n                .replace(/<\\/?[^>]+>/gi, \"\")\r\n                .replace(/&amp;/g, \"&\")\r\n                .replace(/&lt;/g, \"<\")\r\n                .replace(/&gt;/g, \">\");\r\n        },\r\n\r\n        /**\r\n         * Makes a string lower case except for the first character which will be upper case.\r\n         * @param {String} str Arbitrary string\r\n         * @returns {String} The capitalized string.\r\n         */\r\n        capitalize: function (str) {\r\n            return str.charAt(0).toUpperCase() + str.substring(1).toLowerCase();\r\n        },\r\n\r\n        /**\r\n         * Make numbers given as strings nicer by removing all unnecessary leading and trailing zeroes.\r\n         * @param {String} str\r\n         * @returns {String}\r\n         */\r\n        trimNumber: function (str) {\r\n            str = str.replace(/^0+/, \"\");\r\n            str = str.replace(/0+$/, \"\");\r\n\r\n            if (str[str.length - 1] === \".\" || str[str.length - 1] === \",\") {\r\n                str = str.slice(0, -1);\r\n            }\r\n\r\n            if (str[0] === \".\" || str[0] === \",\") {\r\n                str = \"0\" + str;\r\n            }\r\n\r\n            return str;\r\n        },\r\n\r\n        /**\r\n         * Filter an array of elements.\r\n         * @param {Array} list\r\n         * @param {Object|function} filter\r\n         * @returns {Array}\r\n         */\r\n        filterElements: function (list, filter) {\r\n            var i,\r\n                f,\r\n                item,\r\n                flower,\r\n                value,\r\n                visPropValue,\r\n                pass,\r\n                l = list.length,\r\n                result = [];\r\n\r\n            if (this.exists(filter) && typeof filter !== \"function\" && typeof filter !== 'object') {\r\n                return result;\r\n            }\r\n\r\n            for (i = 0; i < l; i++) {\r\n                pass = true;\r\n                item = list[i];\r\n\r\n                if (typeof filter === 'object') {\r\n                    for (f in filter) {\r\n                        if (filter.hasOwnProperty(f)) {\r\n                            flower = f.toLowerCase();\r\n\r\n                            if (typeof item[f] === 'function') {\r\n                                value = item[f]();\r\n                            } else {\r\n                                value = item[f];\r\n                            }\r\n\r\n                            if (item.visProp && typeof item.visProp[flower] === 'function') {\r\n                                visPropValue = item.visProp[flower]();\r\n                            } else {\r\n                                visPropValue = item.visProp && item.visProp[flower];\r\n                            }\r\n\r\n                            if (typeof filter[f] === 'function') {\r\n                                pass = filter[f](value) || filter[f](visPropValue);\r\n                            } else {\r\n                                pass = value === filter[f] || visPropValue === filter[f];\r\n                            }\r\n\r\n                            if (!pass) {\r\n                                break;\r\n                            }\r\n                        }\r\n                    }\r\n                } else if (typeof filter === 'function') {\r\n                    pass = filter(item);\r\n                }\r\n\r\n                if (pass) {\r\n                    result.push(item);\r\n                }\r\n            }\r\n\r\n            return result;\r\n        },\r\n\r\n        /**\r\n         * Remove all leading and trailing whitespaces from a given string.\r\n         * @param {String} str\r\n         * @returns {String}\r\n         */\r\n        trim: function (str) {\r\n            // str = str.replace(/^\\s+/, '');\r\n            // str = str.replace(/\\s+$/, '');\r\n            //\r\n            // return str;\r\n            return str.replace(/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g, \"\");\r\n        },\r\n\r\n        /**\r\n         * Convert a floating point number to a string integer + fraction.\r\n         * Returns either a string of the form '3 1/3' (in case of useTeX=false)\r\n         * or '3 \\\\frac{1}{3}' (in case of useTeX=true).\r\n         *\r\n         * @param {Number} x\r\n         * @param {Boolean} [useTeX=false]\r\n         * @param {Number} [order=0.001]\r\n         * @returns {String}\r\n         * @see JXG.Math.decToFraction\r\n         */\r\n        toFraction: function (x, useTeX, order) {\r\n            var arr = Mat.decToFraction(x, order),\r\n                str = '';\r\n\r\n            if (arr[1] === 0 && arr[2] === 0) {\r\n                // 0\r\n                str += '0';\r\n            } else {\r\n                // Sign\r\n                if (arr[0] < 0) {\r\n                    str += '-';\r\n                }\r\n                if (arr[2] === 0) {\r\n                    // Integer\r\n                    str += arr[1];\r\n                } else if (!(arr[2] === 1 && arr[3] === 1)) {\r\n                    // Proper fraction\r\n                    if (arr[1] !== 0) {\r\n                        // Absolute value larger than 1\r\n                        str += arr[1] + ' ';\r\n                    }\r\n                    // Add fractional part\r\n                    if (useTeX === true) {\r\n                        str += '\\\\frac{' + arr[2] + '}{' + arr[3] + '}';\r\n                    } else {\r\n                        str += arr[2] + '/' + arr[3];\r\n                    }\r\n                }\r\n            }\r\n            return str;\r\n        },\r\n\r\n        /**\r\n         * Concat array src to array dest.\r\n         * Uses push instead of JavaScript concat, which is much\r\n         * faster.\r\n         * The array dest is changed in place.\r\n         * <p><b>Attention:</b> if \"dest\" is an anonymous array, the correct result is returned from the function.\r\n         *\r\n         * @param {Array} dest\r\n         * @param {Array} src\r\n         * @returns Array\r\n         */\r\n        concat: function(dest, src) {\r\n            var i,\r\n                le = src.length;\r\n            for (i = 0; i < le; i++) {\r\n                dest.push(src[i]);\r\n            }\r\n            return dest;\r\n        },\r\n\r\n        /**\r\n         * Convert HTML tags to entities or use html_sanitize if the google caja html sanitizer is available.\r\n         * @param {String} str\r\n         * @param {Boolean} caja\r\n         * @returns {String} Sanitized string\r\n         */\r\n        sanitizeHTML: function (str, caja) {\r\n            if (typeof html_sanitize === \"function\" && caja) {\r\n                return html_sanitize(\r\n                    str,\r\n                    function () {\r\n                        return undefined;\r\n                    },\r\n                    function (id) {\r\n                        return id;\r\n                    }\r\n                );\r\n            }\r\n\r\n            if (str && typeof str === 'string') {\r\n                str = str.replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\");\r\n            }\r\n\r\n            return str;\r\n        },\r\n\r\n        /**\r\n         * If <tt>s</tt> is a slider, it returns the sliders value, otherwise it just returns the given value.\r\n         * @param {*} s\r\n         * @returns {*} s.Value() if s is an element of type slider, s otherwise\r\n         */\r\n        evalSlider: function (s) {\r\n            if (s && s.type === Const.OBJECT_TYPE_GLIDER && typeof s.Value === 'function') {\r\n                return s.Value();\r\n            }\r\n\r\n            return s;\r\n        },\r\n\r\n        /**\r\n         * Convert a string containing a MAXIMA /STACK expression into a JSXGraph / JessieCode string\r\n         * or an array of JSXGraph / JessieCode strings.\r\n         * <p>\r\n         * This function is meanwhile superseded by stack_jxg.stack2jsxgraph.\r\n         *\r\n         * @deprecated\r\n         *\r\n         * @example\r\n         * console.log( JXG.stack2jsxgraph(\"%e**x\") );\r\n         * // Output:\r\n         * //    \"EULER**x\"\r\n         *\r\n         * @example\r\n         * console.log( JXG.stack2jsxgraph(\"[%pi*(x**2 - 1), %phi*(x - 1), %gamma*(x+1)]\") );\r\n         * // Output:\r\n         * //    [ \"PI*(x**2 - 1)\", \"1.618033988749895*(x - 1)\", \"0.5772156649015329*(x+1)\" ]\r\n         *\r\n         * @param {String} str\r\n         * @returns String\r\n         */\r\n        stack2jsxgraph: function(str) {\r\n            var t;\r\n\r\n            t = str.\r\n                replace(/%pi/g, 'PI').\r\n                replace(/%e/g, 'EULER').\r\n                replace(/%phi/g, '1.618033988749895').\r\n                replace(/%gamma/g, '0.5772156649015329').\r\n                trim();\r\n\r\n            // String containing array -> array containing strings\r\n            if (t[0] === '[' && t[t.length - 1] === ']') {\r\n                t = t.slice(1, -1).split(/\\s*,\\s*/);\r\n            }\r\n\r\n            return t;\r\n        }\r\n    }\r\n);\r\n\r\nexport default JXG;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG:true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport JXG from \"./jxg.js\";\r\nimport Const from \"./base/constants.js\";\r\nimport Mat from \"./math/math.js\";\r\nimport Color from \"./utils/color.js\";\r\nimport Type from \"./utils/type.js\";\r\n\r\n/**\r\n * Options Namespace\r\n * @description These are the default options of the board and of all geometry elements.\r\n * @namespace\r\n * @name JXG.Options\r\n */\r\nJXG.Options = {\r\n\r\n    jc: {\r\n        enabled: true,\r\n        compile: true\r\n    },\r\n\r\n    /*\r\n     * Options that are used directly within the board class\r\n     */\r\n    board: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        //updateType: 'hierarchical', // 'all'\r\n\r\n        /**\r\n         * Time (in msec) between two animation steps. Used in\r\n         * {@link JXG.CoordsElement#moveAlong}, {@link JXG.CoordsElement#moveTo} and\r\n         * {@link JXG.CoordsElement#visit}.\r\n         *\r\n         * @name JXG.Board#animationDelay\r\n         * @type Number\r\n         * @default 35\r\n         * @see JXG.CoordsElement#moveAlong\r\n         * @see JXG.CoordsElement#moveTo\r\n         * @see JXG.CoordsElement#visit\r\n         */\r\n        animationDelay: 35,\r\n\r\n        /**\r\n         * Show default axis.\r\n         * If shown, the horizontal axis can be accessed via JXG.Board.defaultAxes.x, the\r\n         * vertical axis can be accessed via JXG.Board.defaultAxes.y.\r\n         * Both axes have a sub-element \"defaultTicks\".\r\n         *\r\n         * Value can be Boolean or an object containing axis attributes.\r\n         *\r\n         * @name JXG.Board#axis\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        axis: false,\r\n\r\n        /**\r\n         * Bounding box of the visible area in user coordinates.\r\n         * It is an array consisting of four values:\r\n         * [x<sub>1</sub>, y<sub>1</sub>, x<sub>2</sub>, y<sub>2</sub>]\r\n         *\r\n         * The canvas will be spanned from the upper left corner (x<sub>1</sub>, y<sub>1</sub>)\r\n         * to the lower right corner (x<sub>2</sub>, y<sub>2</sub>).\r\n         *\r\n         * @name JXG.Board#boundingBox\r\n         * @type Array\r\n         * @see JXG.Board#maxBoundingBox\r\n         * @see JXG.Board#keepAspectRatio\r\n         *\r\n         * @default [-5, 5, 5, -5]\r\n         * @example\r\n         * var board = JXG.JSXGraph.initBoard('jxgbox', {\r\n         *         boundingbox: [-5, 5, 5, -5],\r\n         *         axis: true\r\n         *     });\r\n         */\r\n        boundingBox: [-5, 5, 5, -5],\r\n\r\n        /**\r\n         * Enable browser scrolling on touch interfaces if the user double taps into an empty region\r\n         * of the board. In turn, browser scrolling is deactivated as soon as a JSXGraph element is dragged.\r\n         *\r\n         * <ul>\r\n         * <li> Implemented for pointer touch devices - not with mouse, pen or old iOS touch.\r\n         * <li> It only works if browserPan:true\r\n         * <li> One finger action by the settings \"pan.enabled:true\" and \"pan.needTwoFingers:false\" has priority.\r\n         * </ul>\r\n         *\r\n         * @name JXG.Board#browserPan\r\n         * @see JXG.Board#pan\r\n         * @type Boolean\r\n         * @default false\r\n         *\r\n         * @example\r\n         * const board = JXG.JSXGraph.initBoard('jxgbox', {\r\n         *     boundingbox: [-5, 5, 5, -5], axis: true,\r\n         *     pan: {\r\n         *         enabled: true,\r\n         *         needTwoFingers: true,\r\n         *     },\r\n         *     browserPan: true,\r\n         *     zoom: {\r\n         *         enabled: false\r\n         *     }\r\n         * });\r\n         *\r\n         * var p1 = board.create('point', [1, -1]);\r\n         * var p2 = board.create('point', [2.5, -2]);\r\n         * var li1 = board.create('line', [p1, p2]);\r\n         *\r\n         * </pre><div id=\"JXGcd50c814-be81-4280-9458-d73e50cece8d\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGcd50c814-be81-4280-9458-d73e50cece8d',\r\n         *             {showcopyright: false, shownavigation: false,\r\n         *              axis: true,\r\n         *              pan: {\r\n         *                enabled: true,\r\n         *                needTwoFingers: true,\r\n         *             },\r\n         *             browserPan: true,\r\n         *             zoom: {\r\n         *               enabled: false\r\n         *             }\r\n         *          });\r\n         *\r\n         *     var p1 = board.create('point', [1, -1]);\r\n         *     var p2 = board.create('point', [2.5, -2]);\r\n         *     var li1 = board.create('line', [p1, p2]);\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         *\r\n         */\r\n        browserPan: false,\r\n\r\n        /**\r\n         *\r\n         * Maximum time delay (in msec) between two clicks to be considered\r\n         * as double click. This attribute is used together with {@link JXG.Board#dblClickSuppressClick}.\r\n         * The JavaScript standard is that\r\n         * a click event is preceded by two click events,\r\n         * see {@link https://developer.mozilla.org/en-US/docs/Web/API/Element/dblclick_event}.\r\n         * In case of {@link JXG.Board#dblClickSuppressClick} being true, the JavaScript standard is ignored and\r\n         * this time delay is used to suppress the two click events if they are followed by a double click event.\r\n         * <p>\r\n         * In case of {@link JXG.Board#dblClickSuppressClick} being false, this attribute is used\r\n         * to clear the list of clicked elements after the time specified by this attribute.\r\n         * <p>\r\n         * Recommendation: if {@link JXG.Board#dblClickSuppressClick} is true, use a value of approx. 300,\r\n         * otherwise stay with the default 600.\r\n         *\r\n         * @name JXG.Board#clickDelay\r\n         * @type Number\r\n         * @default 600\r\n         * @see JXG.Board#dblClickSuppressClick\r\n         */\r\n        clickDelay: 600,\r\n\r\n        /**\r\n         * If false (default), JSXGraph follows the JavaScript standard and fires before a dblclick event two\r\n         * click events.\r\n         * <p>\r\n         * If true, the click events are suppressed if there is a dblclick event.\r\n         * The consequence is that in this case any click event is fired with a delay specified by\r\n         * {@link JXG.Board#clickDelay}.\r\n         *\r\n         * @name JXG.Board#dblClickSuppressClick\r\n         * @type Boolean\r\n         * @default false\r\n         * @see JXG.Board#clickDelay\r\n         *\r\n         */\r\n        dblClickSuppressClick: false,\r\n\r\n        /**\r\n         * Attributes for the default axes in case of the attribute\r\n         * axis:true in {@link JXG.JSXGraph#initBoard}.\r\n         *\r\n         * @name JXG.Board#defaultAxes\r\n         * @type Object\r\n         * @default <tt>{x: {name:'x'}, y: {name: 'y'}}</tt>\r\n         *\r\n         * @example\r\n         * const board = JXG.JSXGraph.initBoard('id', {\r\n         *     boundingbox: [-5, 5, 5, -5], axis:true,\r\n         *     defaultAxes: {\r\n         *         x: {\r\n         *           name: 'Distance (mi)',\r\n         *           withLabel: true,\r\n         *           label: {\r\n         *             position: 'rt',\r\n         *             offset: [-5, 15],\r\n         *             anchorX: 'right'\r\n         *           }\r\n         *         },\r\n         *         y: {\r\n         *           withLabel: true,\r\n         *           name: 'Y',\r\n         *           label: {\r\n         *             position: 'rt',\r\n         *             offset: [-20, -5],\r\n         *             anchorY: 'top'\r\n         *           }\r\n         *         }\r\n         *     }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXGc3af5eb8-7401-4476-80b5-379ecbd068c6\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *     var board = JXG.JSXGraph.initBoard('JXGc3af5eb8-7401-4476-80b5-379ecbd068c6', {\r\n         *         showcopyright: false, shownavigation: false,\r\n         *         boundingbox: [-5, 5, 5, -5], axis:true,\r\n         *         defaultAxes: {\r\n         *             x: {\r\n         *               name: 'Distance (mi)',\r\n         *               withLabel: true,\r\n         *               label: {\r\n         *                 position: 'rt',\r\n         *                 offset: [-5, 15],\r\n         *                 anchorX: 'right'\r\n         *               }\r\n         *             },\r\n         *             y: {\r\n         *               withLabel: true,\r\n         *               name: 'Y',\r\n         *               label: {\r\n         *                 position: 'rt',\r\n         *                 offset: [-20, -5],\r\n         *                 anchorY: 'top'\r\n         *               }\r\n         *             }\r\n         *         }\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         *  // Display ticks labels as fractions\r\n         *  var board = JXG.JSXGraph.initBoard('jxgbox', {\r\n         *      boundingbox: [-1.2, 2.3, 1.2, -2.3],\r\n         *      axis: true,\r\n         *      defaultAxes: {\r\n         *          x: {\r\n         *              ticks: {\r\n         *                  label: {\r\n         *                      useMathJax: true,\r\n         *                      display: 'html',\r\n         *                      toFraction: true\r\n         *                  }\r\n         *              }\r\n         *          },\r\n         *          y: {\r\n         *              ticks: {\r\n         *                  label: {\r\n         *                      useMathJax: true,\r\n         *                      display: 'html',\r\n         *                      toFraction: true\r\n         *                  }\r\n         *              }\r\n         *          }\r\n         *      }\r\n         *  });\r\n         *\r\n         * </pre><div id=\"JXG484d2f00-c853-4acb-a8bd-46a9e232d13b\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script src=\"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js\" id=\"MathJax-script\"></script>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG484d2f00-c853-4acb-a8bd-46a9e232d13b',\r\n         *             {boundingbox: [-1.2, 2.3, 1.2, -2.3],\r\n         *              axis: true, showcopyright: false, shownavigation: true,\r\n         *                 defaultAxes: {\r\n         *                     x: {\r\n         *                         ticks: {\r\n         *                             label: {\r\n         *                                 useMathJax: true,\r\n         *                                 display: 'html',\r\n         *                                 toFraction: true\r\n         *                             }\r\n         *                         }\r\n         *                     },\r\n         *                     y: {\r\n         *                         ticks: {\r\n         *                             label: {\r\n         *                                 useMathJax: true,\r\n         *                                 display: 'html',\r\n         *                                 toFraction: true\r\n         *                             }\r\n         *                         }\r\n         *                     }\r\n         *                 }\r\n         *             });\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        defaultAxes: {\r\n            x: {\r\n                name: 'x',\r\n                fixed: true,\r\n                needsRegularUpdate: false,\r\n                ticks: {\r\n                    label: {\r\n                        visible: 'inherit',\r\n                        anchorX: 'middle',\r\n                        anchorY: 'top',\r\n                        fontSize: 12,\r\n                        offset: [0, -3]\r\n                    },\r\n                    tickEndings: [0, 1],\r\n                    majorTickEndings: [1, 1],\r\n                    drawZero: false,\r\n                    visible: 'inherit'\r\n                }\r\n            },\r\n            y: {\r\n                name: 'y',\r\n                fixed: true,\r\n                needsRegularUpdate: false,\r\n                ticks: {\r\n                    label: {\r\n                        visible: 'inherit',\r\n                        anchorX: 'right',\r\n                        anchorY: 'middle',\r\n                        fontSize: 12,\r\n                        offset: [-6, 0]\r\n                    },\r\n                    tickEndings: [1, 0],\r\n                    majorTickEndings: [1, 1],\r\n                    drawZero: false,\r\n                    visible: 'inherit'\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Supply the document object. Defaults to window.document\r\n         *\r\n         * @name JXG.Board#document\r\n         * @type Object\r\n         * @description DOM object\r\n         * @default false (meaning window.document)\r\n         */\r\n        document: false,\r\n\r\n        /**\r\n         * Control the possibilities for dragging objects.\r\n         *\r\n         * Possible sub-attributes with default values are:\r\n         * <pre>\r\n         * drag: {\r\n         *   enabled: true   // Allow dragging\r\n         * }\r\n         * </pre>\r\n         *\r\n         * @name JXG.Board#drag\r\n         * @type Object\r\n         * @default <tt>{enabled: true}</tt>\r\n         */\r\n        drag: {\r\n            enabled: true\r\n        },\r\n\r\n        /**\r\n         * Attribute(s) to control the fullscreen icon. The attribute \"showFullscreen\"\r\n         * controls if the icon is shown.\r\n         * The following attribute(s) can be set:\r\n         * <ul>\r\n         *  <li> symbol (String): Unicode symbol which is shown in the navigation bar.  Default: svg code for '\\u26f6', other\r\n         * possibilities are the unicode symbols '\\u26f6' and '\\u25a1'. However, '\\u26f6' is not supported by MacOS and iOS.\r\n         *  <li> scale (number between 0 and 1): Relative size of the larger side of the JSXGraph board in the fullscreen window. 1.0 gives full width or height.\r\n         * Default value is 0.85.\r\n         *  <li> id (String): Id of the HTML element which is brought to full screen or null if the JSXgraph div is taken.\r\n         * It may be an outer div element, e.g. if the old aspect ratio trick is used. Default: null, i.e. use the JSXGraph div.\r\n         * </ul>\r\n         *\r\n         * @example\r\n         * var board = JXG.JSXGraph.initBoard('35bec5a2-fd4d-11e8-ab14-901b0e1b8723',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true,\r\n         *             showcopyright: false,\r\n         *             showFullscreen: true,\r\n         *             fullscreen: {\r\n         *                  symbol: '\\u22c7',\r\n         *                  scale: 0.95\r\n         *              }\r\n         *             });\r\n         * var pol = board.create('polygon', [[0, 1], [3,4], [1,-4]], {fillColor: 'yellow'});\r\n         *\r\n         * </pre><div id=\"JXGa35bec5a2-fd4d-11e8-ab14-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGa35bec5a2-fd4d-11e8-ab14-901b0e1b8723',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false,\r\n         *              showFullscreen: true,\r\n         *              fullscreen: {\r\n         *                  symbol: '\\u22c7',\r\n         *                  scale: 0.95\r\n         *                  }\r\n         *             });\r\n         *     var pol = board.create('polygon', [[0, 1], [3,4], [1,-4]], {fillColor: 'yellow'});\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @name JXG.Board#fullscreen\r\n         * @default svg code\r\n         * @see JXG.Board#showFullscreen\r\n         * @see JXG.AbstractRenderer#drawNavigationBar\r\n         * @type Object\r\n         */\r\n        fullscreen: {\r\n            symbol: '<svg height=\"1em\" width=\"1em\" version=\"1.1\" viewBox=\"10 10 18 18\"><path fill=\"#666\" d=\"m 10,16 2,0 0,-4 4,0 0,-2 L 10,10 l 0,6 0,0 z\"></path><path fill=\"#666\" d=\"m 20,10 0,2 4,0 0,4 2,0 L 26,10 l -6,0 0,0 z\"></path><path fill=\"#666\" d=\"m 24,24 -4,0 0,2 L 26,26 l 0,-6 -2,0 0,4 0,0 z\"></path><path fill=\"#666\" d=\"M 12,20 10,20 10,26 l 6,0 0,-2 -4,0 0,-4 0,0 z\"></path></svg>',\r\n            // symbol: '\\u26f6', // '\\u26f6' (not supported by MacOS),\r\n            scale: 0.85,\r\n            id: null\r\n        },\r\n\r\n        /**\r\n         * If set true and\r\n         * hasPoint() is true for both an element and it's label,\r\n         * the element (and not the label) is taken as drag element.\r\n         * <p>\r\n         * If set false and hasPoint() is true for both an element and it's label,\r\n         * the label is taken (if it is on a higher layer than the element)\r\n         * <p>\r\n         * Meanwhile, this feature might be irrelevant.\r\n         * @name JXG.Board#ignoreLabels\r\n         * @type Booelan\r\n         * @default true\r\n         */\r\n        ignoreLabels: true,\r\n\r\n        /**\r\n         * Support for internationalization of number formatting. This affects\r\n         * <ul>\r\n         *  <li> axis labels\r\n         *  <li> infobox\r\n         *  <li> texts consisting of numbers only\r\n         *  <li> smartlabel elements\r\n         *  <li> slider labels\r\n         *  <li> tapemeasure elements\r\n         *  <li> integral element labels\r\n         * </ul>\r\n         * See <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat\">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat</a>\r\n         * for an overview on the possibilities and the options.\r\n         * <p>\r\n         * User generated texts consisting of texts AND numbers have to be internationalized by the user, see\r\n         * {@link Text#intl}.\r\n         * Language locale and options can be individually controlled for each element by its intl attribute.\r\n         * If no locale is set, the default language of the browser is used.\r\n         *\r\n         * @name JXG.Board#intl\r\n         * @type Object\r\n         * @default <tt>{enabled: false}</tt>\r\n         * @see Integral#label\r\n         * @see Slider#intl\r\n         * @see Text#intl\r\n         * @see Ticks#intl\r\n         * @see JXG.Board.infobox\r\n         *\r\n         * @example\r\n         * // Set the board-wide locale and use individual\r\n         * // options for a text.\r\n         * const board = JXG.JSXGraph.initBoard(BOARDID, {\r\n         *     axis: true,\r\n         *     intl: {\r\n         *         enabled: true,\r\n         *         locale: 'de-DE'\r\n         *     },\r\n         *     boundingbox:[-0.5, 0.5, 0.5, -0.5]\r\n         * });\r\n         *\r\n         * var t = board.create('text', [0.05, 0.2, -Math.PI*100], {\r\n         *         digits: 2,\r\n         *         intl: {\r\n         *                 enabled: true,\r\n         *                 options: {\r\n         *                     style: 'unit',\r\n         *                     unit: 'celsius'\r\n         *                 }\r\n         *             }\r\n         *     });\r\n         *\r\n         * </pre><div id=\"JXGcbb0305d-92e2-4628-a58a-d0d515c8fec9\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *     var board = JXG.JSXGraph.initBoard('JXGcbb0305d-92e2-4628-a58a-d0d515c8fec9', {\r\n         *         axis: true, showcopyright: false, shownavigation: false,\r\n         *         intl: {\r\n         *             enabled: true,\r\n         *             locale: 'de-DE'\r\n         *         },\r\n         *     boundingbox:[-0.5, 0.5, 0.5, -0.5]\r\n         *     });\r\n         *     var t = board.create('text', [0.05, 0.2, -Math.PI*100], {\r\n         *         digits: 2,\r\n         *         intl: {\r\n         *                 enabled: true,\r\n         *                 options: {\r\n         *                     style: 'unit',\r\n         *                     unit: 'celsius'\r\n         *                 }\r\n         *             }\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         * // Here, locale is disabled in general, but enabled for the horizontal\r\n         * // axis and the infobox.\r\n         * const board = JXG.JSXGraph.initBoard(BOARDID, {\r\n         *     boundingbox: [-0.5, 0.5, 0.5, -0.5],\r\n         *     intl: {\r\n         *         enabled: false,\r\n         *         locale: 'de-DE'\r\n         *     },\r\n         *     keepaspectratio: true,\r\n         *     axis: true,\r\n         *     defaultAxes: {\r\n         *         x: {\r\n         *             ticks: {\r\n         *                 intl: {\r\n         *                         enabled: true,\r\n         *                         options: {\r\n         *                             style: 'unit',\r\n         *                             unit: 'kilometer-per-hour',\r\n         *                             unitDisplay: 'narrow'\r\n         *                         }\r\n         *                 }\r\n         *             }\r\n         *         },\r\n         *         y: {\r\n         *             ticks: {\r\n         *             }\r\n         *         }\r\n         *     },\r\n         *     infobox: {\r\n         *         fontSize: 12,\r\n         *         intl: {\r\n         *             enabled: true,\r\n         *             options: {\r\n         *                 minimumFractionDigits: 4,\r\n         *                 maximumFractionDigits: 5\r\n         *             }\r\n         *         }\r\n         *     }\r\n         * });\r\n         *\r\n         * var p = board.create('point', [0.1, 0.1], {});\r\n         *\r\n         * </pre><div id=\"JXG07d5d95c-9324-4fc4-aad3-098e433f195f\" class=\"jxgbox\" style=\"width: 600px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *     var board = JXG.JSXGraph.initBoard('JXG07d5d95c-9324-4fc4-aad3-098e433f195f', {\r\n         *         boundingbox: [-0.5, 0.5, 0.5, -0.5], showcopyright: false, shownavigation: false,\r\n         *         intl: {\r\n         *             enabled: false,\r\n         *             locale: 'de-DE'\r\n         *         },\r\n         *         keepaspectratio: true,\r\n         *         axis: true,\r\n         *         defaultAxes: {\r\n         *             x: {\r\n         *                 ticks: {\r\n         *                     intl: {\r\n         *                             enabled: true,\r\n         *                             options: {\r\n         *                                 style: 'unit',\r\n         *                                 unit: 'kilometer-per-hour',\r\n         *                                 unitDisplay: 'narrow'\r\n         *                             }\r\n         *                     }\r\n         *                 }\r\n         *             },\r\n         *             y: {\r\n         *                 ticks: {\r\n         *                 }\r\n         *             }\r\n         *         },\r\n         *         infobox: {\r\n         *             fontSize: 12,\r\n         *             intl: {\r\n         *                 enabled: true,\r\n         *                 options: {\r\n         *                     minimumFractionDigits: 4,\r\n         *                     maximumFractionDigits: 5\r\n         *                 }\r\n         *             }\r\n         *         }\r\n         *     });\r\n         *\r\n         *     var p = board.create('point', [0.1, 0.1], {});\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        intl: {\r\n            enabled: false\r\n        },\r\n\r\n        /**\r\n         * If set to true, the ratio between horizontal and vertical unit sizes\r\n         * stays constant - independent of size changes of the hosting HTML div element.\r\n         * <p>\r\n         * If the aspect ration of the hosting div changes, JSXGraphs will change\r\n         * the user supplied bounding box accordingly.\r\n         * This is necessary if circles should look like circles and not\r\n         * like ellipses. It is recommended to set keepAspectRatio = true\r\n         * for geometric applets.\r\n         * <p>\r\n         * For function plotting keepAspectRatio = false\r\n         * might be the better choice.\r\n         *\r\n         * @name JXG.Board#keepAspectRatio\r\n         * @see JXG.Board#boundingBox\r\n         * @see JXG.Board#maxBoundingBox\r\n         * @see JXG.Board#setBoundingBox\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        keepAspectRatio: false,\r\n\r\n        /**\r\n         * Control using the keyboard to change the construction.\r\n         * <ul>\r\n         * <li> enabled: true / false\r\n         * <li> dx: horizontal shift amount per key press\r\n         * <li> dy: vertical shift amount per key press\r\n         * <li> panShift: zoom if shift key is pressed\r\n         * <li> panCtrl: zoom if ctrl key is pressed\r\n         * </ul>\r\n         *\r\n         * @example\r\n         * var board = JXG.JSXGraph.initBoard(\"jxgbox\", {boundingbox: [-5,5,5,-5],\r\n         *     axis: true,\r\n         *     showCopyright:true,\r\n         *     showNavigation:true,\r\n         *     keyboard: {\r\n         *         enabled: true,\r\n         *         dy: 30,\r\n         *         panShift: true,\r\n         *         panCtrl: false\r\n         *     }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXGb1d3aab6-ced2-4fe9-8fa5-b0accc8c7266\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGb1d3aab6-ced2-4fe9-8fa5-b0accc8c7266',\r\n         *             {boundingbox: [-5,5,5,-5],\r\n         *         axis: true,\r\n         *         showCopyright:true,\r\n         *         showNavigation:true,\r\n         *         keyboard: {\r\n         *             enabled: true,\r\n         *             dy: 30,\r\n         *             panShift: true,\r\n         *             panCtrl: false\r\n         *         }\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         *\r\n         * @see JXG.Board#keyDownListener\r\n         * @see JXG.Board#keyFocusInListener\r\n         * @see JXG.Board#keyFocusOutListener\r\n         *\r\n         * @name JXG.Board#keyboard\r\n         * @type Object\r\n         * @default <tt>{enabled: true, dx: 10, dy:10, panShift: true, panCtrl: false}</tt>\r\n         */\r\n        keyboard: {\r\n            enabled: true,\r\n            dx: 10,\r\n            dy: 10,\r\n            panShift: true,\r\n            panCtrl: false\r\n        },\r\n\r\n        /**\r\n         * If enabled, user activities are logged in array \"board.userLog\".\r\n         *\r\n         * @name JXG.Board#logging\r\n         * @type Object\r\n         * @default <tt>{enabled: false}</tt>\r\n         *\r\n         * @example\r\n         * var board = JXG.JSXGraph.initBoard(BOARDID,\r\n         *          {\r\n         *              boundingbox: [-8, 8, 8,-8],\r\n         *              axis: true,\r\n         *              logging: {enabled: true},\r\n         *              showcopyright: false,\r\n         *              shownavigation: false\r\n         *          });\r\n         * var A = board.create('point', [-4, 0], { name: 'A' });\r\n         * var B = board.create('point', [1, 2], { name: 'B' });\r\n         * var showUserLog = function() {\r\n         *     var txt = '';\r\n         *\r\n         *     for (let i = 0; i < board.userLog.length; i++) {\r\n         *         txt += JSON.stringify(board.userLog[i]) + '\\n';\r\n         *     }\r\n         *     alert(txt);\r\n         * };\r\n         * var but = board.create('button', [4, 4, 'Show user log', showUserLog]);\r\n         *\r\n         * </pre><div id=\"JXGe152375c-f478-41aa-a9e6-e104403fc75d\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGe152375c-f478-41aa-a9e6-e104403fc75d',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, logging: {enabled: true},\r\n         *              showcopyright: false, shownavigation: false});\r\n         *     var A = board.create('point', [-4, 0], { name: 'A' });\r\n         *     var B = board.create('point', [1, 2], { name: 'B' });\r\n         *     var showUserLog = function() {\r\n         *         var txt = '';\r\n         *\r\n         *         for (let i = 0; i < board.userLog.length; i++) {\r\n         *             txt += JSON.stringify(board.userLog[i]) + '\\n';\r\n         *         }\r\n         *         alert(txt);\r\n         *     };\r\n         *     var but = board.create('button', [4, 4, 'Show user log', showUserLog]);\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         *\r\n         * @see JXG.Board#userLog\r\n         */\r\n        logging: {\r\n            enabled: false\r\n        },\r\n\r\n        /**\r\n         * Change redraw strategy in SVG rendering engine.\r\n         * <p>\r\n         * This optimization seems to be <b>obsolete</b> in newer browsers (from 2021 on, at least)\r\n         * and even slow down the constructions. Therefore, the default is set to 'none' since v1.2.4.\r\n         * <p>\r\n         * If set to 'svg', before every redrawing of the JSXGraph construction\r\n         * the SVG sub-tree of the DOM tree is taken out of the DOM.\r\n         *\r\n         * If set to 'all', before every redrawing of the JSXGraph construction the\r\n         * complete DOM tree is taken out of the DOM.\r\n         * If set to 'none' the redrawing is done in-place.\r\n         *\r\n         * Using 'svg' or 'all' speeds up the update process considerably. The risk\r\n         * is that if there is an exception, only a white div or window is left.\r\n         *\r\n         *\r\n         * @name JXG.Board#minimizeReflow\r\n         * @type String\r\n         * @default 'none'\r\n         */\r\n        minimizeReflow: 'none',\r\n\r\n        /**\r\n         * Maximal bounding box of the visible area in user coordinates.\r\n         * It is an array consisting of four values:\r\n         * [x<sub>1</sub>, y<sub>1</sub>, x<sub>2</sub>, y<sub>2</sub>]\r\n         *\r\n         * The bounding box of the canvas must be inside of this maximal\r\n         * bounding box.\r\n         *\r\n         * @name JXG.Board#maxBoundingBox\r\n         * @type Array\r\n         * @see JXG.Board#boundingBox\r\n         * @default [-Infinity, Infinity, Infinity, -Infinity]\r\n         *\r\n         * @example\r\n         * var board = JXG.JSXGraph.initBoard('jxgbox', {\r\n         *         boundingBox: [-5, 5, 5, -5],\r\n         *         maxBoundingBox: [-8, 8, 8, -8],\r\n         *         pan: {enabled: true},\r\n         *         axis: true\r\n         *     });\r\n         *\r\n         * </pre><div id=\"JXG065e2750-217c-48ed-a52b-7d7df6de7055\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG065e2750-217c-48ed-a52b-7d7df6de7055', {\r\n         *             showcopyright: false, shownavigation: false,\r\n         *             boundingbox: [-5,5,5,-5],\r\n         *             maxboundingbox: [-8,8,8,-8],\r\n         *             pan: {enabled: true},\r\n         *             axis:true\r\n         *         });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        maxBoundingBox: [-Infinity, Infinity, Infinity, -Infinity],\r\n\r\n        /**\r\n         * Maximum frame rate of the board, i.e. maximum number of updates per second\r\n         * triggered by move events.\r\n         *\r\n         * @name JXG.Board#maxFrameRate\r\n         * @type Number\r\n         * @default 40\r\n         */\r\n        maxFrameRate: 40,\r\n\r\n        /**\r\n         * Maximum number of digits in automatic label generation.\r\n         * For example, if set to 1 automatic point labels end at \"Z\".\r\n         * If set to 2, point labels end at \"ZZ\".\r\n         *\r\n         * @name JXG.Board#maxNameLength\r\n         * @see JXG.Board#generateName\r\n         * @type Number\r\n         * @default 1\r\n         */\r\n        maxNameLength: 1,\r\n\r\n        /**\r\n         * Element which listens to move events of the pointing device.\r\n         * This allows to drag elements of a JSXGraph construction outside of the board.\r\n         * Especially, on mobile devices this enhances the user experience.\r\n         * However, it is recommended to allow dragging outside of the JSXGraph board only\r\n         * in certain constructions where users may not \"loose\" points outside of the board.\r\n         * In such a case, points may become unreachable.\r\n         * <p>\r\n         * A situation where dragging outside of the board is uncritical is for example if\r\n         * only sliders are used to interact with the construction.\r\n         * <p>\r\n         * Possible values for this attributes are:\r\n         * <ul>\r\n         * <li> an element specified by document.getElementById('some id');\r\n         * <li> null: to use the JSXGraph container div element\r\n         * <li> document\r\n         * </ul>\r\n         * <p>\r\n         * Since the introduction of this attribute \"moveTarget\", the value \"document\" has become sort of\r\n         * default on touch devices like smartphones. However, it is no longer the case that the document listens to\r\n         * move events, but there is the new feature \"setPointerCapture\", which is also implicitly enabled on certain devices.\r\n         * In future versions, JSXGraph may adopt this new standard and distinguish only two cases:\r\n         * <ul>\r\n         * <li>null: no pointerCapture\r\n         * <li>document: use pointerCapture\r\n         * </ul>\r\n         * <p>\r\n         * This attribute is immutable.\r\n         * It can be changed as follows:\r\n         *\r\n         * @example\r\n         * board.setAttribute({moveTarget: null});\r\n         * board.removeEventHandlers();\r\n         * board.addEventHandlers();\r\n         *\r\n         * @name JXG.Board#moveTarget\r\n         * @type Object\r\n         * @description HTML node or document\r\n         * @default null\r\n         *\r\n         * @example\r\n         *     var board = JXG.JSXGraph.initBoard('jxgbox', {\r\n         *         boundingbox: [-5,5,5,-5],\r\n         *         axis: true,\r\n         *         moveTarget: document\r\n         *     });\r\n         *\r\n         * </pre><div id=\"JXG973457e5-c63f-4516-8570-743f2cc560e1\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG973457e5-c63f-4516-8570-743f2cc560e1',\r\n         *             {boundingbox: [-5,5,5,-5],\r\n         *             axis: true,\r\n         *             moveTarget: document\r\n         *         });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         *\r\n         */\r\n        moveTarget: null,\r\n\r\n        /**\r\n         * A number that will be added to the absolute position of the board used in mouse coordinate\r\n         * calculations in {@link JXG.Board#getCoordsTopLeftCorner}.\r\n         *\r\n         * @name JXG.Board#offsetX\r\n         * @see JXG.Board#offsetY\r\n         * @type Number\r\n         * @default 0\r\n         */\r\n        offsetX: 0,\r\n\r\n        /**\r\n         * A number that will be added to the absolute position of the board used in mouse coordinate\r\n         * calculations in {@link JXG.Board#getCoordsTopLeftCorner}.\r\n         *\r\n         * @name JXG.Board#offsetY\r\n         * @see JXG.Board#offsetX\r\n         * @type Number\r\n         * @default 0\r\n         */\r\n        offsetY: 0,\r\n\r\n        /**\r\n         * Control the possibilities for panning interaction (i.e. moving the origin).\r\n         *\r\n         * Possible sub-attributes with default values are:\r\n         * <pre>\r\n         * pan: {\r\n         *   enabled: true   // Allow panning\r\n         *   needTwoFingers: false, // panning is done with two fingers on touch devices\r\n         *   needShift: true, // mouse panning needs pressing of the shift key\r\n         * }\r\n         * </pre>\r\n         *\r\n         * @name JXG.Board#pan\r\n         * @see JXG.Board#browserPan\r\n         *\r\n         * @type Object\r\n         */\r\n        pan: {\r\n            enabled: true,\r\n            needShift: true,\r\n            needTwoFingers: false\r\n        },\r\n\r\n        /**\r\n         * Allow user interaction by registering pointer events (including mouse and\r\n         * touch events), fullscreen, keyboard, resize, and zoom events.\r\n         * The latter events are essentially mouse wheel events.\r\n         * Decide if JSXGraph listens to these events.\r\n         * <p>\r\n         * Using a Boolean value turns on all events (or not), supplying an object of\r\n         * the form\r\n         * <pre>\r\n         *  {\r\n         *     fullscreen: true / false,\r\n         *     keyboard: true / false,\r\n         *     pointer: true / false,\r\n         *     resize: true / false,\r\n         *     wheel: true / false\r\n         *  }\r\n         * </pre>\r\n         * activates individual event handlers. If an event is NOT given,\r\n         * it will be activated.\r\n         * <p>This attribute is immutable. Please use\r\n         * {@link JXG.Board#addEventHandlers()} and\r\n         * {@link JXG.Board#removeEventHandlers()} directly.\r\n         *\r\n         * @name JXG.Board.registerEvents\r\n         * @see JXG.Board#keyboard\r\n         * @see JXG.Board.registerResizeEvent\r\n         * @see JXG.Board.registerFullscreenEvent\r\n         * @type Boolean\r\n         * @default true\r\n         */\r\n        registerEvents: true,\r\n\r\n        // /**\r\n        //  * Listen to fullscreen event.\r\n        //  *\r\n        //  * <p>This attribute is immutable. Please use\r\n        //  * {@link JXG.Board#addFullscreenEventHandlers()} and\r\n        //  * {@link JXG.Board#removeEventHandlers()} directly.\r\n        //  *\r\n        //  * @name JXG.Board#registerFullscreenEvent\r\n        //  * @see JXG.Board#registerEvents\r\n        //  * @see JXG.Board#registerResizeEvent\r\n        //  * @type Boolean\r\n        //  * @default true\r\n        //  */\r\n        // registerFullscreenEvent: true,\r\n\r\n        // /**\r\n        //  * Listen to resize events, i.e. start \"resizeObserver\" or handle the resize event with\r\n        //  * \"resizeListener\". This is independent from the mouse, touch, pointer events.\r\n        //  *\r\n        //  * <p>This attribute is immutable. Please use\r\n        //  * {@link JXG.Board#addResizeEventHandlers()} and\r\n        //  * {@link JXG.Board#removeEventHandlers()} directly.\r\n        //  * <p>\r\n        //  * This attribute just starts a resizeObserver. If the resizeObserver reacts\r\n        //  * to size changed is controlled with {@link JXG.Board#resize}.\r\n        //  *\r\n        //  * @name JXG.Board#registerResizeEvent\r\n        //  * @see JXG.Board#resize\r\n        //  * @see JXG.Board#registerEvents\r\n        //  * @see JXG.Board#registerFullscreenEvent\r\n        //  * @type Boolean\r\n        //  * @default true\r\n        //  */\r\n        // registerResizeEvent: true,\r\n\r\n        /**\r\n         * Default rendering engine. Possible values are 'svg', 'canvas', 'vml', 'no', or 'auto'.\r\n         * If the rendering engine is not available JSXGraph tries to detect a different engine.\r\n         *\r\n         * <p>\r\n         * In case of 'canvas' it is advisable to call 'board.update()' after all elements have been\r\n         * constructed. This ensures that all elements are drawn with their intended visual appearance.\r\n         *\r\n         * <p>\r\n         * This attribute is immutable.\r\n         *\r\n         * @name JXG.Board#renderer\r\n         * @type String\r\n         * @default 'auto'\r\n         */\r\n        renderer: 'auto',\r\n\r\n        /**\r\n         * Control if JSXGraph reacts to resizing of the JSXGraph container element\r\n         * by the user / browser.\r\n         * The attribute \"throttle\" determines the minimal time in msec between to\r\n         * resize calls.\r\n         * <p>\r\n         * <b>Attention:</b> if the JSXGraph container has no CSS property like width or height and max-width or max-height set, but\r\n         * has a property like box-sizing:content-box, then the interplay between CSS and the resize attribute may result in an\r\n         * infinite loop with ever increasing JSXGraph container.\r\n         *\r\n         * @see JXG.Board#startResizeObserver\r\n         * @see JXG.Board#resizeListener\r\n         *\r\n         * @name JXG.Board#resize\r\n         * @type Object\r\n         * @default <tt>{enabled: true, throttle: 10}</tt>\r\n         *\r\n         * @example\r\n         *     var board = JXG.JSXGraph.initBoard('jxgbox', {\r\n         *         boundingbox: [-5,5,5,-5],\r\n         *         keepAspectRatio: true,\r\n         *         axis: true,\r\n         *         resize: {enabled: true, throttle: 200}\r\n         *     });\r\n         *\r\n         * </pre><div id=\"JXGb55d4608-5d71-4bc3-b332-18c15fbda8c3\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGb55d4608-5d71-4bc3-b332-18c15fbda8c3', {\r\n         *             boundingbox: [-5,5,5,-5],\r\n         *             keepAspectRatio: true,\r\n         *             axis: true,\r\n         *             resize: {enabled: true, throttle: 200}\r\n         *         });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         *\r\n         */\r\n        resize: {\r\n            enabled: true,\r\n            throttle: 10\r\n        },\r\n\r\n        /**\r\n         * Attributes to control the screenshot function.\r\n         * The following attributes can be set:\r\n         * <ul>\r\n         *  <li>scale: scaling factor (default=1.0)\r\n         *  <li>type: format of the screenshot image. Default: png\r\n         *  <li>symbol: Unicode symbol which is shown in the navigation bar. Default: '\\u2318'\r\n         *  <li>css: CSS rules to format the div element containing the screen shot image\r\n         *  <li>cssButton: CSS rules to format the close button of the div element containing the screen shot image\r\n         * </ul>\r\n         * The screenshot will fail if the board contains text elements or foreign objects\r\n         * containing SVG again.\r\n         *\r\n         * @name JXG.Board#screenshot\r\n         * @type Object\r\n         */\r\n        screenshot: {\r\n            scale: 1,\r\n            type: 'png',\r\n            symbol: '\\u2318', //'\\u22b9', //'\\u26f6',\r\n            css: 'background-color:#eeeeee; opacity:1.0; border:2px solid black; border-radius:10px; text-align:center',\r\n            cssButton: 'padding: 4px 10px; border: solid #356AA0 1px; border-radius: 5px; position: absolute; right: 2ex; top: 2ex; background-color: rgba(255, 255, 255, 0.3);'\r\n        },\r\n\r\n        /**\r\n         * Control the possibilities for a selection rectangle.\r\n         * Starting a selection event triggers the \"startselecting\" event.\r\n         * When the mouse pointer is released, the \"stopselecting\" event is fired.\r\n         * The \"stopselecting\" event is supplied by the user.\r\n         * <p>\r\n         * So far it works in SVG renderer only.\r\n         * <p>\r\n         * Possible sub-attributes with default values are:\r\n         * <pre>\r\n         * selection: {\r\n         *   enabled: false,\r\n         *   name: 'selectionPolygon',\r\n         *   needShift: false,  // mouse selection needs pressing of the shift key\r\n         *   needCtrl: true,    // mouse selection needs pressing of the shift key\r\n         *   fillColor: '#ffff00'\r\n         * }\r\n         * </pre>\r\n         * <p>\r\n         * Board events triggered by selection manipulation:\r\n         * 'startselecting', 'stopselecting', 'mousestartselecting', 'mousestopselecting',\r\n         * 'pointerstartselecting', 'pointerstopselecting', 'touchstartselecting', 'touchstopselecting'.\r\n         *\r\n         * @example\r\n         * board.on('stopselecting', function(){\r\n         *     var box = board.stopSelectionMode(),\r\n         *     // bbox has the coordinates of the selectionr rectangle.\r\n         *     // Attention: box[i].usrCoords have the form [1, x, y], i.e.\r\n         *     // are homogeneous coordinates.\r\n         *     bbox = box[0].usrCoords.slice(1).concat(box[1].usrCoords.slice(1));\r\n         *     // Set a new bounding box\r\n         *     board.setBoundingBox(bbox, false);\r\n         * });\r\n         *\r\n         * @name JXG.Board#selection\r\n         *\r\n         * @see JXG.Board#startSelectionMode\r\n         * @see JXG.Board#stopSelectionMode\r\n         *\r\n         * @type Object\r\n         * @default\r\n         */\r\n        selection: {\r\n            enabled: false,\r\n            name: 'selectionPolygon',\r\n            needShift: false,\r\n            needCtrl: true,\r\n            fillColor: '#ffff00',\r\n\r\n            // immutable:\r\n            visible: false,\r\n            withLines: false,\r\n            vertices: {\r\n                visible: false\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Show a button which allows to clear all traces of a board.\r\n         * This button can be accessed by JavaScript or CSS with\r\n         * the ID <tt>\"{board_id}_navigation_button_cleartraces\"</tt> or by the CSS classes\r\n         * <tt>JXG_navigation_button\"</tt> or\r\n         * <tt>JXG_navigation_button_cleartraces\"</tt>.\r\n         *\r\n         * @name JXG.Board#showClearTraces\r\n         * @type Boolean\r\n         * @default false\r\n         * @see JXG.AbstractRenderer#drawNavigationBar\r\n         */\r\n        showClearTraces: false,\r\n\r\n        /**\r\n         * Show copyright string and logo in the top left corner of the board.\r\n         *\r\n         * @name JXG.Board#showCopyright\r\n         * @see JXG.Board#showLogo\r\n         * @type Boolean\r\n         * @default true\r\n         */\r\n        showCopyright: true,\r\n\r\n        /**\r\n         * Show a button in the navigation bar to start fullscreen mode.\r\n         * This button can be accessed by JavaScript or CSS with\r\n         * the ID <tt>\"{board_id}_navigation_button_fullscreen\"</tt> or by the CSS classes\r\n         * <tt>JXG_navigation_button\"</tt> or\r\n         * <tt>JXG_navigation_button_fullscreen\"</tt>.\r\n         *\r\n         * @name JXG.Board#showFullscreen\r\n         * @type Boolean\r\n         * @see JXG.Board#fullscreen\r\n         * @default false\r\n         * @see JXG.AbstractRenderer#drawNavigationBar\r\n         * @see JXG.AbstractRenderer#drawNavigationBar\r\n         */\r\n        showFullscreen: false,\r\n\r\n        /**\r\n         * If true, the infobox is shown on mouse/pen over for all points\r\n         * which have set their attribute showInfobox to 'inherit'.\r\n         * If a point has set its attribute showInfobox to false or true,\r\n         * that value will have priority over this value.\r\n         *\r\n         * @name JXG.Board#showInfobox\r\n         * @see Point#showInfobox\r\n         * @type Boolean\r\n         * @default true\r\n         */\r\n        showInfobox: true,\r\n\r\n        /**\r\n         * Show JSXGraph logo in the top left corner of the board anyhow\r\n         * even if {@link JXG.Board#showCopyright} is false.\r\n         *\r\n         * @name JXG.Board#showLogo\r\n         * @type Boolean\r\n         * @default false\r\n         * @see JXG.Board#showCopyright\r\n         */\r\n        showLogo: false,\r\n\r\n        /**\r\n         * Display of navigation arrows and zoom buttons in the navigation bar.\r\n         * <p>\r\n         * The navigation bar has the\r\n         * the ID <tt>\"{board_id}_navigation\"</tt> and the CSS class\r\n         * <tt>JXG_navigation\"</tt>.\r\n         * The individual buttons can be accessed by JavaScript or CSS with\r\n         * the ID <tt>\"{board_id}_navigation_button_{type}\"</tt> or by the CSS classes\r\n         * <tt>JXG_navigation_button\"</tt> or\r\n         * <tt>JXG_navigation_button_{type}\"</tt>, where <tt>{type}</tt>\r\n         * is one of <tt>left</tt>, <tt>right</tt>, or <tt>up</tt>, <tt>down</tt>,\r\n         * <tt>in</tt>, <tt>100</tt>, or <tt>out</tt>,\r\n         * <tt>fullscreen</tt>, <tt>screenshot</tt>, <tt>cleartraces</tt>, <tt>reload</tt>.\r\n         *\r\n         * @name JXG.Board#showNavigation\r\n         * @type Boolean\r\n         * @default true\r\n         * @see JXG.AbstractRenderer#drawNavigationBar\r\n         */\r\n        showNavigation: true,\r\n\r\n        /**\r\n         * Show a button in the navigation bar to force reload of a construction.\r\n         * Works only with the JessieCode tag.\r\n         * This button can be accessed by JavaScript or CSS with\r\n         * the ID <tt>\"{board_id}_navigation_button_reload\"</tt> or by the CSS classes\r\n         * <tt>JXG_navigation_button\"</tt> or\r\n         * <tt>JXG_navigation_button_reload\"</tt>.\r\n         *\r\n         * @name JXG.Board#showReload\r\n         * @type Boolean\r\n         * @default false\r\n         * @see JXG.AbstractRenderer#drawNavigationBar\r\n         */\r\n        showReload: false,\r\n\r\n        /**\r\n         * Show a button in the navigation bar to enable screenshots.\r\n         * This button can be accessed by JavaScript or CSS with\r\n         * the ID <tt>\"{board_id}_navigation_button_screenshot\"</tt> or by the CSS classes\r\n         * <tt>JXG_navigation_button\"</tt> or\r\n         * <tt>JXG_navigation_button_screenshot\"</tt>.\r\n         *\r\n         * @name JXG.Board#showScreenshot\r\n         * @type Boolean\r\n         * @default false\r\n         * @see JXG.AbstractRenderer#drawNavigationBar\r\n         */\r\n        showScreenshot: false,\r\n\r\n        /**\r\n         * Display of zoom buttons in the navigation bar. To show zoom buttons, additionally\r\n         * showNavigation has to be set to true.\r\n         * <p>\r\n         * The individual buttons can be accessed by JavaScript or CSS with\r\n         * the ID <tt>\"{board_id}_navigation_button_{type}\"</tt> or by the CSS classes\r\n         * <tt>JXG_navigation_button\"</tt> or\r\n         * <tt>JXG_navigation_button_{type}\"</tt>, where <tt>{type}</tt>\r\n         * is <tt>in</tt>, <tt>100</tt>, or <tt>out</tt>.\r\n         *\r\n         * @name JXG.Board#showZoom\r\n         * @type Boolean\r\n         * @default true\r\n         * @see JXG.AbstractRenderer#drawNavigationBar\r\n         */\r\n        showZoom: true,\r\n\r\n        /**\r\n         * If true the first element of the set JXG.board.objects having hasPoint==true is taken as drag element.\r\n         *\r\n         * @name JXG.Board#takeFirst\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        takeFirst: false,\r\n\r\n        /**\r\n        * If true, when read from a file or string - the size of the div can be changed by the construction text.\r\n        *\r\n        * @name JXG.Board#takeSizeFromFile\r\n        * @type Boolean\r\n        * @default false\r\n        */\r\n        takeSizeFromFile: false,\r\n\r\n        /**\r\n         * Set a visual theme for a board. At the moment this attribute is immutable.\r\n         * Available themes are\r\n         * <ul>\r\n         * <li> 'default'\r\n         * <li> 'mono_thin': a black / white theme using thin strokes. Restricted to 2D.\r\n         * </ul>\r\n         *\r\n         * @name JXG.Board#theme\r\n         * @type String\r\n         * @default 'default'\r\n         * @example\r\n         *  const board = JXG.JSXGraph.initBoard('jxgbox', {\r\n         *      boundingbox: [-5, 5, 5, -5], axis: true,\r\n         *      theme: 'mono_thin'\r\n         *  });\r\n         *\r\n         *  var a = board.create('slider', [[1, 4], [3, 4], [-10, 1, 10]]);\r\n         *  var p1 = board.create('point', [1, 2]);\r\n         *  var ci1 = board.create('circle', [p1, 0.7]);\r\n         *  var cu = board.create('functiongraph', ['x^2']);\r\n         *  var l1 = board.create('line', [2, 3, -1]);\r\n         *  var l2 = board.create('line', [-5, -3, -1], { dash: 2 });\r\n         *  var i1 = board.create('intersection', [l1, l2]);\r\n         *  var pol = board.create('polygon', [[1, 0], [4, 0], [3.5, 1]]);\r\n         *  var an = board.create('angle', [pol.vertices[1], pol.vertices[0], pol.vertices[2]]);\r\n         *  var se = board.create('sector', [pol.vertices[1], pol.vertices[2], pol.vertices[0]]);\r\n         *  var ci1 = board.create('circle', [[-3, -3], 0.7], { center: { visible: true } });\r\n         *\r\n         * </pre><div id=\"JXG1c5f7a2a-176b-4410-ac06-8593f1a09879\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG1c5f7a2a-176b-4410-ac06-8593f1a09879',\r\n         *             {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false,\r\n         *              theme: 'mono_thin' });\r\n         *\r\n         *    var a = board.create('slider', [[1, 4], [3, 4], [-10, 1, 10]]);\r\n         *    var p1 = board.create('point', [1, 2]);\r\n         *    var ci1 = board.create('circle', [p1, 0.7]);\r\n         *    var cu = board.create('functiongraph', ['x^2']);\r\n         *    var l1 = board.create('line', [2, 3, -1]);\r\n         *    var l2 = board.create('line', [-5, -3, -1], { dash: 2 });\r\n         *    var i1 = board.create('intersection', [l1, l2]);\r\n         *    var pol = board.create('polygon', [[1, 0], [4, 0], [3.5, 1]]);\r\n         *    var an = board.create('angle', [pol.vertices[1], pol.vertices[0], pol.vertices[2]]);\r\n         *    var se = board.create('sector', [pol.vertices[1], pol.vertices[2], pol.vertices[0]]);\r\n         *    var ci1 = board.create('circle', [[-3, -3], 0.7], { center: { visible: true } });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        theme: 'default',\r\n\r\n        /**\r\n         * Title string for the board.\r\n         * Primarily used in an invisible text element for assistive technologies.\r\n         * The title is implemented with the attribute 'aria-label' in the JSXGraph container.\r\n         *\r\n         * Content should be accessible to all users, not just to those with\r\n         * screen readers.  Consider instead adding a text element with the title and add the attribute\r\n         * <b>aria:{enable:true,label:\"Your Title\"}</b>\r\n         *\r\n         * @name JXG.Board#title\r\n         * @type String\r\n         * @default ''\r\n         *\r\n         */\r\n        title: '',\r\n\r\n        /**\r\n         * Control the possibilities for zoom interaction.\r\n         *\r\n         * Possible sub-attributes with default values are:\r\n         * <pre>\r\n         * zoom: {\r\n         *   enabled: true,  // turns off zooming completely, if set to false.\r\n         *   factorX: 1.25,  // horizontal zoom factor (multiplied to {@link JXG.Board#zoomX})\r\n         *   factorY: 1.25,  // vertical zoom factor (multiplied to {@link JXG.Board#zoomY})\r\n         *   wheel: true,    // allow zooming by mouse wheel\r\n         *   needShift: true,  // mouse wheel zooming needs pressing of the shift key\r\n         *   min: 0.001,       // minimal values of {@link JXG.Board#zoomX} and {@link JXG.Board#zoomY}, limits zoomOut\r\n         *   max: 1000.0,      // maximal values of {@link JXG.Board#zoomX} and {@link JXG.Board#zoomY}, limits zoomIn\r\n         *   center: 'auto',   // 'auto': the center of zoom is at the position of the mouse or at the midpoint of two fingers\r\n         *                     // 'board': the center of zoom is at the board's center\r\n         *   pinch: true,      // pinch-to-zoom gesture for proportional zoom\r\n         *   pinchHorizontal: true, // Horizontal pinch-to-zoom zooms horizontal axis. Only available if keepaspectratio:false\r\n         *   pinchVertical: true,   // Vertical pinch-to-zoom zooms vertical axis only. Only available if keepaspectratio:false\r\n         *   pinchSensitivity: 7    // Sensitivity (in degrees) for recognizing horizontal or vertical pinch-to-zoom gestures.\r\n         * }\r\n         * </pre>\r\n         *\r\n         * If the zoom buttons are visible, zooming by clicking the buttons is still possible, regardless of zoom.enabled:true/false.\r\n         * If this should be prevented, set showZoom:false.\r\n         *\r\n         * Deprecated: zoom.eps which is superseded by zoom.min\r\n         *\r\n         * @name JXG.Board#zoom\r\n         * @type Object\r\n         * @default See above\r\n         * @see JXG.Board#showZoom\r\n         *\r\n         */\r\n        zoom: {\r\n            enabled: true,\r\n            factorX: 1.25,\r\n            factorY: 1.25,\r\n            wheel: true,\r\n            needShift: true,\r\n            center: 'auto',\r\n            min: 0.0001,\r\n            max: 10000.0,\r\n            pinch: true,\r\n            pinchHorizontal: true,\r\n            pinchVertical: true,\r\n            pinchSensitivity: 7\r\n        },\r\n\r\n        // /**\r\n        //  * Additional zoom factor multiplied to {@link JXG.Board#zoomX} and {@link JXG.Board#zoomY}.\r\n        //  *\r\n        //  * @name JXG.Board#zoomFactor\r\n        //  * @type Number\r\n        //  * @default 1.0\r\n        //  */\r\n        // zoomFactor: 1,\r\n\r\n        /**\r\n         * Zoom factor in horizontal direction.\r\n         *\r\n         * @name JXG.Board#zoomX\r\n         * @see JXG.Board#zoomY\r\n         * @type Number\r\n         * @default 1.0\r\n         */\r\n        zoomX: 1,\r\n\r\n        /**\r\n         * Zoom factor in vertical direction.\r\n         *\r\n         * @name JXG.Board#zoomY\r\n         * @see JXG.Board#zoomX\r\n         * @type Number\r\n         * @default 1.0\r\n         */\r\n        zoomY: 1\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /**\r\n     * Options that are used by the navigation bar.\r\n     *\r\n     * Default values are\r\n     * <pre>\r\n     * JXG.Option.navbar: {\r\n     *   strokeColor: '#333333',\r\n     *   fillColor: 'transparent',\r\n     *   highlightFillColor: '#aaaaaa',\r\n     *   padding: '2px',\r\n     *   position: 'absolute',\r\n     *   fontSize: '14px',\r\n     *   cursor: 'pointer',\r\n     *   zIndex: '100',\r\n     *   right: '5px',\r\n     *   bottom: '5px'\r\n     * },\r\n     * </pre>\r\n     * These settings are overruled by the CSS class 'JXG_navigation'.\r\n     * @deprecated\r\n     * @type Object\r\n     * @name JXG.Options#navbar\r\n     *\r\n     */\r\n    navbar: {\r\n        strokeColor: '#333333', //'#aaaaaa',\r\n        fillColor: 'transparent', //#f5f5f5',\r\n        highlightFillColor: '#aaaaaa',\r\n        padding: '2px',\r\n        position: 'absolute',\r\n        fontSize: '14px',\r\n        cursor: 'pointer',\r\n        zIndex: '100',\r\n        right: '5px',\r\n        bottom: '5px'\r\n        //border: 'none 1px black',\r\n        //borderRadius: '4px'\r\n    },\r\n\r\n    /*\r\n     *  Generic options used by {@link JXG.GeometryElement}\r\n     */\r\n    elements: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n        // This is a meta tag: http://code.google.com/p/jsdoc-toolkit/wiki/MetaTags\r\n\r\n        /**\r\n         * ARIA settings for JSXGraph elements.\r\n         * Besides 'label' and 'live', all available properties from\r\n         * <a href=\"https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA\">https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA</a> may be set.\r\n         * In JSXGraph, the available properties are used without the leading 'aria-'.\r\n         * For example, the value of the JSXGraph attribute 'aria.label' will be set to the\r\n         * HTML attribute 'aria-label' (ignoring 'aria.enabled').\r\n         *\r\n         * @name aria\r\n         * @memberOf JXG.GeometryElement.prototype\r\n         * @type Object\r\n         * @default <pre>{\r\n         *   enabled: false,\r\n         *   label: '',\r\n         *   live: 'assertive'\r\n         *  }</pre>\r\n         */\r\n        aria: {\r\n            enabled: false,\r\n            label: '',\r\n            live: 'assertive' // 'assertive', 'polite', 'none'\r\n        },\r\n\r\n        /**\r\n         * Apply CSS classes to an element in non-highlighted view. It is possible to supply one or more\r\n         * CSS classes separated by blanks.\r\n         * <p>\r\n         * For non-text and non-image elements, this feature is available for the SVG renderer, only.\r\n         * <p>\r\n         * For text and image elements the specificity (priority) of JSXGraph attributes is higher than the CSS class properties, see\r\n         * {@link Text#cssDefaultStyle}\r\n         * For other elements, however, the specificity of a CSS class is higher than the corresponding JSXGraph attribute, see the example below.\r\n         * The fill-properties of a CSS class will be set only if the corresponding JSXGraph attributes are set (to a dummy value).\r\n         *\r\n         * @example\r\n         * // CSS class\r\n         * .line {\r\n         *     stroke: blue;\r\n         *     stroke-width: 10px;\r\n         *     fill: yellow;\r\n         * }\r\n         *\r\n         * // JavaScript\r\n         * var line = board.create('line', [[0, 0], [3, 3]], {\r\n         *   cssClass: 'line',\r\n         *   strokeColor: 'black',\r\n         *   strokeWidth: 2,\r\n         *   fillColor: '' // Necessary to enable the yellow fill color of the CSS class\r\n         * });\r\n         *\r\n         * // The line is blue and has stroke-width 10px;\r\n         *\r\n         *\r\n         * @name cssClass\r\n         * @memberOf JXG.GeometryElement.prototype\r\n         * @type String\r\n         * @default ''\r\n         * @see Text#cssClass\r\n         * @see JXG.GeometryElement#highlightCssClass\r\n         */\r\n        cssClass: '',\r\n\r\n        /**\r\n         * Apply CSS classes to an element in highlighted view. It is possible to supply one or more\r\n         * CSS classes separated by blanks.\r\n         * <p>\r\n         * For non-text and non-image elements, this feature is available for the SVG renderer, only.\r\n         *\r\n         * @name highlightCssClass\r\n         * @memberOf JXG.GeometryElement.prototype\r\n         * @type String\r\n         * @default ''\r\n         * @see Text#highlightCssClass\r\n         * @see JXG.GeometryElement#cssClass\r\n         */\r\n        highlightCssClass: '',\r\n\r\n        /**\r\n         * Determines the elements border-style.\r\n         * Possible values are:\r\n         * <ul><li>0 for a solid line</li>\r\n         * <li>1 for a dotted line</li>\r\n         * <li>2 for a line with small dashes</li>\r\n         * <li>3 for a line with medium dashes</li>\r\n         * <li>4 for a line with big dashes</li>\r\n         * <li>5 for a line with alternating medium and big dashes and large gaps</li>\r\n         * <li>6 for a line with alternating medium and big dashes and small gaps</li>\r\n         * <li>7 for a dotted line. Needs {@link JXG.GeometryElement#linecap} set to \"round\" for round dots.</li>\r\n         * </ul>\r\n         * The dash patterns are defined in {@link JXG.AbstractRenderer#dashArray}.\r\n         *\r\n         * @type Number\r\n         * @name JXG.GeometryElement#dash\r\n         * @default 0\r\n         *\r\n         * @see JXG.GeometryElement#lineCap\r\n         * @see JXG.AbstractRenderer#dashArray\r\n         */\r\n        dash: 0,\r\n\r\n        /**\r\n         * If true, the dash pattern is multiplied by strokeWidth / 2.\r\n         * @name JXG.GeometryElement#dashScale\r\n         * @type Boolean\r\n         * @default false\r\n         *\r\n         * @see JXG.GeometryElement#dash\r\n         * @see JXG.AbstractRenderer#dashArray\r\n         */\r\n        dashScale: false,\r\n\r\n        /**\r\n         * If draft.draft: true the element will be drawn in grey scale colors (as default)\r\n         * to visualize that it's only a draft.\r\n         *\r\n         * @name JXG.GeometryElement#draft\r\n         * @type Object\r\n         * @default <tt>{@link JXG.Options.elements.draft#draft}</tt>\r\n         */\r\n        draft: {\r\n            draft: false,\r\n            strokeColor: '#565656',\r\n            fillColor: '#565656',\r\n            strokeOpacity: 0.8,\r\n            fillOpacity: 0.8,\r\n            strokeWidth: 1\r\n        },\r\n\r\n        /**\r\n         * If the element is dragged it will be moved on mousedown or touchstart to the\r\n         * top of its layer. Works only for SVG renderer and for simple elements\r\n         * consisting of one SVG node.\r\n         * @example\r\n         * var li1 = board.create('line', [1, 1, 1], {strokeWidth: 20, dragToTopOfLayer: true});\r\n         * var li2 = board.create('line', [1, -1, 1], {strokeWidth: 20, strokeColor: 'red'});\r\n         *\r\n         * </pre><div id=\"JXG38449fee-1ab4-44de-b7d1-43caa1f50f86\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG38449fee-1ab4-44de-b7d1-43caa1f50f86',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var li1 = board.create('line', [1, 1, 1], {strokeWidth: 20, dragToTopOfLayer: true});\r\n         *     var li2 = board.create('line', [1, -1, 1], {strokeWidth: 20, strokeColor: 'red'});\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @type Boolean\r\n         * @default false\r\n         * @name JXG.GeometryElement#dragToTopOfLayer\r\n         */\r\n        dragToTopOfLayer: false,\r\n\r\n        /**\r\n         * Links to the defining 3D element of a 2D element. Otherwise it is null.\r\n         *\r\n         * @name JXG.GeometryElement#element3D\r\n         * @default null\r\n         * @private\r\n         */\r\n        element3D: null,\r\n\r\n        /**\r\n         * The fill color of this geometry element.\r\n         * @type String\r\n         * @name JXG.GeometryElement#fillColor\r\n         * @see JXG.GeometryElement#highlightFillColor\r\n         * @see JXG.GeometryElement#fillOpacity\r\n         * @see JXG.GeometryElement#highlightFillOpacity\r\n         * @default JXG.palette.red\r\n         */\r\n        fillColor: Color.palette.red,\r\n\r\n        /**\r\n         * Opacity for fill color.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#fillOpacity\r\n         * @see JXG.GeometryElement#fillColor\r\n         * @see JXG.GeometryElement#highlightFillColor\r\n         * @see JXG.GeometryElement#highlightFillOpacity\r\n         * @default 1\r\n         */\r\n        fillOpacity: 1,\r\n\r\n        /**\r\n         * If true the element is fixed and can not be dragged around. The element\r\n         * will be repositioned on zoom and moveOrigin events.\r\n         * @type Boolean\r\n         * @default false\r\n         * @name JXG.GeometryElement#fixed\r\n         */\r\n        fixed: false,\r\n\r\n        /**\r\n         * If true the element is fixed and can not be dragged around. The element\r\n         * will even stay at its position on zoom and moveOrigin events.\r\n         * Only free elements like points, texts, images, curves can be frozen.\r\n         *\r\n         * @type Boolean\r\n         * @default false\r\n         * @name JXG.GeometryElement#frozen\r\n         *\r\n         * @example\r\n         * var txt = board.create('text', [1, 2, 'Hello'], {frozen: true, fontSize: 24});\r\n         * var sli = board.create('slider', [[-4, 4], [-1.5, 4], [-10, 1, 10]], {\r\n         *     name:'a',\r\n         *     frozen: true\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXG02f88c9d-8c0a-4174-9219-f0ea43749159\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG02f88c9d-8c0a-4174-9219-f0ea43749159',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var txt = board.create('text', [1, 2, 'Hello'], {frozen: true, fontSize: 24});\r\n         *     var sli = board.create('slider', [[-4, 4], [-1.5, 4], [-10, 1, 10]], {\r\n         *         name:'a',\r\n         *         frozen: true\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        frozen: false,\r\n\r\n        /**\r\n         * Gradient type. Possible values are 'linear'. 'radial' or null.\r\n         *\r\n         * @example\r\n         *     var a = board.create('slider', [[0, -0.2], [3.5, -0.2], [0, 0, 2 * Math.PI]], {name: 'angle'});\r\n         *     var b = board.create('slider', [[0, -0.4], [3.5, -0.4], [0, 0, 1]], {name: 'offset1'});\r\n         *     var c = board.create('slider', [[0, -0.6], [3.5, -0.6], [0, 1, 1]], {name: 'offset2'});\r\n         *\r\n         *     var pol = board.create('polygon', [[0, 0], [4, 0], [4,4], [0,4]], {\r\n         *                 fillOpacity: 1,\r\n         *                 fillColor: 'yellow',\r\n         *                 gradient: 'linear',\r\n         *                 gradientSecondColor: 'blue',\r\n         *                 gradientAngle: function() { return a.Value(); },\r\n         *                 gradientStartOffset: function() { return b.Value(); },\r\n         *                 gradientEndOffset: function() { return c.Value(); },\r\n         *                 hasInnerPoints: true\r\n         *         });\r\n         *\r\n         * </pre><div id=\"JXG3d04b5fd-0cd4-4f49-8c05-4e9686cd7ff0\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG3d04b5fd-0cd4-4f49-8c05-4e9686cd7ff0',\r\n         *             {boundingbox: [-1.5, 4.5, 5, -1.5], axis: true, showcopyright: false, shownavigation: false});\r\n         *         var a = board.create('slider', [[0, -0.2], [3.5, -0.2], [0, 0, 2 * Math.PI]], {name: 'angle'});\r\n         *         var b = board.create('slider', [[0, -0.4], [3.5, -0.4], [0, 0, 1]], {name: 'offset1'});\r\n         *         var c = board.create('slider', [[0, -0.6], [3.5, -0.6], [0, 1, 1]], {name: 'offset2'});\r\n         *\r\n         *         var pol = board.create('polygon', [[0, 0], [4, 0], [4,4], [0,4]], {\r\n         *                     fillOpacity: 1,\r\n         *                     fillColor: 'yellow',\r\n         *                     gradient: 'linear',\r\n         *                     gradientSecondColor: 'blue',\r\n         *                     gradientAngle: function() { return a.Value(); },\r\n         *                     gradientStartOffset: function() { return b.Value(); },\r\n         *                     gradientEndOffset: function() { return c.Value(); },\r\n         *                     hasInnerPoints: true\r\n         *             });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         *     var cx = board.create('slider', [[0, -.2], [3.5, -.2], [0, 0.5, 1]], {name: 'cx, cy'});\r\n         *     var fx = board.create('slider', [[0, -.4], [3.5, -.4], [0, 0.5, 1]], {name: 'fx, fy'});\r\n         *     var o1 = board.create('slider', [[0, -.6], [3.5, -.6], [0, 0.0, 1]], {name: 'offset1'});\r\n         *     var o2 = board.create('slider', [[0, -.8], [3.5, -.8], [0, 1, 1]], {name: 'offset2'});\r\n         *     var r = board.create('slider', [[0, -1], [3.5, -1], [0, 0.5, 1]], {name: 'r'});\r\n         *     var fr = board.create('slider', [[0, -1.2], [3.5, -1.2], [0, 0, 1]], {name: 'fr'});\r\n         *\r\n         *     var pol = board.create('polygon', [[0, 0], [4, 0], [4,4], [0,4]], {\r\n         *                 fillOpacity: 1,\r\n         *                 fillColor: 'yellow',\r\n         *                 gradient: 'radial',\r\n         *                 gradientSecondColor: 'blue',\r\n         *                 gradientCX: function() { return cx.Value(); },\r\n         *                 gradientCY: function() { return cx.Value(); },\r\n         *                 gradientR: function() { return r.Value(); },\r\n         *                 gradientFX: function() { return fx.Value(); },\r\n         *                 gradientFY: function() { return fx.Value(); },\r\n         *                 gradientFR: function() { return fr.Value(); },\r\n         *                 gradientStartOffset: function() { return o1.Value(); },\r\n         *                 gradientEndOffset: function() { return o2.Value(); },\r\n         *                 hasInnerPoints: true\r\n         *     });\r\n         *\r\n         * </pre><div id=\"JXG6081ca7f-0d09-4525-87ac-325a02fe2225\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG6081ca7f-0d09-4525-87ac-325a02fe2225',\r\n         *             {boundingbox: [-1.5, 4.5, 5, -1.5], axis: true, showcopyright: false, shownavigation: false});\r\n         *         var cx = board.create('slider', [[0, -.2], [3.5, -.2], [0, 0.5, 1]], {name: 'cx, cy'});\r\n         *         var fx = board.create('slider', [[0, -.4], [3.5, -.4], [0, 0.5, 1]], {name: 'fx, fy'});\r\n         *         var o1 = board.create('slider', [[0, -.6], [3.5, -.6], [0, 0.0, 1]], {name: 'offset1'});\r\n         *         var o2 = board.create('slider', [[0, -.8], [3.5, -.8], [0, 1, 1]], {name: 'offset2'});\r\n         *         var r = board.create('slider', [[0, -1], [3.5, -1], [0, 0.5, 1]], {name: 'r'});\r\n         *         var fr = board.create('slider', [[0, -1.2], [3.5, -1.2], [0, 0, 1]], {name: 'fr'});\r\n         *\r\n         *         var pol = board.create('polygon', [[0, 0], [4, 0], [4,4], [0,4]], {\r\n         *                     fillOpacity: 1,\r\n         *                     fillColor: 'yellow',\r\n         *                     gradient: 'radial',\r\n         *                     gradientSecondColor: 'blue',\r\n         *                     gradientCX: function() { return cx.Value(); },\r\n         *                     gradientCY: function() { return cx.Value(); },\r\n         *                     gradientR: function() { return r.Value(); },\r\n         *                     gradientFX: function() { return fx.Value(); },\r\n         *                     gradientFY: function() { return fx.Value(); },\r\n         *                     gradientFR: function() { return fr.Value(); },\r\n         *                     gradientStartOffset: function() { return o1.Value(); },\r\n         *                     gradientEndOffset: function() { return o2.Value(); },\r\n         *                     hasInnerPoints: true\r\n         *         });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         *\r\n         * @type String\r\n         * @name JXG.GeometryElement#gradient\r\n         * @see JXG.GeometryElement#gradientSecondColor\r\n         * @see JXG.GeometryElement#gradientSecondOpacity\r\n         * @default null\r\n         */\r\n        gradient: null,\r\n\r\n        /**\r\n         * Angle (in radians) of the gradiant in case the gradient is of type 'linear'.\r\n         * If the angle is 0, the first color is on the left and the second color is on the right.\r\n         * If the angle is &pi;/2 the first color is on top and the second color at the\r\n         * bottom.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#gradientAngle\r\n         * @see JXG.GeometryElement#gradient\r\n         * @default 0\r\n         */\r\n        gradientAngle: 0,\r\n\r\n        /**\r\n         * From the SVG specification: ‘cx’, ‘cy’ and ‘r’ define the largest (i.e., outermost) circle for the radial gradient.\r\n         * The gradient will be drawn such that the 100% gradient stop is mapped to the perimeter of this largest (i.e., outermost) circle.\r\n         * For radial gradients in canvas this is the value 'x1'.\r\n         * Takes a value between 0 and 1.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#gradientCX\r\n         * @see JXG.GeometryElement#gradient\r\n         * @see JXG.GeometryElement#gradientCY\r\n         * @see JXG.GeometryElement#gradientR\r\n         * @default 0.5\r\n         */\r\n        gradientCX: 0.5,\r\n\r\n        /**\r\n         * From the SVG specification: ‘cx’, ‘cy’ and ‘r’ define the largest (i.e., outermost) circle for the radial gradient.\r\n         * The gradient will be drawn such that the 100% gradient stop is mapped to the perimeter of this largest (i.e., outermost) circle.\r\n         * For radial gradients in canvas this is the value 'y1'.\r\n         * Takes a value between 0 and 1.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#gradientCY\r\n         * @see JXG.GeometryElement#gradient\r\n         * @see JXG.GeometryElement#gradientCX\r\n         * @see JXG.GeometryElement#gradientR\r\n         * @default 0.5\r\n         */\r\n        gradientCY: 0.5,\r\n\r\n        /**\r\n         * The gradientEndOffset attribute is a number (ranging from 0 to 1) which indicates where the second gradient stop is placed,\r\n         * see the SVG specification for more information.\r\n         * For linear gradients, this attribute represents a location along the gradient vector.\r\n         * For radial gradients, it represents a percentage distance from (fx,fy) to the edge of the outermost/largest circle.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#gradientEndOffset\r\n         * @see JXG.GeometryElement#gradient\r\n         * @see JXG.GeometryElement#gradientStartOffset\r\n         * @default 1.0\r\n         */\r\n        gradientEndOffset: 1.0,\r\n\r\n        /**\r\n         * ‘fx’ and ‘fy’ define the focal point for the radial gradient.\r\n         * The gradient will be drawn such that the 0% gradient stop is mapped to (fx, fy).\r\n         * For radial gradients in canvas this is the value 'x0'.\r\n         * Takes a value between 0 and 1.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#gradientFX\r\n         * @see JXG.GeometryElement#gradient\r\n         * @see JXG.GeometryElement#gradientFY\r\n         * @see JXG.GeometryElement#gradientFR\r\n         * @default 0.5\r\n         */\r\n        gradientFX: 0.5,\r\n\r\n        /**\r\n         * y-coordinate of the circle center for the second color in case of gradient 'radial'. (The attribute fy in SVG)\r\n         * For radial gradients in canvas this is the value 'y0'.\r\n         * Takes a value between 0 and 1.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#gradientFY\r\n         * @see JXG.GeometryElement#gradient\r\n         * @see JXG.GeometryElement#gradientFX\r\n         * @see JXG.GeometryElement#gradientFR\r\n         * @default 0.5\r\n         */\r\n        gradientFY: 0.5,\r\n\r\n        /**\r\n         * This attribute defines the radius of the start circle of the radial gradient.\r\n         * The gradient will be drawn such that the 0% &lt;stop&gt; is mapped to the perimeter of the start circle.\r\n         * For radial gradients in canvas this is the value 'r0'.\r\n         * Takes a value between 0 and 1.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#gradientFR\r\n         * @see JXG.GeometryElement#gradient\r\n         * @see JXG.GeometryElement#gradientFX\r\n         * @see JXG.GeometryElement#gradientFY\r\n         * @default 0.0\r\n         */\r\n        gradientFR: 0.0,\r\n\r\n        /**\r\n         * From the SVG specification: ‘cx’, ‘cy’ and ‘r’ define the largest (i.e., outermost) circle for the radial gradient.\r\n         * The gradient will be drawn such that the 100% gradient stop is mapped to the perimeter of this largest (i.e., outermost) circle.\r\n         * For radial gradients in canvas this is the value 'r1'.\r\n         * Takes a value between 0 and 1.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#gradientR\r\n         * @see JXG.GeometryElement#gradient\r\n         * @see JXG.GeometryElement#gradientCX\r\n         * @see JXG.GeometryElement#gradientCY\r\n         * @default 0.5\r\n         */\r\n        gradientR: 0.5,\r\n\r\n        /**\r\n         * Second color for gradient.\r\n         * @type String\r\n         * @name JXG.GeometryElement#gradientSecondColor\r\n         * @see JXG.GeometryElement#gradient\r\n         * @see JXG.GeometryElement#gradientSecondOpacity\r\n         * @default '#ffffff'\r\n         */\r\n        gradientSecondColor: '#ffffff',\r\n\r\n        /**\r\n         * Opacity of second gradient color. Takes a value between 0 and 1.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#gradientSecondOpacity\r\n         * @see JXG.GeometryElement#gradient\r\n         * @see JXG.GeometryElement#gradientSecondColor\r\n         * @default 1\r\n         */\r\n        gradientSecondOpacity: 1,\r\n\r\n        /**\r\n         * The gradientStartOffset attribute is a number (ranging from 0 to 1) which indicates where the first gradient stop is placed,\r\n         * see the SVG specification for more information.\r\n         * For linear gradients, this attribute represents a location along the gradient vector.\r\n         * For radial gradients, it represents a percentage distance from (fx,fy) to the edge of the outermost/largest circle.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#gradientStartOffset\r\n         * @see JXG.GeometryElement#gradient\r\n         * @see JXG.GeometryElement#gradientEndOffset\r\n         * @default 0.0\r\n         */\r\n        gradientStartOffset: 0.0,\r\n\r\n        /**\r\n         * @type Boolean\r\n         * @default true\r\n         * @name JXG.GeometryElement#highlight\r\n         */\r\n        highlight: true,\r\n\r\n        /**\r\n         * The fill color of the given geometry element when the mouse is pointed over it.\r\n         * @type String\r\n         * @name JXG.GeometryElement#highlightFillColor\r\n         * @see JXG.GeometryElement#fillColor\r\n         * @see JXG.GeometryElement#fillOpacity\r\n         * @see JXG.GeometryElement#highlightFillOpacity\r\n         * @default 'none'\r\n         */\r\n        highlightFillColor: 'none',\r\n\r\n        /**\r\n         * Opacity for fill color when the object is highlighted.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#highlightFillOpacity\r\n         * @see JXG.GeometryElement#fillColor\r\n         * @see JXG.GeometryElement#highlightFillColor\r\n         * @see JXG.GeometryElement#fillOpacity\r\n         * @default 1\r\n         */\r\n        highlightFillOpacity: 1,\r\n\r\n        /**\r\n         * The stroke color of the given geometry element when the user moves the mouse over it.\r\n         * @type String\r\n         * @name JXG.GeometryElement#highlightStrokeColor\r\n         * @see JXG.GeometryElement#strokeColor\r\n         * @see JXG.GeometryElement#strokeWidth\r\n         * @see JXG.GeometryElement#strokeOpacity\r\n         * @see JXG.GeometryElement#highlightStrokeOpacity\r\n         * @default '#c3d9ff'\r\n         */\r\n        highlightStrokeColor: '#c3d9ff',\r\n\r\n        /**\r\n         * Opacity for stroke color when the object is highlighted.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#highlightStrokeOpacity\r\n         * @see JXG.GeometryElement#strokeColor\r\n         * @see JXG.GeometryElement#highlightStrokeColor\r\n         * @see JXG.GeometryElement#strokeWidth\r\n         * @see JXG.GeometryElement#strokeOpacity\r\n         * @default 1\r\n         */\r\n        highlightStrokeOpacity: 1,\r\n\r\n        /**\r\n         * Width of the element's stroke when the mouse is pointed over it.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#highlightStrokeWidth\r\n         * @see JXG.GeometryElement#strokeColor\r\n         * @see JXG.GeometryElement#highlightStrokeColor\r\n         * @see JXG.GeometryElement#strokeOpacity\r\n         * @see JXG.GeometryElement#highlightStrokeOpacity\r\n         * @see JXG.GeometryElement#highlightFillColor\r\n         * @default 2\r\n         */\r\n        highlightStrokeWidth: 2,\r\n\r\n        /**\r\n         * @name JXG.GeometryElement#isLabel\r\n         * @default false\r\n         * @private\r\n        */\r\n        // By default, an element is not a label. Do not change this.\r\n        isLabel: false,\r\n\r\n        /**\r\n         * Display layer which will contain the element.\r\n         * @name JXG.GeometryElement#layer\r\n         * @see JXG.Options#layer\r\n         * @default See {@link JXG.Options#layer}\r\n         */\r\n        layer: 0,\r\n\r\n        /**\r\n         * Line endings (linecap) of a stroke element, i.e. line, circle, curve.\r\n         * Possible values are:\r\n         * <ul>\r\n         * <li> 'butt',\r\n         * <li> 'round',\r\n         * <li> 'square'.\r\n         * </ul>\r\n         * Not available for VML renderer.\r\n         *\r\n         * @name JXG.GeometryElement#lineCap\r\n         * @type String\r\n         * @default 'butt'\r\n         */\r\n        lineCap: 'butt',\r\n\r\n        /**\r\n         * If this is set to true, the element is updated in every update\r\n         * call of the board. If set to false, the element is updated only after\r\n         * zoom events or more generally, when the bounding box has been changed.\r\n         * Examples for the latter behavior should be axes.\r\n         * @type Boolean\r\n         * @default true\r\n         * @see JXG.GeometryElement#needsRegularUpdate\r\n         * @name JXG.GeometryElement#needsRegularUpdate\r\n         */\r\n        needsRegularUpdate: true,\r\n\r\n        /**\r\n         * If some size of an element is controlled by a function, like the circle radius\r\n         * or segments of fixed length, this attribute controls what happens if the value\r\n         * is negative. By default, the absolute value is taken. If true, the maximum\r\n         * of 0 and the value is used.\r\n         *\r\n         * @type Boolean\r\n         * @default false\r\n         * @name JXG.GeometryElement#nonnegativeOnly\r\n         * @example\r\n         * var slider = board.create('slider', [[4, -3], [4, 3], [-4, 1, 4]], { name: 'a'});\r\n         * var circle = board.create('circle', [[-1, 0], 1], {\r\n         *     nonnegativeOnly: true\r\n         * });\r\n         * circle.setRadius('a');         // Use JessieCode\r\n         * var seg = board.create('segment', [[-4, 3], [0, 3], () => slider.Value()], {\r\n         *     point1: {visible: true},\r\n         *     point2: {visible: true},\r\n         *     nonnegativeOnly: true\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXG9cb76224-1f78-4488-b20f-800788768bc9\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG9cb76224-1f78-4488-b20f-800788768bc9',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var slider = board.create('slider', [[4, -3], [4, 3], [-4, 1, 4]], { name: 'a'});\r\n         *     var circle = board.create('circle', [[-1, 0], 1], {\r\n         *         nonnegativeOnly: true\r\n         *     });\r\n         *     circle.setRadius('a');         // Use JessieCode\r\n         *     var seg = board.create('segment', [[-4, 3], [0, 3], () => slider.Value()], {\r\n         *         point1: {visible: true},\r\n         *         point2: {visible: true},\r\n         *         nonnegativeOnly: true\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        nonnegativeOnly: false,\r\n\r\n        /**\r\n         * Precision options for JSXGraph elements.\r\n         * This attributes takes either the value 'inherit' or an object of the form:\r\n         * <pre>\r\n         * precision: {\r\n         *      touch: 30,\r\n         *      mouse: 4,\r\n         *      pen: 4\r\n         * }\r\n         * </pre>\r\n         *\r\n         * In the first case, the global, JSXGraph-wide values of JXGraph.Options.precision\r\n         * are taken.\r\n         *\r\n         * @type {String|Object}\r\n         * @name JXG.GeometryElement#precision\r\n         * @see JXG.Options#precision\r\n         * @default 'inherit'\r\n         */\r\n        precision: 'inherit',\r\n\r\n        /**\r\n         * A private element will be inaccessible in certain environments, e.g. a graphical user interface.\r\n         *\r\n         * @name JXG.GeometryElement#priv\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        priv: false,\r\n\r\n        /**\r\n         * Determines whether two-finger manipulation may rotate this object.\r\n         * If set to false, the object can only be scaled and translated.\r\n         * <p>\r\n         * In case the element is a polygon or line and it has the attribute \"rotatable:false\",\r\n         * moving the element with two fingers results in a rotation or translation.\r\n         * <p>\r\n         * If an element is set to be neither scalable nor rotatable, it can only be translated.\r\n         * <p>\r\n         * In case of a polygon, scaling is only possible if <i>no</i> vertex has snapToGrid or snapToPoints\r\n         * enabled and no vertex is fixed by some other constraint. Also, the polygon itself has to have\r\n         * snapToGrid disabled.\r\n         *\r\n         * @type Boolean\r\n         * @default true\r\n         * @name JXG.GeometryElement#rotatable\r\n         * @see JXG.GeometryElement#scalable\r\n         */\r\n        rotatable: true,\r\n\r\n        /**\r\n         * Determines whether two-finger manipulation of this object may change its size.\r\n         * If set to false, the object is only rotated and translated.\r\n         * <p>\r\n         * In case the element is a horizontal or vertical line having ticks, \"scalable:true\"\r\n         * enables zooming of the board by dragging ticks lines. This feature is enabled,\r\n         * for the ticks element of the line element the attribute \"fixed\" has to be false\r\n         * and the line element's scalable attribute has to be true.\r\n         * <p>\r\n         * In case the element is a polygon or line and it has the attribute \"scalable:false\",\r\n         * moving the element with two fingers results in a rotation or translation.\r\n         * <p>\r\n         * If an element is set to be neither scalable nor rotatable, it can only be translated.\r\n         * <p>\r\n         * In case of a polygon, scaling is only possible if <i>no</i> vertex has snapToGrid or snapToPoints\r\n         * enabled and no vertex is fixed by some other constraint. Also, the polygon itself has to have\r\n         * snapToGrid disabled.\r\n         *\r\n         * @type Boolean\r\n         * @default true\r\n         * @name JXG.GeometryElement#scalable\r\n         * @see JXG.Ticks#fixed\r\n         * @see JXG.GeometryElement#rotatable\r\n         */\r\n        scalable: true,\r\n\r\n        /**\r\n         * If enabled:true the (stroke) element will get a customized shadow.\r\n         * <p>\r\n         * Customize <i>color</i> and <i>opacity</i>:\r\n         * If the object's RGB stroke color is <tt>[r,g,b]</tt> and its opacity is <tt>op</i>, and\r\n         * the shadow parameters <i>color</i> is given as <tt>[r', g', b']</tt> and <i>opacity</i> as <tt>op'</tt>\r\n         * the shadow will receive the RGB color\r\n         * <center>\r\n         * <tt>[blend*r + r', blend*g + g', blend*b + b'] </tt>\r\n         * </center>\r\n         * and its opacity will be equal to <tt>op * op'</tt>.\r\n         * Further, the parameters <i>blur</i> and <i>offset</i> can be adjusted.\r\n         * <p>\r\n         * This attribute is only available with SVG, not with canvas.\r\n         *\r\n         * @type Object\r\n         * @name JXG.GeometryElement#shadow\r\n         * @default shadow: {\r\n         *   enabled: false,\r\n         *   color: [0, 0, 0],\r\n         *   opacity: 1,\r\n         *   blur: 3,\r\n         *   blend: 0.1,\r\n         *   offset: [5, 5]\r\n         * }\r\n         *\r\n         * @example\r\n         * board.options.line.strokeWidth = 2\r\n         * // No shadow\r\n         * var li1 = board.create('line', [[-2, 5], [2, 6]], {strokeColor: 'red', shadow: false});\r\n         *\r\n         * // Default shadow\r\n         * var li2 = board.create('line', [[-2, 3], [2, 4]], {strokeColor: 'red', shadow: true});\r\n         *\r\n         * // No shadow\r\n         * var li3 = board.create('line', [[-2, 1], [2, 2]], {strokeColor: 'blue', shadow: {enabled: false}});\r\n         *\r\n         * // Shadow uses same color as line\r\n         * var li4 = board.create('line', [[-2, -1], [2, 0]], {strokeColor: 'blue',\r\n         *             shadow: {enabled: true, color: '#000000', blend: 1}\r\n         *         });\r\n         *\r\n         * // Shadow color as a mixture between black and the line color, additionally set opacity\r\n         * var li5 = board.create('line', [[-2, -3], [2, -2]], {strokeColor: 'blue',\r\n         *             shadow: {enabled: true, color: '#000000', blend: 0.5, opacity: 0.5}\r\n         *         });\r\n         *\r\n         * // Use different value for blur and offset [dx, dy]\r\n         * var li6 = board.create('line', [[-2, -5], [2, -4]], {strokeColor: 'blue',\r\n         *             shadow: {enabled: true, offset:[0, 25], blur: 6}\r\n         *         });\r\n         *\r\n         * </pre><div id=\"JXG1185a9fa-0fa5-425f-8c15-55b56e1be958\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG1185a9fa-0fa5-425f-8c15-55b56e1be958',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     board.options.line.strokeWidth = 2\r\n         *     // No shadow\r\n         *     var li1 = board.create('line', [[-2, 5], [2, 6]], {strokeColor: 'red', shadow: false});\r\n         *\r\n         *     // Default shadow\r\n         *     var li2 = board.create('line', [[-2, 3], [2, 4]], {strokeColor: 'red', shadow: true});\r\n         *\r\n         *     // No shadow\r\n         *     var li3 = board.create('line', [[-2, 1], [2, 2]], {strokeColor: 'blue', shadow: {enabled: false}});\r\n         *\r\n         *     // Shadow uses same color as line\r\n         *     var li4 = board.create('line', [[-2, -1], [2, 0]], {strokeColor: 'blue',\r\n         *                 shadow: {enabled: true, color: '#000000', blend: 1}\r\n         *             });\r\n         *\r\n         *     // Shadow color as a mixture between black and the line color, additionally set opacity\r\n         *     var li5 = board.create('line', [[-2, -3], [2, -2]], {strokeColor: 'blue',\r\n         *                 shadow: {enabled: true, color: '#000000', blend: 0.5, opacity: 0.5}\r\n         *             });\r\n         *\r\n         *     // Use different value for blur and offset [dx, dy]\r\n         *     var li6 = board.create('line', [[-2, -5], [2, -4]], {strokeColor: 'blue',\r\n         *                 shadow: {enabled: true, offset:[0, 25], blur: 6}\r\n         *             });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        shadow: {\r\n            enabled: false,\r\n            color: [0, 0, 0],\r\n            opacity: 1,\r\n            blur: 3,\r\n            blend: 0.1,\r\n            offset: [5, 5]\r\n        },\r\n\r\n        /**\r\n         * Snaps the element or its parents to the grid. Currently only relevant for points, circles,\r\n         * and lines. Points are snapped to grid directly, on circles and lines it's only the parent\r\n         * points that are snapped\r\n         * @type Boolean\r\n         * @default false\r\n         * @name JXG.GeometryElement#snapToGrid\r\n         */\r\n        snapToGrid: false,\r\n\r\n        /**\r\n         * The stroke color of the given geometry element.\r\n         * @type String\r\n         * @name JXG.GeometryElement#strokeColor\r\n         * @see JXG.GeometryElement#highlightStrokeColor\r\n         * @see JXG.GeometryElement#strokeWidth\r\n         * @see JXG.GeometryElement#strokeOpacity\r\n         * @see JXG.GeometryElement#highlightStrokeOpacity\r\n         * @default JXG.palette.blue\r\n         */\r\n        strokeColor: Color.palette.blue,\r\n\r\n        /**\r\n         * Opacity for element's stroke color.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#strokeOpacity\r\n         * @see JXG.GeometryElement#strokeColor\r\n         * @see JXG.GeometryElement#highlightStrokeColor\r\n         * @see JXG.GeometryElement#strokeWidth\r\n         * @see JXG.GeometryElement#highlightStrokeOpacity\r\n         * @default 1\r\n         */\r\n        strokeOpacity: 1,\r\n\r\n        /**\r\n         * Width of the element's stroke.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#strokeWidth\r\n         * @see JXG.GeometryElement#strokeColor\r\n         * @see JXG.GeometryElement#highlightStrokeColor\r\n         * @see JXG.GeometryElement#strokeOpacity\r\n         * @see JXG.GeometryElement#highlightStrokeOpacity\r\n         * @default 2\r\n         */\r\n        strokeWidth: 2,\r\n\r\n        /**\r\n         * Controls if an element can get the focus with the tab key.\r\n         * tabindex corresponds to the HTML attribute of the same name.\r\n         * See <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex\">description at MDN</a>.\r\n         * The additional value \"null\" completely disables focus of an element.\r\n         * The value will be ignored if keyboard control of the board is not enabled or\r\n         * if the element is not visible.\r\n         *\r\n         * @name JXG.GeometryElement#tabindex\r\n         * @type Number\r\n         * @default -1\r\n         * @see JXG.Board#keyboard\r\n         * @see JXG.GeometryElement#fixed\r\n         * @see JXG.GeometryElement#visible\r\n         */\r\n        tabindex: -1,\r\n\r\n        /**\r\n         * If true the element will be traced, i.e. on every movement the element will be copied\r\n         * to the background. Use {@link JXG.GeometryElement#clearTrace} to delete the trace elements.\r\n         *\r\n         * The calling of element.setAttribute({trace:false}) additionally\r\n         * deletes all traces of this element. By calling\r\n         * element.setAttribute({trace:'pause'})\r\n         * the removal of already existing traces can be prevented.\r\n         *\r\n         * The visual appearance of the trace can be influenced by {@link JXG.GeometryElement#traceAttributes}.\r\n         *\r\n         * @see JXG.GeometryElement#clearTrace\r\n         * @see JXG.GeometryElement#traces\r\n         * @see JXG.GeometryElement#numTraces\r\n         * @see JXG.GeometryElement#traceAttributes\r\n         * @type Boolean|String\r\n         * @default false\r\n         * @name JXG.GeometryElement#trace\r\n         */\r\n        trace: false,\r\n\r\n        /**\r\n         * Extra visual properties for traces of an element\r\n         * @type Object\r\n         * @see JXG.GeometryElement#trace\r\n         * @name JXG.GeometryElement#traceAttributes\r\n         * @default <tt>{}</tt>\r\n         *\r\n         * @example\r\n         * JXG.Options.elements.traceAttributes = {\r\n         *     size: 2\r\n         * };\r\n         *\r\n         * const board = JXG.JSXGraph.initBoard(BOARDID, {\r\n         *     boundingbox: [-4, 4, 4, -4],\r\n         *     keepaspectratio: true\r\n         * });\r\n         *\r\n         * var p = board.create('point', [0.0, 2.0], {\r\n         *     trace: true,\r\n         *     size: 10,\r\n         *     traceAttributes: {\r\n         *         color: 'black',\r\n         *         face: 'x'\r\n         *     }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXG504889cb-bb6f-4b65-85db-3ad555c08bcf\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *     JXG.Options.elements.traceAttributes = {\r\n         *         size: 2\r\n         *     };\r\n         *         var board = JXG.JSXGraph.initBoard('JXG504889cb-bb6f-4b65-85db-3ad555c08bcf',\r\n         *             {boundingbox: [-4, 4, 4, -4], axis: true, showcopyright: false, shownavigation: true, showClearTraces: true});\r\n         *\r\n         *     var p = board.create('point', [0.0, 2.0], {\r\n         *         trace: true,\r\n         *         size: 10,\r\n         *         traceAttributes: {\r\n         *             color: 'black',\r\n         *             face: 'x'\r\n         *         }\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        traceAttributes: {},\r\n\r\n        /**\r\n         * Transition duration (in milliseconds) for certain cahnges of properties like color and opacity.\r\n         * The properties can be set in the attribute transitionProperties\r\n         * Works in SVG renderer, only.\r\n         * @type Number\r\n         * @name JXG.GeometryElement#transitionDuration\r\n         * @see JXG.GeometryElement#transitionProperties\r\n         * @see JXG.GeometryElement#strokeColor\r\n         * @see JXG.GeometryElement#highlightStrokeColor\r\n         * @see JXG.GeometryElement#strokeOpacity\r\n         * @see JXG.GeometryElement#highlightStrokeOpacity\r\n         * @see JXG.GeometryElement#fillColor\r\n         * @see JXG.GeometryElement#highlightFillColor\r\n         * @see JXG.GeometryElement#fillOpacity\r\n         * @see JXG.GeometryElement#highlightFillOpacity\r\n         * @default 100 {@link JXG.Options.elements#transitionDuration}\r\n         */\r\n        transitionDuration: 100,\r\n\r\n        /**\r\n         * Properties which change smoothly in the time set in transitionDuration.\r\n         * Possible values are\r\n         * ['fill', 'fill-opacity', 'stroke', 'stroke-opacity', 'stroke-width', 'width', 'height', 'rx', 'ry']\r\n         * (and maybe more) for geometry elements and\r\n         * ['color', 'opacity', 'all'] for HTML texts.\r\n         *\r\n         * @type Array\r\n         * @name JXG.GeometryElement#transitionProperties\r\n         * @see JXG.GeometryElement#transitionDuration\r\n         *\r\n         *\r\n         * @example\r\n         * var p1 = board.create(\"point\", [0, 2], {\r\n         *     name: \"A\",\r\n         *     highlightStrokeWidth: 10,\r\n         *     transitionDuration: 1000,\r\n         *     transitionProperties: ['width', 'height', 'stroke-width',\r\n         *         'fill', 'fill-opacity', 'rx', 'ry', 'stroke', 'stroke-opacity'] });\r\n         *\r\n         * </pre><div id=\"JXGdf5230a1-5870-43db-b6ff-4d5b2f5b786b\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGdf5230a1-5870-43db-b6ff-4d5b2f5b786b',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var p1 = board.create(\"point\", [0, 2], {\r\n         *         name: \"A\",\r\n         *         highlightStrokeWidth: 20,\r\n         *         transitionDuration: 1000,\r\n         *         transitionProperties: ['width', 'height', 'stroke-width',\r\n         *             'fill', 'fill-opacity', 'rx', 'ry', 'stroke', 'stroke-opacity'] });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        transitionProperties: ['fill', 'fill-opacity', 'stroke', 'stroke-opacity', 'stroke-width'],\r\n\r\n        /**\r\n         * If false the element won't be visible on the board, otherwise it is shown.\r\n         * @type Boolean\r\n         * @name JXG.GeometryElement#visible\r\n         * @see JXG.GeometryElement#hideElement\r\n         * @see JXG.GeometryElement#showElement\r\n         * @default true\r\n         */\r\n        visible: true,\r\n\r\n        /**\r\n         * If true a label will display the element's name.\r\n         * Using this to suppress labels is more efficient than visible:false.\r\n         *\r\n         * @name JXG.GeometryElement#withLabel\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        withLabel: false,\r\n\r\n        /**\r\n         * Decides if the element should be ignored when using auto positioning\r\n         * for some label.\r\n         * @name JXG.GeometryElement#ignoreForLabelAutoposition\r\n         * @type boolean\r\n         * @default false\r\n         * @see Label#autoPosition\r\n         */\r\n        ignoreForLabelAutoposition: false\r\n\r\n        // close the meta tag\r\n        /**#@-*/\r\n    },\r\n\r\n    /*\r\n     *  Generic options used by {@link JXG.Ticks}\r\n     */\r\n    ticks: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * A function that expects two {@link JXG.Coords}, the first one representing the coordinates of the\r\n         * tick that is to be labeled, the second one the coordinates of the center (the tick with position 0).\r\n         * The third parameter is a null, number or a string. In the latter two cases, this value is taken.\r\n         * Returns a string.\r\n         *\r\n         * @type function\r\n         * @name Ticks#generateLabelText\r\n         *\r\n         * @example\r\n         * const board = JXG.JSXGraph.initBoard('jxgbox', { boundingBox: [-10, 10, 10, -10], axis: true,\r\n         *     defaultAxes: {\r\n         *         x: {\r\n         *                 margin: -4,\r\n         *                 ticks: {\r\n         *                     minTicksDistance: 0,\r\n         *                     minorTicks:4,\r\n         *                     ticksDistance: 3,\r\n         *                     scale: Math.PI,\r\n         *                     scaleSymbol: 'π',\r\n         *                     insertTicks: true\r\n         *                 }\r\n         *              },\r\n         *         y: {}\r\n         *     }\r\n         * });\r\n         *\r\n         * // Generate a logarithmic labelling of the vertical axis by defining the function generateLabelText directly.\r\n         * board.defaultAxes.y.ticks[0].generateLabelText = function (tick, zero) {\r\n         *     var value = Math.pow(10, Math.round(tick.usrCoords[2] - zero.usrCoords[2]));\r\n         *     return this.formatLabelText(value);\r\n         * };\r\n         *\r\n         * </pre><div id=\"JXG3d2203ee-a797-416a-a33c-409581fafdd7\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG3d2203ee-a797-416a-a33c-409581fafdd7',\r\n         *             {boundingbox: [-10, 10, 10, -10], axis: true, showcopyright: false, shownavigation: false,\r\n         *         defaultAxes: {\r\n         *             x: {\r\n         *                     margin: -4,\r\n         *                     ticks: {\r\n         *                         minTicksDistance: 0,\r\n         *                         minorTicks:4,\r\n         *                         ticksDistance: 3,\r\n         *                         scale: Math.PI,\r\n         *                         scaleSymbol: 'π',\r\n         *                         insertTicks: true\r\n         *                     }\r\n         *                  },\r\n         *             y: {}\r\n         *         }\r\n         *     });\r\n         *\r\n         *     // Generate a logarithmic labelling of the vertical axis.\r\n         *     board.defaultAxes.y.ticks[0].generateLabelText = function (tick, zero) {\r\n         *         var value = Math.pow(10, Math.round(tick.usrCoords[2] - zero.usrCoords[2]));\r\n         *         return this.formatLabelText(value);\r\n         *     };\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         * @example\r\n         * // Generate a logarithmic labelling of the vertical axis by setting the attribute generateLabelText.\r\n         * const board = JXG.JSXGraph.initBoard('jxgbox', {\r\n         *   boundingBox: [-10, 10, 10, -10], axis: true,\r\n         *   defaultAxes: {\r\n         *     x: {\r\n         *       margin: -4,\r\n         *       ticks: {\r\n         *         minTicksDistance: 0,\r\n         *         minorTicks: 4,\r\n         *         ticksDistance: 3,\r\n         *         scale: Math.PI,\r\n         *         scaleSymbol: 'π',\r\n         *         insertTicks: true\r\n         *       }\r\n         *     },\r\n         *     y: {\r\n         *       ticks: {\r\n         *         // Generate a logarithmic labelling of the vertical axis.\r\n         *         generateLabelText: function (tick, zero) {\r\n         *           var value = Math.pow(10, Math.round(tick.usrCoords[2] - zero.usrCoords[2]));\r\n         *           return this.formatLabelText(value);\r\n         *         }\r\n         *       }\r\n         *     }\r\n         *   }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXGa2873c8f-df8d-4a1d-ae15-5f1bdc55a0e9\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGa2873c8f-df8d-4a1d-ae15-5f1bdc55a0e9',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *\r\n         *         const board = JXG.JSXGraph.initBoard('jxgbox', {\r\n         *           boundingBox: [-10, 10, 10, -10], axis: true,\r\n         *           defaultAxes: {\r\n         *             x: {\r\n         *               margin: -4,\r\n         *               ticks: {\r\n         *                 minTicksDistance: 0,\r\n         *                 minorTicks: 4,\r\n         *                 ticksDistance: 3,\r\n         *                 scale: Math.PI,\r\n         *                 scaleSymbol: 'π',\r\n         *                 insertTicks: true\r\n         *               }\r\n         *             },\r\n         *             y: {\r\n         *               ticks: {\r\n         *                 // Generate a logarithmic labelling of the vertical axis.\r\n         *                 generateLabelText: function (tick, zero) {\r\n         *                   var value = Math.pow(10, Math.round(tick.usrCoords[2] - zero.usrCoords[2]));\r\n         *                   return this.formatLabelText(value);\r\n         *                 }\r\n         *               }\r\n         *             }\r\n         *           }\r\n         *         });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         *\r\n         */\r\n        generateLabelText: null,\r\n\r\n        /**\r\n         * A function that expects two {@link JXG.Coords}, the first one representing the coordinates of the\r\n         * tick that is to be labeled, the second one the coordinates of the center (the tick with position 0).\r\n         *\r\n         * @deprecated Use {@link JGX.Options@generateLabelText}\r\n         * @type function\r\n         * @name Ticks#generateLabelValue\r\n         */\r\n        generateLabelValue: null,\r\n\r\n        /**\r\n         * Draw labels yes/no\r\n         *\r\n         * @type Boolean\r\n         * @name Ticks#drawLabels\r\n         * @default false\r\n         */\r\n        drawLabels: false,\r\n\r\n        /**\r\n         * Attributes for the ticks labels.\r\n         *\r\n         * @name Ticks#label\r\n         * @type Object\r\n         * @default <pre>{\r\n         *   tabindex: null,\r\n         *   layer: 7, // line\r\n         *   highlight: false\r\n         *   }</pre>\r\n         *\r\n         */\r\n        label: {\r\n            tabindex: null,\r\n            layer: 7, // line\r\n            highlight: false,\r\n            autoPosition: false\r\n        },\r\n\r\n        /**\r\n        * Format tick labels that were going to have scientific notation\r\n        * like 5.00e+6 to look like 5•10⁶.\r\n        *\r\n        * @example\r\n        * var board = JXG.JSXGraph.initBoard(\"jxgbox\", {\r\n        *     boundingbox: [-500000, 500000, 500000, -500000],\r\n        *     axis: true,\r\n        *     defaultAxes: {\r\n        *         x: {\r\n        *             scalable: true,\r\n        *             ticks: {\r\n        *                 beautifulScientificTickLabels: true\r\n        *           },\r\n        *         },\r\n        *         y: {\r\n        *             scalable: true,\r\n        *             ticks: {\r\n        *                 beautifulScientificTickLabels: true\r\n        *           },\r\n        *         }\r\n        *     },\r\n        * });\r\n        *\r\n        * </pre><div id=\"JXGc1e46cd1-e025-4002-80aa-b450869fdaa2\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n        * <script type=\"text/javascript\">\r\n        *     (function() {\r\n        *     var board = JXG.JSXGraph.initBoard('JXGc1e46cd1-e025-4002-80aa-b450869fdaa2', {\r\n        *         boundingbox: [-500000, 500000, 500000, -500000],\r\n        *         showcopyright: false, shownavigation: false,\r\n        *         axis: true,\r\n        *         defaultAxes: {\r\n        *             x: {\r\n        *                 scalable: true,\r\n        *                 ticks: {\r\n        *                     beautifulScientificTickLabels: true\r\n        *               },\r\n        *             },\r\n        *             y: {\r\n        *                 scalable: true,\r\n        *                 ticks: {\r\n        *                     beautifulScientificTickLabels: true\r\n        *               },\r\n        *             }\r\n        *         },\r\n        *     });\r\n        *\r\n        *     })();\r\n        *\r\n        * </script><pre>\r\n        *\r\n        * @name Ticks#beautifulScientificTickLabels\r\n        * @type Boolean\r\n        * @default false\r\n        */\r\n        beautifulScientificTickLabels: false,\r\n\r\n        /**\r\n         * Use the unicode character 0x2212, i.e. the HTML entity &amp;minus; as minus sign.\r\n         * That is &minus;1 instead of -1.\r\n         *\r\n         * @type Boolean\r\n         * @name Ticks#useUnicodeMinus\r\n         * @default true\r\n         */\r\n        useUnicodeMinus: true,\r\n\r\n        /**\r\n         * Determine the position of the tick with value 0. 'left' means point1 of the line, 'right' means point2,\r\n         * and 'middle' is equivalent to the midpoint of the defining points. This attribute is ignored if the parent\r\n         * line is of type axis.\r\n         *\r\n         * @type String\r\n         * @name Ticks#anchor\r\n         * @default 'left'\r\n         *\r\n         * @example\r\n         * var li = board.create('segment', [[-4, -3], [4, 2]]);\r\n         * var t = board.create('ticks', [li], {\r\n         *     // drawZero: true,\r\n         *     anchor: 'left',\r\n         *     drawLabels: true,\r\n         *     minorTicks: 0,\r\n         *     label: {\r\n         *         anchorX: 'middle',\r\n         *         anchorY: 'top',\r\n         *         offset: [0, -5]\r\n         *     }\r\n         * });\r\n         *\r\n         *\r\n         * </pre><div id=\"JXG3dd23f77-a31d-4649-b0f0-7472722158d8\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG3dd23f77-a31d-4649-b0f0-7472722158d8',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var li = board.create('segment', [[-4, -3], [4, 2]]);\r\n         *     var t = board.create('ticks', [li], {\r\n         *         // drawZero: true,\r\n         *         anchor: 'left',\r\n         *         drawLabels: true,\r\n         *         minorTicks: 0,\r\n         *         label: {\r\n         *             anchorX: 'middle',\r\n         *             anchorY: 'top',\r\n         *             offset: [0, -5]\r\n         *         }\r\n         *     });\r\n         *\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         * var li = board.create('segment', [[-4, -3], [4, 2]]);\r\n         * var t = board.create('ticks', [li], {\r\n         *     drawZero: true,\r\n         *     anchor: 'middle',\r\n         *     drawLabels: true,\r\n         *     minorTicks: 0,\r\n         *     label: {\r\n         *         anchorX: 'middle',\r\n         *         anchorY: 'top',\r\n         *         offset: [0, -5]\r\n         *     }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXG430914fd-4e12-44de-b510-e3cc2fd473e0\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG430914fd-4e12-44de-b510-e3cc2fd473e0',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var li = board.create('segment', [[-4, -3], [4, 2]]);\r\n         *     var t = board.create('ticks', [li], {\r\n         *         drawZero: true,\r\n         *         anchor: 'middle',\r\n         *         drawLabels: true,\r\n         *         minorTicks: 0,\r\n         *         label: {\r\n         *             anchorX: 'middle',\r\n         *             anchorY: 'top',\r\n         *             offset: [0, -5]\r\n         *         }\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        anchor: 'left',\r\n\r\n        /**\r\n         * Draw the zero tick, that lies at line.point1?\r\n         *\r\n         * @type Boolean\r\n         * @name Ticks#drawZero\r\n         * @default false\r\n         *\r\n         * @example\r\n         * var li = board.create('segment', [[-4, 2], [4, 2]]);\r\n         * var t = board.create('ticks', [li], {\r\n         *     drawZero: false,\r\n         *     anchor: 'middle',\r\n         *     drawLabels: true,\r\n         *     minorTicks: 0,\r\n         *     label: {\r\n         *         anchorX: 'middle',\r\n         *         anchorY: 'top',\r\n         *         offset: [0, -5]\r\n         *     }\r\n         * });\r\n         *\r\n         * var li2 = board.create('segment', [[-4, -2], [4, -2]]);\r\n         * var t2 = board.create('ticks', [li2], {\r\n         *     drawZero: true,\r\n         *     anchor: 'middle',\r\n         *     drawLabels: true,\r\n         *     minorTicks: 0,\r\n         *     label: {\r\n         *         anchorX: 'middle',\r\n         *         anchorY: 'top',\r\n         *         offset: [0, -5]\r\n         *     }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXG91584dc4-0ca8-4b3e-841c-c877f2ccdcf1\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG91584dc4-0ca8-4b3e-841c-c877f2ccdcf1',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n         *     var li = board.create('segment', [[-4, 2], [4, 2]]);\r\n         *     var t = board.create('ticks', [li], {\r\n         *         drawZero: false,\r\n         *         anchor: 'middle',\r\n         *         drawLabels: true,\r\n         *         minorTicks: 0,\r\n         *         label: {\r\n         *             anchorX: 'middle',\r\n         *             anchorY: 'top',\r\n         *             offset: [0, -5]\r\n         *         }\r\n         *     });\r\n         *\r\n         *     var li2 = board.create('segment', [[-4, -2], [4, -2]]);\r\n         *     var t2 = board.create('ticks', [li2], {\r\n         *         drawZero: true,\r\n         *         anchor: 'middle',\r\n         *         drawLabels: true,\r\n         *         minorTicks: 0,\r\n         *         label: {\r\n         *             anchorX: 'middle',\r\n         *             anchorY: 'top',\r\n         *             offset: [0, -5]\r\n         *         }\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        drawZero: false,\r\n\r\n        /**\r\n         * Let JSXGraph determine the distance between ticks automatically.\r\n         * If <tt>true</tt>, the attribute <tt>ticksDistance</tt> is ignored.\r\n         * The distance between ticks is affected by the size of the board and\r\n         * the attribute <tt>minTicksDistance</tt> (in pixel).\r\n         *\r\n         * @type Boolean\r\n         * @name Ticks#insertTicks\r\n         * @see Ticks#ticksDistance\r\n         * @see Ticks#minTicksDistance\r\n         * @default false\r\n         * @example\r\n         * // Create an axis providing two coord pairs.\r\n         *   var p1 = board.create('point', [0, 0]);\r\n         *   var p2 = board.create('point', [50, 25]);\r\n         *   var l1 = board.create('line', [p1, p2]);\r\n         *   var t = board.create('ticks', [l1], {\r\n         *      insertTicks: true,\r\n         *      majorHeight: -1,\r\n         *      label: {\r\n         *          offset: [4, -9]\r\n         *      },\r\n         *      drawLabels: true\r\n         *  });\r\n         * </pre><div class=\"jxgbox\" id=\"JXG2f6fb842-40bd-4223-aa28-3e9369d2097f\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         * (function () {\r\n         *   var board = JXG.JSXGraph.initBoard('JXG2f6fb842-40bd-4223-aa28-3e9369d2097f', {\r\n         *     boundingbox: [-100, 70, 70, -100], axis: true, showcopyright: false, shownavigation: true});\r\n         *   var p1 = board.create('point', [0, 0]);\r\n         *   var p2 = board.create('point', [50, 25]);\r\n         *   var l1 = board.create('line', [p1, p2]);\r\n         *   var t = board.create('ticks', [l1], {insertTicks: true, majorHeight: -1, label: {offset: [4, -9]}, drawLabels: true});\r\n         * })();\r\n         * </script><pre>\r\n         */\r\n        insertTicks: false,\r\n\r\n        /**\r\n         * Minimum distance in pixel of equidistant ticks in case insertTicks==true.\r\n         * @name Ticks#minTicksDistance\r\n         * @type Number\r\n         * @default 10\r\n         * @see Ticks#insertTicks\r\n         */\r\n        minTicksDistance: 10,\r\n\r\n        /**\r\n         * Total height of a minor tick. If negative the full height of the board is taken.\r\n         *\r\n         * @type Number\r\n         * @name Ticks#minorHeight\r\n         * @default 4\r\n         */\r\n        minorHeight: 4,\r\n\r\n        /**\r\n         * Total height of a major tick. If negative the full height of the board is taken.\r\n         *\r\n         * @type Number\r\n         * @name Ticks#majorHeight\r\n         * @default 10\r\n         */\r\n        majorHeight: 10,\r\n\r\n        /**\r\n         * Decides in which direction minor ticks are visible. Possible values are either the constants\r\n         * 0=false or 1=true or a function returning 0 or 1.\r\n         *\r\n         * In case of [0,1] the tick is only visible to the right of the line. In case of\r\n         * [1,0] the tick is only visible to the left of the line.\r\n         *\r\n         * @type Array\r\n         * @name Ticks#tickEndings\r\n         * @see Ticks#majorTickEndings\r\n         * @default [1, 1]\r\n         */\r\n        tickEndings: [1, 1],\r\n\r\n        /**\r\n         * Decides in which direction major ticks are visible. Possible values are either the constants\r\n         * 0=false or 1=true or a function returning 0 or 1.\r\n         *\r\n         * In case of [0,1] the tick is only visible to the right of the line. In case of\r\n         * [1,0] the tick is only visible to the left of the line.\r\n         *\r\n        * @example\r\n        *         var board = JXG.JSXGraph.initBoard(\"jxgbox\", {\r\n        *             boundingbox: [-5, 5, 5, -5],\r\n        *             axis: true,\r\n        *             defaultAxes: {\r\n        *                 x: {\r\n        *                     ticks: {\r\n        *                         majorTickEndings: [1, 0],\r\n        *                         ignoreInfiniteTickEndings: false\r\n        *                     }\r\n        *                 },\r\n        *                 y: {\r\n        *                     ticks: {\r\n        *                         majorTickEndings: [0, 1],\r\n        *                         ignoreInfiniteTickEndings: false\r\n        *                     }\r\n        *                 }\r\n        *             }\r\n        *         });\r\n        *\r\n        *         var p = board.create('point', [1, 1]);\r\n        *         var l = board.create('line', [1, -1, 1]);\r\n        *\r\n        * </pre><div id=\"JXGf9ccb731-7a73-44d1-852e-f9c9c405a9d1\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n        * <script type=\"text/javascript\">\r\n        *     (function() {\r\n        *         var board = JXG.JSXGraph.initBoard('JXGf9ccb731-7a73-44d1-852e-f9c9c405a9d1',\r\n        *             {   showcopyright: false, shownavigation: false,\r\n        *                 boundingbox: [-5, 5, 5, -5],\r\n        *                 axis: true,\r\n        *                 defaultAxes: {\r\n        *                     x: {\r\n        *                         ticks: {\r\n        *                             majorTickEndings: [1, 0],\r\n        *                             ignoreInfiniteTickEndings: false\r\n        *                         }\r\n        *                     },\r\n        *                     y: {\r\n        *                         ticks: {\r\n        *                             majorTickEndings: [0, 1],\r\n        *                             ignoreInfiniteTickEndings: false\r\n        *                         }\r\n        *                     }\r\n        *                 }\r\n        *             });\r\n        *\r\n        *             var p = board.create('point', [1, 1]);\r\n        *             var l = board.create('line', [1, -1, 1]);\r\n        *\r\n        *     })();\r\n        *\r\n        * </script><pre>\r\n        *\r\n        * @type Array\r\n         * @name Ticks#majorTickEndings\r\n         * @see Ticks#tickEndings\r\n         * @see Ticks#ignoreInfiniteTickEndings\r\n         * @default [1, 1]\r\n         */\r\n        majorTickEndings: [1, 1],\r\n\r\n        /**\r\n         * If true, ignore the tick endings attribute for infinite (full height) ticks.\r\n         * This affects major and minor ticks.\r\n         *\r\n         * @type Boolean\r\n         * @name Ticks#ignoreInfiniteTickEndings\r\n         * @see Ticks#tickEndings\r\n         * @see Ticks#majorTickEndings\r\n         * @default true\r\n         */\r\n        ignoreInfiniteTickEndings: true,\r\n\r\n        /**\r\n         * The number of minor ticks between two major ticks.\r\n         * @type Number\r\n         * @name Ticks#minorTicks\r\n         * @default 4\r\n         */\r\n        minorTicks: 4,\r\n\r\n        /**\r\n         * By default, i.e. if ticksPerLabel==false, labels are generated for major ticks, only.\r\n         * If ticksPerLabel is set to a(n integer) number, this denotes the number of minor ticks\r\n         * between two labels.\r\n         *\r\n         * @type {Number|Boolean}\r\n         * @name Ticks#ticksPerLabel\r\n         * @default false\r\n         *\r\n         * @example\r\n         * const board = JXG.JSXGraph.initBoard('jxgbox', {\r\n         *     boundingbox: [-4, 4, 4, -4],\r\n         *     axis: true,\r\n         *     defaultAxes: {\r\n         *         x: {\r\n         *             ticks: {\r\n         *                 minorTicks: 7,\r\n         *                 ticksPerLabel: 4,\r\n         *                 minorHeight: 20,\r\n         *             }\r\n         *         },\r\n         *         y: {\r\n         *             ticks: {\r\n         *                 minorTicks: 3,\r\n         *                 ticksPerLabel: 2,\r\n         *                 minorHeight: 20\r\n         *             }\r\n         *         }\r\n         *     }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXGbc45a421-c867-4b0a-9b8d-2b2576020690\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGbc45a421-c867-4b0a-9b8d-2b2576020690',\r\n         *             {showcopyright: false, shownavigation: false,\r\n         *              boundingbox: [-4, 4, 4, -4],\r\n         *         axis: true,\r\n         *         defaultAxes: {\r\n         *             x: {\r\n         *                 ticks: {\r\n         *                     minorTicks: 7,\r\n         *                     ticksPerLabel: 4,\r\n         *                     minorHeight: 20,\r\n         *                 }\r\n         *             },\r\n         *             y: {\r\n         *                 ticks: {\r\n         *                     minorTicks: 3,\r\n         *                     ticksPerLabel: 2,\r\n         *                     minorHeight: 20\r\n         *                 }\r\n         *             }\r\n         *         }\r\n         *     });\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         */\r\n        ticksPerLabel: false,\r\n\r\n        /**\r\n         * Scale the ticks but not the tick labels.\r\n         * @type Number\r\n         * @default 1\r\n         * @name Ticks#scale\r\n         * @see Ticks#scaleSymbol\r\n         *\r\n         * @example\r\n         * const board = JXG.JSXGraph.initBoard('jxgbox', { boundingBox: [-10, 10, 10, -10], axis: true,\r\n         *     defaultAxes: {\r\n         *         x : {\r\n         *                 margin: -4,\r\n         *                 ticks: {\r\n         *                     minTicksDistance: 0,\r\n         *                     minorTicks:4,\r\n         *                     ticksDistance: 3,\r\n         *                     scale: Math.PI,\r\n         *                     scaleSymbol: 'π',\r\n         *                     insertTicks: true\r\n         *                 }\r\n         *              },\r\n         *         y : {}\r\n         *     }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXG23bfda5d-4a85-4469-a552-aa9b4cf62b4a\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG23bfda5d-4a85-4469-a552-aa9b4cf62b4a',\r\n         *             {boundingbox: [-10, 10, 10, -10], axis: true, showcopyright: false, shownavigation: false,\r\n         *         defaultAxes: {\r\n         *             x : {\r\n         *                     margin: -4,\r\n         *                     ticks: {\r\n         *                         minTicksDistance: 0,\r\n         *                         minorTicks:4,\r\n         *                         ticksDistance: 3,\r\n         *                         scale: Math.PI,\r\n         *                         scaleSymbol: 'π',\r\n         *                         insertTicks: true\r\n         *                     }\r\n         *                  },\r\n         *             y : {\r\n         *                  }\r\n         *         }\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         */\r\n        scale: 1,\r\n\r\n        /**\r\n         * A string that is appended to every tick, used to represent the scale\r\n         * factor given in {@link Ticks#scale}.\r\n         *\r\n         * @type String\r\n         * @default ''\r\n         * @name Ticks#scaleSymbol\r\n         * @see Ticks#scale\r\n         */\r\n        scaleSymbol: '',\r\n\r\n        /**\r\n         * User defined labels for special ticks. Instead of the i-th tick's position, the i-th string stored in this array\r\n         * is shown. If the number of strings in this array is less than the number of special ticks, the tick's position is\r\n         * shown as a fallback.\r\n         *\r\n         * @type Array\r\n         * @name Ticks#labels\r\n         * @default []\r\n         */\r\n        labels: [],\r\n\r\n        /**\r\n         * The maximum number of characters a tick label can use.\r\n         *\r\n         * @type Number\r\n         * @name Ticks#maxLabelLength\r\n         * @see Ticks#digits\r\n         * @default 5\r\n         */\r\n        maxLabelLength: 5,\r\n\r\n        /**\r\n         * If a label exceeds {@link Ticks#maxLabelLength} this determines the precision used to shorten the tick label.\r\n         * Deprecated! Replaced by the attribute <tt>digits</tt>.\r\n         *\r\n         * @type Number\r\n         * @name Ticks#precision\r\n         * @see Ticks#maxLabelLength\r\n         * @see Ticks#digits\r\n         * @deprecated\r\n         * @default 3\r\n         */\r\n        precision: 3,\r\n\r\n        /**\r\n         * If a label exceeds {@link Ticks#maxLabelLength} this determines the number of digits used to shorten the tick label.\r\n         *\r\n         * @type Number\r\n         * @name Ticks#digits\r\n         * @see Ticks#maxLabelLength\r\n         * @deprecated\r\n         * @default 3\r\n         */\r\n        digits: 3,\r\n\r\n        /**\r\n         * The default distance (in user coordinates, not  pixels) between two ticks. Please be aware that this value is overruled\r\n         * if {@link Ticks#insertTicks} is set to true. In case, {@link Ticks#insertTicks} is false, the maximum number of ticks\r\n         * is hard coded to be less than 2048.\r\n         *\r\n         * @type Number\r\n         * @name Ticks#ticksDistance\r\n         * @see Ticks#insertTicks\r\n         * @default 1\r\n         */\r\n        ticksDistance: 1,\r\n\r\n        /**\r\n         * Tick face for major ticks of finite length.  By default (face: '|') this is a straight line.\r\n         * Possible other values are '<' and '>'. These faces are used in\r\n         * {@link JXG.Hatch} for hatch marking parallel lines.\r\n         * @type String\r\n         * @name Ticks#face\r\n         * @see hatch\r\n         * @default '|'\r\n         * @example\r\n         *   var p1 = board.create('point', [0, 3]);\r\n         *   var p2 = board.create('point', [1, 3]);\r\n         *   var l1 = board.create('line', [p1, p2]);\r\n         *   var t = board.create('ticks', [l1], {ticksDistance: 2, face: '>', minorTicks: 0});\r\n         *\r\n         * </pre><div id=\"JXG950a568a-1264-4e3a-b61d-b6881feecf4b\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG950a568a-1264-4e3a-b61d-b6881feecf4b',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *       var p1 = board.create('point', [0, 3]);\r\n         *       var p2 = board.create('point', [1, 3]);\r\n         *       var l1 = board.create('line', [p1, p2]);\r\n         *       var t = board.create('ticks', [l1], {ticksDistance: 2, face: '>', minorTicks: 0});\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        face: '|',\r\n\r\n        strokeOpacity: 1,\r\n        strokeWidth: 1,\r\n        strokeColor: '#000000',\r\n        highlightStrokeColor: '#888888',\r\n        fillColor: 'none',\r\n        highlightFillColor: 'none',\r\n        visible: 'inherit',\r\n\r\n        /**\r\n         * Whether line boundaries should be included or not in the lower and upper bounds when\r\n         * creating ticks. In mathematical terms: if a segment considered as interval is open (includeBoundaries:false)\r\n         * or closed (includeBoundaries:true). In case of open interval, the interval is shortened by a small\r\n         * &epsilon;.\r\n         *\r\n         * @type Boolean\r\n         * @name Ticks#includeBoundaries\r\n         * @default false\r\n         *\r\n         * @example\r\n         * var li = board.create('segment', [[-4, 2], [4, 2]]);\r\n         * var t = board.create('ticks', [li], {\r\n         *     includeBoundaries: true,\r\n         *     drawZero: true,\r\n         *     anchor: 'middle',\r\n         *     drawLabels: true,\r\n         *     minorTicks: 0,\r\n         *     label: {\r\n         *         anchorX: 'middle',\r\n         *         anchorY: 'top',\r\n         *         offset: [0, -5]\r\n         *     }\r\n         * });\r\n         *\r\n         * var li2 = board.create('segment', [[-4, -2], [4, -2]]);\r\n         * var t2 = board.create('ticks', [li2], {\r\n         *     includeBoundaries: false,\r\n         *     drawZero: true,\r\n         *     anchor: 'middle',\r\n         *     drawLabels: true,\r\n         *     minorTicks: 0,\r\n         *     label: {\r\n         *         anchorX: 'middle',\r\n         *         anchorY: 'top',\r\n         *         offset: [0, -5]\r\n         *     }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXG08e79180-7c9a-4638-bb72-8aa7fd8a8b96\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG08e79180-7c9a-4638-bb72-8aa7fd8a8b96',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n         *     var li = board.create('segment', [[-4, 2], [4, 2]]);\r\n         *     var t = board.create('ticks', [li], {\r\n         *         includeBoundaries: true,\r\n         *         drawZero: true,\r\n         *         anchor: 'middle',\r\n         *         drawLabels: true,\r\n         *         minorTicks: 0,\r\n         *         label: {\r\n         *             anchorX: 'middle',\r\n         *             anchorY: 'top',\r\n         *             offset: [0, -5]\r\n         *         }\r\n         *     });\r\n         *\r\n         *     var li2 = board.create('segment', [[-4, -2], [4, -2]]);\r\n         *     var t2 = board.create('ticks', [li2], {\r\n         *         includeBoundaries: false,\r\n         *         drawZero: true,\r\n         *         anchor: 'middle',\r\n         *         drawLabels: true,\r\n         *         minorTicks: 0,\r\n         *         label: {\r\n         *             anchorX: 'middle',\r\n         *             anchorY: 'top',\r\n         *             offset: [0, -5]\r\n         *         }\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        includeBoundaries: false,\r\n\r\n        /**\r\n         * Set the ticks type.\r\n         * Possible values are 'linear' or 'polar'.\r\n         *\r\n         * @type String\r\n         * @name Ticks#type\r\n         * @default 'linear'\r\n         *\r\n         * @example\r\n         * var ax = board.create('axis', [[0,0], [1,0]], {\r\n         *              needsRegularUpdate: false,\r\n         *              ticks: {\r\n         *                      type: 'linear',\r\n         *                      majorHeight: 0\r\n         *                  }\r\n         *              });\r\n         * var ay = board.create('axis', [[0,0], [0,1]], {\r\n         *              ticks: {\r\n         *                      type: 'polar'\r\n         *                  }\r\n         *              });\r\n         *\r\n         * var p = board.create('point', [3, 2]);\r\n         *\r\n         * </pre><div id=\"JXG9ab0b50c-b486-4f95-9698-c0dd276155ff\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG9ab0b50c-b486-4f95-9698-c0dd276155ff',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n         *     var ax = board.create('axis', [[0,0], [1,0]], { needsRegularUpdate: false, ticks: { type: 'linear', majorHeight: 0}});\r\n         *     var ay = board.create('axis', [[0,0], [0,1]], { ticks: { type: 'polar'}});\r\n         *\r\n         *     var p = board.create('point', [3, 2]);\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        type: 'linear',\r\n\r\n        /**\r\n         * Internationalization support for ticks labels.\r\n         * @name intl\r\n         * @memberOf Ticks.prototype\r\n         * @default <pre>{\r\n         *    enabled: 'inherit',\r\n         *    options: {}\r\n         * }</pre>\r\n         * @see JXG.Board#intl\r\n         * @see Text#intl\r\n         *\r\n                  * @example\r\n         * // Here, locale is disabled in general, but enabled for the horizontal\r\n         * // axis and the infobox.\r\n         * const board = JXG.JSXGraph.initBoard(BOARDID, {\r\n         *     boundingbox: [-0.5, 0.5, 0.5, -0.5],\r\n         *     intl: {\r\n         *         enabled: false,\r\n         *         locale: 'de-DE'\r\n         *     },\r\n         *     keepaspectratio: true,\r\n         *     axis: true,\r\n         *     defaultAxes: {\r\n         *         x: {\r\n         *             ticks: {\r\n         *                 intl: {\r\n         *                         enabled: true,\r\n         *                         options: {\r\n         *                             style: 'unit',\r\n         *                             unit: 'kilometer-per-hour',\r\n         *                             unitDisplay: 'narrow'\r\n         *                         }\r\n         *                 }\r\n         *             }\r\n         *         },\r\n         *         y: {\r\n         *             ticks: {\r\n         *             }\r\n         *         }\r\n         *     },\r\n         *     infobox: {\r\n         *         fontSize: 12,\r\n         *         intl: {\r\n         *             enabled: true,\r\n         *             options: {\r\n         *                 minimumFractionDigits: 4,\r\n         *                 maximumFractionDigits: 5\r\n         *             }\r\n         *         }\r\n         *     }\r\n         * });\r\n         *\r\n         * var p = board.create('point', [0.1, 0.1], {});\r\n         *\r\n         * </pre><div id=\"JXG820b60ff-b453-4be9-a9d5-06c0342a9dbe\" class=\"jxgbox\" style=\"width: 600px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *     var board = JXG.JSXGraph.initBoard('JXG820b60ff-b453-4be9-a9d5-06c0342a9dbe', {\r\n         *         boundingbox: [-0.5, 0.5, 0.5, -0.5], showcopyright: false, shownavigation: false,\r\n         *         intl: {\r\n         *             enabled: false,\r\n         *             locale: 'de-DE'\r\n         *         },\r\n         *         keepaspectratio: true,\r\n         *         axis: true,\r\n         *         defaultAxes: {\r\n         *             x: {\r\n         *                 ticks: {\r\n         *                     intl: {\r\n         *                             enabled: true,\r\n         *                             options: {\r\n         *                                 style: 'unit',\r\n         *                                 unit: 'kilometer-per-hour',\r\n         *                                 unitDisplay: 'narrow'\r\n         *                             }\r\n         *                     }\r\n         *                 }\r\n         *             },\r\n         *             y: {\r\n         *                 ticks: {\r\n         *                 }\r\n         *             }\r\n         *         },\r\n         *         infobox: {\r\n         *             fontSize: 12,\r\n         *             intl: {\r\n         *                 enabled: true,\r\n         *                 options: {\r\n         *                     minimumFractionDigits: 4,\r\n         *                     maximumFractionDigits: 5\r\n         *                 }\r\n         *             }\r\n         *         }\r\n         *     });\r\n         *\r\n         *     var p = board.create('point', [0.1, 0.1], {});\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        intl: {\r\n            enabled: 'inherit',\r\n            options: {}\r\n        },\r\n\r\n        // TODO implementation and documentation\r\n        minorTicksInArrow: false,\r\n        majorTicksInArrow: true,\r\n        labelInArrow: true,\r\n        minorTicksInMargin: false,\r\n        majorTicksInMargin: true,\r\n        labelInMargin: true,\r\n\r\n        ignoreForLabelAutoposition: true\r\n\r\n        // close the meta tag\r\n        /**#@-*/\r\n    },\r\n\r\n    /*\r\n     *  Generic options used by {@link JXG.Hatch}\r\n     */\r\n    hatch: {\r\n        drawLabels: false,\r\n        drawZero: true,\r\n        majorHeight: 20,\r\n        anchor: 'middle',\r\n        face: '|',\r\n        strokeWidth: 2,\r\n        strokeColor: Color.palette.blue,\r\n        /**\r\n         * The default distance (in user coordinates, not  pixels) between two hatch symbols.\r\n         *\r\n         * @type Number\r\n         * @name Hatch#ticksDistance\r\n         * @default 0.2\r\n         */\r\n        ticksDistance: 0.2\r\n    },\r\n\r\n    /**\r\n     * Precision options, defining how close a pointer device (mouse, finger, pen) has to be\r\n     * to an object such that the object is highlighted or can be dragged.\r\n     * These values are board-wide and can be overwritten for individual elements by\r\n     * changing their precision attribute.\r\n     *\r\n     * The default values are\r\n     * <pre>\r\n     * JXG.Options.precision: {\r\n     *   touch: 30,\r\n     *   touchMax: 100,\r\n     *   mouse: 4,\r\n     *   pen: 4,\r\n     *   epsilon: 0.0001,\r\n     *   hasPoint: 4\r\n     * }\r\n     * </pre>\r\n     *\r\n     * @type Object\r\n     * @name JXG.Options#precision\r\n     * @see JXG.GeometryElement#precision\r\n     */\r\n    precision: {\r\n        touch: 30,\r\n        touchMax: 100,\r\n        mouse: 4,\r\n        pen: 4,\r\n        epsilon: 0.0001, // Unused\r\n        hasPoint: 4\r\n    },\r\n\r\n    /**\r\n     * Default ordering of the layers.\r\n     * The numbering starts from 0 and the highest layer number is numlayers-1.\r\n     *\r\n     * The default values are\r\n     * <pre>\r\n     * JXG.Options.layer: {\r\n     *   numlayers: 20, // only important in SVG\r\n     *   text: 9,\r\n     *   point: 9,\r\n     *   glider: 9,\r\n     *   arc: 8,\r\n     *   line: 7,\r\n     *   circle: 6,\r\n     *   curve: 5,\r\n     *   turtle: 5,\r\n     *   polygon: 3,\r\n     *   sector: 3,\r\n     *   angle: 3,\r\n     *   integral: 3,\r\n     *   axis: 2,\r\n     *   ticks: 2,\r\n     *   grid: 1,\r\n     *   image: 0,\r\n     *   trace: 0\r\n     * }\r\n     * </pre>\r\n     * @type Object\r\n     * @name JXG.Options#layer\r\n     */\r\n    layer: {\r\n        numlayers: 20, // only important in SVG\r\n        unused9: 19,\r\n        unused8: 18,\r\n        unused7: 17,\r\n        unused6: 16,\r\n        unused5: 15,\r\n        unused4: 14,\r\n        unused3: 13,\r\n        unused2: 12,\r\n        unused1: 11,\r\n        unused0: 10,\r\n        text: 9,\r\n        point: 9,\r\n        glider: 9,\r\n        arc: 8,\r\n        line: 7,\r\n        circle: 6,\r\n        curve: 5,\r\n        turtle: 5,\r\n        polygon: 3,\r\n        sector: 3,\r\n        angle: 3,\r\n        integral: 3,\r\n        axis: 2,\r\n        ticks: 2,\r\n        grid: 1,\r\n        image: 0,\r\n        trace: 0\r\n    },\r\n\r\n    /* special angle options */\r\n    angle: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        withLabel: true,\r\n\r\n        /**\r\n         * Radius of the sector, displaying the angle.\r\n         * The radius can be given as number (in user coordinates)\r\n         * or as string 'auto'. In the latter case, the angle\r\n         * is set to an value between 20 and 50 px.\r\n         *\r\n         * @type {Number|String}\r\n         * @name Angle#radius\r\n         * @default 'auto'\r\n         * @visprop\r\n         */\r\n        radius: 'auto',\r\n\r\n        /**\r\n         * Display type of the angle field. Possible values are\r\n         * 'sector' or 'sectordot' or 'square' or 'none'.\r\n         *\r\n         * @type String\r\n         * @default 'sector'\r\n         * @name Angle#type\r\n         * @visprop\r\n         */\r\n        type: 'sector',\r\n\r\n        /**\r\n         * Display type of the angle field in case of a right angle. Possible values are\r\n         * 'sector' or 'sectordot' or 'square' or 'none'.\r\n         *\r\n         * @type String\r\n         * @default square\r\n         * @name Angle#orthoType\r\n         * @see Angle#orthoSensitivity\r\n         * @visprop\r\n         */\r\n        orthoType: 'square',\r\n\r\n        /**\r\n         * Sensitivity (in degrees) to declare an angle as right angle.\r\n         * If the angle measure is inside this distance from a rigth angle, the orthoType\r\n         * of the angle is used for display.\r\n         *\r\n         * @type Number\r\n         * @default 1.0\r\n         * @name Angle#orthoSensitivity\r\n         * @see Angle#orthoType\r\n         * @visprop\r\n         */\r\n        orthoSensitivity: 1.0,\r\n\r\n        fillColor: Color.palette.orange,\r\n        highlightFillColor: Color.palette.orange,\r\n        strokeColor: Color.palette.orange,\r\n        // fillColor: '#ff7f00',\r\n        // highlightFillColor: '#ff7f00',\r\n        // strokeColor: '#ff7f00',\r\n\r\n        fillOpacity: 0.3,\r\n        highlightFillOpacity: 0.3,\r\n\r\n        /**\r\n         * @name Angle#radiuspoint\r\n         * @type Object\r\n         * @deprecated\r\n         */\r\n        radiuspoint: {\r\n            withLabel: false,\r\n            visible: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * @name Angle#pointsquare\r\n         * @type Object\r\n         * @deprecated\r\n         */\r\n        pointsquare: {\r\n            withLabel: false,\r\n            visible: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes of the dot point marking right angles.\r\n         * @name Angle#dot\r\n         * @type Object\r\n         * @default <tt>{face: 'o', size: 2}</tt>\r\n         */\r\n        dot: {\r\n            visible: false,\r\n            strokeColor: 'none',\r\n            fillColor: '#000000',\r\n            size: 2,\r\n            face: 'o',\r\n            withLabel: false,\r\n            name: ''\r\n        },\r\n\r\n        label: {\r\n            position: 'top',\r\n            offset: [0, 0],\r\n            strokeColor: Color.palette.blue\r\n        },\r\n\r\n        /**\r\n         * Attributes for sub-element arc. In general, the arc will run through the first point and\r\n         * thus will not have the same radius as the angle sector.\r\n         *\r\n         * @type Arc\r\n         * @name Angle#arc\r\n         * @default '{visible:false}'\r\n         */\r\n        arc: {\r\n            visible: false,\r\n            fillColor: 'none'\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special arc options */\r\n    arc: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Type of arc. Possible values are 'minor', 'major', and 'auto'.\r\n         *\r\n         * @type String\r\n         * @name Arc#selection\r\n         * @default 'auto'\r\n         */\r\n        selection: 'auto',\r\n\r\n        /**\r\n         * If <tt>true</tt>, moving the mouse over inner points triggers hasPoint.\r\n         *\r\n         * @see JXG.GeometryElement#hasPoint\r\n         * @name Arc#hasInnerPoints\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        hasInnerPoints: false,\r\n\r\n        label: {\r\n            anchorX: 'auto',\r\n            anchorY: 'auto'\r\n        },\r\n        firstArrow: false,\r\n        lastArrow: false,\r\n        fillColor: 'none',\r\n        highlightFillColor: 'none',\r\n        strokeColor: Color.palette.blue,\r\n        highlightStrokeColor: '#c3d9ff',\r\n\r\n        /**\r\n         * If true, there is a fourth parent point, i.e. the parents are [center, p1, p2, p3].\r\n         * p1 is still the radius point, p2 the angle point. The arc will be that part of the\r\n         * the circle with center 'center' which starts at p1, ends at the ray between center\r\n         * and p2, and passes p3.\r\n         * <p>\r\n         * This attribute is immutable (by purpose).\r\n         * This attribute is necessary for circumCircleArcs\r\n         *\r\n         * @type Boolean\r\n         * @name Arc#useDirection\r\n         * @default false\r\n         * @private\r\n         */\r\n        useDirection: false,\r\n\r\n        /**\r\n         * Attributes for center point.\r\n         *\r\n         * @type Point\r\n         * @name Arc#center\r\n         * @default {}\r\n         */\r\n        center: {\r\n        },\r\n\r\n        /**\r\n         * Attributes for radius point.\r\n         *\r\n         * @type Point\r\n         * @name Arc#radiusPoint\r\n         * @default {}\r\n         */\r\n        radiusPoint: {\r\n        },\r\n\r\n        /**\r\n         * Attributes for angle point.\r\n         *\r\n         * @type Point\r\n         * @name Arc#anglePoint\r\n         * @default {}\r\n         */\r\n        anglePoint: {\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special arrow options */\r\n    arrow: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        firstArrow: false,\r\n\r\n        lastArrow: {\r\n            type: 1,\r\n            highlightSize: 6,\r\n            size: 6\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special arrowparallel options */\r\n    arrowparallel: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        firstArrow: false,\r\n\r\n        lastArrow: {\r\n            type: 1,\r\n            highlightSize: 6,\r\n            size: 6\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special axis options */\r\n    axis: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        name: '',                            // By default, do not generate names for axes.\r\n        needsRegularUpdate: false,           // Axes only updated after zooming and moving of the origin.\r\n        strokeWidth: 1,\r\n        lastArrow: {\r\n            type: 1,\r\n            highlightSize: 8,\r\n            size: 8\r\n        },\r\n        strokeColor: '#666666',\r\n        highlightStrokeWidth: 1,\r\n        highlightStrokeColor: '#888888',\r\n\r\n        /**\r\n         * Is used to define the behavior of the axis.\r\n         * Settings in this attribute only have an effect if the axis is exactly horizontal or vertical.\r\n         * Possible values are:\r\n         * <ul>\r\n         *     <li><tt>'static'</tt>: Standard behavior of the axes as know in JSXGraph.\r\n         *     <li><tt>'fixed'</tt>: The axis is placed in a fixed position. Depending on the attribute <tt>anchor</tt>, it is positioned to the right or left of the edge of the board as seen from the axis with a distance defined in <tt>distanceBoarder</tt>. The axis will stay at the given position, when the user navigates through the board.\r\n         *     <li><tt>'sticky'</tt>: This mixes the two settings <tt>static</tt> and <tt>fixed</tt>. When the user navigates in the board, the axis remains in the visible area (taking into account <tt>anchor</tt> and <tt>anchorDist</tt>). If the axis itself is in the visible area, the axis can be moved by navigation.\r\n         * </ul>\r\n         *\r\n         * @type {String}\r\n         * @name Axis#position\r\n         * @default 'static'\r\n         * @see Axis#anchor\r\n         * @see Axis#anchorDist\r\n         *\r\n         * @example // Use navigation to see effect.\r\n         *  var axis1, axis2, circle;\r\n         *\r\n         *  board.create('axis', [[0,0],[1,0]],{\r\n         *      position: 'fixed',\r\n         *      anchor: 'right',\r\n         *      anchorDist: '0.1fr'\r\n         *  });\r\n         *\r\n         *  board.create('axis', [[0,0],[0,1]], {\r\n         *      position: 'fixed',\r\n         *      anchor: 'left',\r\n         *      anchorDist: 1\r\n         *  });\r\n         *\r\n         * </pre><div id=\"JXG6dff2f81-65ce-46a3-bea0-8ce25cc1cb4a\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *      var board = JXG.JSXGraph.initBoard('JXG6dff2f81-65ce-46a3-bea0-8ce25cc1cb4a',\r\n         *             {boundingbox: [-1, 10, 10,-1], axis: false, showcopyright: false, shownavigation: true});\r\n         *\r\n         *      board.create('axis', [[0,0],[1,0]],{\r\n         *          position: 'fixed',\r\n         *          anchor: 'right',\r\n         *          anchorDist: '0.1fr'\r\n         *      });\r\n         *\r\n         *      board.create('axis', [[0,0],[0,1]], {\r\n         *          position: 'fixed',\r\n         *          anchor: 'left',\r\n         *          anchorDist: 1\r\n         *      });\r\n         *\r\n         *      board.create('circle', [[5,5], 2.5]);\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @example // Use navigation to see effect.\r\n         *      board.create('axis', [[0,0],[1,0]],{\r\n         *          position: 'sticky',\r\n         *          anchor: 'right',\r\n         *          anchorDist: '0.2fr'\r\n         *      });\r\n         *\r\n         *      board.create('axis', [[0,0],[0,1]], {\r\n         *          position: 'sticky',\r\n         *          anchor: 'right left',\r\n         *          anchorDist: '75px'\r\n         *      });\r\n         *\r\n         * </pre><div id=\"JXG42a90935-80aa-4a6b-8adf-279deef84485\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *          var board = JXG.JSXGraph.initBoard('JXG42a90935-80aa-4a6b-8adf-279deef84485',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: true});\r\n         *          board.create('axis', [[0,0],[1,0]],{\r\n         *              position: 'sticky',\r\n         *              anchor: 'right',\r\n         *              anchorDist: '0.2fr'\r\n         *          });\r\n         *\r\n         *          board.create('axis', [[0,0],[0,1]], {\r\n         *              position: 'sticky',\r\n         *              anchor: 'right left',\r\n         *              anchorDist: '75px'\r\n         *          });\r\n         *\r\n         *          board.create('functiongraph', [function(x){ return 1/(x-5) + 2;}]);\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        position: 'static',\r\n\r\n        /**\r\n         * Position is used in cases: <tt>position=='sticky'</tt> or <tt>position=='fixed'</tt>.\r\n         * Possible values are <tt>'right'</tt>, <tt>'left'</tt>, <tt>'right left'</tt>. Left and right indicate the side as seen from the axis.\r\n         * It is used in combination with the attribute position to decide on which side of the board the axis should stick or be fixed.\r\n         *\r\n         * @type {String}\r\n         * @name Axis#anchor\r\n         * @default ''\r\n         * @example\r\n         *  board.create('axis', [[0,0],[0,1]],{\r\n         *      position: 'fixed',\r\n         *      anchor: 'left',\r\n         *      anchorDist: 2,\r\n         *      strokeColor : 'green',\r\n         *      ticks: {\r\n         *          majorHeight: 7,\r\n         *          drawZero: true,\r\n         *      }\r\n         *  });\r\n         *\r\n         *  board.create('axis', [[0,0],[0,1]], {\r\n         *      position: 'fixed',\r\n         *      anchor: 'right',\r\n         *      anchorDist: 2,\r\n         *      strokeColor : 'blue',\r\n         *      ticks: {\r\n         *          majorHeight: 7,\r\n         *          drawZero: true,\r\n         *      }\r\n         *  });\r\n         *\r\n         *  board.create('axis', [[0,0],[0,-1]], {\r\n         *      position: 'fixed',\r\n         *      anchor: 'left',\r\n         *      anchorDist: 4,\r\n         *      strokeColor : 'red',\r\n         *      ticks:{\r\n         *          majorHeight: 7,\r\n         *          drawZero: true,\r\n         *      }\r\n         *  });\r\n         *\r\n         * </pre><div id=\"JXG11448b49-02b4-48d4-b0e0-8f06a94e909c\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *      var board = JXG.JSXGraph.initBoard('JXG11448b49-02b4-48d4-b0e0-8f06a94e909c',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: true});\r\n         *\r\n         *      board.create('axis', [[0,0],[0,1]],{\r\n         *          position: 'fixed',\r\n         *          anchor: 'left',\r\n         *          anchorDist: 4,\r\n         *          strokeColor : 'green',\r\n         *          ticks: {\r\n         *              majorHeight: 7,\r\n         *              drawZero: true,\r\n         *          }\r\n         *      });\r\n         *\r\n         *      board.create('axis', [[0,0],[0,1]], {\r\n         *          position: 'fixed',\r\n         *          anchor: 'right',\r\n         *          anchorDist: 2,\r\n         *          strokeColor : 'blue',\r\n         *          ticks: {\r\n         *              majorHeight: 7,\r\n         *              drawZero: true,\r\n         *          }\r\n         *      });\r\n         *\r\n         *      board.create('axis', [[0,0],[0,-1]], {\r\n         *          position: 'fixed',\r\n         *          anchor: 'left',\r\n         *          anchorDist: 4,\r\n         *          strokeColor : 'red',\r\n         *          ticks:{\r\n         *              majorHeight: 7,\r\n         *              drawZero: true,\r\n         *          }\r\n         *      });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         */\r\n        anchor: '',\r\n\r\n        /**\r\n         * Used to define at which distance to the edge of the board the axis should stick or be fixed.\r\n         * This only has an effect if <tt>position=='sticky'</tt> or <tt>position=='fixed'</tt>.\r\n         * There are the following possibilities:\r\n         * <ul>\r\n         *     <li>Numbers or strings which are numbers (e.g. '10') are interpreted as usrCoords.\r\n         *     <li>Strings with the unit 'px' are interpreted as screen pixels.\r\n         *     <li>Strings with the unit '%' or 'fr' are interpreted as a ratio to the width/height of the board. (e.g. 50% = 0.5fr)\r\n         * </ul>\r\n         *\r\n         * @type {Number|String}\r\n         * @name Axis#anchorDist\r\n         * @default '10%'\r\n         */\r\n        anchorDist: '10%',\r\n\r\n        /**\r\n         * If set to true, the tick labels of the axis are automatically positioned in the narrower area between the axis and the side of the board.\r\n         * Settings in this attribute only have an effect if the axis is exactly horizontal or vertical.\r\n         * This option overrides <tt>offset</tt>, <tt>anchorX</tt> and <tt>anchorY</tt> of axis tick labels.\r\n         *\r\n         * @type {Boolean}\r\n         * @name Axis#ticksAutoPos\r\n         * @default false\r\n         * @example\r\n         * // Navigate to see an effect.\r\n         * board.create('axis', [[0, 0], [1, 0]], {\r\n         *     position: 'sticky',\r\n         *     anchor: 'left right',\r\n         *     anchorDist: '0.1',\r\n         *     ticksAutoPos: true,\r\n         * });\r\n         *\r\n         * board.create('axis', [[0, 0], [0, 1]], {\r\n         *     position: 'sticky',\r\n         *     anchor: 'left right',\r\n         *     anchorDist: '0.1',\r\n         *     ticksAutoPos: true,\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXG557c9b5d-e1bd-4d3b-8362-ff7a863255f3\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG557c9b5d-e1bd-4d3b-8362-ff7a863255f3',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n         *\r\n         *     board.create('axis', [[0, 0], [1, 0]], {\r\n         *         position: 'sticky',\r\n         *         anchor: 'left right',\r\n         *         anchorDist: '0.1',\r\n         *         ticksAutoPos: true,\r\n         *     });\r\n         *\r\n         *     board.create('axis', [[0, 0], [0, 1]], {\r\n         *         position: 'sticky',\r\n         *         anchor: 'left right',\r\n         *         anchorDist: '0.1',\r\n         *         ticksAutoPos: true,\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         */\r\n        ticksAutoPos: false,\r\n\r\n        /**\r\n         * Defines, when <tt>ticksAutoPos</tt> takes effect.\r\n         * There are the following possibilities:\r\n         * <ul>\r\n         *     <li>Numbers or strings which are numbers (e.g. '10') are interpreted as usrCoords.\r\n         *     <li>Strings with the unit 'px' are interpreted as screen pixels.\r\n         *     <li>Strings with the unit '%' or 'fr' are interpreted as a ratio to the width/height of the board. (e.g. 50% = 0.5fr)\r\n         * </ul>\r\n         *\r\n         * @type {Number|String}\r\n         * @name Axis#ticksAutoPosThreshold\r\n         * @default '5%'\r\n         */\r\n        ticksAutoPosThreshold: '5%',\r\n\r\n        /**\r\n         * Show / hide ticks.\r\n         *\r\n         * Deprecated. Suggested alternative is \"ticks: {visible: false}\"\r\n         *\r\n         * @type Boolean\r\n         * @name Axis#withTicks\r\n         * @default true\r\n         * @deprecated\r\n         */\r\n        withTicks: true,\r\n        straightFirst: true,\r\n        straightLast: true,\r\n        margin: -4,\r\n        withLabel: false,\r\n        scalable: false,\r\n\r\n        /**\r\n         * Attributes for ticks of the axis.\r\n         *\r\n         * @type Ticks\r\n         * @name Axis#ticks\r\n         */\r\n        ticks: {\r\n            label: {\r\n                offset: [4, -12 + 3],     // This seems to be a good offset for 12 point fonts\r\n                parse: false,\r\n                needsRegularUpdate: false,\r\n                display: 'internal',\r\n                visible: 'inherit',\r\n                layer: 9\r\n            },\r\n            visible: 'inherit',\r\n            needsRegularUpdate: false,\r\n            strokeWidth: 1,\r\n            strokeColor: '#666666',\r\n            highlightStrokeColor: '#888888',\r\n            drawLabels: true,\r\n            drawZero: false,\r\n            insertTicks: true,\r\n            minTicksDistance: 5,\r\n            minorHeight: 10,          // if <0: full width and height\r\n            majorHeight: -1,          // if <0: full width and height\r\n            tickEndings: [0, 1],\r\n            majorTickEndings: [1, 1],\r\n            minorTicks: 4,\r\n            ticksDistance: 1,         // TODO doc\r\n            strokeOpacity: 0.25\r\n        },\r\n\r\n        /**\r\n         * Attributes for first point the axis.\r\n         *\r\n         * @type Point\r\n         * @name Axis#point1\r\n         */\r\n        point1: {                  // Default values for point1 if created by line\r\n            needsRegularUpdate: false,\r\n            visible: false\r\n        },\r\n\r\n        /**\r\n         * Attributes for second point the axis.\r\n         *\r\n         * @type Point\r\n         * @name Axis#point2\r\n         */\r\n        point2: {                  // Default values for point2 if created by line\r\n            needsRegularUpdate: false,\r\n            visible: false\r\n        },\r\n\r\n        tabindex: -1,\r\n\r\n        /**\r\n         * Attributes for the axis label.\r\n         *\r\n         * @type Label\r\n         * @name Axis#label\r\n         */\r\n        label: {\r\n            position: 'lft',\r\n            offset: [10, 10]\r\n        },\r\n\r\n        ignoreForLabelAutoposition: true\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for angle bisector of 3 points */\r\n    bisector: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        strokeColor: '#000000', // Bisector line\r\n\r\n        /**\r\n         * Attributes for the helper point of the bisector.\r\n         *\r\n         * @type Point\r\n         * @name Bisector#point\r\n         */\r\n        point: {               // Bisector point\r\n            visible: false,\r\n            fixed: false,\r\n            withLabel: false,\r\n            name: ''\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for the 2 bisectors of 2 lines */\r\n    bisectorlines: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Attributes for first line.\r\n         *\r\n         * @type Line\r\n         * @name Bisectorlines#line1\r\n         */\r\n        line1: {               //\r\n            strokeColor: '#000000'\r\n        },\r\n\r\n        /**\r\n         * Attributes for second line.\r\n         *\r\n         * @type Line\r\n         * @name Bisectorlines#line2\r\n         */\r\n        line2: {               //\r\n            strokeColor: '#000000'\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for boxplot curves */\r\n    boxplot: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         *  Direction of the box plot: 'vertical' or 'horizontal'\r\n         *\r\n         * @type String\r\n         * @name Boxplot#dir\r\n         * @default 'vertical'\r\n         */\r\n        dir: 'vertical',\r\n\r\n        /**\r\n         * Relative width of the maximum and minimum quantile\r\n         *\r\n         * @type Number\r\n         * @name Boxplot#smallWidth\r\n         * @default 0.5\r\n         */\r\n        smallWidth: 0.5,\r\n\r\n        strokeWidth: 2,\r\n        strokeColor: Color.palette.blue,\r\n        fillColor: Color.palette.blue,\r\n        fillOpacity: 0.2,\r\n        highlightStrokeWidth: 2,\r\n        highlightStrokeColor: Color.palette.blue,\r\n        highlightFillColor: Color.palette.blue,\r\n        highlightFillOpacity: 0.1\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special button options */\r\n    button: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Control the attribute \"disabled\" of the HTML button.\r\n         *\r\n         * @name disabled\r\n         * @memberOf Button.prototype\r\n         *\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        disabled: false,\r\n\r\n        display: 'html'\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special cardinal spline options */\r\n    cardinalspline: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Controls if the data points of the cardinal spline when given as\r\n         * arrays should be converted into {@link JXG.Points}.\r\n         *\r\n         * @name createPoints\r\n         * @memberOf Cardinalspline.prototype\r\n         *\r\n         * @see Cardinalspline#points\r\n         *\r\n         * @type Boolean\r\n         * @default true\r\n         */\r\n        createPoints: true,\r\n\r\n        /**\r\n         * If set to true, the supplied coordinates are interpreted as\r\n         * [[x_0, y_0], [x_1, y_1], p, ...].\r\n         * Otherwise, if the data consists of two arrays of equal length,\r\n         * it is interpreted as\r\n         * [[x_o x_1, ..., x_n], [y_0, y_1, ..., y_n]]\r\n         *\r\n         * @name isArrayOfCoordinates\r\n         * @memberOf Cardinalspline.prototype\r\n         * @type Boolean\r\n         * @default true\r\n         */\r\n        isArrayOfCoordinates: true,\r\n\r\n        /**\r\n         * Attributes for the points generated by Cardinalspline in cases\r\n         * {@link createPoints} is set to true\r\n         *\r\n         * @name points\r\n         * @memberOf Cardinalspline.prototype\r\n         *\r\n         * @see Cardinalspline#createPoints\r\n         * @type Object\r\n         */\r\n        points: {\r\n            strokeOpacity: 0.05,\r\n            fillOpacity: 0.05,\r\n            highlightStrokeOpacity: 1.0,\r\n            highlightFillOpacity: 1.0,\r\n            withLabel: false,\r\n            name: '',\r\n            fixed: false\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special chart options */\r\n    chart: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        chartStyle: 'line',\r\n        colors: ['#B02B2C', '#3F4C6B', '#C79810', '#D15600', '#FFFF88', '#c3d9ff', '#4096EE', '#008C00'],\r\n        highlightcolors: null,\r\n        fillcolor: null,\r\n        highlightonsector: false,\r\n        highlightbysize: false,\r\n\r\n        fillOpacity: 0.6,\r\n        withLines: false,\r\n\r\n        label: {\r\n        }\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special html slider options */\r\n    checkbox: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Control the attribute \"disabled\" of the HTML checkbox.\r\n         *\r\n         * @name disabled\r\n         * @memberOf Checkbox.prototype\r\n         *\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        disabled: false,\r\n\r\n        /**\r\n         * Control the attribute \"checked\" of the HTML checkbox.\r\n         *\r\n         * @name checked\r\n         * @memberOf Checkbox.prototype\r\n         *\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        checked: false,\r\n\r\n        display: 'html'\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /*special circle options */\r\n    circle: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * If <tt>true</tt>, moving the mouse over inner points triggers hasPoint.\r\n         *\r\n         * @see JXG.GeometryElement#hasPoint\r\n         * @name Circle#hasInnerPoints\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        hasInnerPoints: false,\r\n\r\n        fillColor: 'none',\r\n        highlightFillColor: 'none',\r\n        strokeColor: Color.palette.blue,\r\n        highlightStrokeColor: '#c3d9ff',\r\n\r\n        /**\r\n         * Attributes for center point.\r\n         *\r\n         * @type Point\r\n         * @name Circle#center\r\n         */\r\n        center: {\r\n            visible: false,\r\n            withLabel: false,\r\n            fixed: false,\r\n\r\n            fillColor: Color.palette.red,\r\n            strokeColor: Color.palette.red,\r\n            highlightFillColor: '#c3d9ff',\r\n            highlightStrokeColor: '#c3d9ff',\r\n            layer: 9,\r\n\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for center point.\r\n         *\r\n         * @type Point\r\n         * @name Circle#point2\r\n         */\r\n        point2: {\r\n            fillColor: Color.palette.red,\r\n            strokeColor: Color.palette.red,\r\n            highlightFillColor: '#c3d9ff',\r\n            highlightStrokeColor: '#c3d9ff',\r\n            layer: 9,\r\n\r\n            visible: false,\r\n            withLabel: false,\r\n            fixed: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for circle label.\r\n         *\r\n         * @type Label\r\n         * @name Circle#label\r\n         */\r\n        label: {\r\n            position: 'urt'\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for circumcircle of 3 points */\r\n    circumcircle: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        fillColor: 'none',\r\n        highlightFillColor: 'none',\r\n        strokeColor: Color.palette.blue,\r\n        highlightStrokeColor: '#c3d9ff',\r\n\r\n        /**\r\n         * Attributes for center point.\r\n         *\r\n         * @type Point\r\n         * @name Circumcircle#center\r\n         */\r\n        center: {               // center point\r\n            visible: false,\r\n            fixed: false,\r\n            withLabel: false,\r\n            fillColor: Color.palette.red,\r\n            strokeColor: Color.palette.red,\r\n            highlightFillColor: '#c3d9ff',\r\n            highlightStrokeColor: '#c3d9ff',\r\n            name: ''\r\n        }\r\n        /**#@-*/\r\n    },\r\n\r\n    circumcirclearc: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        fillColor: 'none',\r\n        highlightFillColor: 'none',\r\n        strokeColor: Color.palette.blue,\r\n        highlightStrokeColor: '#c3d9ff',\r\n        useDirection: true,\r\n\r\n        /**\r\n         * Attributes for center point.\r\n         *\r\n         * @type Point\r\n         * @name CircumcircleArc#center\r\n         */\r\n        center: {\r\n            visible: false,\r\n            withLabel: false,\r\n            fixed: false,\r\n            name: ''\r\n        }\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for circumcircle sector of 3 points */\r\n    circumcirclesector: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        useDirection: true,\r\n        fillColor: Color.palette.yellow,\r\n        highlightFillColor: Color.palette.yellow,\r\n        fillOpacity: 0.3,\r\n        highlightFillOpacity: 0.3,\r\n        strokeColor: Color.palette.blue,\r\n        highlightStrokeColor: '#c3d9ff',\r\n\r\n        /**\r\n         * Attributes for center point.\r\n         *\r\n         * @type Point\r\n         * @name Circle#point\r\n         */\r\n        point: {\r\n            visible: false,\r\n            fixed: false,\r\n            withLabel: false,\r\n            name: ''\r\n        }\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for comb */\r\n    comb: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Frequency of comb elements.\r\n         *\r\n         * @type Number\r\n         * @name Comb#frequency\r\n         * @default 0.2\r\n         */\r\n        frequency: 0.2,\r\n\r\n        /**\r\n         * Width of the comb.\r\n         *\r\n         * @type Number\r\n         * @name Comb#width\r\n         * @default 0.4\r\n         */\r\n        width: 0.4,\r\n\r\n        /**\r\n         * Angle - given in radians - under which comb elements are positioned.\r\n         *\r\n         * @type Number\r\n         * @name Comb#angle\r\n         * @default Math.PI / 3 (i.e. &pi; /3  or 60^° degrees)\r\n         */\r\n        angle: Math.PI / 3,\r\n\r\n        /**\r\n         * Should the comb go right to left instead of left to right.\r\n         *\r\n         * @type Boolean\r\n         * @name Comb#reverse\r\n         * @default false\r\n         */\r\n        reverse: false,\r\n\r\n        /**\r\n         * Attributes for first defining point of the comb.\r\n         *\r\n         * @type Point\r\n         * @name Comb#point1\r\n         */\r\n        point1: {\r\n            visible: false,\r\n            withLabel: false,\r\n            fixed: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for second defining point of the comb.\r\n         *\r\n         * @type Point\r\n         * @name Comb#point2\r\n         */\r\n        point2: {\r\n            visible: false,\r\n            withLabel: false,\r\n            fixed: false,\r\n            name: ''\r\n        },\r\n\r\n        // /**\r\n        //  * Attributes for the curve displaying the comb.\r\n        //  *\r\n        //  * @type Curve\r\n        //  * @name Comb#curve\r\n        //  */\r\n        // curve: {\r\n        //     strokeWidth: 1,\r\n        //     strokeColor: '#0000ff',\r\n        //     fillColor: 'none'\r\n        // },\r\n        strokeWidth: 1,\r\n        strokeColor: '#0000ff',\r\n        fillColor: 'none'\r\n    },\r\n\r\n    /* special conic options */\r\n    conic: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        fillColor: 'none',\r\n        highlightFillColor: 'none',\r\n        strokeColor: Color.palette.blue,\r\n        highlightStrokeColor: '#c3d9ff',\r\n\r\n        /**\r\n         * Attributes for foci points.\r\n         *\r\n         * @type Point\r\n         * @name Conic#foci\r\n         */\r\n        foci: {\r\n            // points\r\n            fixed: false,\r\n            visible: false,\r\n            withLabel: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for center point.\r\n         *\r\n         * @type Point\r\n         * @name Conic#center\r\n         */\r\n        center: {\r\n            visible: false,\r\n            withLabel: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for five points defining the conic, if some of them are given as coordinates.\r\n         *\r\n         * @type Point\r\n         * @name Conic#point\r\n         */\r\n        point: {\r\n            withLabel: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for parabola line in case the line is given by two\r\n         * points or coordinate pairs.\r\n         *\r\n         * @type Line\r\n         * @name Conic#line\r\n         */\r\n        line: {\r\n            visible: false\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special curve options */\r\n    curve: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        strokeWidth: 1,\r\n        strokeColor: Color.palette.blue,\r\n        fillColor: 'none',\r\n        fixed: true,\r\n\r\n        /**\r\n         * The curveType is set in {@link JXG.Curve#generateTerm} and used in {@link JXG.Curve#updateCurve}.\r\n         * Possible values are <ul>\r\n         * <li>'none'</li>\r\n         * <li>'plot': Data plot</li>\r\n         * <li>'parameter': we can not distinguish function graphs and parameter curves</li>\r\n         * <li>'functiongraph': function graph</li>\r\n         * <li>'polar'</li>\r\n         * <li>'implicit' (not yet)</li></ul>\r\n         * Only parameter and plot are set directly. Polar is set with {@link JXG.GeometryElement#setAttribute} only.\r\n         * @name Curve#curveType\r\n         * @type String\r\n         * @default null\r\n         */\r\n        curveType: null,\r\n\r\n        /**\r\n         * If true use a recursive bisection algorithm.\r\n         * It is slower, but usually the result is better. It tries to detect jumps\r\n         * and singularities.\r\n         *\r\n         * @name Curve#doAdvancedPlot\r\n         * @type Boolean\r\n         * @default true\r\n         */\r\n        doAdvancedPlot: true,\r\n\r\n        /**\r\n         * If true use the algorithm by Gillam and Hohenwarter, which was default until version 0.98.\r\n         *\r\n         * @name Curve#doAdvancedPlotOld\r\n         * @see Curve#doAdvancedPlot\r\n         * @type Boolean\r\n         * @default false\r\n         * @deprecated\r\n         */\r\n        doAdvancedPlotOld: false,   // v1\r\n\r\n        /**\r\n         * Configure arrow head at the start position for curve.\r\n         * Recommended arrow head type is 7.\r\n         *\r\n         * @name Curve#firstArrow\r\n         * @type Boolean | Object\r\n         * @default false\r\n         * @see Line#firstArrow for options\r\n         */\r\n        firstArrow: false,\r\n\r\n        /**\r\n         * The data points of the curve are not connected with straight lines but with bezier curves.\r\n         * @name Curve#handDrawing\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        handDrawing: false,\r\n\r\n        /**\r\n         * Attributes for curve label.\r\n         *\r\n         * @type Label\r\n         * @name Curve#label\r\n         */\r\n        label: {\r\n            position: 'lft'\r\n        },\r\n\r\n        /**\r\n         * Configure arrow head at the end position for curve.\r\n         * Recommended arrow head type is 7.\r\n         *\r\n         * @name Curve#lastArrow\r\n         * @see Line#lastArrow for options\r\n         * @type Boolean | Object\r\n         * @default false\r\n         */\r\n        lastArrow: false,\r\n\r\n        /**\r\n         * Line endings (linecap) of a curve stroke.\r\n         * Possible values are:\r\n         * <ul>\r\n         * <li> 'butt',\r\n         * <li> 'round',\r\n         * <li> 'square'.\r\n         * </ul>\r\n         *\r\n         * @name JXG.Curve#lineCap\r\n         * @type String\r\n         * @default 'round'\r\n         */\r\n        lineCap: 'round',\r\n\r\n        /**\r\n         * Number of points used for plotting triggered by up events\r\n         * (i.e. high quality plotting) in case\r\n         * {@link Curve#doAdvancedPlot} is false.\r\n         *\r\n         * @name Curve#numberPointsHigh\r\n         * @see Curve#doAdvancedPlot\r\n         * @type Number\r\n         * @default 1600\r\n         */\r\n        numberPointsHigh: 1600,  // Number of points on curves after mouseUp\r\n\r\n        /**\r\n         * Number of points used for plotting triggered by move events\r\n         * (i.e. lower quality plotting but fast) in case\r\n         * {@link Curve#doAdvancedPlot} is false.\r\n         *\r\n         * @name Curve#numberPointsLow\r\n         * @see Curve#doAdvancedPlot\r\n         * @type Number\r\n         * @default 400\r\n         */\r\n        numberPointsLow: 400,    // Number of points on curves after mousemove\r\n\r\n        /**\r\n         * Select the version of the plot algorithm.\r\n         * <ul>\r\n         * <li> Version 1 is very outdated\r\n         * <li> Version 2 is the default version in JSXGraph v0.99.*, v1.0, and v1.1, v1.2.0\r\n         * <li> Version 3 is an internal version that was never published in  a stable version.\r\n         * <li> Version 4 is available since JSXGraph v1.2.0\r\n         * </ul>\r\n         * Version 4 plots correctly logarithms if the function term is supplied as string (i.e. as JessieCode)\r\n         *\r\n         * @example\r\n         *   var c = board.create('functiongraph', [\"log(x)\"]);\r\n         *\r\n         * @name Curve#plotVersion\r\n         * @type Number\r\n         * @default 2\r\n         */\r\n        plotVersion: 2,\r\n\r\n        /**\r\n         * Configure arrow head at the start position for curve.\r\n         * Recommended arrow head type is 7.\r\n         *\r\n         * @name Curve#recursionDepthHigh\r\n         * @see Curve#doAdvancedPlot\r\n         * @type Number\r\n         * @default 17\r\n         */\r\n        recursionDepthHigh: 17,\r\n\r\n        /**\r\n         * Number of points used for plotting triggered by move events in case\r\n         * (i.e. lower quality plotting but fast)\r\n         * {@link Curve#doAdvancedPlot} is true.\r\n         *\r\n         * @name Curve#recursionDepthLow\r\n         * @see Curve#doAdvancedPlot\r\n         * @type Number\r\n         * @default 13\r\n         */\r\n        recursionDepthLow: 15\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special foreignObject options */\r\n    foreignobject: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        fixed: true,\r\n        visible: true,\r\n        needsRegularUpdate: false,\r\n\r\n        /**\r\n         * List of attractor elements. If the distance of the foreignobject is less than\r\n         * attractorDistance the foreignobject is made to glider of this element.\r\n         *\r\n         * @name ForeignObject#attractors\r\n         *\r\n         * @type Array\r\n         * @default empty\r\n         */\r\n        attractors: [],\r\n\r\n        /**\r\n         * If set to true, this object is only evaluated once and not re-evaluated on update.\r\n         * This is necessary if you want to have a board within a foreignObject of another board.\r\n         *\r\n         * @name ForeignObject#evaluateOnlyOnce\r\n         *\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        evaluateOnlyOnce: false\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special functiongraph options */\r\n    functiongraph: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special glider options */\r\n    glider: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        label: {}\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special grid options */\r\n    grid: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        needsRegularUpdate: false,\r\n        hasGrid: false,  // Used in standardoptions\r\n        highlight: false,\r\n\r\n        /**\r\n         * Deprecated. Use {@link Grid#majorStep} instead.\r\n         *\r\n         * @deprecated\r\n         * @type {Number|String}\r\n         * @name Grid#gridX\r\n         * @default null\r\n         */\r\n        gridX: null,\r\n\r\n        /**\r\n         * Deprecated. Use {@link Grid#majorStep} instead.\r\n         *\r\n         * @deprecated\r\n         * @type {Number|String}\r\n         * @name Grid#gridY\r\n         * @default null\r\n         */\r\n        gridY: null,\r\n\r\n        /**\r\n         * Distance of major grid elements. There are three possibilities:\r\n         * <ul>\r\n         *     <li>If it is set to 'auto' the distance of the major grid equals the distance of majorTicks of the corresponding axis.\r\n         *     <li>Numbers or strings which are numbers (e.g. '10') are interpreted as distance in usrCoords.\r\n         *     <li>Strings with the unit 'px' are interpreted as distance in screen pixels.\r\n         *     <li>Strings with the unit '%' or 'fr' are interpreted as a ratio to the width/height of the board. (e.g. 50% = 0.5fr)\r\n         * </ul>\r\n         * Instead of one value you can provide two values as an array <tt>[x, y]</tt> here.\r\n         * These are used as distance in x- and y-direction.\r\n         *\r\n         * @type {Number|String|Array}\r\n         * @name Grid#majorStep\r\n         * @default 'auto'\r\n         * @see JXG.Ticks#getDistanceMajorTicks\r\n         */\r\n        majorStep: 'auto',\r\n\r\n        /**\r\n         * Number of elements in minor grid between elements of the major grid. There are three possibilities:\r\n         * <ul>\r\n         *     <li>If set to 'auto', the number minor elements is equal to the number of minorTicks of the corresponding axis.\r\n         *     <li>Numbers or strings which are numbers (e.g. '10') are interpreted as quantity.\r\n         * </ul>\r\n         * Instead of one value you can provide two values as an array <tt>[x, y]</tt> here.\r\n         * These are used as number in x- and y-direction.\r\n         *\r\n         * @type {Number|String|Array}\r\n         * @name Grid#minorElements\r\n         * @default 0\r\n         */\r\n        minorElements: 0,\r\n\r\n        /**\r\n         * To print a quadratic grid with same distance of major grid elements in x- and y-direction.\r\n         * <tt>'min'</tt> or <tt>true</tt> will set both distances of major grid elements in x- and y-direction to the primarily lesser value,\r\n         * <tt>'max'</tt> to the primarily greater value.\r\n         *\r\n         * @type {Boolean|String}\r\n         * @name Grid#forceSquare\r\n         * @default false\r\n         */\r\n        forceSquare: false,\r\n\r\n        /**\r\n         * To decide whether major or minor grid elements on boundaries of the boundingBox shall be shown, half-ones as well.\r\n         *\r\n         * @type {Boolean}\r\n         * @name Grid#includeBoundaries\r\n         * @default false\r\n         */\r\n        includeBoundaries: false,\r\n\r\n        /**\r\n         * Size of grid elements. There are the following possibilities:\r\n         * <ul>\r\n         *     <li>Numbers or strings which are numbers (e.g. '10') are interpreted as size in pixels.\r\n         *     <li>Strings with additional '%' (e.g. '95%') are interpreted as the ratio of used space for one element.\r\n         * </ul>\r\n         * Unused for 'line' which will use the value of strokeWidth.\r\n         * Instead of one value you can provide two values as an array <tt>[x, y]</tt> here.\r\n         * These are used as size in x- and y-direction.\r\n         *\r\n         * <p><b><i>This attribute can be set individually for major and minor grid as a sub-entry of {@link Grid#major} or {@link Grid#minor}</i></b>,\r\n         * e.g. <tt>major: {size: ...}</tt>\r\n         * For default values have a look there.</p>\r\n         *\r\n         * @type {Number|String|Array}\r\n         * @name Grid#size\r\n         */\r\n        // This attribute only exists for documentation purposes. It has no effect and is overwritten with actual values in major and minor.\r\n        size: undefined,\r\n\r\n        /**\r\n         * Appearance of grid elements.\r\n         * There are different styles which differ in appearance.\r\n         * Possible values are (comparing to {@link Point#face}):\r\n         * <table>\r\n         * <tr><th>Input</th><th>Output</th><th>Fillable by fillColor,...</th></tr>\r\n         * <tr><td>point, .</td><td>.</td><td>no</td></tr>\r\n         * <tr><td>line</td><td>&minus;</td><td>no</td></tr>\r\n         * <tr><td>cross, x</td><td>x</td><td>no</td></tr>\r\n         * <tr><td>circle, o</td><td>o</td><td>yes</td></tr>\r\n         * <tr><td>square, []</td><td>[]</td><td>yes</td></tr>\r\n         * <tr><td>plus, +</td><td>+</td><td>no</td></tr>\r\n         * <tr><td>minus, -</td><td>-</td><td>no</td></tr>\r\n         * <tr><td>divide, |</td><td>|</td><td>no</td></tr>\r\n         * <tr><td>diamond, &lt;&gt;</td><td>&lt;&gt;</td><td>yes</td></tr>\r\n         * <tr><td>diamond2, &lt;&lt;&gt;&gt;</td><td>&lt;&gt; (bigger)</td><td>yes</td></tr>\r\n         * <tr><td>triangleup, ^, a, A</td><td>^</td><td>no</td></tr>\r\n         * <tr><td>triangledown, v</td><td>v</td><td>no</td></tr>\r\n         * <tr><td>triangleleft, &lt;</td><td> &lt;</td><td>no</td></tr>\r\n         * <tr><td>triangleright, &gt;</td><td>&gt;</td><td>no</td></tr>\r\n         * <tr><td>regularPolygon, regpol</td><td>⬡</td><td>yes</td></tr>\r\n         * </table>\r\n         *\r\n         * <p><b><i>This attribute can be set individually for major and minor grid as a sub-entry of {@link Grid#major} or {@link Grid#minor}</i></b>,\r\n         * e.g. <tt>major: {face: ...}</tt>\r\n         * For default values have a look there.</p>\r\n         *\r\n         * @type {String}\r\n         * @name Grid#face\r\n         */\r\n         // This attribute only exists for documentation purposes. It has no effect and is overwritten with actual values in major and minor.\r\n        face: undefined,\r\n\r\n        /**\r\n         * This number (pixel value) controls where grid elements end at the canvas edge. If zero, the line\r\n         * ends exactly at the end, if negative there is a margin to the inside, if positive the line\r\n         * ends outside of the canvas (which is invisible).\r\n         *\r\n         * <p><b><i>This attribute can be set individually for major and minor grid as a sub-entry of {@link Grid#major} or {@link Grid#minor}</i></b>,\r\n         * e.g. <tt>major: {margin: ...}</tt>\r\n         * For default values have a look there.</p>\r\n         *\r\n         * @name Grid#margin\r\n         * @type {Number}\r\n         */\r\n        // This attribute only exists for documentation purposes. It has no effect and is overwritten with actual values in major and minor.\r\n        margin: undefined,\r\n\r\n        /**\r\n         * This attribute determines whether the grid elements located at <tt>x=0</tt>, <tt>y=0</tt>\r\n         * and (for major grid only) at <tt>(0, 0)</tt> are displayed.\r\n         * The main reason to set this attribute to \"false\", might be in combination with axes.\r\n         * <ul>\r\n         *     <li>If <tt>false</tt>, then all these elements are hidden.\r\n         *     <li>If <tt>true</tt>, all these elements are shown.\r\n         *     <li>If an object of the following form is given, the three cases can be distinguished individually:<br>\r\n         *     <tt>{x: true|false, y: true|false, origin: true|false}</tt>\r\n         * </ul>\r\n         *\r\n         * <p><b><i>This attribute can be set individually for major and minor grid as a sub-entry of {@link Grid#major} or {@link Grid#minor}</i></b>,\r\n         * e.g. <tt>major: {drawZero: ...}</tt>\r\n         * For default values have a look there.</p>\r\n         *\r\n         * @type {Boolean|Object}\r\n         * @name Grid#drawZero\r\n         */\r\n        // This attribute only exists for documentation purposes. It has no effect and is overwritten with actual values in major and minor.\r\n        drawZero: undefined,\r\n\r\n        /**\r\n         * Number of vertices for face 'polygon'.\r\n         *\r\n         * <p><b><i>This attribute can be set individually for major and minor grid as a sub-entry of {@link Grid#major} or {@link Grid#minor}</i></b>,\r\n         * e.g. <tt>major: {polygonVertices: ...}</tt>\r\n         * For default values have a look there.</p>\r\n         *\r\n         * @type {Number}\r\n         * @name Grid#polygonVertices\r\n         */\r\n        // This attribute only exists for documentation purposes. It has no effect and is overwritten with actual values in major and minor.\r\n        polygonVertices: undefined,\r\n\r\n        /**\r\n         * This object contains the attributes for major grid elements.\r\n         * You can override the following grid attributes individually here:\r\n         * <ul>\r\n         *     <li>{@link Grid#size}\r\n         *     <li>{@link Grid#face}\r\n         *     <li>{@link Grid#margin}\r\n         *     <li>{@link Grid#drawZero}\r\n         *     <li>{@link Grid#polygonVertices}\r\n         * </ul>\r\n         * Default values are:\r\n         * <pre>{\r\n         *      size: 5,\r\n         *      face: 'line',\r\n         *      margin: 0,\r\n         *      drawZero: true,\r\n         *      polygonVertices: 6\r\n         *  }</pre>\r\n         *\r\n         * @name Grid#major\r\n         * @type {Object}\r\n         */\r\n        major: {\r\n\r\n            /**\r\n             * Documented in Grid#size\r\n             * @class\r\n             * @ignore\r\n             */\r\n            size: 5,\r\n\r\n            /**\r\n             * Documented in Grid#face\r\n             * @class\r\n             * @ignore\r\n             */\r\n            face: 'line',\r\n\r\n            /**\r\n             * Documented in Grid#margin\r\n             * @class\r\n             * @ignore\r\n             */\r\n            margin: 0,\r\n\r\n            /**\r\n             * Documented in Grid#drawZero\r\n             * @class\r\n             * @ignore\r\n             */\r\n            drawZero: true,\r\n\r\n            /**\r\n             * Documented in Grid#polygonVertices\r\n             * @class\r\n             * @ignore\r\n             */\r\n            polygonVertices: 6\r\n        },\r\n\r\n        /**\r\n         * This object contains the attributes for minor grid elements.\r\n         * You can override the following grid attributes individually here:\r\n         * <ul>\r\n         *     <li>{@link Grid#size}\r\n         *     <li>{@link Grid#face}\r\n         *     <li>{@link Grid#margin}\r\n         *     <li>{@link Grid#drawZero}\r\n         *     <li>{@link Grid#polygonVertices}\r\n         * </ul>\r\n         * Default values are:\r\n         * <pre>{\r\n         *      size: 3,\r\n         *      face: 'point',\r\n         *      margin: 0,\r\n         *      drawZero: true,\r\n         *      polygonVertices: 6\r\n         *  }</pre>\r\n         *\r\n         * @name Grid#minor\r\n         * @type {Object}\r\n         */\r\n        minor: {\r\n\r\n            /**\r\n             * @class\r\n             * @ignore\r\n             */\r\n            visible: 'inherit',\r\n\r\n            /**\r\n             * Documented in Grid#size\r\n             * @class\r\n             * @ignore\r\n             */\r\n            size: 3,\r\n\r\n            /**\r\n             * Documented in Grid#face\r\n             * @class\r\n             * @ignore\r\n             */\r\n            face: 'point',\r\n\r\n            /**\r\n             * Documented in Grid#margin\r\n             * @class\r\n             * @ignore\r\n             */\r\n            margin: 0,\r\n\r\n            /**\r\n             * Documented in Grid#drawZero\r\n             * @class\r\n             * @ignore\r\n             */\r\n            drawZero: true,\r\n\r\n            /**\r\n             * Documented in Grid#polygonVertices\r\n             * @class\r\n             * @ignore\r\n             */\r\n            polygonVertices: 6\r\n        },\r\n\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         * @deprecated\r\n         */\r\n        snapToGrid: false,\r\n\r\n        strokeColor: '#c0c0c0',\r\n        strokeWidth: 1,\r\n        strokeOpacity: 0.5,\r\n        dash: 0,\r\n\r\n        /**\r\n         * Use a predefined theme for grid.\r\n         * Attributes can be overwritten by explicitly set the specific value.\r\n         *\r\n         * @type {Number}\r\n         * @default 0\r\n         * @see Grid#themes\r\n         */\r\n        theme: 0,\r\n\r\n        /**\r\n         * Array of theme attributes.\r\n         * The index of the entry is the number of the theme.\r\n         *\r\n         * @type {Array}\r\n         * @name Grid#themes\r\n         * @private\r\n         *\r\n         * @example\r\n         * // Theme 1\r\n         * // quadratic grid appearance with distance of major grid elements set to the primarily greater one\r\n         *\r\n         * JXG.JSXGraph.initBoard('jxgbox', {\r\n         *     boundingbox: [-4, 4, 4, -4], axis: true,\r\n         *     defaultAxes: {\r\n         *         x: { ticks: {majorHeight: 10} },\r\n         *         y: { ticks: {majorHeight: 10} }\r\n         *     },\r\n         *     grid: { theme: 1 },\r\n         * });\r\n         * </pre> <div id=\"JXGb8d606c4-7c67-4dc0-9941-3b3bd0932898\" class=\"jxgbox\" style=\"width: 300px; height: 200px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         JXG.JSXGraph.initBoard('JXGb8d606c4-7c67-4dc0-9941-3b3bd0932898',\r\n         *             {boundingbox: [-4, 4, 4, -4], axis: true, showcopyright: false, shownavigation: false,\r\n         *                 defaultAxes: {\r\n         *                     x: { ticks: {majorHeight: 10} },\r\n         *                     y: { ticks: {majorHeight: 10} }\r\n         *                 },\r\n         *                grid: { theme: 1 },\r\n         *             });\r\n         *     })();\r\n         * </script> <pre>\r\n         *\r\n         * @example\r\n         * // Theme 2\r\n         * // lines and points in between\r\n         *\r\n         * JXG.JSXGraph.initBoard('jxgbox', {\r\n         *     boundingbox: [-4, 4, 4, -4], axis: false,\r\n         *     grid: { theme: 2 },\r\n         * });\r\n         * </pre> <div id=\"JXG4e11e6e3-472a-48e0-b7d0-f80d397c769b\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         JXG.JSXGraph.initBoard('JXG4e11e6e3-472a-48e0-b7d0-f80d397c769b',\r\n         *             {boundingbox: [-4, 4, 4, -4], axis: false, showcopyright: false, shownavigation: false,\r\n         *                 grid: { theme: 2 },\r\n         *             })\r\n         *     })();\r\n         * </script> <pre>\r\n         *\r\n         * @example\r\n         * // Theme 3\r\n         * // lines and thinner lines in between\r\n         *\r\n         * JXG.JSXGraph.initBoard('jxgbox', {\r\n         *     boundingbox: [-4, 4, 4, -4], axis: false,\r\n         *     grid: { theme: 3 },\r\n         * });\r\n         * </pre> <div id=\"JXG334814a3-03a7-4231-a5a7-a42d3b8dc2de\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         JXG.JSXGraph.initBoard('JXG334814a3-03a7-4231-a5a7-a42d3b8dc2de',\r\n         *             {boundingbox: [-4, 4, 4, -4], axis: false, showcopyright: false, shownavigation: false,\r\n         *                 grid: { theme: 3 }\r\n         *         });\r\n         *     })();\r\n         * </script> <pre>\r\n         *\r\n         * @example\r\n         * // Theme 4\r\n         * // lines with grid of '+'s plotted in between\r\n         *\r\n         * JXG.JSXGraph.initBoard('jxgbox', {\r\n         *     boundingbox: [-4, 4, 4, -4], axis: false,\r\n         *     grid: { theme: 4 },\r\n         * });\r\n         * </pre> <div id=\"JXG9e2bb29c-d998-428c-9432-4a7bf6cd9222\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         JXG.JSXGraph.initBoard('JXG9e2bb29c-d998-428c-9432-4a7bf6cd9222',\r\n         *             {boundingbox: [-4, 4, 4, -4], axis: false, showcopyright: false, shownavigation: false,\r\n         *                 grid: { theme: 4 },\r\n         *             });\r\n         *     })();\r\n         * </script> <pre>\r\n         *\r\n         * @example\r\n         * // Theme 5\r\n         * // grid of '+'s and points in between\r\n         *\r\n         * JXG.JSXGraph.initBoard('jxgbox', {\r\n         *     boundingbox: [-4, 4, 4, -4], axis: false,\r\n         *     grid: { theme: 5 },\r\n         * });\r\n         * </pre> <div id=\"JXG6a967d83-4179-4827-9e97-63fbf1e872c8\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         JXG.JSXGraph.initBoard('JXG6a967d83-4179-4827-9e97-63fbf1e872c8',\r\n         *             {boundingbox: [-4, 4, 4, -4], axis: false, showcopyright: false, shownavigation: false,\r\n         *                 grid: { theme: 5 },\r\n         *         });\r\n         *     })();\r\n         * </script> <pre>\r\n         *\r\n         * @example\r\n         * // Theme 6\r\n         * // grid of circles with points in between\r\n         *\r\n         * JXG.JSXGraph.initBoard('jxgbox', {\r\n         *     boundingbox: [-4, 4, 4, -4], axis: false,\r\n         *     grid: { theme: 6 },\r\n         * });\r\n         * </pre> <div id=\"JXG28bee3da-a7ef-4590-9a18-38d1b99d09ce\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         JXG.JSXGraph.initBoard('JXG28bee3da-a7ef-4590-9a18-38d1b99d09ce',\r\n         *             {boundingbox: [-4, 4, 4, -4], axis: false, showcopyright: false, shownavigation: false,\r\n         *                 grid: { theme: 6 },\r\n         *         });\r\n         *     })();\r\n         * </script> <pre>\r\n         */\r\n        themes: [\r\n            {\r\n                // default values\r\n            },\r\n\r\n            {   // Theme 1: quadratic grid appearance with distance of major grid elements in x- and y-direction set to the primarily smaller one\r\n                forceSquare: 'min',\r\n                major: {\r\n                    face: 'line'\r\n                }\r\n            },\r\n\r\n            {   // Theme 2: lines and points in between\r\n                major: {\r\n                    face: 'line'\r\n                },\r\n                minor: {\r\n                    size: 3,\r\n                    face: 'point'\r\n                },\r\n                minorElements: 'auto'\r\n            },\r\n\r\n            {   // Theme 3: lines and thinner lines in between\r\n                major: {\r\n                    face: 'line'\r\n                },\r\n                minor: {\r\n                    face: 'line',\r\n                    strokeOpacity: 0.25\r\n                },\r\n                minorElements: 'auto'\r\n            },\r\n\r\n            {   // Theme 4: lines with grid of '+'s plotted in between\r\n                major: {\r\n                    face: 'line'\r\n                },\r\n                minor: {\r\n                    face: '+',\r\n                    size: '95%'\r\n                },\r\n                minorElements: 'auto'\r\n            },\r\n\r\n            {   // Theme 5: grid of '+'s and more points in between\r\n                major: {\r\n                    face: '+',\r\n                    size: 10,\r\n                    strokeOpacity: 1\r\n                },\r\n                minor: {\r\n                    face: 'point',\r\n                    size: 3\r\n                },\r\n                minorElements: 'auto'\r\n            },\r\n\r\n            {   // Theme 6: grid of circles with points in between\r\n                major: {\r\n                    face: 'circle',\r\n                    size: 8,\r\n                    fillColor: '#c0c0c0'\r\n                },\r\n                minor: {\r\n                    face: 'point',\r\n                    size: 3\r\n                },\r\n                minorElements: 'auto'\r\n            }\r\n        ]\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    group: {\r\n        needsRegularUpdate: true\r\n    },\r\n\r\n    /* special html slider options */\r\n    htmlslider: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        // /**\r\n        //  *\r\n        //  * These affect the DOM element input type=\"range\".\r\n        //  * The other attributes affect the DOM element div containing the range element.\r\n        //  */\r\n        widthRange: 100,\r\n        widthOut: 34,\r\n        step: 0.01,\r\n\r\n        frozen: true,\r\n        isLabel: false,\r\n        strokeColor: '#000000',\r\n        display: 'html',\r\n        anchorX: 'left',\r\n        anchorY: 'middle',\r\n        withLabel: false\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special image options */\r\n    image: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        imageString: null,\r\n        fillOpacity: 1.0,\r\n        highlightFillOpacity: 0.6,\r\n\r\n\r\n        /**\r\n         * Defines the CSS class used by the image. CSS attributes defined in\r\n         * this class will overwrite the corresponding JSXGraph attributes, e.g.\r\n         * opacity.\r\n         * The default CSS class is defined in jsxgraph.css.\r\n         *\r\n         * @name Image#cssClass\r\n         *\r\n         * @see Image#highlightCssClass\r\n         * @type String\r\n         * @default 'JXGimage'\r\n         * @see Image#highlightCssClass\r\n         * @see Text#cssClass\r\n         * @see JXG.GeometryElement#cssClass\r\n         */\r\n        cssClass: 'JXGimage',\r\n\r\n        /**\r\n         * Defines the CSS class used by the image when highlighted.\r\n         * CSS attributes defined in this class will overwrite the\r\n         * corresponding JSXGraph attributes, e.g. highlightFillOpacity.\r\n         * The default CSS class is defined in jsxgraph.css.\r\n         *\r\n         * @name Image#highlightCssClass\r\n         *\r\n         * @see Image#cssClass\r\n         * @type String\r\n         * @default 'JXGimageHighlight'\r\n         * @see Image#cssClass\r\n         * @see Image#highlightCssClass\r\n         * @see JXG.GeometryElement#highlightCssClass\r\n         */\r\n        highlightCssClass: 'JXGimageHighlight',\r\n\r\n        /**\r\n         * Image rotation in degrees.\r\n         *\r\n         * @name Image#rotate\r\n         * @type Number\r\n         * @default 0\r\n         */\r\n        rotate: 0,\r\n\r\n        /**\r\n         * Defines together with {@link Image#snapSizeY} the grid the image snaps on to.\r\n         * The image will only snap on user coordinates which are\r\n         * integer multiples to snapSizeX in x and snapSizeY in y direction.\r\n         * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks\r\n         * of the default ticks of the default x axes of the board.\r\n         *\r\n         * @name Image#snapSizeX\r\n         *\r\n         * @see Point#snapToGrid\r\n         * @see Image#snapSizeY\r\n         * @see JXG.Board#defaultAxes\r\n         * @type Number\r\n         * @default 1\r\n         */\r\n        snapSizeX: 1,\r\n\r\n        /**\r\n         * Defines together with {@link Image#snapSizeX} the grid the image snaps on to.\r\n         * The image will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.\r\n         * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks\r\n         * of the default ticks of the default y axes of the board.\r\n         *\r\n         * @name Image#snapSizeY\r\n         *\r\n         * @see Point#snapToGrid\r\n         * @see Image#snapSizeX\r\n         * @see JXG.Board#defaultAxes\r\n         * @type Number\r\n         * @default 1\r\n         */\r\n        snapSizeY: 1,\r\n\r\n        /**\r\n         * List of attractor elements. If the distance of the image is less than\r\n         * attractorDistance the image is made to glider of this element.\r\n         *\r\n         * @name Image#attractors\r\n         *\r\n         * @type Array\r\n         * @default empty\r\n         */\r\n        attractors: []\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special implicitcurve options */\r\n    implicitcurve: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Defines the margin (in user coordinates) around the JSXGraph board in which the\r\n         * implicit curve is plotted.\r\n         *\r\n         * @name ImplicitCurve#margin\r\n         * @type {Number|Function}\r\n         * @default 1\r\n         */\r\n        margin: 1,\r\n\r\n        /**\r\n         * Horizontal resolution: distance (in pixel) between vertical lines to search for components of the implicit curve.\r\n         * A small number increases the running time. For large number components may be missed.\r\n         * Minimum value is 0.01.\r\n         *\r\n         * @name ImplicitCurve#resolution_outer\r\n         * @type {Number|Function}\r\n         * @default 5\r\n         */\r\n        resolution_outer: 5,\r\n\r\n        /**\r\n         * Vertical resolution (in pixel) to search for components of the implicit curve.\r\n         * A small number increases the running time. For large number components may be missed.\r\n         * Minimum value is 0.01.\r\n         *\r\n         * @name ImplicitCurve#resolution_inner\r\n         * @type {Number|Function}\r\n         * @default 5\r\n         */\r\n        resolution_inner: 5,\r\n\r\n        /**\r\n         * Maximum iterations for one component of the implicit curve.\r\n         *\r\n         * @name ImplicitCurve#max_steps\r\n         * @type {Number|Function}\r\n         * @default 1024\r\n         */\r\n        max_steps: 1024,\r\n\r\n        /**\r\n         * Angle &alpha;<sub>0</sub> between two successive tangents: determines the smoothness of\r\n         * the curve.\r\n         *\r\n         * @name ImplicitCurve#alpha_0\r\n         * @type {Number|Function}\r\n         * @default 0.05\r\n         */\r\n        alpha_0: 0.05,\r\n\r\n        /**\r\n         * Tolerance to find starting points for the tracing phase of a component.\r\n         *\r\n         * @name ImplicitCurve#tol_0\r\n         * @type {Number|Function}\r\n         * @default JXG.Math.eps\r\n         */\r\n        tol_u0: Mat.eps,\r\n\r\n        /**\r\n         * Tolerance for the Newton steps.\r\n         *\r\n         * @name ImplicitCurve#tol_newton\r\n         * @type {Number|Function}\r\n         * @default 1.0e-7\r\n         */\r\n        tol_newton: 1.0e-7,\r\n\r\n        /**\r\n         * Tolerance for cusp / bifurcation detection.\r\n         *\r\n         * @name ImplicitCurve#tol_cusp\r\n         * @type {Number|Function}\r\n         * @default 0.05\r\n         */\r\n        tol_cusp: 0.05,\r\n\r\n        /**\r\n         * If two points are closer than this value, we bail out of the tracing phase for that\r\n         * component.\r\n         *\r\n         * @name ImplicitCurve#tol_progress\r\n         * @type {Number|Function}\r\n         * @default 0.0001\r\n         */\r\n        tol_progress: 0.0001,\r\n\r\n        /**\r\n         * Half of the box size (in user units) to search for existing line segments in the quadtree.\r\n         *\r\n         * @name ImplicitCurve#qdt_box\r\n         * @type {Number|Function}\r\n         * @default 0.2\r\n         */\r\n        qdt_box: 0.2,\r\n\r\n        /**\r\n         * Inverse of desired number of Newton steps.\r\n         *\r\n         * @name ImplicitCurve#kappa_0\r\n         * @type {Number|Function}\r\n         * @default 0.2\r\n         */\r\n        kappa_0: 0.2,\r\n\r\n        /**\r\n         * Allowed distance (in user units) of predictor point to curve.\r\n         *\r\n         * @name ImplicitCurve#delta_0\r\n         * @type {Number|Function}\r\n         * @default 0.05\r\n         */\r\n        delta_0: 0.05,\r\n\r\n        /**\r\n         * Initial step width (in user units).\r\n         *\r\n         * @name ImplicitCurve#h_initial\r\n         * @type {Number|Function}\r\n         * @default 0.1\r\n         */\r\n        h_initial: 0.1,\r\n\r\n        /**\r\n         * If h is below this threshold (in user units), we bail out\r\n         * of the tracing phase of that component.\r\n         *\r\n         * @name ImplicitCurve#h_critical\r\n         * @type {Number|Function}\r\n         * @default 0.001\r\n         */\r\n        h_critical: 0.001,\r\n\r\n        /**\r\n         * Maximum step width (in user units).\r\n         *\r\n         * @name ImplicitCurve#h_max\r\n         * @type {Number|Function}\r\n         * @default 0.5\r\n         */\r\n        h_max: 0.5,\r\n\r\n        /**\r\n         * Allowed distance (in user units multiplied by actual step width) to detect loop.\r\n         *\r\n         * @name ImplicitCurve#loop_dist\r\n         * @type {Number|Function}\r\n         * @default 0.09\r\n         */\r\n        loop_dist: 0.09,\r\n\r\n        /**\r\n         * Minimum acos of angle to detect loop.\r\n         *\r\n         * @name ImplicitCurve#loop_dir\r\n         * @type {Number|Function}\r\n         * @default 0.99\r\n         */\r\n        loop_dir: 0.99,\r\n\r\n        /**\r\n         * Use Gosper's loop detector.\r\n         *\r\n         * @name ImplicitCurve#loop_detection\r\n         * @type {Boolean|Function}\r\n         * @default true\r\n         */\r\n        loop_detection: true\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for incircle of 3 points */\r\n    incircle: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        fillColor: 'none',\r\n        highlightFillColor: 'none',\r\n        strokeColor: Color.palette.blue,\r\n        highlightStrokeColor: '#c3d9ff',\r\n\r\n        /**\r\n         * Attributes of circle center.\r\n         *\r\n         * @type Point\r\n         * @name Incircle#center\r\n         */\r\n        center: {               // center point\r\n            visible: false,\r\n            fixed: false,\r\n            withLabel: false,\r\n            fillColor: Color.palette.red,\r\n            strokeColor: Color.palette.red,\r\n            highlightFillColor: '#c3d9ff',\r\n            highlightStrokeColor: '#c3d9ff',\r\n            name: ''\r\n        }\r\n        /**#@-*/\r\n    },\r\n\r\n    inequality: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        fillColor: Color.palette.red,\r\n        fillOpacity: 0.2,\r\n        strokeColor: 'none',\r\n\r\n        /**\r\n         * By default an inequality is less (or equal) than. Set inverse to <tt>true</tt> will consider the inequality\r\n         * greater (or equal) than.\r\n         *\r\n         * @type Boolean\r\n         * @default false\r\n         * @name Inequality#inverse\r\n         * @visprop\r\n         */\r\n        inverse: false\r\n        /**#@-*/\r\n    },\r\n\r\n    infobox: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Horizontal offset in pixel of the infobox text from its anchor point.\r\n         *\r\n         * @type Number\r\n         * @default -20\r\n         * @name JXG.Board.infobox#distanceX\r\n         * @visprop\r\n         */\r\n        distanceX: -20,\r\n\r\n        /**\r\n         * Vertical offset in pixel of the infobox text from its anchor point.\r\n         *\r\n         * @type Number\r\n         * @default 25\r\n         * @name JXG.Board.infobox#distanceY\r\n         * @visprop\r\n         */\r\n        distanceY: 25,\r\n\r\n        /**\r\n         * Internationalization support for infobox text.\r\n         *\r\n         * @name JXG.Board.infobox#intl\r\n         * @type object\r\n         * @default <pre>{\r\n         *    enabled: 'inherit',\r\n         *    options: {}\r\n         * }</pre>\r\n         * @visprop\r\n         * @see JXG.Board#intl\r\n         * @see Text#intl\r\n         */\r\n        intl: {\r\n            enabled: 'inherit',\r\n            options: {}\r\n        },\r\n\r\n        fontSize: 12,\r\n        isLabel: false,\r\n        strokeColor: '#bbbbbb',\r\n        display: 'html',             // 'html' or 'internal'\r\n        anchorX: 'left',             //  'left', 'middle', or 'right': horizontal alignment\r\n        //  of the text.\r\n        anchorY: 'middle',           //  'top', 'middle', or 'bottom': vertical alignment\r\n        //  of the text.\r\n        cssClass: 'JXGinfobox',\r\n        rotate: 0,                   // works for non-zero values only in combination\r\n        // with display=='internal'\r\n        visible: true,\r\n        parse: false,\r\n        transitionDuration: 0,\r\n        needsRegularUpdate: false,\r\n        tabindex: null,\r\n        viewport: [0, 0, 0, 0],\r\n\r\n        ignoreForLabelAutoposition: true\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for integral */\r\n    integral: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        axis: 'x',        // 'x' or 'y'\r\n        withLabel: true,    // Show integral value as text\r\n        fixed: true,\r\n        strokeWidth: 0,\r\n        strokeOpacity: 0,\r\n        fillColor: Color.palette.red,\r\n        fillOpacity: 0.3,\r\n        highlightFillColor: Color.palette.red,\r\n        highlightFillOpacity: 0.2,\r\n\r\n        /**\r\n         * Attributes of the (left) starting point of the integral.\r\n         *\r\n         * @type Point\r\n         * @name Integral#curveLeft\r\n         * @see Integral#baseLeft\r\n         */\r\n        curveLeft: {    // Start point\r\n            visible: true,\r\n            withLabel: false,\r\n            color: Color.palette.red,\r\n            fillOpacity: 0.8,\r\n            layer: 9\r\n        },\r\n\r\n        /**\r\n         * Attributes of the (left) base point of the integral.\r\n         *\r\n         * @type Point\r\n         * @name Integral#baseLeft\r\n         * @see Integral#curveLeft\r\n         */\r\n        baseLeft: {    // Start point\r\n            visible: false,\r\n            fixed: false,\r\n            withLabel: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes of the (right) end point of the integral.\r\n         *\r\n         * @type Point\r\n         * @name Integral#curveRight\r\n         * @see Integral#baseRight\r\n         */\r\n        curveRight: {      // End point\r\n            visible: true,\r\n            withLabel: false,\r\n            color: Color.palette.red,\r\n            fillOpacity: 0.8,\r\n            layer: 9\r\n        },\r\n\r\n        /**\r\n         * Attributes of the (right) base point of the integral.\r\n         *\r\n         * @type Point\r\n         * @name Integral#baseRight\r\n         * @see Integral#curveRight\r\n         */\r\n        baseRight: {      // End point\r\n            visible: false,\r\n            fixed: false,\r\n            withLabel: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for integral label.\r\n         *\r\n         * @type Label\r\n         * @name Integral#label\r\n         * @default <pre>{\r\n         *      fontSize: 20,\r\n         *      digits: 4,\r\n         *      intl: {\r\n         *          enabled: false,\r\n         *          options: {}\r\n         *      }\r\n         *    }</pre>\r\n         */\r\n        label: {\r\n            fontSize: 20,\r\n            digits: 4,\r\n            intl: {\r\n                enabled: false,\r\n                options: {}\r\n            }\r\n        }\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special input options */\r\n    input: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Control the attribute \"disabled\" of the HTML input field.\r\n         *\r\n         * @name disabled\r\n         * @memberOf Input.prototype\r\n         *\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        disabled: false,\r\n\r\n        /**\r\n         * Control the attribute \"maxlength\" of the HTML input field.\r\n         *\r\n         * @name maxlength\r\n         * @memberOf Input.prototype\r\n         *\r\n         * @type Number\r\n         * @default 524288 (as in HTML)\r\n         */\r\n        maxlength: 524288,\r\n\r\n        display: 'html'\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special intersection point options */\r\n    intersection: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Used in {@link JXG.Intersection}.\r\n         * This flag sets the behaviour of intersection points of e.g.\r\n         * two segments. If true, the intersection is treated as intersection of lines. If false\r\n         * the intersection point exists if the segments intersect setwise.\r\n         *\r\n         * @name Intersection.alwaysIntersect\r\n         * @type Boolean\r\n         * @default true\r\n         */\r\n        alwaysIntersect: true\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special label options */\r\n    label: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        visible: 'inherit',\r\n        strokeColor: '#000000',\r\n        strokeOpacity: 1,\r\n        highlightStrokeOpacity: 0.666666,\r\n        highlightStrokeColor: '#000000',\r\n\r\n        fixed: true,\r\n        tabindex: null,\r\n\r\n        /**\r\n         * Point labels are positioned by setting {@link Point#anchorX}, {@link Point#anchorY}\r\n         * and {@link Label#offset}.\r\n         * For line, circle and curve elements (and their derived objects)\r\n         * there are two possibilities to position labels.\r\n         * <ul>\r\n         * <li> The first (old) possibility uses the <a href=\"https://www.tug.org/metapost.html\">MetaPost</a> system:\r\n         * Possible string values for the position of a label for\r\n         * label anchor points are:\r\n         * <ul>\r\n         * <li> 'first' (lines only)\r\n         * <li> 'last' (lines only)\r\n         * <li> 'lft'\r\n         * <li> 'rt'\r\n         * <li> 'top'\r\n         * <li> 'bot'\r\n         * <li> 'ulft'\r\n         * <li> 'urt'\r\n         * <li> 'llft'\r\n         * <li> 'lrt'\r\n         * </ul>\r\n         * <li> the second (preferred) possibility (since v1.9.0) is:\r\n         * with <tt>position: 'len side'</tt> the label can be positioned exactly along the\r\n         * element's path. Here,\r\n         * <ul>\r\n         * <li> 'len' is an expression of the form\r\n         *   <ul>\r\n         *     <li> xfr, denoting a fraction of the whole. x is expected to be a number between 0 and 1.\r\n         *     <li> x%, a percentage. x is expected to be a number between 0 and 100.\r\n         *     <li> x, a number: only possible for line elements and circles. For lines, the label is positioned x\r\n         *          user units from the starting point. For circles, the number is interpreted as degree, e.g. 45°.\r\n         *          For everything else, 0 is taken instead.\r\n         *     <li> xpx, a pixel value: only possible for line elements.\r\n         *          The label is positioned x pixels from the starting point.\r\n         *          For non-lines, 0% is taken instead.\r\n         *   </ul>\r\n         *   If the domain of a curve is not connected, a position of the label close to the line\r\n         *   between the first and last point of the curve is chosen.\r\n         * <li> 'side' is either 'left' or 'right'. The label is positioned to the left or right of the path, when moving from the\r\n         * first point to the last. For circles, 'left' means inside of the circle, 'right' means outside of the circle.\r\n         * The distance of the label from the path can be controlled by {@link Label#distance}.\r\n         * </ul>\r\n         * Recommended for this second possibility is to use anchorX: 'middle' and 'anchorY: 'middle'.\r\n         * </ul>\r\n         *\r\n         * @example\r\n         * var l1 = board.create('segment', [[-3, 2], [3, 2]], {\r\n         *     name: 'l_1',\r\n         *     withLabel: true,\r\n         *     point1: { visible: true, name: 'A', withLabel: true },\r\n         *     point2: { visible: true, name: 'B', withLabel: true },\r\n         *     label: {\r\n         *         anchorX: 'middle',\r\n         *         anchorY: 'middle',\r\n         *         offset: [0, 0],\r\n         *         distance: 1.2,\r\n         *         position: '0.2fr left'\r\n         *     }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXG66395d34-fd7f-42d9-97dc-14ae8882c11f\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG66395d34-fd7f-42d9-97dc-14ae8882c11f',\r\n         *             {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var l1 = board.create('segment', [[-3, 2], [3, 2]], {\r\n         *         name: 'l_1',\r\n         *         withLabel: true,\r\n         *         point1: { visible: true, name: 'A', withLabel: true },\r\n         *         point2: { visible: true, name: 'B', withLabel: true },\r\n         *         label: {\r\n         *             anchorX: 'middle',\r\n         *             anchorY: 'middle',\r\n         *             offset: [0, 0],\r\n         *             distance: 1.2,\r\n         *             position: '0.2fr left'\r\n         *         }\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         * var c1 = board.create('circle', [[0, 0], 3], {\r\n         *     name: 'c_1',\r\n         *     withLabel: true,\r\n         *     label: {\r\n         *         anchorX: 'middle',\r\n         *         anchorY: 'middle',\r\n         *         offset: [0, 0],\r\n         *         fontSize: 32,\r\n         *         distance: 1.5,\r\n         *         position: '50% right'\r\n         *     }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXG98ee16ab-fc5f-476c-bf57-0107ac69d91e\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG98ee16ab-fc5f-476c-bf57-0107ac69d91e',\r\n         *             {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var c1 = board.create('circle', [[0, 0], 3], {\r\n         *         name: 'c_1',\r\n         *         withLabel: true,\r\n         *         label: {\r\n         *             anchorX: 'middle',\r\n         *             anchorY: 'middle',\r\n         *             offset: [0, 0],\r\n         *             fontSize: 32,\r\n         *             distance: 1.5,\r\n         *             position: '50% right'\r\n         *         }\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         * var cu1 = board.create('functiongraph', ['3 * sin(x)', -3, 3], {\r\n         *     name: 'cu_1',\r\n         *     withLabel: true,\r\n         *     label: {\r\n         *         anchorX: 'middle',\r\n         *         anchorY: 'middle',\r\n         *         offset: [0, 0],\r\n         *         distance: 2,\r\n         *         position: '0.8fr right'\r\n         *     }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXG65b2edee-12d8-48a1-94b2-d6e79995de8c\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG65b2edee-12d8-48a1-94b2-d6e79995de8c',\r\n         *             {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var cu1 = board.create('functiongraph', ['3 * sin(x)', -3, 3], {\r\n         *         name: 'cu_1',\r\n         *         withLabel: true,\r\n         *         label: {\r\n         *             anchorX: 'middle',\r\n         *             anchorY: 'middle',\r\n         *             offset: [0, 0],\r\n         *             distance: 2,\r\n         *             position: '0.8fr right'\r\n         *         }\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         * var A = board.create('point', [-1, 4]);\r\n         * var B = board.create('point', [-1, -4]);\r\n         * var C = board.create('point', [1, 1]);\r\n         * var cu2 = board.create('ellipse', [A, B, C], {\r\n         *     name: 'cu_2',\r\n         *     withLabel: true,\r\n         *     label: {\r\n         *         anchorX: 'middle',\r\n         *         anchorY: 'middle',\r\n         *         offset: [0, 0],\r\n         *         fontSize: 20,\r\n         *         distance: 1.5,\r\n         *         position: '75% right'\r\n         *     }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXG9c3b2213-1b5a-4cb8-b547-a8d179b851f2\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG9c3b2213-1b5a-4cb8-b547-a8d179b851f2',\r\n         *             {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var A = board.create('point', [-1, 4]);\r\n         *     var B = board.create('point', [-1, -4]);\r\n         *     var C = board.create('point', [1, 1]);\r\n         *     var cu2 = board.create('ellipse', [A, B, C], {\r\n         *         name: 'cu_2',\r\n         *         withLabel: true,\r\n         *         label: {\r\n         *             anchorX: 'middle',\r\n         *             anchorY: 'middle',\r\n         *             offset: [0, 0],\r\n         *             fontSize: 20,\r\n         *             distance: 1.5,\r\n         *             position: '75% right'\r\n         *         }\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         *\r\n         * @name Label#position\r\n         * @type String\r\n         * @default 'urt'\r\n         * @see Label#distance\r\n         * @see Label#offset\r\n         */\r\n        position: 'urt',\r\n\r\n        /**\r\n         * Distance of the label from a path element, like line, circle, curve.\r\n         * The true distance is this value multiplied by 0.5 times the size of the bounding box of the label text.\r\n         * That means, with a value of 1 the label will touch the path element.\r\n         * @name Label#distance\r\n         * @type Number\r\n         * @default 1.5\r\n         *\r\n         * @see Label#position\r\n         *\r\n         */\r\n        distance: 1.5,\r\n\r\n        /**\r\n         *  Label offset from label anchor.\r\n         *  The label anchor is determined by {@link Label#position}\r\n         *\r\n         * @name Label#offset\r\n         * @see Label#position\r\n         * @type Array\r\n         * @default [10,10]\r\n         */\r\n        offset: [10, 10],\r\n\r\n        /**\r\n         * Automatic position of label text. When called first, the positioning algorithm\r\n         * starts at the position defined by offset.\r\n         * The algorithm tries to find a position with the least number of\r\n         * overlappings with other elements, while retaining the distance\r\n         * to the anchor element.\r\n         *\r\n         * @name Label#autoPosition\r\n         * @see Label#offset\r\n         * @type Boolean\r\n         * @see GeometryElement#ignoreForLabelAutoposition\r\n         * @see Label#autoPositionMinDistance\r\n         * @see Label#autoPositionMaxDistance\r\n         * @see Label#autoPositionWhitelist\r\n         * @default false\r\n         *\r\n         * @example\r\n         * \tvar p1 = board.create('point', [-2, 1], {id: 'A'});\r\n         * \tvar p2 = board.create('point', [-0.85, 1], {\r\n         *      name: 'B', id: 'B', label:{autoPosition: true, offset:[10, 10]}\r\n         *  });\r\n         * \tvar p3 = board.create('point', [-1, 1.2], {\r\n         *      name: 'C', id: 'C', label:{autoPosition: true, offset:[10, 10]}\r\n         *  });\r\n         *  var c = board.create('circle', [p1, p2]);\r\n         * \tvar l = board.create('line', [p1, p2]);\r\n         *\r\n         * </pre><div id=\"JXG7d4dafe7-1a07-4d3f-95cb-bfed9d96dea2\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG7d4dafe7-1a07-4d3f-95cb-bfed9d96dea2',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     \tvar p1 = board.create('point', [-2, 1], {id: 'A'});\r\n         *     \tvar p2 = board.create('point', [-0.85, 1], {name: 'B', id: 'B', label:{autoPosition: true, offset:[10, 10]}});\r\n         *     \tvar p3 = board.create('point', [-1, 1.2], {name: 'C', id: 'C', label:{autoPosition: true, offset:[10, 10]}});\r\n         *      var c = board.create('circle', [p1, p2]);\r\n         *     \tvar l = board.create('line', [p1, p2]);\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         *\r\n         */\r\n        autoPosition: false,\r\n\r\n        /**\r\n         * The auto position algorithm tries to put a label to a conflict-free\r\n         * position around it's anchor element. For this, the algorithm tests 12 positions\r\n         * around the anchor element starting at a distance from the anchor\r\n         * defined here (in pixel).\r\n         *\r\n         * @name Label#autoPositionMinDistance\r\n         * @see Label#autoPosition\r\n         * @see Label#autoPositionMaxDistance\r\n         * @see Label#autoPositionWhitelist\r\n         * @type Number\r\n         * @default 12\r\n         *\r\n         */\r\n        autoPositionMinDistance: 12,\r\n\r\n        /**\r\n         * The auto position algorithm tries to put a label to a conflict-free\r\n         * position around it's anchor element. For this, the algorithm tests 12 positions\r\n         * around the anchor element up to a distance from the anchor\r\n         * defined here (in pixel).\r\n         *\r\n         * @name Label#autoPositionMaxDistance\r\n         * @see Label#autoPosition\r\n         * @see Label#autoPositionMinDistance\r\n         * @see Label#autoPositionWhitelist\r\n         * @type Number\r\n         * @default 28\r\n         *\r\n         */\r\n        autoPositionMaxDistance: 28,\r\n\r\n        /**\r\n         * List of object ids which should be ignored on setting automatic position of label text.\r\n         *\r\n         * @name Label#autoPositionWhitelist\r\n         * @see Label#autoPosition\r\n         * @see Label#autoPositionMinDistance\r\n         * @see Label#autoPositionMaxDistance\r\n         * @type Array\r\n         * @default []\r\n         */\r\n        autoPositionWhitelist: []\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special legend options */\r\n    legend: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Default style of a legend element. The only possible value is 'vertical'.\r\n         * @name Legend#style\r\n         * @type String\r\n         * @default 'vertical'\r\n         */\r\n        style: 'vertical',\r\n\r\n        /**\r\n         * Label names of a legend element.\r\n         * @name Legend#labels\r\n         * @type Array\r\n         * @default \"['1', '2', '3', '4', '5', '6', '7', '8']\"\r\n         */\r\n        labels: ['1', '2', '3', '4', '5', '6', '7', '8'],\r\n\r\n        /**\r\n         * (Circular) array of label colors.\r\n         * @name Legend#colors\r\n         * @type Array\r\n         * @default \"['#B02B2C', '#3F4C6B', '#C79810', '#D15600', '#FFFF88', '#c3d9ff', '#4096EE', '#008C00']\"\r\n         */\r\n        colors: ['#B02B2C', '#3F4C6B', '#C79810', '#D15600', '#FFFF88', '#c3d9ff', '#4096EE', '#008C00'],\r\n\r\n        /**\r\n         * Length of line in one legend entry\r\n         * @name Legend#lineLength\r\n         * @type Number\r\n         * @default 1\r\n         *\r\n         */\r\n        lineLength: 1,\r\n\r\n        /**\r\n         * (Circular) array of opacity for legend line stroke color for one legend entry.\r\n         * @name Legend#strokeOpacity\r\n         * @type Array\r\n         * @default [1]\r\n         *\r\n         */\r\n        strokeOpacity: [1],\r\n\r\n        /**\r\n         * Height (in px) of one legend entry\r\n         * @name Legend#rowHeight\r\n         * @type Number\r\n         * @default 20\r\n         *\r\n         */\r\n        rowHeight: 20,\r\n\r\n        /**\r\n         * Height (in px) of one legend entry\r\n         * @name Legend#strokeWidth\r\n         * @type Number\r\n         * @default 5\r\n         *\r\n         */\r\n        strokeWidth: 5,\r\n\r\n        /**\r\n         * The element can be fixed and may not be dragged around. If true, the legend will even stay at its position on zoom and\r\n         * moveOrigin events.\r\n         * @name Legend#frozen\r\n         * @type Boolean\r\n         * @default false\r\n         * @see JXG.GeometryElement#frozen\r\n         *\r\n         */\r\n        frozen: false\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special line options */\r\n    line: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Configure the arrow head at the position of its first point or the corresponding\r\n         * intersection with the canvas border\r\n         *\r\n         * The attribute firstArrow can be a Boolean or an object with the following sub-attributes:\r\n         * <pre>\r\n         * {\r\n         *      type: 1, // possible values are 1, 2, ..., 7. Default value is 1.\r\n         *      size: 6, // size of the arrow head. Default value is 6.\r\n         *               // This value is multiplied with the strokeWidth of the line\r\n         *               // Exception: for type=7 size is ignored\r\n         *      highlightSize: 6, // size of the arrow head in case the element is highlighted. Default value\r\n         * }\r\n         * </pre>\r\n         * type=7 is the default for curves if firstArrow: true\r\n         * <p>\r\n         * An arrow head can be turned off with line.setAttribute({firstArrow: false}).\r\n         *\r\n         * @example\r\n         *     board.options.line.lastArrow = false;\r\n         *     board.options.line.firstArrow = {size: 10, highlightSize: 10};\r\n         *     board.options.line.point1 = {visible: false, withLabel: true, label: {visible: true, anchorX: 'right'}};\r\n         *     board.options.line.strokeWidth = 4;\r\n         *     board.options.line.highlightStrokeWidth = 4;\r\n         *\r\n         *     board.create('segment', [[-5,4], [3,4]], {firstArrow: {type: 1}, point1: {name: 'type:1'}});\r\n         *     board.create('segment', [[-5,3], [3,3]], {firstArrow: {type: 2}, point1: {name: 'type:2'}});\r\n         *     board.create('segment', [[-5,2], [3,2]], {firstArrow: {type: 3}, point1: {name: 'type:3'}});\r\n         *     board.create('segment', [[-5,1], [3,1]], {firstArrow: {type: 4}, point1: {name: 'type:4'}});\r\n         *     board.create('segment', [[-5,0], [3,0]], {firstArrow: {type: 5}, point1: {name: 'type:5'}});\r\n         *     board.create('segment', [[-5,-1], [3,-1]], {firstArrow: {type: 6}, point1: {name: 'type:6'}});\r\n         *     board.create('segment', [[-5,-2], [3,-2]], {firstArrow: {type: 7}, point1: {name: 'type:7'}});\r\n         *\r\n         * </pre><div id=\"JXGc94a93da-c942-4204-8bb6-b39726cbb09b\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGc94a93da-c942-4204-8bb6-b39726cbb09b',\r\n         *             {boundingbox: [-6, 6, 4,-4], axis: false, showcopyright: false, shownavigation: false});\r\n         *         board.options.line.lastArrow = false;\r\n         *         board.options.line.firstArrow = {size: 10, highlightSize: 10};\r\n         *         board.options.line.point1 = {visible: false, withLabel: true, label: {visible: true, anchorX: 'right'}};\r\n         *         board.options.line.strokeWidth = 4;\r\n         *         board.options.line.highlightStrokeWidth = 4;\r\n         *\r\n         *         board.create('segment', [[-5,4], [3,4]], {firstArrow: {type: 1}, point1: {name: 'type:1'}});\r\n         *         board.create('segment', [[-5,3], [3,3]], {firstArrow: {type: 2}, point1: {name: 'type:2'}});\r\n         *         board.create('segment', [[-5,2], [3,2]], {firstArrow: {type: 3}, point1: {name: 'type:3'}});\r\n         *         board.create('segment', [[-5,1], [3,1]], {firstArrow: {type: 4}, point1: {name: 'type:4'}});\r\n         *         board.create('segment', [[-5,0], [3,0]], {firstArrow: {type: 5}, point1: {name: 'type:5'}});\r\n         *         board.create('segment', [[-5,-1], [3,-1]], {firstArrow: {type: 6}, point1: {name: 'type:6'}});\r\n         *         board.create('segment', [[-5,-2], [3,-2]], {firstArrow: {type: 7}, point1: {name: 'type:7'}});\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @name Line#firstArrow\r\n         * @see Line#lastArrow\r\n         * @see Line#touchFirstPoint\r\n         * @type Boolean | Object\r\n         * @default false\r\n         */\r\n        firstArrow: false,\r\n\r\n        /**\r\n         * Configure the arrow head at the position of its second point or the corresponding\r\n         * intersection with the canvas border.\r\n         *\r\n         * The attribute lastArrow can be a Boolean or an object with the following sub-attributes:\r\n         * <pre>\r\n         * {\r\n         *      type: 1, // possible values are 1, 2, ..., 7. Default value is 1.\r\n         *      size: 6, // size of the arrow head. Default value is 6.\r\n         *               // This value is multiplied with the strokeWidth of the line.\r\n         *               // Exception: for type=7 size is ignored\r\n         *      highlightSize: 6, // size of the arrow head in case the element is highlighted. Default value is 6.\r\n         * }\r\n         * </pre>\r\n         * type=7 is the default for curves if lastArrow: true\r\n         * <p>\r\n         * An arrow head can be turned off with line.setAttribute({lastArrow: false}).\r\n         *\r\n         * @example\r\n         *     var p1 = board.create('point', [-5, 2], {size:1});\r\n         *     var p2 = board.create('point', [5, 2], {size:10});\r\n         *     var li = board.create('segment', ['A','B'],\r\n         *         {name:'seg',\r\n         *          strokeColor:'#000000',\r\n         *          strokeWidth:1,\r\n         *          highlightStrokeWidth: 5,\r\n         *          lastArrow: {type: 2, size: 8, highlightSize: 6},\r\n         *          touchLastPoint: true,\r\n         *          firstArrow: {type: 3, size: 8}\r\n         *         });\r\n         *\r\n         * </pre><div id=\"JXG184e915c-c2ef-11e8-bece-04d3b0c2aad3\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG184e915c-c2ef-11e8-bece-04d3b0c2aad3',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *         var p1 = board.create('point', [-5, 2], {size:1});\r\n         *         var p2 = board.create('point', [5, 2], {size:10});\r\n         *         var li = board.create('segment', ['A','B'],\r\n         *             {name:'seg',\r\n         *              strokeColor:'#000000',\r\n         *              strokeWidth:1,\r\n         *              highlightStrokeWidth: 5,\r\n         *              lastArrow: {type: 2, size: 8, highlightSize: 6},\r\n         *              touchLastPoint: true,\r\n         *              firstArrow: {type: 3, size: 8}\r\n         *             });\r\n         *     })();\r\n         *\r\n         * </script>\r\n         *\r\n         * @example\r\n         *     board.options.line.strokeWidth = 4;\r\n         *     board.options.line.highlightStrokeWidth = 4;\r\n         *     board.options.line.firstArrow = false;\r\n         *     board.options.line.lastArrow = {size: 10, highlightSize: 10};\r\n         *     board.options.line.point2 = {visible: false, withLabel: true, label: {visible: true}};\r\n         *\r\n         *     board.create('segment', [[-5,4], [3,4]], {lastArrow: {type: 1}, point2: {name: 'type:1'}});\r\n         *     board.create('segment', [[-5,3], [3,3]], {lastArrow: {type: 2}, point2: {name: 'type:2'}});\r\n         *     board.create('segment', [[-5,2], [3,2]], {lastArrow: {type: 3}, point2: {name: 'type:3'}});\r\n         *     board.create('segment', [[-5,1], [3,1]], {lastArrow: {type: 4}, point2: {name: 'type:4'}});\r\n         *     board.create('segment', [[-5,0], [3,0]], {lastArrow: {type: 5}, point2: {name: 'type:5'}});\r\n         *     board.create('segment', [[-5,-1], [3,-1]], {lastArrow: {type: 6}, point2: {name: 'type:6'}});\r\n         *     board.create('segment', [[-5,-2], [3,-2]], {lastArrow: {type: 7}, point2: {name: 'type:7'}});\r\n         *\r\n         * </pre><div id=\"JXGca206b1c-e319-4899-8b90-778f53fd926d\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGca206b1c-e319-4899-8b90-778f53fd926d',\r\n         *             {boundingbox: [-6, 6, 6,-4], axis: false, showcopyright: false, shownavigation: false});\r\n         *         board.options.line.strokeWidth = 4;\r\n         *         board.options.line.highlightStrokeWidth = 4;\r\n         *         board.options.line.firstArrow = false;\r\n         *         board.options.line.lastArrow = {size: 10, highlightSize: 10};\r\n         *         board.options.line.point2 = {visible: false, withLabel: true, label: {visible: true}};\r\n         *\r\n         *         board.create('segment', [[-5,4], [3,4]], {lastArrow: {type: 1}, point2: {name: 'type:1'}});\r\n         *         board.create('segment', [[-5,3], [3,3]], {lastArrow: {type: 2}, point2: {name: 'type:2'}});\r\n         *         board.create('segment', [[-5,2], [3,2]], {lastArrow: {type: 3}, point2: {name: 'type:3'}});\r\n         *         board.create('segment', [[-5,1], [3,1]], {lastArrow: {type: 4}, point2: {name: 'type:4'}});\r\n         *         board.create('segment', [[-5,0], [3,0]], {lastArrow: {type: 5}, point2: {name: 'type:5'}});\r\n         *         board.create('segment', [[-5,-1], [3,-1]], {lastArrow: {type: 6}, point2: {name: 'type:6'}});\r\n         *         board.create('segment', [[-5,-2], [3,-2]], {lastArrow: {type: 7}, point2: {name: 'type:7'}});\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @name Line#lastArrow\r\n         * @see Line#firstArrow\r\n         * @see Line#touchLastPoint\r\n         * @type Boolean | Object\r\n         * @default false\r\n         */\r\n        lastArrow: false,\r\n\r\n        /**\r\n         * This number (pixel value) controls where infinite lines end at the canvas border. If zero, the line\r\n         * ends exactly at the border, if negative there is a margin to the inside, if positive the line\r\n         * ends outside of the canvas (which is invisible).\r\n         *\r\n         * @name Line#margin\r\n         * @type Number\r\n         * @default 0\r\n         */\r\n        margin: 0,\r\n\r\n        /**\r\n         * If true, line stretches infinitely in direction of its first point.\r\n         * Otherwise it ends at point1.\r\n         *\r\n         * @name Line#straightFirst\r\n         * @see Line#straightLast\r\n         * @type Boolean\r\n         * @default true\r\n         */\r\n        straightFirst: true,\r\n\r\n        /**\r\n         * If true, line stretches infinitely in direction of its second point.\r\n         * Otherwise it ends at point2.\r\n         *\r\n         * @name Line#straightLast\r\n         * @see Line#straightFirst\r\n         * @type Boolean\r\n         * @default true\r\n         */\r\n        straightLast: true,\r\n\r\n        fillColor: 'none',           // Important for VML on IE\r\n        highlightFillColor: 'none',  // Important for VML on IE\r\n        strokeColor: Color.palette.blue,\r\n        highlightStrokeColor: '#c3d9ff',\r\n        withTicks: false,\r\n\r\n        /**\r\n         * Attributes for first defining point of the line.\r\n         *\r\n         * @type Point\r\n         * @name Line#point1\r\n         */\r\n        point1: {                  // Default values for point1 if created by line\r\n            fillColor: Color.palette.red,\r\n            strokeColor: Color.palette.red,\r\n            highlightFillColor: '#c3d9ff',\r\n            highlightStrokeColor: '#c3d9ff',\r\n            layer: 9,\r\n\r\n            visible: false,\r\n            withLabel: false,\r\n            fixed: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for second defining point of the line.\r\n         *\r\n         * @type Point\r\n         * @name Line#point2\r\n         */\r\n        point2: {                  // Default values for point2 if created by line\r\n            fillColor: Color.palette.red,\r\n            strokeColor: Color.palette.red,\r\n            highlightFillColor: '#c3d9ff',\r\n            highlightStrokeColor: '#c3d9ff',\r\n            layer: 9,\r\n\r\n            visible: false,\r\n            withLabel: false,\r\n            fixed: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for ticks of the line.\r\n         *\r\n         * @name Line#ticks\r\n         * @type Object\r\n         * @see Ticks\r\n         */\r\n        ticks: {\r\n            drawLabels: true,\r\n            label: {\r\n                offset: [4, -12 + 3] // This seems to be a good offset for 12 point fonts\r\n            },\r\n            drawZero: false,\r\n            insertTicks: false,\r\n            ticksDistance: 1,\r\n            minTicksDistance: 50,\r\n            minorHeight: 4,          // if <0: full width and height\r\n            majorHeight: -1,         // if <0: full width and height\r\n            minorTicks: 4,\r\n            strokeOpacity: 0.3,\r\n            visible: 'inherit'\r\n        },\r\n\r\n        /**\r\n         * Attributes for the line label.\r\n         *\r\n         * @type Object\r\n         * @name Line#label\r\n         * @see Label\r\n         */\r\n        label: {\r\n            position: 'llft'\r\n        },\r\n\r\n        /**\r\n         * If set to true, the point will snap to a grid defined by\r\n         * {@link Point#snapSizeX} and {@link Point#snapSizeY}.\r\n         *\r\n         * @see Point#snapSizeX\r\n         * @see Point#snapSizeY\r\n         * @type Boolean\r\n         * @name Line#snapToGrid\r\n         * @default false\r\n         */\r\n        snapToGrid: false,\r\n\r\n        /**\r\n         * Defines together with {@link Point#snapSizeY} the grid the point snaps on to.\r\n         * The point will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.\r\n         * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks\r\n         * of the default ticks of the default x axes of the board.\r\n         *\r\n         * @see Point#snapToGrid\r\n         * @see Point#snapSizeY\r\n         * @see JXG.Board#defaultAxes\r\n         * @type Number\r\n         * @name Line#snapSizeX\r\n         * @default 1\r\n         */\r\n        snapSizeX: 1,\r\n\r\n        /**\r\n         * Defines together with {@link Point#snapSizeX} the grid the point snaps on to.\r\n         * The point will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.\r\n         * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks\r\n         * of the default ticks of the default y axes of the board.\r\n         *\r\n         * @see Point#snapToGrid\r\n         * @see Point#snapSizeX\r\n         * @see JXG.Board#defaultAxes\r\n         * @type Number\r\n         * @name Line#snapSizeY\r\n         * @default 1\r\n         */\r\n        snapSizeY: 1,\r\n\r\n        /**\r\n         * If set to true, {@link Line#firstArrow} is set to true and the point is visible,\r\n         * the arrow head will just touch the circle line of the start point of the line.\r\n         *\r\n         * @see Line#firstArrow\r\n         * @type Boolean\r\n         * @name Line#touchFirstPoint\r\n         * @default false\r\n         */\r\n        touchFirstPoint: false,\r\n\r\n        /**\r\n         * If set to true, {@link Line#lastArrow} is set to true and the point is visible,\r\n         * the arrow head will just touch the circle line of the start point of the line.\r\n         * @see Line#firstArrow\r\n         * @type Boolean\r\n         * @name Line#touchLastPoint\r\n         * @default false\r\n         */\r\n        touchLastPoint: false\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for locus curves */\r\n    locus: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        translateToOrigin: false,\r\n        translateTo10: false,\r\n        stretch: false,\r\n        toOrigin: null,\r\n        to10: null\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special measurement options */\r\n    measurement: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * This specifies the unit of measurement in dimension 1 (e.g. length).\r\n         * A power is automatically added to the string.\r\n         * If you want to use different units for each dimension, see {@link Measurement#units}.\r\n         *\r\n         * @example\r\n         * var p1 = board.create(\"point\", [0,1]),\r\n         *     p2 = board.create(\"point\", [3,1]),\r\n         *     c = board.create(\"circle\", [p1, p2]);\r\n         *\r\n         * board.create(\"measurement\", [-2, -3, [\"Perimeter\", c]], {\r\n         *     baseUnit: \" m\"\r\n         * });\r\n         * board.create(\"measurement\", [1, -3, [\"Area\", c]], {\r\n         *     baseUnit: \" m\"\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXG6cb6a7e7-553b-4f2a-af99-ddd78b7ba118\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG6cb6a7e7-553b-4f2a-af99-ddd78b7ba118',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: false, grid: false, showcopyright: false, shownavigation: false});\r\n         *\r\n         *     var p1 = board.create(\"point\", [0,1]),\r\n         *         p2 = board.create(\"point\", [3,1]),\r\n         *         c = board.create(\"circle\", [p1, p2]);\r\n         *\r\n         *     board.create(\"measurement\", [-2, -3, [\"Perimeter\", c]], {\r\n         *         baseUnit: \" m\"\r\n         *     });\r\n         *     board.create(\"measurement\", [1, -3, [\"Area\", c]], {\r\n         *         baseUnit: \" m\"\r\n         *     });\r\n         *\r\n         *     })();\r\n         * </script><pre>\r\n         *\r\n         * @see Measurement#units\r\n         * @name Measurement#baseUnit\r\n         * @type String\r\n         * @default ''\r\n         */\r\n        baseUnit: '',\r\n\r\n        /**\r\n         * This attribute expects an object that has the dimension numbers as keys (as integer or in the form of 'dimxx')\r\n         * and assigns a string to each dimension.\r\n         * If a dimension has no specification, {@link Measurement#baseUnit} is used.\r\n         *\r\n         * @example\r\n         * var p1 = board.create(\"point\", [0,1]),\r\n         *     p2 = board.create(\"point\", [3,1]),\r\n         *     c = board.create(\"circle\", [p1, p2]);\r\n         *\r\n         * board.create(\"measurement\", [-3, -3, [\"Perimeter\", c]], {\r\n         *     baseUnit: \" m\",\r\n         *     units: {\r\n         *          1: \" length unit\",\r\n         *       2: \" area unit\"\r\n         *     },\r\n         * });\r\n         * board.create(\"measurement\", [1, -3, [\"Area\", c]], {\r\n         *     baseUnit: \" m\",\r\n         *     units: {\r\n         *          dim1: \" length unit\",\r\n         *       dim2: \" area unit\"\r\n         *     },\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXGe06456d5-255e-459b-8c8e-4d7d2af7efb8\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGe06456d5-255e-459b-8c8e-4d7d2af7efb8',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: false, grid: false, showcopyright: false, shownavigation: false});\r\n         *     var p1 = board.create(\"point\", [0,1]),\r\n         *         p2 = board.create(\"point\", [3,1]),\r\n         *         c = board.create(\"circle\", [p1, p2]);\r\n         *\r\n         *     board.create(\"measurement\", [-3, -3, [\"Perimeter\", c]], {\r\n         *         baseUnit: \" m\",\r\n         *         units: {\r\n         *          1: \" length unit\",\r\n         *           2: \" area unit\"\r\n         *         },\r\n         *     });\r\n         *     board.create(\"measurement\", [1, -3, [\"Area\", c]], {\r\n         *         baseUnit: \" m\",\r\n         *         units: {\r\n         *          dim1: \" length unit\",\r\n         *           dim2: \" area unit\"\r\n         *         },\r\n         *     });\r\n         *\r\n         *     })();\r\n         * </script><pre>\r\n         *\r\n         * @see Measurement#baseUnit\r\n         * @name Measurement#units\r\n         * @type Object\r\n         * @default {}\r\n         */\r\n        units: {},\r\n\r\n        /**\r\n         * Determines whether a prefix is displayed before the measurement value and unit.\r\n         *\r\n         * @see Measurement#prefix\r\n         * @name Measurement#showPrefix\r\n         * @type Boolean\r\n         * @default true\r\n         */\r\n        showPrefix: true,\r\n\r\n        /**\r\n         * Determines whether a suffix is displayed after the measurement value and unit.\r\n         *\r\n         * @see Measurement#suffix\r\n         * @name Measurement#showSuffix\r\n         * @type Boolean\r\n         * @default true\r\n         */\r\n        showSuffix: true,\r\n\r\n        /**\r\n         * String that is displayed before the measurement and its unit.\r\n         *\r\n         * @see Measurement#showPrefix\r\n         * @name Measurement#prefix\r\n         * @type String\r\n         * @default ''\r\n         */\r\n        prefix: '',\r\n\r\n        /**\r\n         * String that is displayed after the measurement and its unit.\r\n         *\r\n         * @see Measurement#showSuffix\r\n         * @name Measurement#suffix\r\n         * @type String\r\n         * @default ''\r\n         */\r\n        suffix: '',\r\n\r\n        /**\r\n         * Dimension of the measured data. This measurement can only be combined with a measurement of a suitable dimension.\r\n         * Overwrites the dimension returned by the Dimension() method.\r\n         * Normally, the default value null is used here to automatically determine the dimension.\r\n         *\r\n         * However, if the coordinates or a direction vector are measured, the value is usually returned as an array.\r\n         * To tell the measurement that the function {@link Measurement#formatCoords} or {@link Measurement#formatDirection} should be used\r\n         * to display the array properly, 'coords' or 'direction' must be specified here.\r\n         *\r\n         * @see Measurement#formatCoords\r\n         * @see Measurement#formatDirection\r\n         * @name Measurement#dim\r\n         * @type Number|'coords'|'direction'\r\n         * @default null\r\n         */\r\n        dim: null,\r\n\r\n        /**\r\n         * Function to format coordinates. Does only have an effect, if {@link Measurement#dim} is set to 'coords'.\r\n         *\r\n         * @example\r\n         * var p = board.create(\"point\", [-2, 0]);\r\n         *\r\n         * board.create(\"measurement\", [0, -3, [\"Coords\", p]], {\r\n         *     dim: 'coords',\r\n         *     formatCoords: function (_,x,y,z) {\r\n         *         if (parseFloat(z) !== 1)\r\n         *             return 'Infinit coords';\r\n         *         else\r\n         *             return '(' + x + ' | ' + y + ')';\r\n         *     }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXGa0606ad6-971b-47d4-9a72-ca7df65890f5\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGa0606ad6-971b-47d4-9a72-ca7df65890f5',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var p = board.create(\"point\", [-2, 0]);\r\n         *\r\n         *     board.create(\"measurement\", [0, -3, [\"Coords\", p]], {\r\n         *         dim: 'coords',\r\n         *         formatCoords: function (_,x,y,z) {\r\n         *             if (parseFloat(z) !== 1)\r\n         *                 return 'Infinit coords';\r\n         *             else\r\n         *                 return '(' + x + ' | ' + y + ')';\r\n         *         }\r\n         *     });\r\n         *     })();\r\n         * </script><pre>\r\n         *\r\n         * @see Measurement#dim\r\n         * @name Measurement#formatCoords\r\n         * @type Function\r\n         * @param {Measurement} self Pointer to the measurement object itself\r\n         * @param {Number} x c-coordinate\r\n         * @param {Number} y c-coordinate\r\n         * @param {Number} z c-coordinate\r\n         * @returns String\r\n         */\r\n        formatCoords: function (self, x, y, z) {\r\n            if (parseFloat(z) !== 1)\r\n                return 'Infinit coords';\r\n            else\r\n                return '(' + x + ', ' + y + ')';\r\n        },\r\n\r\n        /**\r\n         * Function to format direction vector. Does only have an effect, if {@link Measurement#dim} is set to 'direction'.\r\n         *\r\n         * @example\r\n         * var p1 = board.create(\"point\", [0,1]),\r\n         *     p2 = board.create(\"point\", [3,1]),\r\n         *     s = board.create(\"segment\", [p1, p2]);\r\n         *\r\n         * board.create(\"measurement\", [0, -2, [\"Direction\", s]], {\r\n         *     dim: 'direction',\r\n         *     formatDirection: function (self,x,y) {\r\n         *        return '\\\\[\\\\frac{' + x + '}{' + y + '} = ' +\r\n         *            (!isFinite(x/y) ? '\\\\infty' : JXG.toFixed(x/y, self.visProp.digits)) +\r\n         *            '\\\\]';\r\n         *     },\r\n         *     useMathJax: true\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXG57435de0-16f2-42be-94d8-3d2b31caefcd\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG57435de0-16f2-42be-94d8-3d2b31caefcd',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: false, grid: false, showcopyright: false, shownavigation: false});\r\n         *     var p1 = board.create(\"point\", [0,1]),\r\n         *         p2 = board.create(\"point\", [3,1]),\r\n         *         s = board.create(\"segment\", [p1, p2]);\r\n         *\r\n         *     board.create(\"measurement\", [0, -2, [\"Direction\", s]], {\r\n         *         dim: 'direction',\r\n         *         formatDirection: function (self,x,y) {\r\n         *            return '\\\\[\\\\frac{' + x + '}{' + y + '} = ' +\r\n         *                (!isFinite(x/y) ? '\\\\infty' : JXG.toFixed(x/y, self.visProp.digits)) +\r\n         *                '\\\\]';\r\n         *         },\r\n         *         useMathJax: true\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @name Measurement#formatDirection\r\n         * @type Function\r\n         * @param {Measurement} self Pointer to the measurement object itself\r\n         * @param {Number} x c-coordinate\r\n         * @param {Number} y c-coordinate\r\n         * @returns String\r\n         */\r\n        formatDirection: function (self, x, y) {\r\n            return '(' + x + ', ' + y + ')';\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special metapost spline options */\r\n    metapostspline: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n          * Controls if the data points of the cardinal spline when given as\r\n          * arrays should be converted into {@link JXG.Points}.\r\n          *\r\n          * @name createPoints\r\n          * @memberOf Metapostspline.prototype\r\n          *\r\n          * @see Metapostspline#points\r\n          *\r\n          * @type Boolean\r\n          * @default true\r\n          */\r\n        createPoints: true,\r\n\r\n        /**\r\n         * If set to true, the supplied coordinates are interpreted as\r\n         * [[x_0, y_0], [x_1, y_1], p, ...].\r\n         * Otherwise, if the data consists of two arrays of equal length,\r\n         * it is interpreted as\r\n         * [[x_o x_1, ..., x_n], [y_0, y_1, ..., y_n]]\r\n         *\r\n         * @name isArrayOfCoordinates\r\n         * @memberOf Metapostspline.prototype\r\n         * @type Boolean\r\n         * @default true\r\n         */\r\n        isArrayOfCoordinates: true,\r\n\r\n        /**\r\n         * Attributes for the points generated by Metapost spline in cases\r\n         * {@link createPoints} is set to true\r\n         *\r\n         * @name points\r\n         * @memberOf Metapostspline.prototype\r\n         *\r\n         * @see Metapostspline#createPoints\r\n         * @type Object\r\n         */\r\n        points: {\r\n            strokeOpacity: 0.5,\r\n            fillOpacity: 0.5,\r\n            highlightStrokeOpacity: 1.0,\r\n            highlightFillOpacity: 1.0,\r\n            withLabel: false,\r\n            name: '',\r\n            fixed: false\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special mirrorelement options */\r\n    mirrorelement: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        fixed: true,\r\n\r\n        /**\r\n         * Attributes of mirror point, i.e. the point along which the element is mirrored.\r\n         *\r\n         * @type Point\r\n         * @name mirrorelement#point\r\n         */\r\n        point: {},\r\n\r\n        /**\r\n         * Attributes of circle center, i.e. the center of the circle,\r\n         * if a circle is the mirror element and the transformation type is 'Euclidean'\r\n         *\r\n         * @type Point\r\n         * @name mirrorelement#center\r\n         */\r\n        center: {},\r\n\r\n        /**\r\n         * Type of transformation. Possible values are 'Euclidean', 'projective'.\r\n         *\r\n         * If the value is 'Euclidean', the mirror element of a circle is again a circle,\r\n         * otherwise it is a conic section.\r\n         *\r\n         * @type String\r\n         * @name mirrorelement#type\r\n         * @default 'Euclidean'\r\n         */\r\n        type: 'Euclidean'\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special nonreflexangle options */\r\n    nonreflexangle: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    // /* special options for Msector of 3 points */\r\n    // msector: {\r\n    //     strokeColor: '#000000', // Msector line\r\n    //     point: {               // Msector point\r\n    //         visible: false,\r\n    //         fixed: false,\r\n    //         withLabel: false,\r\n    //         name: ''\r\n    //     }\r\n    // },\r\n\r\n    /* special options for normal lines */\r\n    normal: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        strokeColor: '#000000', //  normal line\r\n\r\n        /**\r\n         * Attributes of helper point of normal.\r\n         *\r\n         * @type Point\r\n         * @name Normal#point\r\n         */\r\n        point: {\r\n            visible: false,\r\n            fixed: false,\r\n            withLabel: false,\r\n            name: ''\r\n        }\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for orthogonal projection points */\r\n    orthogonalprojection: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special otherintersection point options */\r\n    otherintersection: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * This flag sets the behavior of other intersection points of e.g.\r\n         * a circle and a segment. If true, the intersection is treated as intersection with a line. If false\r\n         * the intersection point exists if the segment intersects setwise.\r\n         *\r\n         * @name Otherintersection.alwaysIntersect\r\n         * @type Boolean\r\n         * @default true\r\n         */\r\n        alwaysIntersect: true,\r\n\r\n        /**\r\n         * Minimum distance (in user coordinates) for points to be defined as different.\r\n         * For implicit curves and other non approximate curves this number might have to be\r\n         * increased.\r\n         *\r\n         * @name Otherintersection.precision\r\n         * @type Number\r\n         * @default 0.001\r\n         */\r\n        precision: 0.001\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for parallel lines */\r\n    parallel: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        strokeColor: '#000000', // Parallel line\r\n\r\n        /**\r\n         * Attributes of helper point of normal.\r\n         *\r\n         * @type Point\r\n         * @name Parallel#point\r\n         */\r\n        point: {\r\n            visible: false,\r\n            fixed: false,\r\n            withLabel: false,\r\n            name: ''\r\n        },\r\n\r\n        label: {\r\n            position: 'llft'\r\n        }\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special parallelogram options */\r\n    parallelogram: {\r\n        parallelpoint: {\r\n            withLabel: false,\r\n            name: ''\r\n        }\r\n    },\r\n\r\n    /* special parallelpoint options */\r\n    parallelpoint: {\r\n    },\r\n\r\n    /* special perpendicular options */\r\n    perpendicular: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        strokeColor: '#000000', // Perpendicular line\r\n        straightFirst: true,\r\n        straightLast: true\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special perpendicular options */\r\n    perpendicularsegment: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        strokeColor: '#000000', // Perpendicular segment\r\n        straightFirst: false,\r\n        straightLast: false,\r\n        point: {               // Perpendicular point\r\n            visible: false,\r\n            fixed: true,\r\n            withLabel: false,\r\n            name: ''\r\n        }\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special point options */\r\n    point: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        withLabel: true,\r\n        label: {},\r\n\r\n        /**\r\n         * This attribute was used to determined the point layout. It was derived from GEONExT and was\r\n         * replaced by {@link Point#face} and {@link Point#size}.\r\n         *\r\n         * @name Point#style\r\n         *\r\n         * @see Point#face\r\n         * @see Point#size\r\n         * @type Number\r\n         * @default 5\r\n         * @deprecated\r\n         */\r\n        style: 5,\r\n\r\n        /**\r\n         * There are different point styles which differ in appearance.\r\n         * Posssible values are\r\n         * <table>\r\n         * <tr><th>Input</th><th>Output</th></tr>\r\n         * <tr><td>cross</td><td>x</td></tr>\r\n         * <tr><td>circle</td><td>o</td></tr>\r\n         * <tr><td>square, []</td><td>[]</td></tr>\r\n         * <tr><td>plus</td><td>+</td></tr>\r\n         * <tr><td>minus</td><td>-</td></tr>\r\n         * <tr><td>divide</td><td>|</td></tr>\r\n         * <tr><td>diamond</td><td>&lt;&gt;</td></tr>\r\n         * <tr><td>diamond2</td><td>&lt;&gt; (bigger)</td></tr>\r\n         * <tr><td>triangleup</td><td>^, a, A</td></tr>\r\n         * <tr><td>triangledown</td><td>v</td></tr>\r\n         * <tr><td>triangleleft</td><td>&lt;</td></tr>\r\n         * <tr><td>triangleright</td><td>&gt;</td></tr>\r\n         * </table>\r\n         *\r\n         * @name Point#face\r\n         *\r\n         * @type String\r\n         * @see JXG.Point#setStyle\r\n         * @default circle\r\n         */\r\n        face: 'o',\r\n\r\n        /**\r\n         * Size of a point, either in pixel or user coordinates.\r\n         * Means radius resp. half the width of a point (depending on the face).\r\n         *\r\n         * @name Point#size\r\n         *\r\n         * @see Point#face\r\n         * @see JXG.Point#setStyle\r\n         * @see Point#sizeUnit\r\n         * @type Number\r\n         * @default 3\r\n         */\r\n        size: 3,\r\n\r\n        /**\r\n         * Unit for size.\r\n         * Possible values are 'screen' and 'user.\r\n         *\r\n         * @name Point#sizeUnit\r\n         *\r\n         * @see Point#size\r\n         * @type String\r\n         * @default 'screen'\r\n         */\r\n        sizeUnit: 'screen',\r\n\r\n        strokeWidth: 2,\r\n\r\n        transitionProperties: ['fill', 'fill-opacity', 'stroke', 'stroke-opacity', 'stroke-width', 'width', 'height', 'rx', 'ry'],\r\n        fillColor: Color.palette.red,\r\n        strokeColor: Color.palette.red,\r\n        highlightFillColor: '#c3d9ff',\r\n        highlightStrokeColor: '#c3d9ff',\r\n        // strokeOpacity: 1.0,\r\n        // fillOpacity: 1.0,\r\n        // highlightFillOpacity: 0.5,\r\n        // highlightStrokeOpacity: 0.5,\r\n\r\n        // fillColor: '#ff0000',\r\n        // highlightFillColor: '#eeeeee',\r\n        // strokeWidth: 2,\r\n        // strokeColor: '#ff0000',\r\n        // highlightStrokeColor: '#c3d9ff',\r\n\r\n        /**\r\n         * If true, the point size changes on zoom events.\r\n         *\r\n         * @type Boolean\r\n         * @name Point#zoom\r\n         * @default false\r\n         *\r\n         */\r\n        zoom: false,             // Change the point size on zoom\r\n\r\n        /**\r\n         * If true, the infobox is shown on mouse/pen over, if false not.\r\n         * If the value is 'inherit', the value of\r\n         * {@link JXG.Board#showInfobox} is taken.\r\n         *\r\n         * @name Point#showInfobox\r\n         * @see JXG.Board#showInfobox\r\n         * @type Boolean|String\r\n         * @description true | false | 'inherit'\r\n         * @default true\r\n         */\r\n        showInfobox: 'inherit',\r\n\r\n        /**\r\n         * Truncating rule for the digits in the infobox.\r\n         * <ul>\r\n         * <li>'auto': done automatically by JXG.autoDigits()\r\n         * <li>'none': no truncation\r\n         * <li>number: truncate after \"number digits\" with JXG.toFixed()\r\n         * </ul>\r\n         *\r\n         * @name Point#infoboxDigits\r\n         *\r\n         * @type String| Number\r\n         * @default 'auto'\r\n         * @see JXG#autoDigits\r\n         * @see JXG#toFixed\r\n         */\r\n        infoboxDigits: 'auto',\r\n\r\n        draft: false,\r\n\r\n        /**\r\n         * List of attractor elements. If the distance of the point is less than\r\n         * attractorDistance the point is made to glider of this element.\r\n         *\r\n         * @name Point#attractors\r\n         *\r\n         * @type Array\r\n         * @default empty\r\n         */\r\n        attractors: [],\r\n\r\n        /**\r\n         * Unit for attractorDistance and snatchDistance, used for magnetized points and for snapToPoints.\r\n         * Possible values are 'screen' and 'user'.\r\n         *\r\n         * @name Point#attractorUnit\r\n         *\r\n         * @see Point#attractorDistance\r\n         * @see Point#snatchDistance\r\n         * @see Point#snapToPoints\r\n         * @see Point#attractors\r\n         * @type String\r\n         * @default 'user'\r\n         */\r\n        attractorUnit: 'user',    // 'screen', 'user'\r\n\r\n        /**\r\n         * If the distance of the point to one of its attractors is less\r\n         * than this number the point will be a glider on this\r\n         * attracting element.\r\n         * If set to zero nothing happens.\r\n         *\r\n         * @name Point#attractorDistance\r\n         *\r\n         * @type Number\r\n         * @default 0.0\r\n         */\r\n        attractorDistance: 0.0,\r\n\r\n        /**\r\n         * If the distance of the point to one of its attractors is at least\r\n         * this number the point will be released from being a glider on the\r\n         * attracting element.\r\n         * If set to zero nothing happens.\r\n         *\r\n         * @name Point#snatchDistance\r\n         *\r\n         * @type Number\r\n         * @default 0.0\r\n         */\r\n        snatchDistance: 0.0,\r\n\r\n        /**\r\n         * If set to true, the point will snap to a grid of integer multiples of\r\n         * {@link Point#snapSizeX} and {@link Point#snapSizeY} (in user coordinates).\r\n         * <p>\r\n         * The coordinates of the grid points are either integer multiples of snapSizeX and snapSizeY\r\n         * (given in user coordinates, not pixels) or are the intersection points\r\n         * of the major ticks of the boards default axes in case that snapSizeX, snapSizeY are negative.\r\n         *\r\n         * @name Point#snapToGrid\r\n         *\r\n         * @see Point#snapSizeX\r\n         * @see Point#snapSizeY\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        snapToGrid: false,\r\n\r\n        /**\r\n         * If set to true, the point will only snap to (possibly invisibly) grid points\r\n         * when within {@link Point#attractorDistance} of such a grid point.\r\n         * <p>\r\n         * The coordinates of the grid points are either integer multiples of snapSizeX and snapSizeY\r\n         * (given in user coordinates, not pixels) or are the intersection points\r\n         * of the major ticks of the boards default axes in case that snapSizeX, snapSizeY are negative.\r\n         *\r\n         * @name Point#attractToGrid\r\n         *\r\n         * @see Point#attractorDistance\r\n         * @see Point#attractorUnit\r\n         * @see Point#snapToGrid\r\n         * @see Point#snapSizeX\r\n         * @see Point#snapSizeY\r\n         * @type Boolean\r\n         * @default false\r\n         *\r\n         * @example\r\n         * board.create('point', [3, 3], { attractToGrid: true, attractorDistance: 10, attractorunit: 'screen' });\r\n         *\r\n         * </pre><div id=\"JXG397ab787-cd40-449c-a7e7-a3f7bab1d4f6\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG397ab787-cd40-449c-a7e7-a3f7bab1d4f6',\r\n         *             {boundingbox: [-1, 4, 7,-4], axis: true, showcopyright: false, shownavigation: false});\r\n         *     board.create('point', [3, 3], { attractToGrid: true, attractorDistance: 10, attractorunit: 'screen' });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        attractToGrid: false,\r\n\r\n        /**\r\n         * Defines together with {@link Point#snapSizeY} the grid the point snaps on to.\r\n         * It is given in user coordinates, not in pixels.\r\n         * The point will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.\r\n         * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks\r\n         * of the default ticks of the default x axes of the board.\r\n         *\r\n         * @name Point#snapSizeX\r\n         *\r\n         * @see Point#snapToGrid\r\n         * @see Point#snapSizeY\r\n         * @see JXG.Board#defaultAxes\r\n         * @type Number\r\n         * @default 1\r\n         */\r\n        snapSizeX: 1,\r\n\r\n        /**\r\n         * Defines together with {@link Point#snapSizeX} the grid the point snaps on to.\r\n         * It is given in user coordinates, not in pixels.\r\n         * The point will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.\r\n         * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks\r\n         * of the default ticks of the default y axes of the board.\r\n         *\r\n         * @name Point#snapSizeY\r\n         *\r\n         * @see Point#snapToGrid\r\n         * @see Point#snapSizeX\r\n         * @see JXG.Board#defaultAxes\r\n         * @type Number\r\n         * @default 1\r\n         */\r\n        snapSizeY: 1,\r\n\r\n        /**\r\n         * If set to true, the point will snap to the nearest point in distance of\r\n         * {@link Point#attractorDistance}.\r\n         *\r\n         * @name Point#snapToPoints\r\n         *\r\n         * @see Point#attractorDistance\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        snapToPoints: false,\r\n\r\n        /**\r\n         * List of elements which are ignored by snapToPoints.\r\n         * @name Point#ignoredSnapToPoints\r\n         *\r\n         * @type Array\r\n         * @default empty\r\n         */\r\n        ignoredSnapToPoints: []\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special polygon options */\r\n    polygon: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * If <tt>true</tt>, moving the mouse over inner points triggers hasPoint.\r\n         *\r\n         * @see JXG.GeometryElement#hasPoint\r\n         * @name Polygon#hasInnerPoints\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        hasInnerPoints: false,\r\n\r\n        fillColor: Color.palette.yellow,\r\n        highlightFillColor: Color.palette.yellow,\r\n        // fillColor: '#00ff00',\r\n        // highlightFillColor: '#00ff00',\r\n        fillOpacity: 0.3,\r\n        highlightFillOpacity: 0.2,\r\n\r\n        /**\r\n         * Is the polygon bordered by lines?\r\n         *\r\n         * @type Boolean\r\n         * @name Polygon#withLines\r\n         * @default true\r\n         */\r\n        withLines: true,\r\n\r\n        /**\r\n         * Attributes for the polygon border lines.\r\n         *\r\n         * @type Line\r\n         * @name Polygon#borders\r\n         */\r\n        borders: {\r\n            withLabel: false,\r\n            strokeWidth: 1,\r\n            highlightStrokeWidth: 1,\r\n            // Polygon layer + 1\r\n            layer: 5,\r\n            label: {\r\n                position: 'top'\r\n            },\r\n            visible: 'inherit'\r\n        },\r\n\r\n        /**\r\n         * By default, the strokewidths of the borders of a polygon are not changed during highlighting (only strokeColor and strokeOpacity are changed\r\n         * to highlightStrokeColor, and highlightStrokeOpacity).\r\n         * However, strokewidth is changed to highlightStrokewidth if an individual border gets the focus.\r\n         * <p>\r\n         * With this attribute set to true, also the borders change strokeWidth if the polygon itself gets the focus.\r\n         *\r\n         * @type Boolean\r\n         * @name Polygon#highlightByStrokeWidth\r\n         * @default false\r\n         */\r\n        highlightByStrokeWidth: false,\r\n\r\n        /**\r\n         * Attributes for the polygon vertices.\r\n         *\r\n         * @type Point\r\n         * @name Polygon#vertices\r\n         */\r\n        vertices: {\r\n            layer: 9,\r\n            withLabel: false,\r\n            name: '',\r\n            strokeColor: Color.palette.red,\r\n            fillColor: Color.palette.red,\r\n            fixed: false,\r\n            visible: 'inherit'\r\n        },\r\n\r\n        /**\r\n         * Attributes for the polygon label.\r\n         *\r\n         * @type Label\r\n         * @name Polygon#label\r\n         */\r\n        label: {\r\n            offset: [0, 0]\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special polygonal chain options\r\n    */\r\n    polygonalchain: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        fillColor: 'none',\r\n        highlightFillColor: 'none'\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special prescribed angle options\r\n    * Not yet implemented. But angle.setAngle(val) is implemented.\r\n\r\n    */\r\n    prescribedangle: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Attributes for the helper point of the prescribed angle.\r\n         *\r\n         * @type Point\r\n         * @name Prescribedangle#anglePoint\r\n         * @ignore\r\n         */\r\n        anglePoint: {\r\n            size: 2,\r\n            visible: false,\r\n            withLabel: false\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special reflection options */\r\n    reflection: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        fixed: true,\r\n\r\n        /**\r\n         * Attributes of circle center, i.e. the center of the circle,\r\n         * if a circle is the mirror element and the transformation type is 'Euclidean'\r\n         *\r\n         * @type center\r\n         * @name Reflection#center\r\n         */\r\n        center: {},\r\n\r\n        /**\r\n         * Type of transformation. Possible values are 'Euclidean', 'projective'.\r\n         *\r\n         * If the value is 'Euclidean', the reflected element of a circle is again a circle,\r\n         * otherwise it is a conic section.\r\n         *\r\n         * @type String\r\n         * @name Reflection#type\r\n         * @default 'Euclidean'\r\n         */\r\n        type: 'Euclidean'\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special reflexangle options */\r\n    reflexangle: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special regular polygon options */\r\n    regularpolygon: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * If <tt>true</tt>, moving the mouse over inner points triggers hasPoint.\r\n         * @see JXG.GeometryElement#hasPoint\r\n         *\r\n         * @name RegularPolygon#hasInnerPoints\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        hasInnerPoints: false,\r\n        fillColor: Color.palette.yellow,\r\n        highlightFillColor: Color.palette.yellow,\r\n        fillOpacity: 0.3,\r\n        highlightFillOpacity: 0.2,\r\n\r\n        /**\r\n         * Is the polygon bordered by lines?\r\n         *\r\n         * @type Boolean\r\n         * @name RegularPolygon#withLines\r\n         * @default true\r\n         */\r\n        withLines: true,\r\n\r\n        /**\r\n         * Attributes for the polygon border lines.\r\n         *\r\n         * @type Line\r\n         * @name RegularPolygon#borders\r\n         */\r\n        borders: {\r\n            withLabel: false,\r\n            strokeWidth: 1,\r\n            highlightStrokeWidth: 1,\r\n            // Polygon layer + 1\r\n            layer: 5,\r\n            label: {\r\n                position: 'top'\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Attributes for the polygon vertices.\r\n         *\r\n         * @type Point\r\n         * @name RegularPolygon#vertices\r\n         */\r\n        vertices: {\r\n            layer: 9,\r\n            withLabel: true,\r\n            strokeColor: Color.palette.red,\r\n            fillColor: Color.palette.red,\r\n            fixed: false\r\n        },\r\n\r\n        /**\r\n         * Attributes for the polygon label.\r\n         *\r\n         * @type Label\r\n         * @name RegularPolygon#label\r\n         */\r\n        label: {\r\n            offset: [0, 0]\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for riemann sums */\r\n    riemannsum: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        withLabel: false,\r\n        fillOpacity: 0.3,\r\n        fillColor: Color.palette.yellow\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special sector options */\r\n    sector: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        fillColor: Color.palette.yellow,\r\n        highlightFillColor: Color.palette.yellow,\r\n        // fillColor: '#00ff00',\r\n        // highlightFillColor: '#00ff00',\r\n\r\n        fillOpacity: 0.3,\r\n        highlightFillOpacity: 0.3,\r\n        highlightOnSector: false,\r\n        highlightStrokeWidth: 0,\r\n\r\n        /**\r\n         * If true, there is a fourth parent point, i.e. the parents are [center, p1, p2, p3].\r\n         * p1 is still the radius point, p2 the angle point. The sector will be that part of the\r\n         * the circle with center 'center' which starts at p1, ends at the ray between center\r\n         * and p2, and passes p3.\r\n         * <p>\r\n         * This attribute is immutable (by purpose).\r\n         * This attribute is necessary for circumCircleSectors\r\n         *\r\n         * @type Boolean\r\n         * @name Arc#useDirection\r\n         * @default false\r\n         * @private\r\n         */\r\n        useDirection: false,\r\n\r\n        /**\r\n         * Type of sector. Possible values are 'minor', 'major', and 'auto'.\r\n         *\r\n         * @type String\r\n         * @name Sector#selection\r\n         * @default 'auto'\r\n         */\r\n        selection: 'auto',\r\n\r\n        /**\r\n         * Attributes for sub-element arc. It is only available, if the sector is defined by three points.\r\n         *\r\n         * @type Arc\r\n         * @name Sector#arc\r\n         * @default '{visible:false}'\r\n         */\r\n        arc: {\r\n            visible: false,\r\n            fillColor: 'none',\r\n            withLabel: false,\r\n            name: '',\r\n\r\n            center: {\r\n                visible: false,\r\n                withLabel: false,\r\n                name: ''\r\n            },\r\n\r\n            radiusPoint: {\r\n                visible: false,\r\n                withLabel: false,\r\n                name: ''\r\n            },\r\n\r\n            anglePoint: {\r\n                visible: false,\r\n                withLabel: false,\r\n                name: ''\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Attributes for helper point radiuspoint in case it is provided by coordinates.\r\n         *\r\n         * @type Point\r\n         * @name Sector#radiusPoint\r\n         */\r\n        radiusPoint: {\r\n            visible: false,\r\n            withLabel: false\r\n        },\r\n\r\n        /**\r\n         * Attributes for helper point center in case it is provided by coordinates.\r\n         *\r\n         * @type Point\r\n         * @name Sector#center\r\n         */\r\n        center: {\r\n            visible: false,\r\n            withLabel: false\r\n        },\r\n\r\n        /**\r\n         * Attributes for helper point anglepoint in case it is provided by coordinates.\r\n         *\r\n         * @type Point\r\n         * @name Sector#anglePoint\r\n         */\r\n        anglePoint: {\r\n            visible: false,\r\n            withLabel: false\r\n        },\r\n\r\n        /**\r\n         * Attributes for the sector label.\r\n         *\r\n         * @type Label\r\n         * @name Sector#label\r\n         */\r\n        label: {\r\n            offset: [0, 0],\r\n            anchorX: 'auto',\r\n            anchorY: 'auto'\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special segment options */\r\n    segment: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        label: {\r\n            position: 'top'\r\n        }\r\n        /**#@-*/\r\n    },\r\n\r\n    semicircle: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Attributes for center point of the semicircle.\r\n         *\r\n         * @type Point\r\n         * @name Semicircle#center\r\n         */\r\n        center: {\r\n            visible: false,\r\n            withLabel: false,\r\n            fixed: false,\r\n            fillColor: Color.palette.red,\r\n            strokeColor: Color.palette.red,\r\n            highlightFillColor: '#eeeeee',\r\n            highlightStrokeColor: Color.palette.red,\r\n            name: ''\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special slider options */\r\n    slider: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * The slider only returns integer multiples of this value, e.g. for discrete values set this property to <tt>1</tt>. For\r\n         * continuous results set this to <tt>-1</tt>.\r\n         *\r\n         * @memberOf Slider.prototype\r\n         * @name snapWidth\r\n         * @type Number\r\n         */\r\n        snapWidth: -1,      // -1 = deactivated\r\n\r\n        /**\r\n         * List of values to snap to. If the glider is within snapValueDistance\r\n         * (in user coordinate units) of one of these points,\r\n         * then the glider snaps to that point.\r\n         *\r\n         * @memberOf Slider.prototype\r\n         * @name snapValues\r\n         * @type Array\r\n         * @see Slider#snapValueDistance\r\n         * @default empty\r\n         *\r\n         * @example\r\n         *         var n = board.create('slider', [[-2, 3], [4, 3], [1, 5, 100]], {\r\n         *             name: 'n',\r\n         *             snapWidth: 1,\r\n         *             snapValues: [1, 22, 77, 100],\r\n         *             snapValueDistance: 5\r\n         *         });\r\n         *\r\n         *         var k = board.create('slider', [[-2, -1], [4, -1], [-4, 0, 4]], {\r\n         *             name: 'k',\r\n         *             snapWidth: 0.1,\r\n         *             snapValues: [-3, -1, 1, 3],\r\n         *             snapValueDistance: 0.4\r\n         *         });\r\n         *\r\n         * </pre><div id=\"JXG9be68014-4e14-479a-82b4-e92d9b8f6eef\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG9be68014-4e14-479a-82b4-e92d9b8f6eef',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *             var n = board.create('slider', [[-2, 3], [4, 3], [1, 5, 100]], {\r\n         *                 name: 'n',\r\n         *                 snapWidth: 1,\r\n         *                 snapValues: [1, 22, 77, 100],\r\n         *                 snapValueDistance: 5\r\n         *             });\r\n         *\r\n         *             var k = board.create('slider', [[-2, -1], [4, -1], [-4, 0, 4]], {\r\n         *                 name: 'k',\r\n         *                 snapWidth: 0.1,\r\n         *                 snapValues: [-3, -1, 1, 3],\r\n         *                 snapValueDistance: 0.4\r\n         *             });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        snapValues: [],\r\n\r\n        /**\r\n         * If the difference between the slider value and one of the elements of snapValues is less\r\n         * than this number (in user coordinate units), the slider will snap to that value.\r\n         *\r\n         * @memberOf Slider.prototype\r\n         * @name snapValueDistance\r\n         * @type Number\r\n         * @see Slider#snapValues\r\n         * @default 0.0\r\n         */\r\n        snapValueDistance: 0.0,\r\n\r\n        /**\r\n         * The precision of the slider value displayed in the optional text.\r\n         * Replaced by the attribute \"digits\".\r\n         *\r\n         * @memberOf Slider.prototype\r\n         * @name precision\r\n         * @type Number\r\n         * @deprecated\r\n         * @see Slider#digits\r\n         * @default 2\r\n         */\r\n        precision: 2,\r\n\r\n        /**\r\n         * The number of digits of the slider value displayed in the optional text.\r\n         *\r\n         * @memberOf Slider.prototype\r\n         * @name digits\r\n         * @type Number\r\n         * @default 2\r\n         */\r\n        digits: 2,\r\n\r\n        /**\r\n         * Internationalization support for slider labels.\r\n         *\r\n         * @name intl\r\n         * @memberOf Slider.prototype\r\n         * @type object\r\n         * @default <pre>{\r\n         *    enabled: 'inherit',\r\n         *    options: {}\r\n         * }</pre>\r\n         * @see JXG.Board#intl\r\n         * @see Text#intl\r\n         *\r\n         * @example\r\n         * var s = board.create('slider', [[-2, 3], [2, 3], [0, 1, 360]], {\r\n         *     name: '&alpha;',\r\n         *     snapWidth: 1,\r\n         *     intl: {\r\n         *         enabled: true,\r\n         *         options: {\r\n         *             style: 'unit',\r\n         *             unit: 'degree',\r\n         *         }\r\n         *     }\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXGb49a9779-c0c8-419d-9173-c67232cfd65c\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGb49a9779-c0c8-419d-9173-c67232cfd65c',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var s = board.create('slider', [[-2, 3], [2, 3], [0, 1, 360]], {\r\n         *         name: '&alpha;',\r\n         *         snapWidth: 1,\r\n         *         intl: {\r\n         *             enabled: true,\r\n         *             options: {\r\n         *                 style: 'unit',\r\n         *                 unit: 'degree',\r\n         *             }\r\n         *         }\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        intl: {\r\n            enabled: 'inherit',\r\n            options: {}\r\n        },\r\n\r\n        firstArrow: false,\r\n        lastArrow: false,\r\n\r\n        /**\r\n         * Show slider ticks.\r\n         *\r\n         * @type Boolean\r\n         * @name Slider#withTicks\r\n         * @default true\r\n         */\r\n        withTicks: true,\r\n\r\n        /**\r\n         * Show slider label.\r\n         *\r\n         * @type Boolean\r\n         * @name Slider#withLabel\r\n         * @default true\r\n         */\r\n        withLabel: true,\r\n\r\n        /**\r\n         * If not null, this replaces the part \"name = \" in the slider label.\r\n         * Possible types: string, number or function.\r\n         * @type String\r\n         * @name suffixLabel\r\n         * @memberOf Slider.prototype\r\n         * @default null\r\n         * @see JXG.Slider#unitLabel\r\n         * @see JXG.Slider#postLabel\r\n         */\r\n        suffixLabel: null,\r\n\r\n        /**\r\n         * If not null, this is appended to the value in the slider label.\r\n         * Possible types: string, number or function.\r\n         * @type String\r\n         * @name unitLabel\r\n         * @memberOf Slider.prototype\r\n         * @default null\r\n         * @see JXG.Slider#suffixLabel\r\n         * @see JXG.Slider#postLabel\r\n         */\r\n        unitLabel: null,\r\n\r\n        /**\r\n         * If not null, this is appended to the value and to unitLabel in the slider label.\r\n         * Possible types: string, number or function.\r\n         * @type String\r\n         * @name postLabel\r\n         * @memberOf Slider.prototype\r\n         * @default null\r\n         * @see JXG.Slider#suffixLabel\r\n         * @see JXG.Slider#unitLabel\r\n         */\r\n        postLabel: null,\r\n\r\n        layer: 9,\r\n        showInfobox: false,\r\n        name: '',\r\n        visible: true,\r\n        strokeColor: '#000000',\r\n        highlightStrokeColor: '#888888',\r\n        fillColor: '#ffffff',\r\n        highlightFillColor: 'none',\r\n\r\n        /**\r\n         * Size of slider point.\r\n         *\r\n         * @type Number\r\n         * @name Slider#size\r\n         * @default 6\r\n         * @see Point#size\r\n         */\r\n        size: 6,\r\n\r\n        /**\r\n         * Attributes for first (left) helper point defining the slider position.\r\n         *\r\n         * @type Point\r\n         * @name Slider#point1\r\n         */\r\n        point1: {\r\n            needsRegularUpdate: false,\r\n            showInfobox: false,\r\n            withLabel: false,\r\n            visible: false,\r\n            fixed: true,\r\n            frozen: 'inherit',\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for second (right) helper point defining the slider position.\r\n         *\r\n         * @type Point\r\n         * @name Slider#point2\r\n         */\r\n        point2: {\r\n            needsRegularUpdate: false,\r\n            showInfobox: false,\r\n            withLabel: false,\r\n            visible: false,\r\n            fixed: true,\r\n            frozen: 'inherit',\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for the base line of the slider.\r\n         *\r\n         * @type Line\r\n         * @name Slider#baseline\r\n         */\r\n        baseline: {\r\n            needsRegularUpdate: false,\r\n            visible: 'inherit',\r\n            fixed: true,\r\n            scalable: false,\r\n            tabindex: null,\r\n            name: '',\r\n            strokeWidth: 1,\r\n            strokeColor: '#000000',\r\n            highlightStrokeColor: '#888888'\r\n        },\r\n\r\n        /**\r\n         * Attributes for the ticks of the base line of the slider.\r\n         *\r\n         * @type Ticks\r\n         * @name Slider#ticks\r\n         */\r\n        ticks: {\r\n            needsRegularUpdate: false,\r\n            fixed: true,\r\n\r\n            // Label drawing\r\n            drawLabels: false,\r\n            digits: 2,\r\n            includeBoundaries: true,\r\n            drawZero: true,\r\n            label: {\r\n                offset: [-4, -14],\r\n                display: 'internal'\r\n            },\r\n\r\n            minTicksDistance: 30,\r\n            insertTicks: true,\r\n            ticksDistance: 1,      // Not necessary, since insertTicks = true\r\n            minorHeight: 4,        // if <0: full width and height\r\n            majorHeight: 5,        // if <0: full width and height\r\n            minorTicks: 0,\r\n            strokeOpacity: 1,\r\n            strokeWidth: 1,\r\n            tickEndings: [0, 1],\r\n            majortickEndings: [0, 1],\r\n            strokeColor: '#000000',\r\n            visible: 'inherit'\r\n        },\r\n\r\n        /**\r\n         * Attributes for the highlighting line of the slider.\r\n         *\r\n         * @type Line\r\n         * @name Slider#highline\r\n         */\r\n        highline: {\r\n            strokeWidth: 3,\r\n            visible: 'inherit',\r\n            fixed: true,\r\n            tabindex: null,\r\n            name: '',\r\n            strokeColor: '#000000',\r\n            highlightStrokeColor: '#888888'\r\n        },\r\n\r\n        /**\r\n         * Attributes for the slider label.\r\n         *\r\n         * @type Label\r\n         * @name Slider#label\r\n         */\r\n        label: {\r\n            visible: 'inherit',\r\n            strokeColor: '#000000'\r\n        },\r\n\r\n        /**\r\n         * If true, 'up' events on the baseline will trigger slider moves.\r\n         *\r\n         * @type Boolean\r\n         * @name Slider#moveOnUp\r\n         * @default true\r\n         */\r\n        moveOnUp: true\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special vector field options */\r\n    slopefield: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        strokeWidth: 0.5,\r\n        highlightStrokeWidth: 0.5,\r\n        highlightStrokeColor: Color.palette.blue,\r\n        highlightStrokeOpacity: 0.8,\r\n\r\n        /**\r\n         * Set length of the vectors in user coordinates. This in contrast to vector fields, where this attribute just scales the vector.\r\n         * @name scale\r\n         * @memberOf Slopefield.prototype\r\n         * @type {Number|Function}\r\n         * @see Vectorfield.scale\r\n         * @default 1\r\n         */\r\n        scale: 1,\r\n\r\n        /**\r\n         * Customize arrow heads of vectors. Be careful! If enabled this will slow down the performance.\r\n         * Fields are:\r\n         * <ul>\r\n         *  <li> enabled: Boolean\r\n         *  <li> size: length of the arrow head legs (in pixel)\r\n         *  <li> angle: angle of the arrow head legs In radians.\r\n         * </ul>\r\n         * @name arrowhead\r\n         * @memberOf Slopefield.prototype\r\n         * @type {Object}\r\n         * @default <tt>{enabled: false, size: 5, angle: Math.PI * 0.125}</tt>\r\n         */\r\n        arrowhead: {\r\n            enabled: false,\r\n            size: 5,\r\n            angle: Math.PI * 0.125\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for slope triangle */\r\n    slopetriangle: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        fillColor: Color.palette.red,\r\n        fillOpacity: 0.4,\r\n        highlightFillColor: Color.palette.red,\r\n        highlightFillOpacity: 0.3,\r\n\r\n        borders: {\r\n            lastArrow: {\r\n                type: 1,\r\n                size: 6\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Attributes for the gliding helper point.\r\n         *\r\n         * @type Point\r\n         * @name Slopetriangle#glider\r\n         */\r\n        glider: {\r\n            fixed: true,\r\n            visible: false,\r\n            withLabel: false\r\n        },\r\n\r\n        /**\r\n         * Attributes for the base line.\r\n         *\r\n         * @type Line\r\n         * @name Slopetriangle#baseline\r\n         */\r\n        baseline: {\r\n            visible: false,\r\n            withLabel: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for the base point.\r\n         *\r\n         * @type Point\r\n         * @name Slopetriangle#basepoint\r\n         */\r\n        basepoint: {\r\n            visible: false,\r\n            withLabel: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for the tangent.\r\n         * The tangent is constructed by slop triangle if the construction\r\n         * is based on a glider, solely.\r\n         *\r\n         * @type Line\r\n         * @name Slopetriangle#tangent\r\n         */\r\n        tangent: {\r\n            visible: false,\r\n            withLabel: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for the top point.\r\n         *\r\n         * @type Point\r\n         * @name Slopetriangle#toppoint\r\n         */\r\n        toppoint: {\r\n            visible: false,\r\n            withLabel: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for the slope triangle label.\r\n         *\r\n         * @type Label\r\n         * @name Slopetriangle#label\r\n         */\r\n        label: {\r\n            visible: true,\r\n            position: 'first'\r\n        }\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for smartlabel of angle */\r\n    smartlabelangle: {\r\n        cssClass: 'smart-label-solid smart-label-angle',\r\n        highlightCssClass:'smart-label-solid smart-label-angle',\r\n        anchorX: 'left',\r\n        anchorY: 'middle',\r\n\r\n        unit: '',\r\n        prefix: '',\r\n        suffix: '',\r\n\r\n        measure: 'deg',\r\n        useMathJax: true\r\n    },\r\n\r\n    /* special options for smartlabel of circle */\r\n    smartlabelcircle: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * CSS classes for the smart label. Available classes are:\r\n         * <ul>\r\n         * <li> 'smart-label-solid'\r\n         * <li> 'smart-label-outline'\r\n         * <li> 'smart-label-pure'\r\n         * </ul>\r\n         *\r\n         * By default, an additional class is given specific for the element type.\r\n         * Available classes are 'smart-label-angle', 'smart-label-circle',\r\n         * 'smart-label-line', 'smart-label-point', 'smart-label-polygon'.\r\n         *\r\n         * @example\r\n         *  cssClass: 'smart-label-solid smart-label-point'\r\n         *\r\n         * @type String\r\n         * @name Smartlabel#cssClass\r\n         * @see Smartlabel#highlightCssClass\r\n         * @default <ul>\r\n         *  <li> 'smart-label-solid smart-label-circle' for circles</li>\r\n         *  <li> 'smart-label-solid smart-label-point' for points</li>\r\n         *  <li> ...</li>\r\n         * </ul>\r\n         */\r\n        cssClass: 'smart-label-solid smart-label-circle',\r\n\r\n        /**\r\n         * CSS classes for the smart label when highlighted.\r\n         *\r\n         * @type String\r\n         * @name Smartlabel#highlightCssClass\r\n         * @see Smartlabel#cssClass\r\n         * @default <ul>\r\n         *  <li> 'smart-label-solid smart-label-circle' for circles</li>\r\n         *  <li> 'smart-label-solid smart-label-point' for points</li>\r\n         *  <li> ...</li>\r\n         * </ul>\r\n         */\r\n        highlightCssClass:'smart-label-solid smart-label-circle',\r\n        anchorX: 'middle',\r\n        useMathJax: true,\r\n\r\n        /**\r\n         * Measurement unit appended to the output text. For areas, the unit is squared automatically.\r\n         * Comes directly after the measurement value.\r\n         *\r\n         * @type {String|Function}\r\n         * @name Smartlabel#unit\r\n         * @default ''\r\n         */\r\n        unit: '',\r\n\r\n        /**\r\n         * Prefix text for the smartlabel. Comes before the measurement value.\r\n         *\r\n         * @type {String|Function}\r\n         * @name Smartlabel#prefix\r\n         * @default ''\r\n         */\r\n        prefix: '',\r\n\r\n        /**\r\n         * Suffix text for the smartlabel. Comes after unit.\r\n         *\r\n         * @type {String|Function}\r\n         * @name Smartlabel#suffix\r\n         * @default ''\r\n         */\r\n        suffix: '',\r\n\r\n        /**\r\n         * Type of measurement.\r\n         * Available values are:\r\n         *  <ul>\r\n         *  <li> 'deg', 'rad' for angles</li>\r\n         *  <li> 'area', 'perimeter', 'radius' for circles</li>\r\n         *  <li> 'length', 'slope' for lines</li>\r\n         *  <li> 'area', 'perimeter' for polygons</li>\r\n         * </ul>\r\n         * Dependent on this value, i.e. the type of measurement, the label is\r\n         * positioned differently on the object.\r\n         *\r\n         * @type String\r\n         * @name Smartlabel#measure\r\n         * @default <ul>\r\n         *   <li> 'radius' for circles</li>\r\n         *   <li> 'length' for lines</li>\r\n         *   <li> 'area' for polygons</li>\r\n         *   <li> 'deg' for angles</li>\r\n         * </ul>\r\n         */\r\n        measure: 'radius'\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for smartlabel of line */\r\n    smartlabelline: {\r\n        cssClass: 'smart-label-solid smart-label-line',\r\n        highlightCssClass:'smart-label-solid smart-label-line',\r\n        anchorX: 'middle',\r\n\r\n        useMathJax: true,\r\n\r\n        unit: '',\r\n        measure: 'length'\r\n    },\r\n\r\n    /* special options for smartlabel of point */\r\n    smartlabelpoint: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        cssClass: 'smart-label-solid smart-label-point',\r\n        highlightCssClass:'smart-label-solid smart-label-point',\r\n        anchorX: 'middle',\r\n        anchorY: 'top',\r\n\r\n        useMathJax: true,\r\n\r\n        /**\r\n         * Display of point coordinates either as row vector or column vector.\r\n         * Available values are 'row' or 'column'.\r\n         * @type String\r\n         * @name Smartlabel#dir\r\n         * @default 'row'\r\n         */\r\n        dir: 'row',\r\n\r\n        /**\r\n         * Supply a unit suffix.\r\n         *\r\n         * @type String\r\n         * @name Smartlabel#unit\r\n         * @default ''\r\n         */\r\n        unit: ''\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for smartlabel of polygon */\r\n    smartlabelpolygon: {\r\n        cssClass: 'smart-label-solid smart-label-polygon',\r\n        highlightCssClass:'smart-label-solid smart-label-polygon',\r\n        anchorX: 'middle',\r\n\r\n        useMathJax: true,\r\n\r\n        unit: '',\r\n        measure: 'area'\r\n    },\r\n\r\n    /* special options for step functions */\r\n    stepfunction: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special tangent options */\r\n    tangent: {\r\n    },\r\n\r\n    /* special tangent options */\r\n    tangentto: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Attributes for the polar line of the tangentto construction.\r\n         *\r\n         * @name polar\r\n         * @memberOf TangentTo.prototype\r\n         * @type JXG.Line\r\n         */\r\n        polar: {\r\n            visible: false,\r\n            strokeWidth: 1,\r\n            dash: 3\r\n        },\r\n\r\n        /**\r\n         * Attributes for the intersection point of the conic/circle with the polar line of the tangentto construction.\r\n         *\r\n         * @name point\r\n         * @memberOf TangentTo.prototype\r\n         * @type JXG.Point\r\n         */\r\n        point: {\r\n            visible: false\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special tape measure options */\r\n    tapemeasure: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        strokeColor: '#000000',\r\n        strokeWidth: 2,\r\n        highlightStrokeColor: '#000000',\r\n\r\n        /**\r\n         * Show tape measure ticks.\r\n         *\r\n         * @type Boolean\r\n         * @name Tapemeasure#withTicks\r\n         * @default true\r\n         */\r\n        withTicks: true,\r\n\r\n        /**\r\n         * Show tape measure label.\r\n         *\r\n         * @type Boolean\r\n         * @name Tapemeasure#withLabel\r\n         * @default true\r\n         */\r\n        withLabel: true,\r\n\r\n        /**\r\n         * Text rotation in degrees.\r\n         *\r\n         * @name Tapemeasure#rotate\r\n         * @type Number\r\n         * @default 0\r\n         */\r\n        rotate: 0,\r\n\r\n        /**\r\n         * The precision of the tape measure value displayed in the optional text.\r\n         * Replaced by the attribute digits\r\n         *\r\n         * @memberOf Tapemeasure.prototype\r\n         * @name precision\r\n         * @type Number\r\n         * @deprecated\r\n         * @see Tapemeasure#digits\r\n         * @default 2\r\n         */\r\n        precision: 2,\r\n\r\n        /**\r\n         * The precision of the tape measure value displayed in the optional text.\r\n         * @memberOf Tapemeasure.prototype\r\n         * @name digits\r\n         * @type Number\r\n         * @default 2\r\n         */\r\n        digits: 2,\r\n\r\n        /**\r\n         * Attributes for first helper point defining the tape measure position.\r\n         *\r\n         * @type Point\r\n         * @name Tapemeasure#point1\r\n         */\r\n        point1: {\r\n            visible: true,\r\n            strokeColor: '#000000',\r\n            fillColor: '#ffffff',\r\n            fillOpacity: 0.0,\r\n            highlightFillOpacity: 0.1,\r\n            size: 6,\r\n            snapToPoints: true,\r\n            attractorUnit: 'screen',\r\n            attractorDistance: 20,\r\n            showInfobox: false,\r\n            withLabel: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for second helper point defining the tape measure position.\r\n         *\r\n         * @type Point\r\n         * @name Tapemeasure#point2\r\n         */\r\n        point2: {\r\n            visible: true,\r\n            strokeColor: '#000000',\r\n            fillColor: '#ffffff',\r\n            fillOpacity: 0.0,\r\n            highlightFillOpacity: 0.1,\r\n            size: 6,\r\n            snapToPoints: true,\r\n            attractorUnit: 'screen',\r\n            attractorDistance: 20,\r\n            showInfobox: false,\r\n            withLabel: false,\r\n            name: ''\r\n        },\r\n\r\n        /**\r\n         * Attributes for the ticks of the tape measure.\r\n         *\r\n         * @type Ticks\r\n         * @name Tapemeasure#ticks\r\n         */\r\n        ticks: {\r\n            drawLabels: false,\r\n            drawZero: true,\r\n            insertTicks: true,\r\n            ticksDistance: 0.1, // Ignored, since insertTicks=true\r\n            minorHeight: 8,\r\n            majorHeight: 16,\r\n            minorTicks: 4,\r\n            tickEndings: [0, 1],\r\n            majorTickEndings: [0, 1],\r\n            strokeOpacity: 1,\r\n            strokeWidth: 1,\r\n            strokeColor: '#000000',\r\n            visible: 'inherit',\r\n            label: {\r\n                anchorY: 'top',\r\n                anchorX: 'middle',\r\n                offset: [0, -10]\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Attributes for the tape measure label.\r\n         *\r\n         * @type Label\r\n         * @name Tapemeasure#label\r\n         */\r\n        label: {\r\n            position: 'top'\r\n        }\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special text options */\r\n    text: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * The font size in pixels.\r\n         *\r\n         * @name fontSize\r\n         * @memberOf Text.prototype\r\n         * @default 12\r\n         * @type Number\r\n         * @see Text#fontUnit\r\n         */\r\n        fontSize: 12,\r\n\r\n        /**\r\n         * CSS unit for the font size of a text element. Usually, this will be the default value 'px' but\r\n         * for responsive application, also 'vw', 'vh', vmax', 'vmin' or 'rem' might be useful.\r\n         *\r\n         * @name fontUnit\r\n         * @memberOf Text.prototype\r\n         * @default 'px'\r\n         * @type String\r\n         * @see Text#fontSize\r\n         *\r\n         * @example\r\n         * var txt = board.create('text', [2, 2, \"hello\"], {fontSize: 8, fontUnit: 'vmin'});\r\n         *\r\n         * </pre><div id=\"JXG2da7e972-ac62-416b-a94b-32559c9ec9f9\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG2da7e972-ac62-416b-a94b-32559c9ec9f9',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var txt = board.create('text', [2, 2, \"hello\"], {fontSize: 8, fontUnit: 'vmin'});\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        fontUnit: 'px',\r\n\r\n        /**\r\n         * If the text content is solely a number and\r\n         * this attribute is true (default) then the number is either formatted\r\n         * according to the number of digits\r\n         * given by the attribute 'digits' or converted into a fraction if 'toFraction'\r\n         * is true.\r\n         * <p>\r\n         * Otherwise, display the raw number.\r\n         *\r\n         * @name formatNumber\r\n         * @memberOf Text.prototype\r\n         * @default false\r\n         * @type Boolean\r\n         *\r\n         */\r\n        formatNumber: false,\r\n\r\n        /**\r\n         * Used to round texts given by a number.\r\n         *\r\n         * @name digits\r\n         * @memberOf Text.prototype\r\n         * @default 2\r\n         * @type Number\r\n         */\r\n        digits: 2,\r\n\r\n        /**\r\n         * Internationalization support for texts consisting of a number only.\r\n         * <p>\r\n         * Setting the local overwrites the board-wide locale set in the board attributes.\r\n         * The JSXGraph attribute digits is overruled by the\r\n         * Intl attributes \"minimumFractionDigits\" and \"maximumFractionDigits\".\r\n         * See <a href=\"https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat\">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat</a>\r\n         * for more information about possible options.\r\n         * <p>\r\n         * See below for an example where the text is composed from a string and a locale formatted number.\r\n         *\r\n         * @name intl\r\n         * @memberOf Text.prototype\r\n         * @type object\r\n         * @default <pre>{\r\n         *    enabled: 'inherit',\r\n         *    options: {\r\n         *      minimumFractionDigits: 0,\r\n         *      maximumFractionDigits: 2\r\n         *    }\r\n         * }</pre>\r\n         * @see JXG.Board#intl\r\n         *\r\n         * @example\r\n         * var t = board.create('text', [1, 2, -Math.PI*100], {\r\n         *         digits: 2,\r\n         *         intl: {\r\n         *                 enabled: true,\r\n         *                 options: {\r\n         *                     style: 'unit',\r\n         *                     unit: 'celsius'\r\n         *                 }\r\n         *             }\r\n         *     });\r\n         *\r\n         * </pre><div id=\"JXGb7162923-1beb-4e56-8817-19aa66e226d1\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGb7162923-1beb-4e56-8817-19aa66e226d1',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var t = board.create('text', [1, 2, -Math.PI*100], {\r\n         *             digits: 2,\r\n         *             intl: {\r\n         *                     enabled: true,\r\n         *                     options: {\r\n         *                         style: 'unit',\r\n         *                         unit: 'celsius'\r\n         *                     }\r\n         *                 }\r\n         *         });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         *\r\n         * @example\r\n         * var t = board.create('text', [0.05, -0.2, ''], {\r\n         *     intl: {\r\n         *         enabled: true,\r\n         *         locale: 'it-IT',\r\n         *         options: {\r\n         *             style: 'unit',\r\n         *             unit: 'kilometer-per-hour',\r\n         *             unitDisplay: 'narrow',\r\n         *             maximumFractionDigits: 2\r\n         *         }\r\n         *     }\r\n         * });\r\n         *\r\n         * // Set dynamic text consisting of text and number.\r\n         * t.setText(function() {\r\n         *     var txt = 'Speed: ',\r\n         *         number = t.X();\r\n         *\r\n         *     // Add formatted number to variable txt\r\n         *     // with fallback if locale is not supported.\r\n         *     if (t.useLocale()) {\r\n         *         txt += t.formatNumberLocale(number);\r\n         *     } else {\r\n         *         txt += JXG.toFixed(number, 2);\r\n         *     }\r\n         *     return txt;\r\n         * });\r\n         *\r\n         * </pre><div id=\"JXG560aeb1c-55fb-45da-8ad5-d3ad26216056\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG560aeb1c-55fb-45da-8ad5-d3ad26216056',\r\n         *             {boundingbox: [-0.5, 0.5, 0.5, -0.5], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var t = board.create('text', [0.3, -0.3, ''], {\r\n         *         intl: {\r\n         *             enabled: true,\r\n         *             locale: 'it-IT',\r\n         *             options: {\r\n         *                 style: 'unit',\r\n         *                 unit: 'kilometer-per-hour',\r\n         *                 unitDisplay: 'narrow',\r\n         *                 maximumFractionDigits: 2\r\n         *             }\r\n         *         }\r\n         *     });\r\n         *\r\n         *     // Set dynamic text consisting of text and number.\r\n         *     t.setText(function() {\r\n         *         var txt = 'Speed: ',\r\n         *             number = t.X();\r\n         *\r\n         *         // Add formatted number to variable txt\r\n         *         if (t.useLocale()) {\r\n         *             txt += t.formatNumberLocale(number);\r\n         *         } else {\r\n         *             txt += JXG.toFixed(number, 2);\r\n         *         }\r\n         *         return txt;\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        intl: {\r\n            enabled: 'inherit',\r\n            options: {\r\n                minimumFractionDigits: 0,\r\n                maximumFractionDigits: 2\r\n            }\r\n        },\r\n\r\n        /**\r\n         * If set to true, the text is parsed and evaluated.\r\n         * For labels parse==true results in converting names of the form k_a to subscripts.\r\n         * If the text is given by string and parse==true, the string is parsed as\r\n         * JessieCode expression.\r\n         *\r\n         * @name parse\r\n         * @memberOf Text.prototype\r\n         * @default true\r\n         * @type Boolean\r\n         */\r\n        parse: true,\r\n\r\n        /**\r\n         * If set to true and caja's sanitizeHTML function can be found it\r\n         * will be used to sanitize text output.\r\n         *\r\n         * @name useCaja\r\n         * @memberOf Text.prototype\r\n         * @default false\r\n         * @type Boolean\r\n         */\r\n        useCaja: false,\r\n\r\n        /**\r\n         * If enabled, the text will be handled as label. Intended for internal use.\r\n         *\r\n         * @name isLabel\r\n         * @memberOf Text.prototype\r\n         * @default false\r\n         * @type Boolean\r\n         */\r\n        isLabel: false,\r\n\r\n        strokeColor: '#000000',\r\n        highlightStrokeColor: '#000000',\r\n        highlightStrokeOpacity: 0.666666,\r\n\r\n        /**\r\n         * Default CSS properties of the HTML text element.\r\n         * <p>\r\n         * The CSS properties which are set here, are handed over to the style property\r\n         * of the HTML text element. That means, they have higher property than any\r\n         * CSS class.\r\n         * <p>\r\n         * If a property which is set here should be overruled by a CSS class\r\n         * then this property should be removed here.\r\n         * <p>\r\n         * The reason, why this attribute should be kept to its default value at all,\r\n         * is that screen dumps of SVG boards with <tt>board.renderer.dumpToCanvas()</tt>\r\n         * will ignore the font-family if it is set in a CSS class.\r\n         * It has to be set explicitly as style attribute.\r\n         * <p>\r\n         * In summary, the order of priorities (specificity) from high to low is\r\n         * <ol>\r\n         *  <li> JXG.Options.text.cssStyle\r\n         *  <li> JXG.Options.text.cssDefaultStyle\r\n         *  <li> JXG.Options.text.cssClass\r\n         * </ol>\r\n         * @example\r\n         * If all texts should get its font-family from the default CSS class\r\n         * before initializing the board\r\n         * <pre>\r\n         *   JXG.Options.text.cssDefaultStyle = '';\r\n         *   JXG.Options.text.highlightCssDefaultStyle = '';\r\n         * </pre>\r\n         * should be called.\r\n         *\r\n         * @name cssDefaultStyle\r\n         * @memberOf Text.prototype\r\n         * @default  'font-family: Arial, Helvetica, Geneva, sans-serif;'\r\n         * @type String\r\n         * @see Text#highlightCssDefaultStyle\r\n         * @see Text#cssStyle\r\n         * @see Text#highlightCssStyle\r\n         */\r\n        cssDefaultStyle: 'font-family: Arial, Helvetica, Geneva, sans-serif;',\r\n\r\n        /**\r\n         * Default CSS properties of the HTML text element in case of highlighting.\r\n         * <p>\r\n         * The CSS properties which are set here, are handed over to the style property\r\n         * of the HTML text element. That means, they have higher property than any\r\n         * CSS class.\r\n         * @example\r\n         * If all texts should get its font-family from the default CSS class\r\n         * before initializing the board\r\n         * <pre>\r\n         *   JXG.Options.text.cssDefaultStyle = '';\r\n         *   JXG.Options.text.highlightCssDefaultStyle = '';\r\n         * </pre>\r\n         * should be called.\r\n         *\r\n         * @name highlightCssDefaultStyle\r\n         * @memberOf Text.prototype\r\n         * @default  'font-family: Arial, Helvetica, Geneva, sans-serif;'\r\n         * @type String\r\n         * @see Text#cssDefaultStyle\r\n         * @see Text#cssStyle\r\n         * @see Text#highlightCssStyle\r\n        */\r\n        highlightCssDefaultStyle: 'font-family: Arial, Helvetica, Geneva, sans-serif;',\r\n\r\n        /**\r\n         * CSS properties of the HTML text element.\r\n         * <p>\r\n         * The CSS properties which are set here, are handed over to the style property\r\n         * of the HTML text element. That means, they have higher property (specificity) han any\r\n         * CSS class.\r\n         *\r\n         * @name cssStyle\r\n         * @memberOf Text.prototype\r\n         * @default  ''\r\n         * @type String\r\n         * @see Text#cssDefaultStyle\r\n         * @see Text#highlightCssDefaultStyle\r\n         * @see Text#highlightCssStyle\r\n        */\r\n        cssStyle: '',\r\n\r\n        /**\r\n         * CSS properties of the HTML text element in case of highlighting.\r\n         * <p>\r\n         * The CSS properties which are set here, are handed over to the style property\r\n         * of the HTML text element. That means, they have higher property (specificity) than any\r\n         * CSS class.\r\n         *\r\n         * @name highlightCssStyle\r\n         * @memberOf Text.prototype\r\n         * @default  ''\r\n         * @type String\r\n         * @see Text#cssDefaultStyle\r\n         * @see Text#highlightCssDefaultStyle\r\n         * @see Text#cssStyle\r\n        */\r\n        highlightCssStyle: '',\r\n\r\n        transitionProperties: ['color', 'opacity'],\r\n\r\n        /**\r\n         * If true, the input will be given to ASCIIMathML before rendering.\r\n         *\r\n         * @name useASCIIMathML\r\n         * @memberOf Text.prototype\r\n         * @default false\r\n         * @type Boolean\r\n         */\r\n        useASCIIMathML: false,\r\n\r\n        /**\r\n         * If true, MathJax will be used to render the input string.\r\n         * Supports MathJax 2 as well as Mathjax 3.\r\n         * It is recommended to use this option together with the option\r\n         * \"parse: false\". Otherwise, 4 backslashes (e.g. \\\\\\\\alpha) are needed\r\n         * instead of two (e.g. \\\\alpha).\r\n         *\r\n         * @name useMathJax\r\n         * @memberOf Text.prototype\r\n         * @default false\r\n         * @type Boolean\r\n         * @see Text#parse\r\n         *\r\n         * @example\r\n         *  // Before loading MathJax, it has to be configured something like this:\r\n         * window.MathJax = {\r\n         *   tex: {\r\n         *     inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\r\n         *     displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ],\r\n         *     packages: ['base', 'ams']\r\n         *   },\r\n         *   options: {\r\n         *     ignoreHtmlClass: 'tex2jax_ignore',\r\n         *     processHtmlClass: 'tex2jax_process'\r\n         *   }\r\n         * };\r\n         *\r\n         * // Display style\r\n         * board.create('text',[ 2,2,  function(){return '$$X=\\\\frac{2}{x}$$'}], {\r\n         *     fontSize: 15, color:'green', useMathJax: true});\r\n         *\r\n         * // Inline style\r\n         * board.create('text',[-2,2,  function(){return '$X_A=\\\\frac{2}{x}$'}], {\r\n         *     fontSize: 15, color:'green', useMathJax: true});\r\n         *\r\n         * var A = board.create('point', [-2, 0]);\r\n         * var B = board.create('point', [1, 0]);\r\n         * var C = board.create('point', [0, 1]);\r\n         *\r\n         * var graph = board.create('ellipse', [A, B, C], {\r\n         *         fixed: true,\r\n         *         withLabel: true,\r\n         *         strokeColor: 'black',\r\n         *         strokeWidth: 2,\r\n         *         fillColor: '#cccccc',\r\n         *         fillOpacity: 0.3,\r\n         *         highlightStrokeColor: 'red',\r\n         *         highlightStrokeWidth: 3,\r\n         *         name: '$1=\\\\frac{(x-h)^2}{a^2}+\\\\frac{(y-k)^2}{b^2}$',\r\n         *         label: {useMathJax: true}\r\n         *     });\r\n         *\r\n         * var nvect1 = board.create('text', [-4, -3, '\\\\[\\\\overrightarrow{V}\\\\]'],\r\n         * {\r\n         *   fontSize: 24, parse: false\r\n         * });\r\n         * var nvect1 = board.create('text', [-2, -4, function() {return '$\\\\overrightarrow{G}$';}],\r\n         * {\r\n         *   fontSize: 24, useMathJax: true\r\n         * });\r\n         *\r\n         * </pre>\r\n         * <script>\r\n         * window.MathJax = {\r\n         *   tex: {\r\n         *     inlineMath: [ ['$','$'], [\"\\\\(\",\"\\\\)\"] ],\r\n         *     displayMath: [ ['$$','$$'], [\"\\\\[\",\"\\\\]\"] ],\r\n         *     packages: ['base', 'ams']\r\n         *   },\r\n         *   options: {\r\n         *     ignoreHtmlClass: 'tex2jax_ignore',\r\n         *     processHtmlClass: 'tex2jax_process'\r\n         *   }\r\n         * };\r\n         * </script>\r\n         * <script src=\"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js\" id=\"MathJax-script\"></script>\r\n         * <div id=\"JXGe2a04876-5813-4db0-b7e8-e48bf4e220b9\" class=\"jxgbox\" style=\"width: 400px; height: 400px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGe2a04876-5813-4db0-b7e8-e48bf4e220b9',\r\n         *             {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false});\r\n         *     // Display style\r\n         *     board.create('text',[ 2,2,  function(){return '$$X=\\\\frac{2}{x}$$'}], {\r\n         *         fontSize: 15, color:'green', useMathJax: true});\r\n         *\r\n         *     // Inline style\r\n         *     board.create('text',[-2,2,  function(){return '$X_A=\\\\frac{2}{x}$'}], {\r\n         *         fontSize: 15, color:'green', useMathJax: true});\r\n         *\r\n         *     var A = board.create('point', [-2, 0]);\r\n         *     var B = board.create('point', [1, 0]);\r\n         *     var C = board.create('point', [0, 1]);\r\n         *\r\n         *     var graph = board.create('ellipse', [A, B, C], {\r\n         *             fixed: true,\r\n         *             withLabel: true,\r\n         *             strokeColor: 'black',\r\n         *             strokeWidth: 2,\r\n         *             fillColor: '#cccccc',\r\n         *             fillOpacity: 0.3,\r\n         *             highlightStrokeColor: 'red',\r\n         *             highlightStrokeWidth: 3,\r\n         *             name: '$1=\\\\frac{(x-h)^2}{a^2}+\\\\frac{(y-k)^2}{b^2}$',\r\n         *             label: {useMathJax: true}\r\n         *         });\r\n         *\r\n         *     var nvect1 = board.create('text', [-4, -3, '\\\\[\\\\overrightarrow{V}\\\\]'],\r\n         *     {\r\n         *       fontSize: 24, parse: false\r\n         *     });\r\n         *     var nvect1 = board.create('text', [-2, -4, function() {return '$\\\\overrightarrow{G}$';}],\r\n         *     {\r\n         *       fontSize: 24, useMathJax: true\r\n         *     });\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         *\r\n         * @example\r\n         * // Load MathJax:\r\n         * // &lt;script src=\"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js\"&lt;&lt;/script&gt;\r\n         *\r\n         * // function and its derivative\r\n         * var f1 = function(x) { return x * x * x; },\r\n         * graph1 = board.create('functiongraph', [f1, -0.1, 1.1]),\r\n         *\r\n         * A = board.create('glider', [0.5, f1(0.5), graph1], {\r\n         *             name: 'f(x)',\r\n         *             color: 'black',\r\n         *             face:'x',\r\n         *             fixed: true,\r\n         *             size: 3,\r\n         *             label: {offset: [-30, 10], fontSize: 15}\r\n         *         }),\r\n         * B = board.create('glider', [0.7, f1(0.7), graph1], {\r\n         *             name: 'f(x+&Delta;x)',\r\n         *             size: 3,\r\n         *             label: {offset: [-60, 10], fontSize: 15}\r\n         *         }),\r\n         *\r\n         * secant_line = board.create('line', [A,B],{dash: 1, color: 'green'}),\r\n         * a_h_segment = board.create('segment', [A, [\r\n         *                     function(){ return B.X() > A.X() ? B.X() : A.X()},\r\n         *                     function(){ return B.X() > A.X() ? A.Y() : B.Y()}\r\n         *                 ]],{ name: '&Delta;x', dash: 1, color: 'black'});\r\n         *\r\n         * b_v_segment = board.create('segment', [B, [\r\n         *                     function(){ return B.X() > A.X() ? B.X() : A.X()},\r\n         *                     function(){ return B.X() > A.X() ? A.Y() : B.Y()}\r\n         *                 ]],{ name: '&Delta;y', dash: 1, color: 'black'}),\r\n         *\r\n         * ma = board.create('midpoint', [a_h_segment.point1, a_h_segment.point2\r\n         *     ], {visible: false});\r\n         *\r\n         * board.create('text', [0, 0, function() {return '\\\\[\\\\Delta_x='+(B.X()-A.X()).toFixed(4)+'\\\\]'}], {\r\n         *     anchor: ma, useMathJax: true, fixed: true, color: 'green', anchorY: 'top'\r\n         * });\r\n         *\r\n         * mb = board.create('midpoint', [b_v_segment.point1, b_v_segment.point2], {visible: false});\r\n         * board.create('text', [0, 0, function() {return '\\\\[\\\\Delta_y='+(B.Y()-A.Y()).toFixed(4)+'\\\\]'}], {\r\n         *     anchor: mb, useMathJax: true, fixed: true, color: 'green'\r\n         * });\r\n         *\r\n         * dval = board.create('text',[0.1, 0.8,\r\n         *     function(){\r\n         *         return '\\\\[\\\\frac{\\\\Delta_y}{\\\\Delta_x}=\\\\frac{' + ((B.Y()-A.Y()).toFixed(4)) + '}{' + ((B.X()-A.X()).toFixed(4)) +\r\n         *             '}=' + (((B.Y()-A.Y()).toFixed(4))/((B.X()-A.X()).toFixed(4))).toFixed(4) + '\\\\]';\r\n         *     }],{fontSize: 15, useMathJax: true});\r\n         *\r\n         * </pre>\r\n         * <script src=\"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js\" id=\"MathJax-script\"></script>\r\n         * <div id=\"JXG8c2b65e7-4fc4-43f7-b23c-5076a7fa9621\" class=\"jxgbox\" style=\"width: 400px; height: 400px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG8c2b65e7-4fc4-43f7-b23c-5076a7fa9621',\r\n         *             {boundingbox: [-0.1, 1.1, 1.1, -0.1], axis: true, showcopyright: false, shownavigation: false});\r\n         *     // function and its derivative\r\n         *     var f1 = function(x) { return x * x * x; },\r\n         *     graph1 = board.create('functiongraph', [f1, -0.1, 1.1]),\r\n         *\r\n         *     A = board.create('glider', [0.5, f1(0.5), graph1], {\r\n         *                 name: 'f(x)',\r\n         *                 color: 'black',\r\n         *                 face:'x',\r\n         *                 fixed: true,\r\n         *                 size: 3,\r\n         *                 label: {offset: [-30, 10], fontSize: 15}\r\n         *             }),\r\n         *     B = board.create('glider', [0.7, f1(0.7), graph1], {\r\n         *                 name: 'f(x+&Delta;x)',\r\n         *                 size: 3,\r\n         *                 label: {offset: [-60, 10], fontSize: 15}\r\n         *             }),\r\n         *\r\n         *     secant_line = board.create('line', [A,B],{dash: 1, color: 'green'}),\r\n         *     a_h_segment = board.create('segment', [A, [\r\n         *                         function(){ return B.X() > A.X() ? B.X() : A.X()},\r\n         *                         function(){ return B.X() > A.X() ? A.Y() : B.Y()}\r\n         *                     ]],{ name: '&Delta;x', dash: 1, color: 'black'});\r\n         *\r\n         *     b_v_segment = board.create('segment', [B, [\r\n         *                         function(){ return B.X() > A.X() ? B.X() : A.X()},\r\n         *                         function(){ return B.X() > A.X() ? A.Y() : B.Y()}\r\n         *                     ]],{ name: '&Delta;y', dash: 1, color: 'black'}),\r\n         *\r\n         *     ma = board.create('midpoint', [a_h_segment.point1, a_h_segment.point2\r\n         *         ], {visible: false});\r\n         *\r\n         *     board.create('text', [0, 0, function() {return '\\\\[\\\\Delta_x='+(B.X()-A.X()).toFixed(4)+'\\\\]'}], {\r\n         *         anchor: ma, useMathJax: true, fixed: true, color: 'green', anchorY: 'top'\r\n         *     });\r\n         *\r\n         *     mb = board.create('midpoint', [b_v_segment.point1, b_v_segment.point2], {visible: false});\r\n         *     board.create('text', [0, 0, function() {return '\\\\[\\\\Delta_y='+(B.Y()-A.Y()).toFixed(4)+'\\\\]'}], {\r\n         *         anchor: mb, useMathJax: true, fixed: true, color: 'green'\r\n         *     });\r\n         *\r\n         *     dval = board.create('text',[0.1, 0.8,\r\n         *         function(){\r\n         *             return '\\\\[\\\\frac{\\\\Delta_y}{\\\\Delta_x}=\\\\frac{' + ((B.Y()-A.Y()).toFixed(4)) + '}{' + ((B.X()-A.X()).toFixed(4)) +\r\n         *                 '}=' + (((B.Y()-A.Y()).toFixed(4))/((B.X()-A.X()).toFixed(4))).toFixed(4) + '\\\\]';\r\n         *         }],{fontSize: 15, useMathJax: true});\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         * var board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-1, 10, 11, -2], axis: true});\r\n         * board.options.text.useMathjax = true;\r\n         *\r\n         * a = board.create('slider',[[-0.7,1.5],[5,1.5],[0,0.5,1]], {\r\n         *     suffixlabel:'\\\\(t_1=\\\\)',\r\n         *     unitLabel: ' \\\\(\\\\text{ ms}\\\\)',\r\n         *     snapWidth:0.01}),\r\n         *\r\n         * func = board.create('functiongraph',[function(x){return (a.Value()*x*x)}], {strokeColor: \"red\"});\r\n         * text1 = board.create('text', [5, 1, function(){\r\n         *             return '\\\\(a(t)= { 1 \\\\over ' + a.Value().toFixed(3) + '}\\\\)';\r\n         *         }], {fontSize: 15, fixed:true, strokeColor:'red', anchorY: 'top', parse: false});\r\n         *\r\n         * </pre><div id=\"JXGf8bd01db-fb6a-4a5c-9e7f-8823f7aa5ac6\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGf8bd01db-fb6a-4a5c-9e7f-8823f7aa5ac6',\r\n         *             {boundingbox: [-1, 10, 11, -2], axis: true, showcopyright: false, shownavigation: false});\r\n         *     board.options.text.useMathjax = true;\r\n         *\r\n         *     a = board.create('slider',[[-0.7,1.5],[5,1.5],[0,0.5,1]], {\r\n         *         suffixlabel:'\\\\(t_1=\\\\)',\r\n         *         unitLabel: ' \\\\(\\\\text{ ms}\\\\)',\r\n         *         snapWidth:0.01}),\r\n         *\r\n         *     func = board.create('functiongraph',[function(x){return (a.Value()*x*x)}], {strokeColor: \"red\"});\r\n         *     text1 = board.create('text', [5, 1, function(){\r\n         *                 return '\\\\(a(t)= { 1 \\\\over ' + a.Value().toFixed(3) + '}\\\\)';\r\n         *             }], {fontSize: 15, fixed:true, strokeColor:'red', anchorY: 'top', parse: false});\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        useMathJax: false,\r\n\r\n        /**\r\n         *\r\n         * If true, KaTeX will be used to render the input string.\r\n         * For this feature, katex.min.js and katex.min.css have to be included.\r\n         * <p>\r\n         * The example below does not work, because there is a conflict with\r\n         * the MathJax library which is used below.\r\n         * </p>\r\n         *\r\n         * @name useKatex\r\n         * @memberOf Text.prototype\r\n         * @default false\r\n         * @type Boolean\r\n         *\r\n         *\r\n         * @example\r\n         * JXG.Options.text.useKatex = true;\r\n         *\r\n         * const board = JXG.JSXGraph.initBoard('jxgbox', {\r\n         *     boundingbox: [-2, 5, 8, -5], axis:true\r\n         * });\r\n         *\r\n         * var a = board.create('slider',[[-0.7,1.5],[5,1.5],[0,0.5,1]], {\r\n         *     suffixlabel:'t_1=',\r\n         *     unitLabel: ' \\\\text{ ms}',\r\n         *     snapWidth:0.01});\r\n         *\r\n         * func = board.create('functiongraph',[function(x){return (a.Value()*x*x)}], {strokeColor: \"red\"});\r\n         * text1 = board.create('text', [5, 1, function(){\r\n         *             return 'a(t)= { 1 \\\\over ' + a.Value().toFixed(3) + '}';\r\n         *         }], {fontSize: 15, fixed:true, strokeColor:'red', anchorY: 'top'});\r\n         *\r\n         * </pre>\r\n         * <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/katex@0.13.10/dist/katex.min.css\" integrity=\"sha384-0cCFrwW/0bAk1Z/6IMgIyNU3kfTcNirlObr4WjrUU7+hZeD6ravdYJ3kPWSeC31M\" crossorigin=\"anonymous\">\r\n         * <script src=\"https://cdn.jsdelivr.net/npm/katex@0.13.10/dist/katex.min.js\" integrity=\"sha384-dtFDxK2tSkECx/6302Z4VN2ZRqt6Gis+b1IwCjJPrn0kMYFQT9rbtyQWg5NFWAF7\" crossorigin=\"anonymous\"></script>\r\n         * <div id=\"JXG497f065c-cfc1-44c3-ba21-5fa581668869\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG497f065c-cfc1-44c3-ba21-5fa581668869',\r\n         *             {boundingbox: [-2, 5, 8, -5], axis: true, showcopyright: false, shownavigation: false});\r\n         *     board.options.useKatex = true;\r\n         *     var a = board.create('slider',[[-0.7,1.5],[5,1.5],[0,0.5,1]], {\r\n         *         suffixlabel:'t_1=',\r\n         *         unitLabel: ' \\\\text{ ms}',\r\n         *         snapWidth:0.01});\r\n         *\r\n         *     func = board.create('functiongraph',[function(x){return (a.Value()*x*x)}], {strokeColor: \"red\"});\r\n         *     text1 = board.create('text', [5, 1, function(){\r\n         *                 return 'a(t)= { 1 \\\\over ' + a.Value().toFixed(3) + '}';\r\n         *             }], {fontSize: 15, fixed:true, strokeColor:'red', anchorY: 'top'});\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         */\r\n        useKatex: false,\r\n\r\n        /**\r\n         * Object or function returning an object that contains macros for KaTeX.\r\n         *\r\n         * @name katexMacros\r\n         * @memberOf Text.prototype\r\n         * @default <tt>{}</tt>\r\n         * @type Object\r\n         *\r\n         * @example\r\n         * // to globally apply macros to all text elements use:\r\n         * JXG.Options.text.katexMacros = {'\\\\jxg': 'JSXGraph is awesome'};\r\n         *\r\n         * const board = JXG.JSXGraph.initBoard('jxgbox', {\r\n         *     boundingbox: [-2, 5, 8, -5], axis:true\r\n         * });\r\n         *\r\n         * // This macro only get applied to the p ('text') element\r\n         * var p = board.create('text', [1, 0, '\\\\jsg \\\\sR '], { katexMacros: {'\\\\sR':'\\\\mathbb{R}'} });\r\n         */\r\n        katexMacros: {},\r\n\r\n        /**\r\n         * Display number as integer + nominator / denominator. Works together\r\n         * with MathJax, KaTex or as plain text.\r\n         * @name toFraction\r\n         * @memberOf Text.prototype\r\n         * @type Boolean\r\n         * @default false\r\n         * @see JXG#toFraction\r\n         *\r\n         * @example\r\n         *  board.create('text', [2, 2, 2 / 7], { anchorY: 'top', toFraction: true, useMathjax: true });\r\n         *  board.create('text', [2, -2, 2 / 19], { toFraction: true, useMathjax: false });\r\n         *\r\n         * </pre><div id=\"JXGc10fe0b6-15ac-42b6-890f-2593b427d493\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script src=\"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js\" id=\"MathJax-script\"></script>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGc10fe0b6-15ac-42b6-890f-2593b427d493',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *             board.create('text', [2, 2, 2 / 7], { anchorY: 'top', toFraction: true, useMathjax: true });\r\n         *             board.create('text', [2, -2, 2 / 19], { toFraction: true, useMathjax: false });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        toFraction: false,\r\n\r\n        /**\r\n         * Determines the rendering method of the text. Possible values\r\n         * include <tt>'html'</tt> and <tt>'internal</tt>.\r\n         *\r\n         * @name display\r\n         * @memberOf Text.prototype\r\n         * @default 'html'\r\n         * @type String\r\n         */\r\n        display: 'html',\r\n\r\n        /**\r\n         * Anchor element {@link Point}, {@link Text} or {@link Image} of the text.\r\n         * If it exists, the coordinates of the text are relative\r\n         * to this anchor element. In this case, only numbers are possible coordinates,\r\n         * functions are not supported.\r\n         *\r\n         * @name anchor\r\n         * @memberOf Text.prototype\r\n         * @default null\r\n         * @type Object\r\n         */\r\n        anchor: null,\r\n\r\n        /**\r\n         * The horizontal alignment of the text. Possible values include <tt>'auto'</tt>, <tt>'left'</tt>,\r\n         * <tt>'middle'</tt>, and <tt>'right'</tt>.\r\n         *\r\n         * @name anchorX\r\n         * @memberOf Text.prototype\r\n         * @default 'left'\r\n         * @type String\r\n         */\r\n        anchorX: 'left',\r\n\r\n        /**\r\n         * The vertical alignment of the text. Possible values include <tt>'auto</tt>, <tt>'top'</tt>, <tt>'middle'</tt>, and\r\n         * <tt>'bottom'</tt>.\r\n         * For MathJax or KaTeX, 'top' is recommended.\r\n         *\r\n         * @name anchorY\r\n         * @memberOf Text.prototype\r\n         * @default 'middle'\r\n         * @type String\r\n         */\r\n        anchorY: 'middle',\r\n\r\n        /**\r\n         * Apply CSS classes to the text in non-highlighted view. It is possible to supply one or more\r\n         * CSS classes separated by blanks.\r\n         *\r\n         * @name cssClass\r\n         * @memberOf Text.prototype\r\n         * @type String\r\n         * @default 'JXGtext'\r\n         * @see Text#highlightCssClass\r\n         * @see Image#cssClass\r\n         * @see JXG.GeometryElement#cssClass\r\n         */\r\n        cssClass: 'JXGtext',\r\n\r\n        /**\r\n         * Apply CSS classes to the text in highlighted view. It is possible to supply one or more\r\n         * CSS classes separated by blanks.\r\n         *\r\n         * @name highlightCssClass\r\n         * @memberOf Text.prototype\r\n         * @type String\r\n         * @default 'JXGtext'\r\n         * @see Text#cssClass\r\n         * @see Image#highlightCssClass\r\n         * @see JXG.GeometryElement#highlightCssClass\r\n         */\r\n        highlightCssClass: 'JXGtext',\r\n\r\n        /**\r\n         * Sensitive area for dragging the text.\r\n         * Possible values are 'all', or something else.\r\n         * If set to 'small', a sensitivity margin at the right and left border is taken.\r\n         * This may be extended to left, right, ... in the future.\r\n         *\r\n         * @name Text#dragArea\r\n         * @type String\r\n         * @default 'all'\r\n         */\r\n        dragArea: 'all',\r\n\r\n        withLabel: false,\r\n\r\n        /**\r\n         * Text rotation in degrees.\r\n         * Works for non-zero values only in combination with display=='internal'.\r\n         *\r\n         * @name Text#rotate\r\n         * @type Number\r\n         * @default 0\r\n         */\r\n        rotate: 0,\r\n\r\n        /**\r\n         * @name Text#visible\r\n         * @type Boolean\r\n         * @default true\r\n         */\r\n        visible: true,\r\n\r\n        /**\r\n         * Defines together with {@link Text#snapSizeY} the grid the text snaps on to.\r\n         * The text will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.\r\n         * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks\r\n         * of the default ticks of the default x axes of the board.\r\n         *\r\n         * @name snapSizeX\r\n         * @memberOf Text.prototype\r\n         *\r\n         * @see Point#snapToGrid\r\n         * @see Text#snapSizeY\r\n         * @see JXG.Board#defaultAxes\r\n         * @type Number\r\n         * @default 1\r\n         */\r\n        snapSizeX: 1,\r\n\r\n        /**\r\n         * Defines together with {@link Text#snapSizeX} the grid the text snaps on to.\r\n         * The text will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.\r\n         * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks\r\n         * of the default ticks of the default y axes of the board.\r\n         *\r\n         * @name snapSizeY\r\n         * @memberOf Text.prototype\r\n         *\r\n         * @see Point#snapToGrid\r\n         * @see Text#snapSizeX\r\n         * @see JXG.Board#defaultAxes\r\n         * @type Number\r\n         * @default 1\r\n         */\r\n        snapSizeY: 1,\r\n\r\n        /**\r\n         * List of attractor elements. If the distance of the text is less than\r\n         * attractorDistance the text is made to glider of this element.\r\n         *\r\n         * @name attractors\r\n         * @memberOf Text.prototype\r\n         * @type Array\r\n         * @default empty\r\n         */\r\n        attractors: []\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special options for trace curves */\r\n    tracecurve: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n        strokeColor: '#000000',\r\n        fillColor: 'none',\r\n\r\n        /**\r\n         * The number of evaluated data points.\r\n         * @memberOf Tracecurve.prototype\r\n         * @default 100\r\n         * @name numberPoints\r\n         * @type Number\r\n         */\r\n        numberPoints: 100\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special turtle options */\r\n    turtle: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        strokeWidth: 1,\r\n        fillColor: 'none',\r\n        strokeColor: '#000000',\r\n\r\n        /**\r\n         * Attributes for the turtle arrow.\r\n         *\r\n         * @type Curve\r\n         * @name Turtle#arrow\r\n         */\r\n        arrow: {\r\n            strokeWidth: 2,\r\n            withLabel: false,\r\n            strokeColor: Color.palette.red,\r\n            lastArrow: true\r\n        }\r\n        /**#@-*/\r\n    },\r\n\r\n    /* special vector field options */\r\n    vectorfield: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        strokeWidth: 0.5,\r\n        highlightStrokeWidth: 0.5,\r\n        highlightStrokeColor: Color.palette.blue,\r\n        highlightStrokeOpacity: 0.8,\r\n\r\n        /**\r\n         * Scaling factor of the vectors. This in contrast to slope fields, where this attribute sets the vector to the given length.\r\n         * @name scale\r\n         * @memberOf Vectorfield.prototype\r\n         * @type {Number|Function}\r\n         * @see Slopefield.scale\r\n         * @default 1\r\n         */\r\n        scale: 1,\r\n\r\n        /**\r\n         * Customize arrow heads of vectors. Be careful! If enabled this will slow down the performance.\r\n         * Fields are:\r\n         * <ul>\r\n         *  <li> enabled: Boolean\r\n         *  <li> size: length of the arrow head legs (in pixel)\r\n         *  <li> angle: angle of the arrow head legs In radians.\r\n         * </ul>\r\n         * @name arrowhead\r\n         * @memberOf Vectorfield.prototype\r\n         * @type {Object}\r\n         * @default <tt>{enabled: true, size: 5, angle: Math.PI * 0.125}</tt>\r\n         */\r\n        arrowhead: {\r\n            enabled: true,\r\n            size: 5,\r\n            angle: Math.PI * 0.125\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    /**\r\n     * Abbreviations of attributes. Setting the shortcut means setting abbreviated properties\r\n     * to the same value.\r\n     * It is used in {@link JXG.GeometryElement#setAttribute} and in\r\n     * the constructor {@link JXG.GeometryElement}.\r\n     * Attention: In Options.js abbreviations are not allowed.\r\n     * @type Object\r\n     * @name JXG.Options#shortcuts\r\n     *\r\n     */\r\n    shortcuts: {\r\n        color: ['strokeColor', 'fillColor'],\r\n        opacity: ['strokeOpacity', 'fillOpacity'],\r\n        highlightColor: ['highlightStrokeColor', 'highlightFillColor'],\r\n        highlightOpacity: ['highlightStrokeOpacity', 'highlightFillOpacity'],\r\n        strokeWidth: ['strokeWidth', 'highlightStrokeWidth']\r\n    }\r\n};\r\n\r\n    /**\r\n     * Holds all possible properties and the according validators for geometry elements.\r\n     * A validator is either a function\r\n     * which takes one parameter and returns true, if the value is valid for the property,\r\n     * or it is false if no validator is required.\r\n     */\r\n    JXG.Validator = (function () {\r\n        var i,\r\n            validatePixel = function (v) {\r\n                return (/^[0-9]+px$/).test(v);\r\n            },\r\n            validateDisplay = function (v) {\r\n                return (v  === 'html' || v === 'internal');\r\n            },\r\n            validateColor = function (v) {\r\n                // for now this should do it...\r\n                return Type.isString(v);\r\n            },\r\n            validatePointFace = function (v) {\r\n                return Type.exists(JXG.normalizePointFace(v));\r\n            },\r\n            validateNumber = function (v) {\r\n                return Type.isNumber(v, true, false);\r\n            },\r\n            validateInteger = function (v) {\r\n                return (Math.abs(v - Math.round(v)) < Mat.eps);\r\n            },\r\n            validateNotNegativeInteger = function (v) {\r\n                return validateInteger(v) && v >= 0;\r\n            },\r\n            validatePositiveInteger = function (v) {\r\n                return validateInteger(v) && v > 0;\r\n            },\r\n            // validateScreenCoords = function (v) {\r\n            //     return v.length >= 2 && validateInteger(v[0]) && validateInteger(v[1]);\r\n            // },\r\n            validateRenderer = function (v) {\r\n                return (v === 'vml' || v === 'svg' || v === 'canvas' || v === 'no');\r\n            },\r\n            validatePositive = function (v) {\r\n                return v > 0;\r\n            },\r\n            validateNotNegative = function (v) {\r\n                return v >= 0;\r\n            },\r\n            v = {},\r\n            validators = {\r\n                attractorDistance: validateNotNegative,\r\n                color: validateColor,\r\n                // defaultDistance: validateNumber,\r\n                display: validateDisplay,\r\n                doAdvancedPlot: false,\r\n                draft: false,\r\n                drawLabels: false,\r\n                drawZero: false,\r\n                face: validatePointFace,\r\n                factor: validateNumber,\r\n                fillColor: validateColor,\r\n                fillOpacity: validateNumber,\r\n                firstArrow: false,\r\n                fontSize: validateInteger,\r\n                dash: validateInteger,\r\n                gridX: validateNumber,\r\n                gridY: validateNumber,\r\n                // POI: Do we have to add something here?\r\n                hasGrid: false,\r\n                highlightFillColor: validateColor,\r\n                highlightFillOpacity: validateNumber,\r\n                highlightStrokeColor: validateColor,\r\n                highlightStrokeOpacity: validateNumber,\r\n                insertTicks: false,\r\n                //: validateScreenCoords,\r\n                lastArrow: false,\r\n                layer: validateNotNegativeInteger,\r\n                majorHeight: validateInteger,\r\n                minorHeight: validateInteger,\r\n                minorTicks: validateNotNegative,\r\n                minTicksDistance: validatePositiveInteger,\r\n                numberPointsHigh: validatePositiveInteger,\r\n                numberPointsLow: validatePositiveInteger,\r\n                opacity: validateNumber,\r\n                radius: validateNumber,\r\n                RDPsmoothing: false,\r\n                renderer: validateRenderer,\r\n                right: validatePixel,\r\n                showCopyright: false,\r\n                showInfobox: false,\r\n                showNavigation: false,\r\n                size: validateNotNegative, //validateInteger,\r\n                snapSizeX: validatePositive,\r\n                snapSizeY: validatePositive,\r\n                snapWidth: validateNumber,\r\n                snapToGrid: false,\r\n                snatchDistance: validateNotNegative,\r\n                straightFirst: false,\r\n                straightLast: false,\r\n                stretch: false,\r\n                strokeColor: validateColor,\r\n                strokeOpacity: validateNumber,\r\n                strokeWidth: validateNotNegative, //validateInteger,\r\n                takeFirst: false,\r\n                takeSizeFromFile: false,\r\n                to10: false,\r\n                toOrigin: false,\r\n                translateTo10: false,\r\n                translateToOrigin: false,\r\n                useASCIIMathML: false,\r\n                useDirection: false,\r\n                useMathJax: false,\r\n                withLabel: false,\r\n                withTicks: false,\r\n                zoom: false\r\n            };\r\n\r\n        // this seems like a redundant step but it makes sure that\r\n        // all properties in the validator object have lower case names\r\n        // and the validator object is easier to read.\r\n        for (i in validators) {\r\n            if (validators.hasOwnProperty(i)) {\r\n                v[i.toLowerCase()] = validators[i];\r\n            }\r\n        }\r\n\r\n        return v;\r\n    }());\r\n\r\n    /**\r\n     * All point faces can be defined with more than one name, e.g. a cross faced point can be given\r\n     * by face equal to 'cross' or equal to 'x'. This method maps all possible values to fixed ones to\r\n     * simplify if- and switch-clauses regarding point faces. The translation table is as follows:\r\n     * <table>\r\n     * <tr><th>Input</th><th>Output</th></tr>\r\n     * <tr><td>cross</td><td>x</td></tr>\r\n     * <tr><td>circle</td><td>o</td></tr>\r\n     * <tr><td>square, []</td><td>[]</td></tr>\r\n     * <tr><td>plus</td><td>+</td></tr>\r\n     * <tr><td>minus</td><td>-</td></tr>\r\n     * <tr><td>divide</td><td>|</td></tr>\r\n     * <tr><td>diamond</td><td>&lt;&gt;</td></tr>\r\n     * <tr><td>triangleup</td><td>^, a, A</td></tr>\r\n     * <tr><td>triangledown</td><td>v</td></tr>\r\n     * <tr><td>triangleleft</td><td>&lt;</td></tr>\r\n     * <tr><td>triangleright</td><td>&gt;</td></tr>\r\n     * </table>\r\n     * @param {String} s A string which should determine a valid point face.\r\n     * @returns {String} Returns a normalized string or undefined if the given string is not a valid\r\n     * point face.\r\n     */\r\n    JXG.normalizePointFace = function (s) {\r\n        var map = {\r\n            cross: 'x',\r\n            x: 'x',\r\n            circle: 'o',\r\n            o: 'o',\r\n            square: '[]',\r\n            '[]': '[]',\r\n            plus: '+',\r\n            '+': '+',\r\n            divide: '|',\r\n            '|': '|',\r\n            minus: '-',\r\n            '-': '-',\r\n            diamond: '<>',\r\n            '<>': '<>',\r\n            diamond2: '<<>>',\r\n            '<<>>': '<<>>',\r\n            triangleup: '^',\r\n            A: '^',\r\n            a: '^',\r\n            '^': '^',\r\n            triangledown: 'v',\r\n            v: 'v',\r\n            triangleleft: '<',\r\n            '<': '<',\r\n            triangleright: '>',\r\n            '>': '>'\r\n        };\r\n\r\n        return map[s];\r\n    };\r\n\r\n    /**\r\n     * Apply the options stored in this object to all objects on the given board.\r\n     * @param {JXG.Board} board The board to which objects the options will be applied.\r\n     */\r\n    JXG.useStandardOptions = function (board) {\r\n        var el, t, p, copyProps,\r\n            o = JXG.Options,\r\n            boardHadGrid = board.hasGrid;\r\n\r\n        board.options.grid.hasGrid = o.grid.hasGrid;\r\n        board.options.grid.gridX = o.grid.gridX;\r\n        board.options.grid.gridY = o.grid.gridY;\r\n        // POI: Do we have to add something here?\r\n        board.options.grid.gridColor = o.grid.gridColor;\r\n        board.options.grid.gridOpacity = o.grid.gridOpacity;\r\n        board.options.grid.gridDash = o.grid.gridDash;\r\n        board.options.grid.snapToGrid = o.grid.snapToGrid;\r\n        board.options.grid.snapSizeX = o.grid.SnapSizeX;\r\n        board.options.grid.snapSizeY = o.grid.SnapSizeY;\r\n        board.takeSizeFromFile = o.takeSizeFromFile;\r\n\r\n        copyProps = function (p, o) {\r\n            p.visProp.fillcolor = o.fillColor;\r\n            p.visProp.highlightfillcolor = o.highlightFillColor;\r\n            p.visProp.strokecolor = o.strokeColor;\r\n            p.visProp.highlightstrokecolor = o.highlightStrokeColor;\r\n        };\r\n\r\n        for (el in board.objects) {\r\n            if (board.objects.hasOwnProperty(el)) {\r\n                p = board.objects[el];\r\n                if (p.elementClass === Const.OBJECT_CLASS_POINT) {\r\n                    copyProps(p, o.point);\r\n                } else if (p.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                    copyProps(p, o.line);\r\n\r\n                    for (t = 0; t < p.ticks.length; t++) {\r\n                        p.ticks[t].majorTicks = o.line.ticks.majorTicks;\r\n                        p.ticks[t].minTicksDistance = o.line.ticks.minTicksDistance;\r\n                        p.ticks[t].visProp.minorheight = o.line.ticks.minorHeight;\r\n                        p.ticks[t].visProp.majorheight = o.line.ticks.majorHeight;\r\n                    }\r\n                } else if (p.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n                    copyProps(p, o.circle);\r\n                } else if (p.type === Const.OBJECT_TYPE_ANGLE) {\r\n                    copyProps(p, o.angle);\r\n                } else if (p.type === Const.OBJECT_TYPE_ARC) {\r\n                    copyProps(p, o.arc);\r\n                } else if (p.type === Const.OBJECT_TYPE_POLYGON) {\r\n                    copyProps(p, o.polygon);\r\n                } else if (p.type === Const.OBJECT_TYPE_CONIC) {\r\n                    copyProps(p, o.conic);\r\n                } else if (p.type === Const.OBJECT_TYPE_CURVE) {\r\n                    copyProps(p, o.curve);\r\n                } else if (p.type === Const.OBJECT_TYPE_SECTOR) {\r\n                    p.arc.visProp.fillcolor = o.sector.fillColor;\r\n                    p.arc.visProp.highlightfillcolor = o.sector.highlightFillColor;\r\n                    p.arc.visProp.fillopacity = o.sector.fillOpacity;\r\n                    p.arc.visProp.highlightfillopacity = o.sector.highlightFillOpacity;\r\n                }\r\n            }\r\n        }\r\n\r\n        board.fullUpdate();\r\n        if (boardHadGrid && !board.hasGrid) {\r\n            board.removeGrids(board);\r\n        } else if (!boardHadGrid && board.hasGrid) {\r\n            board.create('grid', []);\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Converts all color values to greyscale and calls useStandardOption to put them onto the board.\r\n     * @param {JXG.Board} board The board to which objects the options will be applied.\r\n     * @see JXG.useStandardOptions\r\n     */\r\n    JXG.useBlackWhiteOptions = function (board) {\r\n        var o = JXG.Options;\r\n        o.point.fillColor = Color.rgb2bw(o.point.fillColor);\r\n        o.point.highlightFillColor = Color.rgb2bw(o.point.highlightFillColor);\r\n        o.point.strokeColor = Color.rgb2bw(o.point.strokeColor);\r\n        o.point.highlightStrokeColor = Color.rgb2bw(o.point.highlightStrokeColor);\r\n\r\n        o.line.fillColor = Color.rgb2bw(o.line.fillColor);\r\n        o.line.highlightFillColor = Color.rgb2bw(o.line.highlightFillColor);\r\n        o.line.strokeColor = Color.rgb2bw(o.line.strokeColor);\r\n        o.line.highlightStrokeColor = Color.rgb2bw(o.line.highlightStrokeColor);\r\n\r\n        o.circle.fillColor = Color.rgb2bw(o.circle.fillColor);\r\n        o.circle.highlightFillColor = Color.rgb2bw(o.circle.highlightFillColor);\r\n        o.circle.strokeColor = Color.rgb2bw(o.circle.strokeColor);\r\n        o.circle.highlightStrokeColor = Color.rgb2bw(o.circle.highlightStrokeColor);\r\n\r\n        o.arc.fillColor = Color.rgb2bw(o.arc.fillColor);\r\n        o.arc.highlightFillColor = Color.rgb2bw(o.arc.highlightFillColor);\r\n        o.arc.strokeColor = Color.rgb2bw(o.arc.strokeColor);\r\n        o.arc.highlightStrokeColor = Color.rgb2bw(o.arc.highlightStrokeColor);\r\n\r\n        o.polygon.fillColor = Color.rgb2bw(o.polygon.fillColor);\r\n        o.polygon.highlightFillColor  = Color.rgb2bw(o.polygon.highlightFillColor);\r\n\r\n        o.sector.fillColor = Color.rgb2bw(o.sector.fillColor);\r\n        o.sector.highlightFillColor  = Color.rgb2bw(o.sector.highlightFillColor);\r\n\r\n        o.curve.strokeColor = Color.rgb2bw(o.curve.strokeColor);\r\n        o.grid.gridColor = Color.rgb2bw(o.grid.gridColor);\r\n\r\n        JXG.useStandardOptions(board);\r\n    };\r\n\r\n// needs to be exported\r\nJXG.Options.normalizePointFace = JXG.normalizePointFace;\r\n\r\nexport default JXG.Options;\r\n","/*\r\n JessieCode Interpreter and Compiler\r\n\r\n    Copyright 2011-2023\r\n        Michael Gerhaeuser,\r\n        Alfred Wassermann\r\n\r\n    JessieCode is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JessieCode is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JessieCode. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, window: true, console: true, self: true, document: true, parser: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview JessieCode is a scripting language designed to provide a\r\n * simple scripting language to build constructions\r\n * with JSXGraph. It is similar to JavaScript, but prevents access to the DOM.\r\n * Hence, it can be used in community driven math portals which want to use\r\n * JSXGraph to display interactive math graphics.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Text from \"../base/text.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Interval from \"../math/ia.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Statistics from \"../math/statistics.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Env from \"../utils/env.js\";\r\n\r\n// IE 6-8 compatibility\r\nif (!Object.create) {\r\n    Object.create = function (o, properties) {\r\n        if (typeof o !== 'object' && typeof o !== 'function') throw new TypeError('Object prototype may only be an Object: ' + o);\r\n        else if (o === null) throw new Error(\"This browser's implementation of Object.create is a shim and doesn't support 'null' as the first argument.\");\r\n\r\n        if (typeof properties != 'undefined') throw new Error(\"This browser's implementation of Object.create is a shim and doesn't support a second argument.\");\r\n\r\n        function F() { }\r\n\r\n        F.prototype = o;\r\n\r\n        return new F();\r\n    };\r\n}\r\n\r\nvar priv = {\r\n    modules: {\r\n        'math': Mat,\r\n        'math/geometry': Geometry,\r\n        'math/statistics': Statistics,\r\n        'math/numerics': Mat.Numerics\r\n    }\r\n};\r\n\r\n/**\r\n * A JessieCode object provides an interface to the parser and stores all variables and objects used within a JessieCode script.\r\n * The optional argument <tt>code</tt> is interpreted after initializing. To evaluate more code after initializing a JessieCode instance\r\n * please use {@link JXG.JessieCode#parse}. For code snippets like single expressions use {@link JXG.JessieCode#snippet}.\r\n * @constructor\r\n * @param {String} [code] Code to parse.\r\n * @param {Boolean} [geonext=false] Geonext compatibility mode.\r\n */\r\nJXG.JessieCode = function (code, geonext) {\r\n    // Control structures\r\n\r\n    /**\r\n     * The global scope.\r\n     * @type Object\r\n     */\r\n    this.scope = {\r\n        id: 0,\r\n        hasChild: true,\r\n        args: [],\r\n        locals: {},\r\n        context: null,\r\n        previous: null\r\n    };\r\n\r\n    /**\r\n     * Keeps track of all possible scopes every required.\r\n     * @type Array\r\n     */\r\n    this.scopes = [];\r\n    this.scopes.push(this.scope);\r\n\r\n    /**\r\n     * A stack to store debug information (like line and column where it was defined) of a parameter\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.dpstack = [[]];\r\n\r\n    /**\r\n     * Determines the parameter stack scope.\r\n     * @type Number\r\n     * @private\r\n     */\r\n    this.pscope = 0;\r\n\r\n    /**\r\n     * Used to store the property-value definition while parsing an object literal.\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.propstack = [{}];\r\n\r\n    /**\r\n     * The current scope of the object literal stack {@link JXG.JessieCode#propstack}.\r\n     * @type Number\r\n     * @private\r\n     */\r\n    this.propscope = 0;\r\n\r\n    /**\r\n     * Store the left hand side of an assignment. If an element is constructed and no attributes are given, this is\r\n     * used as the element's name.\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.lhs = [];\r\n\r\n    /**\r\n     * lhs flag, used by JXG.JessieCode#replaceNames\r\n     * @type Boolean\r\n     * @default false\r\n     */\r\n    this.isLHS = false;\r\n\r\n    /**\r\n     * The id of an HTML node in which innerText all warnings are stored (if no <tt>console</tt> object is available).\r\n     * @type String\r\n     * @default 'jcwarn'\r\n     */\r\n    this.warnLog = 'jcwarn';\r\n\r\n    /**\r\n     * Store $log messages in case there's no console.\r\n     * @type Array\r\n     */\r\n    this.$log = [];\r\n\r\n    /**\r\n     * Built-in functions and constants\r\n     * @type Object\r\n     */\r\n    this.builtIn = this.defineBuiltIn();\r\n\r\n    /**\r\n     * List of all possible operands in JessieCode (except of JSXGraph objects).\r\n     * @type Object\r\n     */\r\n    this.operands = this.getPossibleOperands();\r\n\r\n    /**\r\n     * The board which currently is used to create and look up elements.\r\n     * @type JXG.Board\r\n     */\r\n    this.board = null;\r\n\r\n    /**\r\n     * Force slider names to return value instead of node\r\n     * @type Boolean\r\n     */\r\n    this.forceValueCall = false;\r\n\r\n    /**\r\n     * Keep track of which element is created in which line.\r\n     * @type Object\r\n     */\r\n    this.lineToElement = {};\r\n\r\n    this.parCurLine = 1;\r\n    this.parCurColumn = 0;\r\n    this.line = 1;\r\n    this.col = 1;\r\n\r\n    if (JXG.CA) {\r\n        // Old simplifier\r\n        this.CA = new JXG.CA(this.node, this.createNode, this);\r\n    }\r\n    if (JXG.CAS) {\r\n        // New simplifier\r\n        this.CAS = new JXG.CAS(this.node, this.createNode, this);\r\n    }\r\n\r\n    this.code = '';\r\n\r\n    if (typeof code === 'string') {\r\n        this.parse(code, geonext);\r\n    }\r\n};\r\n\r\nJXG.extend(JXG.JessieCode.prototype, /** @lends JXG.JessieCode.prototype */ {\r\n    /**\r\n     * Create a new parse tree node.\r\n     * @param {String} type Type of node, e.g. node_op, node_var, or node_const\r\n     * @param value The nodes value, e.g. a variables value or a functions body.\r\n     * @param {Array} children Arbitrary number of child nodes.\r\n     */\r\n    node: function (type, value, children) {\r\n        return {\r\n            type: type,\r\n            value: value,\r\n            children: children\r\n        };\r\n    },\r\n\r\n    /**\r\n     * Create a new parse tree node. Basically the same as node(), but this builds\r\n     * the children part out of an arbitrary number of parameters, instead of one\r\n     * array parameter.\r\n     * @param {String} type Type of node, e.g. node_op, node_var, or node_const\r\n     * @param value The nodes value, e.g. a variables value or a functions body.\r\n     * @param children Arbitrary number of parameters; define the child nodes.\r\n     */\r\n    createNode: function (type, value, children) {\r\n        var n = this.node(type, value, []),\r\n            i;\r\n\r\n        for (i = 2; i < arguments.length; i++) {\r\n            n.children.push(arguments[i]);\r\n        }\r\n\r\n        if (n.type === 'node_const' && Type.isNumber(n.value)) {\r\n            n.isMath = true;\r\n        }\r\n\r\n        n.line = this.parCurLine;\r\n        n.col = this.parCurColumn;\r\n\r\n        return n;\r\n    },\r\n\r\n    /**\r\n     * Create a new scope.\r\n     * @param {Array} args\r\n     * @returns {Object}\r\n     */\r\n    pushScope: function (args) {\r\n        var scope = {\r\n            args: args,\r\n            locals: {},\r\n            context: null,\r\n            previous: this.scope\r\n        };\r\n\r\n        this.scope.hasChild = true;\r\n        this.scope = scope;\r\n        scope.id = this.scopes.push(scope) - 1;\r\n\r\n        return scope;\r\n    },\r\n\r\n    /**\r\n     * Remove the current scope and reinstate the previous scope\r\n     * @returns {Object}\r\n     */\r\n    popScope: function () {\r\n        var s = this.scope.previous;\r\n\r\n        // make sure the global scope is not lost\r\n        this.scope = s !== null ? s : this.scope;\r\n\r\n        return this.scope;\r\n    },\r\n\r\n    /**\r\n     * Looks up an {@link JXG.GeometryElement} by its id.\r\n     * @param {String} id\r\n     * @returns {JXG.GeometryElement}\r\n     */\r\n    getElementById: function (id) {\r\n        return this.board.objects[id];\r\n    },\r\n\r\n    log: function () {\r\n        this.$log.push(arguments);\r\n\r\n        if (typeof console === 'object' && console.log) {\r\n            console.log.apply(console, arguments);\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Returns a element creator function which takes two parameters: the parents array and the attributes object.\r\n     * @param {String} vname The element type, e.g. 'point', 'line', 'midpoint'\r\n     * @returns {function}\r\n     */\r\n    creator: (function () {\r\n        // stores the already defined creators\r\n        var _ccache = {}, r;\r\n\r\n        r = function (vname) {\r\n            var f;\r\n\r\n            // _ccache is global, i.e. it is the same for ALL JessieCode instances.\r\n            // That's why we need the board id here\r\n            if (typeof _ccache[this.board.id + vname] === 'function') {\r\n                f = _ccache[this.board.id + vname];\r\n            } else {\r\n                f = (function (that) {\r\n                    return function (parameters, attributes) {\r\n                        var attr;\r\n\r\n                        if (Type.exists(attributes)) {\r\n                            attr = attributes;\r\n                        } else {\r\n                            attr = {};\r\n                        }\r\n                        if (attr.name === undefined && attr.id === undefined) {\r\n                            attr.name = (that.lhs[that.scope.id] !== 0 ? that.lhs[that.scope.id] : '');\r\n                        }\r\n                        return that.board.create(vname, parameters, attr);\r\n                    };\r\n                }(this));\r\n\r\n                f.creator = true;\r\n                _ccache[this.board.id + vname] = f;\r\n            }\r\n\r\n            return f;\r\n        };\r\n\r\n        r.clearCache = function () {\r\n            _ccache = {};\r\n        };\r\n\r\n        return r;\r\n    }()),\r\n\r\n    /**\r\n     * Assigns a value to a variable in the current scope.\r\n     * @param {String} vname Variable name\r\n     * @param value Anything\r\n     * @see JXG.JessieCode#sstack\r\n     * @see JXG.JessieCode#scope\r\n     */\r\n    letvar: function (vname, value) {\r\n        if (this.builtIn[vname]) {\r\n            this._warn('\"' + vname + '\" is a predefined value.');\r\n        }\r\n\r\n        this.scope.locals[vname] = value;\r\n    },\r\n\r\n    /**\r\n     * Checks if the given variable name can be found in the current scope chain.\r\n     * @param {String} vname\r\n     * @returns {Object} A reference to the scope object the variable can be found in or null if it can't be found.\r\n     */\r\n    isLocalVariable: function (vname) {\r\n        var s = this.scope;\r\n\r\n        while (s !== null) {\r\n            if (Type.exists(s.locals[vname])) {\r\n                return s;\r\n            }\r\n\r\n            s = s.previous;\r\n        }\r\n\r\n        return null;\r\n    },\r\n\r\n    /**\r\n     * Checks if the given variable name is a parameter in any scope from the current to the global scope.\r\n     * @param {String} vname\r\n     * @returns {Object} A reference to the scope object that contains the variable in its arg list.\r\n     */\r\n    isParameter: function (vname) {\r\n        var s = this.scope;\r\n\r\n        while (s !== null) {\r\n            if (Type.indexOf(s.args, vname) > -1) {\r\n                return s;\r\n            }\r\n\r\n            s = s.previous;\r\n        }\r\n\r\n        return null;\r\n    },\r\n\r\n    /**\r\n     * Checks if the given variable name is a valid creator method.\r\n     * @param {String} vname\r\n     * @returns {Boolean}\r\n     */\r\n    isCreator: function (vname) {\r\n        // check for an element with this name\r\n        return !!JXG.elements[vname];\r\n    },\r\n\r\n    /**\r\n     * Checks if the given variable identifier is a valid member of the JavaScript Math Object.\r\n     * @param {String} vname\r\n     * @returns {Boolean}\r\n     */\r\n    isMathMethod: function (vname) {\r\n        return vname !== 'E' && !!Math[vname];\r\n    },\r\n\r\n    /**\r\n     * Returns true if the given identifier is a builtIn variable/function.\r\n     * @param {String} vname\r\n     * @returns {Boolean}\r\n     */\r\n    isBuiltIn: function (vname) {\r\n        return !!this.builtIn[vname];\r\n    },\r\n\r\n    /**\r\n     * Looks up the value of the given variable. We use a simple type inspection.\r\n     *\r\n     * @param {String} vname Name of the variable\r\n     * @param {Boolean} [local=false] Only look up the internal symbol table and don't look for\r\n     * the <tt>vname</tt> in Math or the element list.\r\n     * @param {Boolean} [isFunctionName=false] Lookup function of type builtIn, Math.*, creator.\r\n     *\r\n     * @see JXG.JessieCode#resolveType\r\n     */\r\n    getvar: function (vname, local, isFunctionName) {\r\n        var s;\r\n\r\n        local = Type.def(local, false);\r\n\r\n        // Local scope has always precedence\r\n        s = this.isLocalVariable(vname);\r\n\r\n        if (s !== null) {\r\n            return s.locals[vname];\r\n        }\r\n\r\n        // Handle the - so far only - few constants by hard coding them.\r\n        if (vname === '$board' || vname === 'EULER' || vname === 'PI') {\r\n            return this.builtIn[vname];\r\n        }\r\n\r\n        if (isFunctionName) {\r\n            if (this.isBuiltIn(vname)) {\r\n                return this.builtIn[vname];\r\n            }\r\n\r\n            if (this.isMathMethod(vname)) {\r\n                return Math[vname];\r\n            }\r\n\r\n            // check for an element with this name\r\n            if (this.isCreator(vname)) {\r\n                return this.creator(vname);\r\n            }\r\n        }\r\n\r\n        if (!local) {\r\n            s = this.board.select(vname);\r\n            if (s !== vname) {\r\n                return s;\r\n            }\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Look up the value of a local variable.\r\n     * @param {string} vname\r\n     * @returns {*}\r\n     */\r\n    resolve: function (vname) {\r\n        var s = this.scope;\r\n\r\n        while (s !== null) {\r\n            if (Type.exists(s.locals[vname])) {\r\n                return s.locals[vname];\r\n            }\r\n\r\n            s = s.previous;\r\n        }\r\n    },\r\n\r\n    /**\r\n     * TODO this needs to be called from JS and should not generate JS code\r\n     * Looks up a variable identifier in various tables and generates JavaScript code that could be eval'd to get the value.\r\n     * @param {String} vname Identifier\r\n     * @param {Boolean} [local=false] Don't resolve ids and names of elements\r\n     * @param {Boolean} [withProps=false]\r\n     */\r\n    getvarJS: function (vname, local, withProps) {\r\n        var s, r = '', re;\r\n\r\n        local = Type.def(local, false);\r\n        withProps = Type.def(withProps, false);\r\n\r\n        s = this.isParameter(vname);\r\n        if (s !== null) {\r\n            return vname;\r\n        }\r\n\r\n        s = this.isLocalVariable(vname);\r\n        if (s !== null && !withProps) {\r\n            return '$jc$.resolve(\\'' + vname + '\\')';\r\n        }\r\n\r\n        // check for an element with this name\r\n        if (this.isCreator(vname)) {\r\n            return '(function () { var a = Array.prototype.slice.call(arguments, 0), props = ' + (withProps ? 'a.pop()' : '{}') + '; return $jc$.board.create.apply($jc$.board, [\\'' + vname + '\\'].concat([a, props])); })';\r\n        }\r\n\r\n        if (withProps) {\r\n            this._error('Syntax error (attribute values are allowed with element creators only)');\r\n        }\r\n\r\n        if (this.isBuiltIn(vname)) {\r\n            // If src does not exist, it is a number. In that case, just return the value.\r\n            r = this.builtIn[vname].src || this.builtIn[vname];\r\n\r\n            // Get the \"real\" name of the function\r\n            if (Type.isNumber(r)) {\r\n                return r;\r\n            }\r\n            // Search a JSXGraph object in board\r\n            if (r.match(/board\\.select/)) {\r\n                return r;\r\n            }\r\n\r\n            /* eslint-disable no-useless-escape */\r\n            vname = r.split('.').pop();\r\n            if (Type.exists(this.board.mathLib)) {\r\n                // Handle builtin case: ln(x) -> Math.log\r\n                re = new RegExp('^Math\\.' + vname);\r\n                if (re.exec(r) !== null) {\r\n                    return r.replace(re, '$jc$.board.mathLib.' + vname);\r\n                }\r\n            }\r\n            if (Type.exists(this.board.mathLibJXG)) {\r\n                // Handle builtin case: factorial(x) -> JXG.Math.factorial\r\n                re = new RegExp('^JXG\\.Math\\.');\r\n                if (re.exec(r) !== null) {\r\n                    return r.replace(re, '$jc$.board.mathLibJXG.');\r\n                }\r\n                return r;\r\n            }\r\n            /* eslint-enable no-useless-escape */\r\n            return r;\r\n\r\n            // return this.builtIn[vname].src || this.builtIn[vname];\r\n        }\r\n\r\n        if (this.isMathMethod(vname)) {\r\n            return '$jc$.board.mathLib.' + vname;\r\n            //                return 'Math.' + vname;\r\n        }\r\n\r\n        // if (!local) {\r\n        //     if (Type.isId(this.board, vname)) {\r\n        //         r = '$jc$.board.objects[\\'' + vname + '\\']';\r\n        //     } else if (Type.isName(this.board, vname)) {\r\n        //         r = '$jc$.board.elementsByName[\\'' + vname + '\\']';\r\n        //     } else if (Type.isGroup(this.board, vname)) {\r\n        //         r = '$jc$.board.groups[\\'' + vname + '\\']';\r\n        //     }\r\n\r\n        //     return r;\r\n        // }\r\n        if (!local) {\r\n            if (Type.isId(this.board, vname)) {\r\n                r = '$jc$.board.objects[\\'' + vname + '\\']';\r\n                if (this.board.objects[vname].elType === 'slider') {\r\n                    r += '.Value()';\r\n                }\r\n            } else if (Type.isName(this.board, vname)) {\r\n                r = '$jc$.board.elementsByName[\\'' + vname + '\\']';\r\n                if (this.board.elementsByName[vname].elType === 'slider') {\r\n                    r += '.Value()';\r\n                }\r\n            } else if (Type.isGroup(this.board, vname)) {\r\n                r = '$jc$.board.groups[\\'' + vname + '\\']';\r\n            }\r\n\r\n            return r;\r\n        }\r\n\r\n        return '';\r\n    },\r\n\r\n    /**\r\n     * Adds the property <tt>isMap</tt> to a function and sets it to true.\r\n     * @param {function} f\r\n     * @returns {function}\r\n     */\r\n    makeMap: function (f) {\r\n        f.isMap = true;\r\n\r\n        return f;\r\n    },\r\n\r\n    functionCodeJS: function (node) {\r\n        var p = node.children[0].join(', '),\r\n            bo = '',\r\n            bc = '';\r\n\r\n        if (node.value === 'op_map') {\r\n            bo = '{ return  ';\r\n            bc = ' }';\r\n        }\r\n\r\n        return 'function (' + p + ') {\\n' +\r\n            'var $oldscope$ = $jc$.scope;\\n' +\r\n            '$jc$.scope = $jc$.scopes[' + this.scope.id + '];\\n' +\r\n            'var r = (function () ' + bo + this.compile(node.children[1], true) + bc + ')();\\n' +\r\n            '$jc$.scope = $oldscope$;\\n' +\r\n            'return r;\\n' +\r\n            '}';\r\n    },\r\n\r\n    /**\r\n     * Converts a node type <tt>node_op</tt> and value <tt>op_map</tt> or <tt>op_function</tt> into a executable\r\n     * function. Does a simple type inspection.\r\n     * @param {Object} node\r\n     * @returns {function}\r\n     * @see JXG.JessieCode#resolveType\r\n     */\r\n    defineFunction: function (node) {\r\n        var fun, i, that = this,\r\n            list = node.children[0],\r\n            scope = this.pushScope(list);\r\n\r\n        if (this.board.options.jc.compile) {\r\n            this.isLHS = false;\r\n\r\n            // we currently need to put the parameters into the local scope\r\n            // until the compiled JS variable lookup code is fixed\r\n            for (i = 0; i < list.length; i++) {\r\n                scope.locals[list[i]] = list[i];\r\n            }\r\n\r\n            this.replaceNames(node.children[1]);\r\n\r\n            /** @ignore */\r\n            fun = (function (jc) {\r\n                var fun,\r\n                    // str = 'var f = ' + $jc$.functionCodeJS(node) + '; f;';\r\n                    str = 'var f = function($jc$) { return ' +\r\n                        jc.functionCodeJS(node) +\r\n                        '}; f;';\r\n\r\n                try {\r\n                    // yeah, eval is evil, but we don't have much choice here.\r\n                    // the str is well defined and there is no user input in it that we didn't check before\r\n\r\n                    /*jslint evil:true*/\r\n                    // fun = eval(str);\r\n                    fun = eval(str)(jc);\r\n                    /*jslint evil:false*/\r\n\r\n                    scope.argtypes = [];\r\n                    for (i = 0; i < list.length; i++) {\r\n                        scope.argtypes.push(that.resolveType(list[i], node));\r\n                    }\r\n\r\n                    return fun;\r\n                } catch (e) {\r\n                    // $jc$._warn('error compiling function\\n\\n' + str + '\\n\\n' + e.toString());\r\n                    jc._warn(\"error compiling function\\n\\n\" + str + \"\\n\\n\" + e.toString());\r\n                    return function () { };\r\n                }\r\n            }(this));\r\n\r\n            // clean up scope\r\n            this.popScope();\r\n        } else {\r\n            /** @ignore */\r\n            fun = (function (_pstack, that, id) {\r\n                return function () {\r\n                    var r, oldscope;\r\n\r\n                    oldscope = that.scope;\r\n                    that.scope = that.scopes[id];\r\n\r\n                    for (r = 0; r < _pstack.length; r++) {\r\n                        that.scope.locals[_pstack[r]] = arguments[r];\r\n                    }\r\n\r\n                    r = that.execute(node.children[1]);\r\n                    that.scope = oldscope;\r\n\r\n                    return r;\r\n                };\r\n            }(list, this, scope.id));\r\n        }\r\n\r\n        fun.node = node;\r\n        fun.scope = scope;\r\n        fun.toJS = fun.toString;\r\n        fun.toString = (function (_that) {\r\n            return function () {\r\n                return _that.compile(_that.replaceIDs(Type.deepCopy(node)));\r\n            };\r\n        }(this));\r\n\r\n        fun.deps = {};\r\n        this.collectDependencies(node.children[1], node.children[0], fun.deps);\r\n\r\n        return fun;\r\n    },\r\n\r\n    /**\r\n     * Merge all attribute values given with an element creator into one object.\r\n     * @param {Object} o An arbitrary number of objects\r\n     * @returns {Object} All given objects merged into one. If properties appear in more (case sensitive) than one\r\n     * object the last value is taken.\r\n     */\r\n    mergeAttributes: function (o) {\r\n        var i, attr = {};\r\n\r\n        for (i = 0; i < arguments.length; i++) {\r\n            attr = Type.deepCopy(attr, arguments[i], true);\r\n        }\r\n\r\n        return attr;\r\n    },\r\n\r\n    /**\r\n     * Sets the property <tt>what</tt> of <tt>o</tt> to <tt>value</tt>\r\n     * @param {JXG.Point|JXG.Text} o\r\n     * @param {String} what\r\n     * @param value\r\n     */\r\n    setProp: function (o, what, value) {\r\n        var par = {}, x, y;\r\n\r\n        if (o.elementClass === Const.OBJECT_CLASS_POINT && (what === 'X' || what === 'Y')) {\r\n            // set coords\r\n\r\n            what = what.toLowerCase();\r\n\r\n            // we have to deal with three cases here:\r\n            // o.isDraggable && typeof value === number:\r\n            //   stay draggable, just set the new coords (e.g. via moveTo)\r\n            // o.isDraggable && typeof value === function:\r\n            //   convert to !o.isDraggable, set the new coords via o.addConstraint()\r\n            // !o.isDraggable:\r\n            //   stay !o.isDraggable, update the given coord by overwriting X/YEval\r\n\r\n            if (o.isDraggable && typeof value === 'number') {\r\n                x = what === 'x' ? value : o.X();\r\n                y = what === 'y' ? value : o.Y();\r\n\r\n                o.setPosition(Const.COORDS_BY_USER, [x, y]);\r\n            } else if (o.isDraggable && (typeof value === 'function' || typeof value === 'string')) {\r\n                x = what === 'x' ? value : o.coords.usrCoords[1];\r\n                y = what === 'y' ? value : o.coords.usrCoords[2];\r\n\r\n                o.addConstraint([x, y]);\r\n            } else if (!o.isDraggable) {\r\n                x = what === 'x' ? value : o.XEval.origin;\r\n                y = what === 'y' ? value : o.YEval.origin;\r\n\r\n                o.addConstraint([x, y]);\r\n            }\r\n\r\n            this.board.update();\r\n        } else if (o.elementClass === Const.OBJECT_CLASS_TEXT && (what === 'X' || what === 'Y')) {\r\n            if (typeof value === 'number') {\r\n                o[what] = function () { return value; };\r\n            } else if (typeof value === 'function') {\r\n                o.isDraggable = false;\r\n                o[what] = value;\r\n            } else if (typeof value === 'string') {\r\n                o.isDraggable = false;\r\n                o[what] = Type.createFunction(value, this.board);\r\n                o[what + 'jc'] = value;\r\n            }\r\n\r\n            o[what].origin = value;\r\n\r\n            this.board.update();\r\n        } else if (o.type && o.elementClass && o.visProp) {\r\n            if (Type.exists(o[o.methodMap[what]]) && typeof o[o.methodMap[what]] !== 'function') {\r\n                o[o.methodMap[what]] = value;\r\n            } else {\r\n                par[what] = value;\r\n                o.setAttribute(par);\r\n            }\r\n        } else {\r\n            o[what] = value;\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Generic method to parse JessieCode.\r\n     * This consists of generating an AST with parser.parse,\r\n     * apply simplifying rules from CA and\r\n     * manipulate the AST according to the second parameter \"cmd\".\r\n     * @param  {String} code      JessieCode code to be parsed\r\n     * @param  {String} cmd       Type of manipulation to be done with AST\r\n     * @param {Boolean} [geonext=false] Geonext compatibility mode.\r\n     * @param {Boolean} [dontstore=false] If false, the code string is stored in this.code,\r\n     *  i.e. in the JessieCode object, e.g. in board.jc.\r\n     * @return {Object} Returns result of computation as directed in cmd.\r\n     */\r\n    _genericParse: function (code, cmd, geonext, dontstore) {\r\n        var i, setTextBackup, ast, result,\r\n            ccode = code.replace(/\\r\\n/g, '\\n').split('\\n'),\r\n            options = {},\r\n            cleaned = [];\r\n\r\n        if (!dontstore) {\r\n            this.code += code + '\\n';\r\n        }\r\n\r\n        if (Text) {\r\n            setTextBackup = Text.prototype.setText;\r\n            Text.prototype.setText = Text.prototype.setTextJessieCode;\r\n        }\r\n\r\n        try {\r\n            if (!Type.exists(geonext)) {\r\n                geonext = false;\r\n            }\r\n\r\n            for (i = 0; i < ccode.length; i++) {\r\n                if (geonext) {\r\n                    ccode[i] = JXG.GeonextParser.geonext2JS(ccode[i], this.board);\r\n                }\r\n                cleaned.push(ccode[i]);\r\n            }\r\n\r\n            code = cleaned.join('\\n');\r\n            ast = parser.parse(code);\r\n            if (this.CA) {\r\n                ast = this.CA.expandDerivatives(ast, null, ast);\r\n                ast = this.CA.removeTrivialNodes(ast);\r\n            }\r\n            if (this.CAS) {\r\n                // Search for expression of form `D(f, x)` and determine the\r\n                // the derivative symbolically.\r\n                ast = this.CAS.expandDerivatives(ast, null, ast);\r\n\r\n                // options.method = options.method || \"strong\";\r\n                // options.form = options.form || \"fractions\";\r\n                // options.steps = options.steps || [];\r\n                // options.iterations = options.iterations || 1000;\r\n                // ast = this.CAS._simplify_aux(ast, options);\r\n            }\r\n            switch (cmd) {\r\n                case 'parse':\r\n                    result = this.execute(ast);\r\n                    break;\r\n                case 'manipulate':\r\n                    result = this.compile(ast);\r\n                    break;\r\n                case 'simplify':\r\n                    if (Type.exists(this.CAS)) {\r\n                        options.method = options.method || \"strong\";\r\n                        options.form = options.form || \"fractions\";\r\n                        options.steps = options.steps || [];\r\n                        options.iterations = options.iterations || 1000;\r\n                        ast = this.CAS.simplify(ast, options);\r\n                        result = this.CAS.compile(ast);\r\n                    } else {\r\n                        result = this.compile(ast);\r\n                    }\r\n                    break;\r\n                case 'getAst':\r\n                    result = ast;\r\n                    break;\r\n                default:\r\n                    result = false;\r\n            }\r\n        } catch (e) {  // catch is mandatory in old IEs\r\n            // console.log(e);\r\n            // We throw the error again,\r\n            // so the user can catch it.\r\n            throw e;\r\n        } finally {\r\n            // make sure the original text method is back in place\r\n            if (Text) {\r\n                Text.prototype.setText = setTextBackup;\r\n            }\r\n        }\r\n\r\n        return result;\r\n    },\r\n\r\n    /**\r\n     * Parses JessieCode.\r\n     * This consists of generating an AST with parser.parse, apply simplifying rules\r\n     * from CA and executing the ast by calling this.execute(ast).\r\n     *\r\n     * @param {String} code             JessieCode code to be parsed\r\n     * @param {Boolean} [geonext=false] Geonext compatibility mode.\r\n     * @param {Boolean} [dontstore=false] If false, the code string is stored in this.code.\r\n     * @return {Object}                 Parse JessieCode code and execute it.\r\n     */\r\n    parse: function (code, geonext, dontstore) {\r\n        return this._genericParse(code, 'parse', geonext, dontstore);\r\n    },\r\n\r\n    /**\r\n     * Manipulate JessieCode.\r\n     * This consists of generating an AST with parser.parse,\r\n     * apply simplifying rules from CA\r\n     * and compile the AST back to JessieCode.\r\n     *\r\n     * @param {String} code             JessieCode code to be parsed\r\n     * @param {Boolean} [geonext=false] Geonext compatibility mode.\r\n     * @param {Boolean} [dontstore=false] If false, the code string is stored in this.code.\r\n     * @return {String}                 Simplified JessieCode code\r\n     */\r\n    manipulate: function (code, geonext, dontstore) {\r\n        return this._genericParse(code, 'manipulate', geonext, dontstore);\r\n    },\r\n\r\n    /**\r\n     * Manipulate JessieCode.\r\n     * This consists of generating an AST with parser.parse,\r\n     * apply simplifying rules from CAS\r\n     * and compile the AST back to JessieCode with minimal number of parentheses.\r\n     *\r\n     * @param {String} code             JessieCode code to be parsed\r\n     * @param {Boolean} [geonext=false] Geonext compatibility mode.\r\n     * @param {Boolean} [dontstore=false] If false, the code string is stored in this.code.\r\n     * @return {String}                 Simplified JessieCode code\r\n     */\r\n    simplify: function (code) {\r\n        return this._genericParse(code, 'simplify');\r\n    },\r\n\r\n    /**\r\n     * Get abstract syntax tree (AST) from JessieCode code.\r\n     * This consists of generating an AST with parser.parse.\r\n     *\r\n     * @param {String} code\r\n     * @param {Boolean} [geonext=false] Geonext compatibility mode.\r\n     * @param {Boolean} [dontstore=false] If false, the code string is stored in this.code.\r\n     * @return {Node}  AST\r\n     */\r\n    getAST: function (code, geonext, dontstore) {\r\n        return this._genericParse(code, 'getAst', geonext, dontstore);\r\n    },\r\n\r\n    /**\r\n     * Parses a JessieCode snippet, e.g. \"3+4\", and wraps it into a function, if desired.\r\n     * @param {String} code A small snippet of JessieCode. Must not be an assignment.\r\n     * @param {Boolean} [funwrap=true] If true, the code is wrapped in a function.\r\n     * @param {String} [varname=''] Name of the parameter(s)\r\n     * @param {Boolean} [geonext=false] Geonext compatibility mode.\r\n     * @param {Boolean} [forceValueCall=true] Force evaluation of value method of sliders.\r\n     */\r\n    snippet: function (code, funwrap, varname, geonext, forceValueCall) {\r\n        var c;\r\n\r\n        funwrap = Type.def(funwrap, true);\r\n        varname = Type.def(varname, '');\r\n        geonext = Type.def(geonext, false);\r\n        this.forceValueCall = Type.def(forceValueCall, true);\r\n\r\n        c = (funwrap ? ' function (' + varname + ') { return ' : '') +\r\n                code +\r\n            (funwrap ? '; }' : '') + ';';\r\n\r\n        return this.parse(c, geonext, true);\r\n    },\r\n\r\n    /**\r\n     * Traverses through the given subtree and changes all values of nodes with the replaced flag set by\r\n     * {@link JXG.JessieCode#replaceNames} to the name of the element (if not empty).\r\n     * @param {Object} node\r\n     */\r\n    replaceIDs: function (node) {\r\n        var i, v;\r\n\r\n        if (node.replaced) {\r\n            // These children exist, if node.replaced is set.\r\n            v = this.board.objects[node.children[1][0].value];\r\n\r\n            if (Type.exists(v) && v.name !== \"\") {\r\n                node.type = 'node_var';\r\n                node.value = v.name;\r\n\r\n                // Maybe it's not necessary, but just to be sure that everything is cleaned up we better delete all\r\n                // children and the replaced flag\r\n                node.children.length = 0;\r\n                delete node.replaced;\r\n            }\r\n        }\r\n\r\n        if (Type.isArray(node)) {\r\n            for (i = 0; i < node.length; i++) {\r\n                node[i] = this.replaceIDs(node[i]);\r\n            }\r\n        }\r\n\r\n        if (node.children) {\r\n            // assignments are first evaluated on the right hand side\r\n            for (i = node.children.length; i > 0; i--) {\r\n                if (Type.exists(node.children[i - 1])) {\r\n                    node.children[i - 1] = this.replaceIDs(node.children[i - 1]);\r\n                }\r\n\r\n            }\r\n        }\r\n\r\n        return node;\r\n    },\r\n\r\n    /**\r\n     * Traverses through the given subtree and changes all elements referenced by names through referencing them by ID.\r\n     * An identifier is only replaced if it is not found in all scopes above the current scope and if it\r\n     * has not been blacklisted within the codeblock determined by the given subtree.\r\n     * @param {Object} node\r\n     * @param {Boolean} [callValuePar=false] if true, uses $value() instead of $() in createReplacementNode\r\n     */\r\n    replaceNames: function (node, callValuePar) {\r\n        var i, v,\r\n            callValue = false;\r\n\r\n        if (callValuePar !== undefined) {\r\n            callValue = callValuePar;\r\n        }\r\n\r\n        v = node.value;\r\n\r\n        // We are interested only in nodes of type node_var and node_op > op_lhs.\r\n        // Currently, we are not checking if the id is a local variable. in this case, we're stuck anyway.\r\n\r\n        if (node.type === 'node_op' && v === 'op_lhs' && node.children.length === 1) {\r\n            this.isLHS = true;\r\n        } else if (node.type === 'node_var') {\r\n            if (this.isLHS) {\r\n                this.letvar(v, true);\r\n            } else if (!Type.exists(this.getvar(v, true)) && Type.exists(this.board.elementsByName[v])) {\r\n                if (callValue && this.board.elementsByName[v].elType !== 'slider') {\r\n                    callValue = false;\r\n                }\r\n                node = this.createReplacementNode(node, callValue);\r\n            }\r\n        }\r\n\r\n        if (Type.isArray(node)) {\r\n            for (i = 0; i < node.length; i++) {\r\n                node[i] = this.replaceNames(node[i], callValue);\r\n            }\r\n        }\r\n\r\n        if (node.children) {\r\n            // Replace slider reference by call of slider.Value()\r\n            if (this.forceValueCall &&              // It must be enforced, see snippet.\r\n                (\r\n                    // 1. case: sin(a), max(a, 0), ...\r\n                    (node.value === \"op_execfun\" &&\r\n                        // Not in cases V(a), $(a)\r\n                        node.children[0].value !== 'V' && node.children[0].value !== '$' &&\r\n                        // Function must be a math function. This ensures that a number is required as input.\r\n                        (Type.exists(Math[node.children[0].value]) || Type.exists(Mat[node.children[0].value])) &&\r\n                        // node.children[1].length === 1 &&\r\n                        node.children[1][0].type === 'node_var'\r\n                    ) ||\r\n                    // 2. case: slider is the whole expression: 'a'\r\n                    (node.value === \"op_return\" &&\r\n                        node.children.length === 1 &&\r\n                        node.children[0].type === 'node_var'\r\n                    )\r\n                )\r\n            ) {\r\n                    callValue = true;\r\n            }\r\n\r\n            // Assignments are first evaluated on the right hand side\r\n            for (i = node.children.length; i > 0; i--) {\r\n                if (Type.exists(node.children[i - 1])) {\r\n                    node.children[i - 1] = this.replaceNames(node.children[i - 1], callValue);\r\n                }\r\n            }\r\n        }\r\n\r\n        if (node.type === 'node_op' && node.value === 'op_lhs' && node.children.length === 1) {\r\n            this.isLHS = false;\r\n        }\r\n\r\n        return node;\r\n    },\r\n\r\n    /**\r\n     * Replaces node_var nodes with node_op&gt;op_execfun nodes, calling the internal $() function with the id of the\r\n     * element accessed by the node_var node.\r\n     * @param {Object} node\r\n     * @param {Boolean} [callValue=undefined] if true, uses $value() instead of $()\r\n     * @returns {Object} op_execfun node\r\n     */\r\n    createReplacementNode: function (node, callValue) {\r\n        var v = node.value,\r\n            el = this.board.elementsByName[v];\r\n\r\n        // If callValue: get handle to this node_var and call its Value method.\r\n        // Otherwise return the object.\r\n        node = this.createNode('node_op', 'op_execfun',\r\n            this.createNode('node_var', (callValue === true ? '$value' : '$')),\r\n            [this.createNode('node_str', el.id)]);\r\n\r\n        node.replaced = true;\r\n\r\n        return node;\r\n    },\r\n\r\n    /**\r\n     * Search the parse tree below <tt>node</tt> for <em>stationary</em> dependencies, i.e. dependencies hard coded into\r\n     * the function.\r\n     * @param {Object} node\r\n     * @param {Array} varnames List of variable names of the function\r\n     * @param {Object} result An object where the referenced elements will be stored. Access key is their id.\r\n     */\r\n    collectDependencies: function (node, varnames, result) {\r\n        var i, v, e, le;\r\n\r\n        if (Type.isArray(node)) {\r\n            le = node.length;\r\n            for (i = 0; i < le; i++) {\r\n                this.collectDependencies(node[i], varnames, result);\r\n            }\r\n            return;\r\n        }\r\n\r\n        v = node.value;\r\n\r\n        if (node.type === 'node_var' &&\r\n            varnames.indexOf(v) < 0 // v is not contained in the list of variables of that function\r\n        ) {\r\n            e = this.getvar(v);\r\n            if (e && e.visProp && e.elType && e.elementClass && e.id\r\n                // Sliders are the only elements which are given by names.\r\n                // Wrong, a counter example is: circle(c, function() { return p1.Dist(p2); })\r\n                // && e.elType === 'slider'\r\n            ) {\r\n                result[e.id] = e;\r\n            }\r\n        }\r\n\r\n        // The $()-function-calls are special because their parameter is given as a string, not as a node_var.\r\n        if (node.type === 'node_op' && node.value === 'op_execfun' &&\r\n            node.children.length > 1 &&\r\n            (node.children[0].value === '$' || node.children[0].value === '$value') &&\r\n            node.children[1].length > 0) {\r\n\r\n            e = node.children[1][0].value;\r\n            result[e] = this.board.objects[e];\r\n        }\r\n\r\n        if (node.children) {\r\n            for (i = node.children.length; i > 0; i--) {\r\n                if (Type.exists(node.children[i - 1])) {\r\n                    this.collectDependencies(node.children[i - 1], varnames, result);\r\n                }\r\n            }\r\n        }\r\n    },\r\n\r\n    resolveProperty: function (e, v, compile) {\r\n        compile = Type.def(compile, false);\r\n\r\n        // is it a geometry element or a board?\r\n        if (e /*&& e.type && e.elementClass*/ && e.methodMap) {\r\n            // yeah, it is. but what does the user want?\r\n            if (Type.exists(e.subs) && Type.exists(e.subs[v])) {\r\n                // a subelement it is, good sir.\r\n                e = e.subs;\r\n            } else if (Type.exists(e.methodMap[v])) {\r\n                // the user wants to call a method\r\n                v = e.methodMap[v];\r\n            } else {\r\n                // the user wants to change an attribute\r\n                e = e.visProp;\r\n                v = v.toLowerCase();\r\n            }\r\n        }\r\n\r\n        if (Type.isFunction(e)) {\r\n            this._error('Accessing function properties is not allowed.');\r\n        }\r\n\r\n        if (!Type.exists(e)) {\r\n            this._error(e + ' is not an object');\r\n        }\r\n\r\n        if (!Type.exists(e[v])) {\r\n            this._error('unknown property ' + v);\r\n        }\r\n\r\n        if (compile && typeof e[v] === 'function') {\r\n            return function () { return e[v].apply(e, arguments); };\r\n        }\r\n\r\n        return e[v];\r\n    },\r\n\r\n    /**\r\n     * Type inspection: check if the string vname appears as function name in the\r\n     * AST node. Used in \"op_execfun\". This allows the JessieCode examples below.\r\n     *\r\n     * @private\r\n     * @param {String} vname\r\n     * @param {Object} node\r\n     * @returns 'any' or 'function'\r\n     * @see JXG.JessieCode#execute\r\n     * @see JXG.JessieCode#getvar\r\n     *\r\n     * @example\r\n     *  var p = board.create('point', [2, 0], {name: 'X'});\r\n     *  var txt = 'X(X)';\r\n     *  console.log(board.jc.parse(txt));\r\n     *\r\n     * @example\r\n     *  var p = board.create('point', [2, 0], {name: 'X'});\r\n     *  var txt = 'f = function(el, X) { return X(el); }; f(X, X);';\r\n     *  console.log(board.jc.parse(txt));\r\n     *\r\n     * @example\r\n     *  var p = board.create('point', [2, 0], {name: 'point'});\r\n     *  var txt = 'B = point(1,3); X(point);';\r\n     *  console.log(board.jc.parse(txt));\r\n     *\r\n     * @example\r\n     *  var p = board.create('point', [2, 0], {name: 'A'});\r\n     *  var q = board.create('point', [-2, 0], {name: 'X'});\r\n     *  var txt = 'getCoord=function(p, f){ return f(p); }; getCoord(A, X);';\r\n     *  console.log(board.jc.parse(txt));\r\n     */\r\n    resolveType: function (vname, node) {\r\n        var i, t,\r\n            type = 'any'; // Possible values: 'function', 'any'\r\n\r\n        if (Type.isArray(node)) {\r\n            // node contains the parameters of a function call or function declaration\r\n            for (i = 0; i < node.length; i++) {\r\n                t = this.resolveType(vname, node[i]);\r\n                if (t !== 'any') {\r\n                    type = t;\r\n                    return type;\r\n                }\r\n            }\r\n        }\r\n\r\n        if (node.type === 'node_op' && node.value === 'op_execfun' &&\r\n            node.children[0].type === 'node_var' && node.children[0].value === vname) {\r\n            return 'function';\r\n        }\r\n\r\n        if (node.type === 'node_op') {\r\n            for (i = 0; i < node.children.length; i++) {\r\n                if (node.children[0].type === 'node_var' && node.children[0].value === vname &&\r\n                    (node.value === 'op_add' || node.value === 'op_sub' || node.value === 'op_mul' ||\r\n                        node.value === 'op_div' || node.value === 'op_mod' || node.value === 'op_exp' ||\r\n                        node.value === 'op_neg')) {\r\n                    return 'any';\r\n                }\r\n            }\r\n\r\n            for (i = 0; i < node.children.length; i++) {\r\n                t = this.resolveType(vname, node.children[i]);\r\n                if (t !== 'any') {\r\n                    type = t;\r\n                    return type;\r\n                }\r\n            }\r\n        }\r\n\r\n        return 'any';\r\n    },\r\n\r\n    /**\r\n     * Resolves the lefthand side of an assignment operation\r\n     * @param node\r\n     * @returns {Object} An object with two properties. <strong>o</strong> which contains the object, and\r\n     * a string <strong>what</strong> which contains the property name.\r\n     */\r\n    getLHS: function (node) {\r\n        var res;\r\n\r\n        if (node.type === 'node_var') {\r\n            res = {\r\n                o: this.scope.locals,\r\n                what: node.value\r\n            };\r\n        } else if (node.type === 'node_op' && node.value === 'op_property') {\r\n            res = {\r\n                o: this.execute(node.children[0]),\r\n                what: node.children[1]\r\n            };\r\n        } else if (node.type === 'node_op' && node.value === 'op_extvalue') {\r\n            res = {\r\n                o: this.execute(node.children[0]),\r\n                what: this.execute(node.children[1])\r\n            };\r\n        } else {\r\n            throw new Error('Syntax error: Invalid left-hand side of assignment.');\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    getLHSCompiler: function (node, js) {\r\n        var res;\r\n\r\n        if (node.type === 'node_var') {\r\n            res = node.value;\r\n        } else if (node.type === 'node_op' && node.value === 'op_property') {\r\n            res = [\r\n                this.compile(node.children[0], js),\r\n                \"'\" + node.children[1] + \"'\"\r\n            ];\r\n        } else if (node.type === 'node_op' && node.value === 'op_extvalue') {\r\n            res = [\r\n                this.compile(node.children[0], js),\r\n                node.children[1].type === 'node_const' ? node.children[1].value : this.compile(node.children[1], js)\r\n            ];\r\n        } else {\r\n            throw new Error('Syntax error: Invalid left-hand side of assignment.');\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Executes a parse subtree.\r\n     * @param {Object} node\r\n     * @returns {Number|String|Object|Boolean} Something\r\n     * @private\r\n     */\r\n    execute: function (node) {\r\n        var ret, v, i, e, l, undef, list, ilist,\r\n            parents = [],\r\n            // exec fun\r\n            fun, attr, sc;\r\n\r\n        ret = 0;\r\n\r\n        if (!node) {\r\n            return ret;\r\n        }\r\n\r\n        this.line = node.line;\r\n        this.col = node.col;\r\n\r\n        switch (node.type) {\r\n            case 'node_op':\r\n                switch (node.value) {\r\n                    case 'op_none':\r\n                        if (node.children[0]) {\r\n                            this.execute(node.children[0]);\r\n                        }\r\n                        if (node.children[1]) {\r\n                            ret = this.execute(node.children[1]);\r\n                        }\r\n                        break;\r\n                    case 'op_assign':\r\n                        v = this.getLHS(node.children[0]);\r\n                        this.lhs[this.scope.id] = v.what;\r\n\r\n                        if (v.o.type && v.o.elementClass && v.o.methodMap && v.what === 'label') {\r\n                            this._error('Left-hand side of assignment is read-only.');\r\n                        }\r\n\r\n                        ret = this.execute(node.children[1]);\r\n                        if (v.o !== this.scope.locals || (Type.isArray(v.o) && typeof v.what === 'number')) {\r\n                            // it is either an array component being set or a property of an object.\r\n                            this.setProp(v.o, v.what, ret);\r\n                        } else {\r\n                            // this is just a local variable inside JessieCode\r\n                            this.letvar(v.what, ret);\r\n                        }\r\n                        this.lhs[this.scope.id] = 0;\r\n                        break;\r\n                    case 'op_if':\r\n                        if (this.execute(node.children[0])) {\r\n                            ret = this.execute(node.children[1]);\r\n                        }\r\n                        break;\r\n                    case 'op_conditional':\r\n                    // fall through\r\n                    case 'op_if_else':\r\n                        if (this.execute(node.children[0])) {\r\n                            ret = this.execute(node.children[1]);\r\n                        } else {\r\n                            ret = this.execute(node.children[2]);\r\n                        }\r\n                        break;\r\n                    case 'op_while':\r\n                        while (this.execute(node.children[0])) {\r\n                            this.execute(node.children[1]);\r\n                        }\r\n                        break;\r\n                    case 'op_do':\r\n                        do {\r\n                            this.execute(node.children[0]);\r\n                        } while (this.execute(node.children[1]));\r\n                        break;\r\n                    case 'op_for':\r\n                        for (this.execute(node.children[0]); this.execute(node.children[1]); this.execute(node.children[2])) {\r\n                            this.execute(node.children[3]);\r\n                        }\r\n                        break;\r\n                    case 'op_proplst':\r\n                        if (node.children[0]) {\r\n                            this.execute(node.children[0]);\r\n                        }\r\n                        if (node.children[1]) {\r\n                            this.execute(node.children[1]);\r\n                        }\r\n                        break;\r\n                    case 'op_emptyobject':\r\n                        ret = {};\r\n                        break;\r\n                    case 'op_proplst_val':\r\n                        this.propstack.push({});\r\n                        this.propscope++;\r\n\r\n                        this.execute(node.children[0]);\r\n                        ret = this.propstack[this.propscope];\r\n\r\n                        this.propstack.pop();\r\n                        this.propscope--;\r\n                        break;\r\n                    case 'op_prop':\r\n                        // child 0: Identifier\r\n                        // child 1: Value\r\n                        this.propstack[this.propscope][node.children[0]] = this.execute(node.children[1]);\r\n                        break;\r\n                    case 'op_array':\r\n                        ret = [];\r\n                        l = node.children[0].length;\r\n\r\n                        for (i = 0; i < l; i++) {\r\n                            ret.push(this.execute(node.children[0][i]));\r\n                        }\r\n\r\n                        break;\r\n                    case 'op_extvalue':\r\n                        ret = this.execute(node.children[0]);\r\n                        i = this.execute(node.children[1]);\r\n\r\n                        if (typeof i === 'number' && Math.abs(Math.round(i) - i) < 1.e-12) {\r\n                            ret = ret[i];\r\n                        } else {\r\n                            ret = undef;\r\n                        }\r\n                        break;\r\n                    case 'op_return':\r\n                        if (this.scope === 0) {\r\n                            this._error('Unexpected return.');\r\n                        } else {\r\n                            return this.execute(node.children[0]);\r\n                        }\r\n                        break;\r\n                    case 'op_map':\r\n                        if (!node.children[1].isMath && node.children[1].type !== 'node_var') {\r\n                            this._error('execute: In a map only function calls and mathematical expressions are allowed.');\r\n                        }\r\n\r\n                        /** @ignore */\r\n                        fun = this.defineFunction(node);\r\n                        fun.isMap = true;\r\n\r\n                        ret = fun;\r\n                        break;\r\n                    case 'op_function':\r\n                        // parse the parameter list\r\n                        // after this, the parameters are in pstack\r\n\r\n                        /** @ignore */\r\n                        fun = this.defineFunction(node);\r\n                        fun.isMap = false;\r\n\r\n                        ret = fun;\r\n                        break;\r\n                    case 'op_execfun':\r\n                        // node.children:\r\n                        //   [0]: Name of the function\r\n                        //   [1]: Parameter list as a parse subtree\r\n                        //   [2]: Properties, only used in case of a create function\r\n                        this.dpstack.push([]);\r\n                        this.pscope++;\r\n\r\n                        // parameter parsing is done below\r\n                        list = node.children[1];\r\n\r\n                        // parse the properties only if given\r\n                        if (Type.exists(node.children[2])) {\r\n                            if (node.children[3]) {\r\n                                ilist = node.children[2];\r\n                                attr = {};\r\n\r\n                                for (i = 0; i < ilist.length; i++) {\r\n                                    attr = Type.deepCopy(attr, this.execute(ilist[i]), true);\r\n                                }\r\n                            } else {\r\n                                attr = this.execute(node.children[2]);\r\n                            }\r\n                        }\r\n\r\n                        // look up the variables name in the variable table\r\n                        node.children[0]._isFunctionName = true;\r\n                        fun = this.execute(node.children[0]);\r\n                        delete node.children[0]._isFunctionName;\r\n\r\n                        // determine the scope the function wants to run in\r\n                        if (Type.exists(fun) && Type.exists(fun.sc)) {\r\n                            sc = fun.sc;\r\n                        } else {\r\n                            sc = this;\r\n                        }\r\n\r\n                        if (!fun.creator && Type.exists(node.children[2])) {\r\n                            this._error('Unexpected value. Only element creators are allowed to have a value after the function call.');\r\n                        }\r\n\r\n                        // interpret ALL the parameters\r\n                        for (i = 0; i < list.length; i++) {\r\n                            if (Type.exists(fun.scope) && Type.exists(fun.scope.argtypes) && fun.scope.argtypes[i] === 'function') {\r\n                                // Type inspection\r\n                                list[i]._isFunctionName = true;\r\n                                parents[i] = this.execute(list[i]);\r\n                                delete list[i]._isFunctionName;\r\n                            } else {\r\n                                parents[i] = this.execute(list[i]);\r\n                            }\r\n                            //parents[i] = Type.evalSlider(this.execute(list[i]));\r\n                            this.dpstack[this.pscope].push({\r\n                                line: node.children[1][i].line,\r\n                                // SketchBin currently works only if the last column of the\r\n                                // parent position is taken. This is due to how I patched JS/CC\r\n                                // to count the lines and columns. So, ecol will do for now\r\n                                col: node.children[1][i].ecol\r\n                            });\r\n                        }\r\n\r\n                        // check for the function in the variable table\r\n                        if (typeof fun === 'function' && !fun.creator) {\r\n                            ret = fun.apply(sc, parents);\r\n                        } else if (typeof fun === 'function' && !!fun.creator) {\r\n                            e = this.line;\r\n\r\n                            // creator methods are the only ones that take properties, hence this special case\r\n                            try {\r\n                                ret = fun(parents, attr);\r\n                                ret.jcLineStart = e;\r\n                                ret.jcLineEnd = node.eline;\r\n\r\n                                for (i = e; i <= node.line; i++) {\r\n                                    this.lineToElement[i] = ret;\r\n                                }\r\n\r\n                                ret.debugParents = this.dpstack[this.pscope];\r\n                            } catch (ex) {\r\n                                this._error(ex.toString());\r\n                            }\r\n                        } else {\r\n                            this._error('Function \\'' + fun + '\\' is undefined.');\r\n                        }\r\n\r\n                        // clear parameter stack\r\n                        this.dpstack.pop();\r\n                        this.pscope--;\r\n                        break;\r\n                    case 'op_property':\r\n                        e = this.execute(node.children[0]);\r\n                        v = node.children[1];\r\n\r\n                        ret = this.resolveProperty(e, v, false);\r\n\r\n                        // set the scope, in case this is a method the user wants to call\r\n                        if (Type.exists(ret) && ['number', 'string', 'boolean'].indexOf(typeof ret) < 0) {\r\n                            ret.sc = e;\r\n                        }\r\n\r\n                        break;\r\n                    case 'op_use':\r\n                        this._warn('Use of the \\'use\\' operator is deprecated.');\r\n                        this.use(node.children[0].toString());\r\n                        break;\r\n                    case 'op_delete':\r\n                        this._warn('Use of the \\'delete\\' operator is deprecated. Please use the remove() function.');\r\n                        v = this.getvar(node.children[0]);\r\n                        ret = this.del(v);\r\n                        break;\r\n                    case 'op_eq':\r\n                        // == is intentional\r\n                        /*jslint eqeq:true*/\r\n                        /* eslint-disable eqeqeq */\r\n                        ret = this.execute(node.children[0]) == this.execute(node.children[1]);\r\n                        /*jslint eqeq:false*/\r\n                        /* eslint-enable eqeqeq */\r\n                        break;\r\n                    case 'op_neq':\r\n                        // != is intentional\r\n                        /*jslint eqeq:true*/\r\n                        /* eslint-disable eqeqeq */\r\n                        ret = this.execute(node.children[0]) != this.execute(node.children[1]);\r\n                        /*jslint eqeq:true*/\r\n                        /* eslint-enable eqeqeq */\r\n                        break;\r\n                    case 'op_approx':\r\n                        ret = Math.abs(this.execute(node.children[0]) - this.execute(node.children[1])) < Mat.eps;\r\n                        break;\r\n                    case 'op_gt':\r\n                        ret = this.execute(node.children[0]) > this.execute(node.children[1]);\r\n                        break;\r\n                    case 'op_lt':\r\n                        ret = this.execute(node.children[0]) < this.execute(node.children[1]);\r\n                        break;\r\n                    case 'op_geq':\r\n                        ret = this.execute(node.children[0]) >= this.execute(node.children[1]);\r\n                        break;\r\n                    case 'op_leq':\r\n                        ret = this.execute(node.children[0]) <= this.execute(node.children[1]);\r\n                        break;\r\n                    case 'op_or':\r\n                        ret = this.execute(node.children[0]) || this.execute(node.children[1]);\r\n                        break;\r\n                    case 'op_and':\r\n                        ret = this.execute(node.children[0]) && this.execute(node.children[1]);\r\n                        break;\r\n                    case 'op_not':\r\n                        ret = !this.execute(node.children[0]);\r\n                        break;\r\n                    case 'op_add':\r\n                        ret = this.add(this.execute(node.children[0]), this.execute(node.children[1]));\r\n                        break;\r\n                    case 'op_sub':\r\n                        ret = this.sub(this.execute(node.children[0]), this.execute(node.children[1]));\r\n                        break;\r\n                    case 'op_div':\r\n                        ret = this.div(this.execute(node.children[0]), this.execute(node.children[1]));\r\n                        break;\r\n                    case 'op_mod':\r\n                        // use mathematical modulo, JavaScript implements the symmetric modulo.\r\n                        ret = this.mod(this.execute(node.children[0]), this.execute(node.children[1]), true);\r\n                        break;\r\n                    case 'op_mul':\r\n                        ret = this.mul(this.execute(node.children[0]), this.execute(node.children[1]));\r\n                        break;\r\n                    case 'op_exp':\r\n                        ret = this.pow(this.execute(node.children[0]), this.execute(node.children[1]));\r\n                        break;\r\n                    case 'op_neg':\r\n                        ret = this.neg(this.execute(node.children[0]));\r\n                        break;\r\n                }\r\n                break;\r\n\r\n            case 'node_var':\r\n                // node._isFunctionName is set in execute: at op_execfun.\r\n                ret = this.getvar(node.value, false, node._isFunctionName);\r\n                break;\r\n\r\n            case 'node_const':\r\n                if (node.value === null) {\r\n                    ret = null;\r\n                } else {\r\n                    ret = Number(node.value);\r\n                }\r\n                break;\r\n\r\n            case 'node_const_bool':\r\n                ret = node.value;\r\n                break;\r\n\r\n            case 'node_str':\r\n                //ret = node.value.replace(/\\\\'/, \"'\").replace(/\\\\\"/, '\"').replace(/\\\\\\\\/, '\\\\');\r\n                /*jslint regexp:true*/\r\n                ret = node.value.replace(/\\\\(.)/g, '$1'); // Remove backslash, important in JessieCode tags\r\n                /*jslint regexp:false*/\r\n                break;\r\n        }\r\n\r\n        return ret;\r\n    },\r\n\r\n    /**\r\n     * Compiles a parse tree back to JessieCode.\r\n     * @param {Object} node\r\n     * @param {Boolean} [js=false] Compile either to JavaScript or back to JessieCode (required for the UI).\r\n     * @returns Something\r\n     * @private\r\n     */\r\n    compile: function (node, js) {\r\n        var e, i, list, scope,\r\n            ret = '';\r\n\r\n        if (!Type.exists(js)) {\r\n            js = false;\r\n        }\r\n\r\n        if (!node) {\r\n            return ret;\r\n        }\r\n\r\n        switch (node.type) {\r\n            case 'node_op':\r\n                switch (node.value) {\r\n                    case 'op_none':\r\n                        if (node.children[0]) {\r\n                            ret = this.compile(node.children[0], js);\r\n                        }\r\n                        if (node.children[1]) {\r\n                            ret += this.compile(node.children[1], js);\r\n                        }\r\n                        break;\r\n                    case 'op_block':\r\n                        ret = '{\\n' + this.compile(node.children[0], js) + ' }\\n';\r\n                        break;\r\n                    case 'op_assign':\r\n                        //e = this.compile(node.children[0], js);\r\n                        if (js) {\r\n                            e = this.getLHSCompiler(node.children[0], js);\r\n                            if (Type.isArray(e)) {\r\n                                ret = '$jc$.setProp(' + e[0] + ', ' + e[1] + ', ' + this.compile(node.children[1], js) + ');\\n';\r\n                            } else {\r\n                                if (this.isLocalVariable(e) !== this.scope) {\r\n                                    this.scope.locals[e] = true;\r\n                                }\r\n                                ret = '$jc$.scopes[' + this.scope.id + '].locals[\\'' + e + '\\'] = ' + this.compile(node.children[1], js) + ';\\n';\r\n                            }\r\n                        } else {\r\n                            e = this.compile(node.children[0]);\r\n                            ret = e + ' = ' + this.compile(node.children[1], js) + ';\\n';\r\n                        }\r\n                        break;\r\n                    case 'op_if':\r\n                        ret = ' if (' + this.compile(node.children[0], js) + ') ' + this.compile(node.children[1], js);\r\n                        break;\r\n                    case 'op_if_else':\r\n                        ret = ' if (' + this.compile(node.children[0], js) + ')' + this.compile(node.children[1], js);\r\n                        ret += ' else ' + this.compile(node.children[2], js);\r\n                        break;\r\n                    case 'op_conditional':\r\n                        ret = '((' + this.compile(node.children[0], js) + ')?(' + this.compile(node.children[1], js);\r\n                        ret += '):(' + this.compile(node.children[2], js) + '))';\r\n                        break;\r\n                    case 'op_while':\r\n                        ret = ' while (' + this.compile(node.children[0], js) + ') {\\n' + this.compile(node.children[1], js) + '}\\n';\r\n                        break;\r\n                    case 'op_do':\r\n                        ret = ' do {\\n' + this.compile(node.children[0], js) + '} while (' + this.compile(node.children[1], js) + ');\\n';\r\n                        break;\r\n                    case 'op_for':\r\n                        //ret = ' for (' + this.compile(node.children[0], js) + '; ' + this.compile(node.children[1], js) + '; ' + this.compile(node.children[2], js) + ') {\\n' + this.compile(node.children[3], js) + '\\n}\\n';\r\n                        ret = ' for (' + this.compile(node.children[0], js) +               // Assignment ends with \";\"\r\n                            this.compile(node.children[1], js) + '; ' +         // Logical test comes without \";\"\r\n                            this.compile(node.children[2], js).slice(0, -2) +   // Counting comes with \";\" which has to be removed\r\n                            ') {\\n' + this.compile(node.children[3], js) + '\\n}\\n';\r\n                        break;\r\n                    case 'op_proplst':\r\n                        if (node.children[0]) {\r\n                            ret = this.compile(node.children[0], js) + ', ';\r\n                        }\r\n\r\n                        ret += this.compile(node.children[1], js);\r\n                        break;\r\n                    case 'op_prop':\r\n                        // child 0: Identifier\r\n                        // child 1: Value\r\n                        ret = node.children[0] + ': ' + this.compile(node.children[1], js);\r\n                        break;\r\n                    case 'op_emptyobject':\r\n                        ret = js ? '{}' : '<< >>';\r\n                        break;\r\n                    case 'op_proplst_val':\r\n                        ret = this.compile(node.children[0], js);\r\n                        break;\r\n                    case 'op_array':\r\n                        list = [];\r\n                        for (i = 0; i < node.children[0].length; i++) {\r\n                            list.push(this.compile(node.children[0][i], js));\r\n                        }\r\n                        ret = '[' + list.join(', ') + ']';\r\n                        break;\r\n                    case 'op_extvalue':\r\n                        ret = this.compile(node.children[0], js) + '[' + this.compile(node.children[1], js) + ']';\r\n                        break;\r\n                    case 'op_return':\r\n                        ret = ' return ' + this.compile(node.children[0], js) + ';\\n';\r\n                        break;\r\n                    case 'op_map':\r\n                        if (!node.children[1].isMath && node.children[1].type !== 'node_var') {\r\n                            this._error('compile: In a map only function calls and mathematical expressions are allowed.');\r\n                        }\r\n\r\n                        list = node.children[0];\r\n                        if (js) {\r\n                            ret = ' $jc$.makeMap(function (' + list.join(', ') + ') { return ' + this.compile(node.children[1], js) + '; })';\r\n                        } else {\r\n                            ret = 'map (' + list.join(', ') + ') -> ' + this.compile(node.children[1], js);\r\n                        }\r\n\r\n                        break;\r\n                    case 'op_function':\r\n                        list = node.children[0];\r\n                        scope = this.pushScope(list);\r\n                        if (js) {\r\n                            ret = this.functionCodeJS(node);\r\n                        } else {\r\n                            ret = ' function (' + list.join(', ') + ') ' + this.compile(node.children[1], js);\r\n                        }\r\n                        this.popScope();\r\n                        break;\r\n                    case 'op_execfunmath':\r\n                        console.log('op_execfunmath: TODO');\r\n                        ret = '-1';\r\n                        break;\r\n                    case 'op_execfun':\r\n                        // parse the properties only if given\r\n                        if (node.children[2]) {\r\n                            list = [];\r\n                            for (i = 0; i < node.children[2].length; i++) {\r\n                                list.push(this.compile(node.children[2][i], js));\r\n                            }\r\n\r\n                            if (js) {\r\n                                e = '$jc$.mergeAttributes(' + list.join(', ') + ')';\r\n                            } else {\r\n                                e = list.join(', ');\r\n                            }\r\n                        }\r\n                        node.children[0].withProps = !!node.children[2];\r\n                        list = [];\r\n                        for (i = 0; i < node.children[1].length; i++) {\r\n                            list.push(this.compile(node.children[1][i], js));\r\n                        }\r\n                        ret = this.compile(node.children[0], js) + '(' + list.join(', ') + (node.children[2] && js ? ', ' + e : '') + ')' + (node.children[2] && !js ? ' ' + e : '');\r\n                        if (js) {\r\n                            // Inserting a newline here allows simultaneously\r\n                            // - procedural calls like Q.moveTo(...); and\r\n                            // - function calls in expressions like log(x) + 1;\r\n                            // Problem: procedural calls will not be ended by a semicolon.\r\n                            ret += '\\n';\r\n                        }\r\n\r\n                        // save us a function call when compiled to javascript\r\n                        if (js && node.children[0].value === '$') {\r\n                            ret = '$jc$.board.objects[' + this.compile(node.children[1][0], js) + ']';\r\n                        }\r\n                        break;\r\n                    case 'op_property':\r\n                        if (js && node.children[1] !== 'X' && node.children[1] !== 'Y') {\r\n                            ret = '$jc$.resolveProperty(' + this.compile(node.children[0], js) + ', \\'' + node.children[1] + '\\', true)';\r\n                        } else {\r\n                            ret = this.compile(node.children[0], js) + '.' + node.children[1];\r\n                        }\r\n                        break;\r\n                    case 'op_use':\r\n                        this._warn('Use of the \\'use\\' operator is deprecated.');\r\n                        if (js) {\r\n                            ret = '$jc$.use(\\'';\r\n                        } else {\r\n                            ret = 'use(\\'';\r\n                        }\r\n\r\n                        ret += node.children[0].toString() + '\\');';\r\n                        break;\r\n                    case 'op_delete':\r\n                        this._warn('Use of the \\'delete\\' operator is deprecated. Please use the remove() function.');\r\n                        if (js) {\r\n                            ret = '$jc$.del(';\r\n                        } else {\r\n                            ret = 'remove(';\r\n                        }\r\n\r\n                        ret += this.compile(node.children[0], js) + ')';\r\n                        break;\r\n                    case 'op_eq':\r\n                        ret = '(' + this.compile(node.children[0], js) + ' === ' + this.compile(node.children[1], js) + ')';\r\n                        break;\r\n                    case 'op_neq':\r\n                        ret = '(' + this.compile(node.children[0], js) + ' !== ' + this.compile(node.children[1], js) + ')';\r\n                        break;\r\n                    case 'op_approx':\r\n                        ret = '(' + this.compile(node.children[0], js) + ' ~= ' + this.compile(node.children[1], js) + ')';\r\n                        break;\r\n                    case 'op_gt':\r\n                        if (js) {\r\n                            ret = '$jc$.gt(' + this.compile(node.children[0], js) + ', ' + this.compile(node.children[1], js) + ')';\r\n                        } else {\r\n                            ret = '(' + this.compile(node.children[0], js) + ' > ' + this.compile(node.children[1], js) + ')';\r\n                        }\r\n                        break;\r\n                    case 'op_lt':\r\n                        if (js) {\r\n                            ret = '$jc$.lt(' + this.compile(node.children[0], js) + ', ' + this.compile(node.children[1], js) + ')';\r\n                        } else {\r\n                            ret = '(' + this.compile(node.children[0], js) + ' < ' + this.compile(node.children[1], js) + ')';\r\n                        }\r\n                        break;\r\n                    case 'op_geq':\r\n                        if (js) {\r\n                            ret = '$jc$.geq(' + this.compile(node.children[0], js) + ', ' + this.compile(node.children[1], js) + ')';\r\n                        } else {\r\n                            ret = '(' + this.compile(node.children[0], js) + ' >= ' + this.compile(node.children[1], js) + ')';\r\n                        }\r\n                        break;\r\n                    case 'op_leq':\r\n                        if (js) {\r\n                            ret = '$jc$.leq(' + this.compile(node.children[0], js) + ', ' + this.compile(node.children[1], js) + ')';\r\n                        } else {\r\n                            ret = '(' + this.compile(node.children[0], js) + ' <= ' + this.compile(node.children[1], js) + ')';\r\n                        }\r\n                        break;\r\n                    case 'op_or':\r\n                        ret = '(' + this.compile(node.children[0], js) + ' || ' + this.compile(node.children[1], js) + ')';\r\n                        break;\r\n                    case 'op_and':\r\n                        ret = '(' + this.compile(node.children[0], js) + ' && ' + this.compile(node.children[1], js) + ')';\r\n                        break;\r\n                    case 'op_not':\r\n                        ret = '!(' + this.compile(node.children[0], js) + ')';\r\n                        break;\r\n                    case 'op_add':\r\n                        if (js) {\r\n                            ret = '$jc$.add(' + this.compile(node.children[0], js) + ', ' + this.compile(node.children[1], js) + ')';\r\n                        } else {\r\n                            ret = '(' + this.compile(node.children[0], js) + ' + ' + this.compile(node.children[1], js) + ')';\r\n                        }\r\n                        break;\r\n                    case 'op_sub':\r\n                        if (js) {\r\n                            ret = '$jc$.sub(' + this.compile(node.children[0], js) + ', ' + this.compile(node.children[1], js) + ')';\r\n                        } else {\r\n                            ret = '(' + this.compile(node.children[0], js) + ' - ' + this.compile(node.children[1], js) + ')';\r\n                        }\r\n                        break;\r\n                    case 'op_div':\r\n                        if (js) {\r\n                            ret = '$jc$.div(' + this.compile(node.children[0], js) + ', ' + this.compile(node.children[1], js) + ')';\r\n                        } else {\r\n                            ret = '(' + this.compile(node.children[0], js) + ' / ' + this.compile(node.children[1], js) + ')';\r\n                        }\r\n                        break;\r\n                    case 'op_mod':\r\n                        if (js) {\r\n                            ret = '$jc$.mod(' + this.compile(node.children[0], js) + ', ' + this.compile(node.children[1], js) + ', true)';\r\n                        } else {\r\n                            ret = '(' + this.compile(node.children[0], js) + ' % ' + this.compile(node.children[1], js) + ')';\r\n                        }\r\n                        break;\r\n                    case 'op_mul':\r\n                        if (js) {\r\n                            ret = '$jc$.mul(' + this.compile(node.children[0], js) + ', ' + this.compile(node.children[1], js) + ')';\r\n                        } else {\r\n                            ret = '(' + this.compile(node.children[0], js) + ' * ' + this.compile(node.children[1], js) + ')';\r\n                        }\r\n                        break;\r\n                    case 'op_exp':\r\n                        if (js) {\r\n                            ret = '$jc$.pow(' + this.compile(node.children[0], js) + ', ' + this.compile(node.children[1], js) + ')';\r\n                        } else {\r\n                            ret = '(' + this.compile(node.children[0], js) + '^' + this.compile(node.children[1], js) + ')';\r\n                        }\r\n                        break;\r\n                    case 'op_neg':\r\n                        if (js) {\r\n                            ret = '$jc$.neg(' + this.compile(node.children[0], js) + ')';\r\n                        } else {\r\n                            ret = '(-' + this.compile(node.children[0], js) + ')';\r\n                        }\r\n                        break;\r\n                }\r\n                break;\r\n\r\n            case 'node_var':\r\n                if (js) {\r\n                    ret = this.getvarJS(node.value, false, node.withProps);\r\n                } else {\r\n                    ret = node.value;\r\n                }\r\n                break;\r\n\r\n            case 'node_const':\r\n                ret = node.value;\r\n                break;\r\n\r\n            case 'node_const_bool':\r\n                ret = node.value;\r\n                break;\r\n\r\n            case 'node_str':\r\n                ret = '\\'' + node.value + '\\'';\r\n                break;\r\n        }\r\n\r\n        if (node.needsAngleBrackets) {\r\n            if (js) {\r\n                ret = '{\\n' + ret + ' }\\n';\r\n            } else {\r\n                ret = '<< ' + ret + ' >>\\n';\r\n            }\r\n        }\r\n\r\n        return ret;\r\n    },\r\n\r\n    /**\r\n     * This is used as the global getName() function.\r\n     * @param {JXG.GeometryElement} obj\r\n     * @param {Boolean} useId\r\n     * @returns {String}\r\n     */\r\n    getName: function (obj, useId) {\r\n        var name = '';\r\n\r\n        if (Type.exists(obj) && Type.exists(obj.getName)) {\r\n            name = obj.getName();\r\n            if ((!Type.exists(name) || name === '') && useId) {\r\n                name = obj.id;\r\n            }\r\n        } else if (useId) {\r\n            name = obj.id;\r\n        }\r\n\r\n        return name;\r\n    },\r\n\r\n    /**\r\n     * This is used as the global X() function.\r\n     * @param {JXG.Point|JXG.Text} e\r\n     * @returns {Number}\r\n     */\r\n    X: function (e) {\r\n        return e.X();\r\n    },\r\n\r\n    /**\r\n     * This is used as the global Y() function.\r\n     * @param {JXG.Point|JXG.Text} e\r\n     * @returns {Number}\r\n     */\r\n    Y: function (e) {\r\n        return e.Y();\r\n    },\r\n\r\n    /**\r\n     * This is used as the global V() function.\r\n     * @param {Glider|Slider} e\r\n     * @returns {Number}\r\n     */\r\n    V: function (e) {\r\n        return e.Value();\r\n    },\r\n\r\n    /**\r\n     * This is used as the global L() function.\r\n     * @param {JXG.Line} e\r\n     * @returns {Number}\r\n     */\r\n    L: function (e) {\r\n        return e.L();\r\n    },\r\n\r\n    /**\r\n     * This is used as the global area() function.\r\n     * @param {JXG.Circle|JXG.Polygon} obj\r\n     * @returns {Number}\r\n     */\r\n    area: function (obj) {\r\n        if (!Type.exists(obj) || !Type.exists(obj.Area)) {\r\n            this._error('Error: Can\\'t calculate area.');\r\n        }\r\n\r\n        return obj.Area();\r\n    },\r\n\r\n    /**\r\n     * This is used as the global perimeter() function.\r\n     * @param {JXG.Circle|JXG.Polygon} obj\r\n     * @returns {Number}\r\n     */\r\n    perimeter: function (obj) {\r\n        if (!Type.exists(obj) || !Type.exists(obj.Perimeter)) {\r\n            this._error('Error: Can\\'t calculate perimeter.');\r\n        }\r\n\r\n        return obj.Perimeter();\r\n    },\r\n\r\n    /**\r\n     * This is used as the global dist() function.\r\n     * @param {JXG.Point} p1\r\n     * @param {JXG.Point} p2\r\n     * @returns {Number}\r\n     */\r\n    dist: function (p1, p2) {\r\n        if (!Type.exists(p1) || !Type.exists(p1.Dist)) {\r\n            this._error('Error: Can\\'t calculate distance.');\r\n        }\r\n\r\n        return p1.Dist(p2);\r\n    },\r\n\r\n    /**\r\n     * This is used as the global radius() function.\r\n     * @param {JXG.Circle|Sector} obj\r\n     * @returns {Number}\r\n     */\r\n    radius: function (obj) {\r\n        if (!Type.exists(obj) || !Type.exists(obj.Radius)) {\r\n            this._error('Error: Can\\'t calculate radius.');\r\n        }\r\n\r\n        return obj.Radius();\r\n    },\r\n\r\n    /**\r\n     * This is used as the global slope() function.\r\n     * @param {JXG.Line} obj\r\n     * @returns {Number}\r\n     */\r\n    slope: function (obj) {\r\n        if (!Type.exists(obj) || !Type.exists(obj.Slope)) {\r\n            this._error('Error: Can\\'t calculate slope.');\r\n        }\r\n\r\n        return obj.Slope();\r\n    },\r\n\r\n    /**\r\n     * + operator implementation\r\n     * @param {Number|Array|JXG.Point} a\r\n     * @param {Number|Array|JXG.Point} b\r\n     * @returns {Number|Array}\r\n     */\r\n    add: function (a, b) {\r\n        var i, len, res;\r\n\r\n        a = Type.evalSlider(a);\r\n        b = Type.evalSlider(b);\r\n\r\n        if (Interval.isInterval(a) || Interval.isInterval(b)) {\r\n            res = Interval.add(a, b);\r\n        } else if (Type.isArray(a) && Type.isArray(b)) {\r\n            len = Math.min(a.length, b.length);\r\n            res = [];\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = a[i] + b[i];\r\n            }\r\n        } else if (Type.isNumber(a) && Type.isNumber(b)) {\r\n            res = a + b;\r\n        } else if (Type.isString(a) || Type.isString(b)) {\r\n            res = a.toString() + b.toString();\r\n        } else {\r\n            this._error('Operation + not defined on operands ' + typeof a + ' and ' + typeof b);\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * - operator implementation\r\n     * @param {Number|Array|JXG.Point} a\r\n     * @param {Number|Array|JXG.Point} b\r\n     * @returns {Number|Array}\r\n     */\r\n    sub: function (a, b) {\r\n        var i, len, res;\r\n\r\n        a = Type.evalSlider(a);\r\n        b = Type.evalSlider(b);\r\n\r\n        if (Interval.isInterval(a) || Interval.isInterval(b)) {\r\n            res = Interval.sub(a, b);\r\n        } else if (Type.isArray(a) && Type.isArray(b)) {\r\n            len = Math.min(a.length, b.length);\r\n            res = [];\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = a[i] - b[i];\r\n            }\r\n        } else if (Type.isNumber(a) && Type.isNumber(b)) {\r\n            res = a - b;\r\n        } else {\r\n            this._error('Operation - not defined on operands ' + typeof a + ' and ' + typeof b);\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * unary - operator implementation\r\n     * @param {Number|Array|JXG.Point} a\r\n     * @returns {Number|Array}\r\n     */\r\n    neg: function (a) {\r\n        var i, len, res;\r\n\r\n        a = Type.evalSlider(a);\r\n\r\n        if (Interval.isInterval(a)) {\r\n            res = Interval.negative(a);\r\n        } else if (Type.isArray(a)) {\r\n            len = a.length;\r\n            res = [];\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = -a[i];\r\n            }\r\n        } else if (Type.isNumber(a)) {\r\n            res = -a;\r\n        } else {\r\n            this._error('Unary operation - not defined on operand ' + typeof a);\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Multiplication of vectors and numbers\r\n     * @param {Number|Array} a\r\n     * @param {Number|Array} b\r\n     * @returns {Number|Array} (Inner) product of the given input values.\r\n     */\r\n    mul: function (a, b) {\r\n        var i, len, res;\r\n\r\n        a = Type.evalSlider(a);\r\n        b = Type.evalSlider(b);\r\n\r\n        if (Type.isArray(a) && Type.isNumber(b)) {\r\n            // swap b and a\r\n            i = a;\r\n            a = b;\r\n            b = a;\r\n        }\r\n\r\n        if (Interval.isInterval(a) || Interval.isInterval(b)) {\r\n            res = Interval.mul(a, b);\r\n        } else if (Type.isArray(a) && Type.isArray(b)) {\r\n            len = Math.min(a.length, b.length);\r\n            res = Mat.innerProduct(a, b, len);\r\n        } else if (Type.isNumber(a) && Type.isArray(b)) {\r\n            len = b.length;\r\n            res = [];\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = a * b[i];\r\n            }\r\n        } else if (Type.isNumber(a) && Type.isNumber(b)) {\r\n            res = a * b;\r\n        } else {\r\n            this._error('Operation * not defined on operands ' + typeof a + ' and ' + typeof b);\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Implementation of the / operator.\r\n     * @param {Number|Array} a\r\n     * @param {Number} b\r\n     * @returns {Number|Array}\r\n     */\r\n    div: function (a, b) {\r\n        var i, len, res;\r\n\r\n        a = Type.evalSlider(a);\r\n        b = Type.evalSlider(b);\r\n\r\n        if (Interval.isInterval(a) || Interval.isInterval(b)) {\r\n            res = Interval.div(a, b);\r\n        } else if (Type.isArray(a) && Type.isNumber(b)) {\r\n            len = a.length;\r\n            res = [];\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = a[i] / b;\r\n            }\r\n        } else if (Type.isNumber(a) && Type.isNumber(b)) {\r\n            res = a / b;\r\n        } else {\r\n            this._error('Operation * not defined on operands ' + typeof a + ' and ' + typeof b);\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Implementation of the % operator.\r\n     * @param {Number|Array} a\r\n     * @param {Number} b\r\n     * @returns {Number|Array}\r\n     */\r\n    mod: function (a, b) {\r\n        var i, len, res;\r\n\r\n        a = Type.evalSlider(a);\r\n        b = Type.evalSlider(b);\r\n\r\n        if (Interval.isInterval(a) || Interval.isInterval(b)) {\r\n            return Interval.fmod(a, b);\r\n        } else if (Type.isArray(a) && Type.isNumber(b)) {\r\n            len = a.length;\r\n            res = [];\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = Mat.mod(a[i], b, true);\r\n            }\r\n        } else if (Type.isNumber(a) && Type.isNumber(b)) {\r\n            res = Mat.mod(a, b, true);\r\n        } else {\r\n            this._error('Operation * not defined on operands ' + typeof a + ' and ' + typeof b);\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Pow function wrapper to allow direct usage of sliders.\r\n     * @param {Number|Slider} a\r\n     * @param {Number|Slider} b\r\n     * @returns {Number}\r\n     */\r\n    pow: function (a, b) {\r\n        a = Type.evalSlider(a);\r\n        b = Type.evalSlider(b);\r\n\r\n        if (Interval.isInterval(a) || Interval.isInterval(b)) {\r\n            return Interval.pow(a, b);\r\n        }\r\n        return Mat.pow(a, b);\r\n    },\r\n\r\n    lt: function (a, b) {\r\n        if (Interval.isInterval(a) || Interval.isInterval(b)) {\r\n            return Interval.lt(a, b);\r\n        }\r\n        return a < b;\r\n    },\r\n    leq: function (a, b) {\r\n        if (Interval.isInterval(a) || Interval.isInterval(b)) {\r\n            return Interval.leq(a, b);\r\n        }\r\n        return a <= b;\r\n    },\r\n    gt: function (a, b) {\r\n        if (Interval.isInterval(a) || Interval.isInterval(b)) {\r\n            return Interval.gt(a, b);\r\n        }\r\n        return a > b;\r\n    },\r\n    geq: function (a, b) {\r\n        if (Interval.isInterval(a) || Interval.isInterval(b)) {\r\n            return Interval.geq(a, b);\r\n        }\r\n        return a >= b;\r\n    },\r\n\r\n    randint: function (min, max, step) {\r\n        if (!Type.exists(step)) {\r\n            step = 1;\r\n        }\r\n        return Math.round(Math.random() * (max - min) / step) * step + min;\r\n    },\r\n\r\n    DDD: function (f) {\r\n        console.log('Dummy derivative function. This should never appear!');\r\n    },\r\n\r\n    /**\r\n     * Implementation of the ?: operator\r\n     * @param {Boolean} cond Condition\r\n     * @param {*} v1\r\n     * @param {*} v2\r\n     * @returns {*} Either v1 or v2.\r\n     */\r\n    ifthen: function (cond, v1, v2) {\r\n        if (cond) {\r\n            return v1;\r\n        }\r\n\r\n        return v2;\r\n    },\r\n\r\n    /**\r\n     * Implementation of the delete() builtin function\r\n     * @param {JXG.GeometryElement} element\r\n     */\r\n    del: function (element) {\r\n        if (typeof element === 'object' && JXG.exists(element.type) && JXG.exists(element.elementClass)) {\r\n            this.board.removeObject(element);\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Implementation of the eval() builtin function. Calls JXG.evaluate().\r\n     * @param {String|Number|Function} v\r\n     */\r\n    eval: function (v) {\r\n        return JXG.evaluate(v);\r\n    },\r\n\r\n    /**\r\n     * Implementation of the use() builtin function\r\n     * @param {String} board\r\n     */\r\n    use: function (board) {\r\n        var b, ref,\r\n            found = false;\r\n\r\n        if (typeof board === 'string') {\r\n            // search all the boards for the one with the appropriate container div\r\n            for (b in JXG.boards) {\r\n                if (JXG.boards.hasOwnProperty(b) && JXG.boards[b].container === board) {\r\n                    ref = JXG.boards[b];\r\n                    found = true;\r\n                    break;\r\n                }\r\n            }\r\n        } else {\r\n            ref = board;\r\n            found = true;\r\n        }\r\n\r\n        if (found) {\r\n            this.board = ref;\r\n            this.builtIn.$board = ref;\r\n            this.builtIn.$board.src = '$jc$.board';\r\n        } else {\r\n            this._error('Board \\'' + board + '\\' not found!');\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Find the first symbol to the given value from the given scope upwards.\r\n     * @param v Value\r\n     * @param {Number} [scope=-1] The scope, default is to start with current scope (-1).\r\n     * @returns {Array} An array containing the symbol and the scope if a symbol could be found,\r\n     * an empty array otherwise;\r\n     */\r\n    findSymbol: function (v, scope) {\r\n        var i, s;\r\n\r\n        scope = Type.def(scope, -1);\r\n\r\n        if (scope === -1) {\r\n            s = this.scope;\r\n        } else {\r\n            s = this.scopes[scope];\r\n        }\r\n\r\n        while (s !== null) {\r\n            for (i in s.locals) {\r\n                if (s.locals.hasOwnProperty(i) && s.locals[i] === v) {\r\n                    return [i, s];\r\n                }\r\n            }\r\n\r\n            s = s.previous;\r\n        }\r\n\r\n        return [];\r\n    },\r\n\r\n    /**\r\n     * Import modules into a JessieCode script.\r\n     * @param {String} module\r\n     */\r\n    importModule: function (module) {\r\n        return priv.modules[module.toLowerCase()];\r\n    },\r\n\r\n    /**\r\n     * Defines built in methods and constants.\r\n     * @returns {Object} BuiltIn control object\r\n     */\r\n    defineBuiltIn: function () {\r\n        var that = this,\r\n            builtIn = {\r\n                PI: Math.PI,\r\n                EULER: Math.E,\r\n                D: that.DDD,\r\n                X: that.X,\r\n                Y: that.Y,\r\n                V: that.V,\r\n                Value: that.V,\r\n                L: that.L,\r\n                Length: that.L,\r\n\r\n                acosh: Mat.acosh,\r\n                acot: Mat.acot,\r\n                asinh: Mat.asinh,\r\n                binomial: Mat.binomial,\r\n                cbrt: Mat.cbrt,\r\n                cosh: Mat.cosh,\r\n                cot: Mat.cot,\r\n                deg: Geometry.trueAngle,\r\n                A: that.area,\r\n                area: that.area,\r\n                Area: that.area,\r\n                perimeter: that.perimeter,\r\n                Perimeter: that.perimeter,\r\n                dist: that.dist,\r\n                Dist: that.dist,\r\n                R: that.radius,\r\n                radius: that.radius,\r\n                Radius: that.radius,\r\n                erf: Mat.erf,\r\n                erfc: Mat.erfc,\r\n                erfi: Mat.erfi,\r\n                factorial: Mat.factorial,\r\n                gcd: Mat.gcd,\r\n                lb: Mat.log2,\r\n                lcm: Mat.lcm,\r\n                ld: Mat.log2,\r\n                lg: Mat.log10,\r\n                ln: Math.log,\r\n                log: Mat.log,\r\n                log10: Mat.log10,\r\n                log2: Mat.log2,\r\n                ndtr: Mat.ndtr,\r\n                ndtri: Mat.ndtri,\r\n                nthroot: Mat.nthroot,\r\n                pow: Mat.pow,\r\n                rad: Geometry.rad,\r\n                ratpow: Mat.ratpow,\r\n                trunc: Type.trunc,\r\n                sinh: Mat.sinh,\r\n                slope: that.slope,\r\n                Slope: that.slope,\r\n\r\n                randint: that.randint,\r\n\r\n                IfThen: that.ifthen,\r\n                'import': that.importModule,\r\n                'eval': that.eval,\r\n                'use': that.use,\r\n                'remove': that.del,\r\n                '$': that.getElementById,\r\n                '$value': function(e) {return that.getElementById(e).Value(); },\r\n                getName: that.getName,\r\n                name: that.getName,\r\n                '$board': that.board,\r\n                '$log': that.log\r\n            };\r\n\r\n        // special scopes for factorial, deg, and rad\r\n        builtIn.rad.sc = Geometry;\r\n        builtIn.deg.sc = Geometry;\r\n        builtIn.factorial.sc = Mat;\r\n\r\n        // set the javascript equivalent for the builtIns\r\n        // some of the anonymous functions should be replaced by global methods later on\r\n        // EULER and PI don't get a source attribute - they will be lost anyways and apparently\r\n        // some browser will throw an exception when a property is assigned to a primitive value.\r\n        builtIn.X.src = '$jc$.X';\r\n        builtIn.Y.src = '$jc$.Y';\r\n        builtIn.V.src = '$jc$.V';\r\n        builtIn.Value.src = '$jc$.V';\r\n        builtIn.L.src = '$jc$.L';\r\n        builtIn.Length.src = '$jc$.L';\r\n\r\n        builtIn.acosh.src = 'JXG.Math.acosh';\r\n        builtIn.acot.src = 'JXG.Math.acot';\r\n        builtIn.asinh.src = 'JXG.Math.asinh';\r\n        builtIn.binomial.src = 'JXG.Math.binomial';\r\n        builtIn.cbrt.src = 'JXG.Math.cbrt';\r\n        builtIn.cot.src = 'JXG.Math.cot';\r\n        builtIn.cosh.src = 'JXG.Math.cosh';\r\n        builtIn.deg.src = 'JXG.Math.Geometry.trueAngle';\r\n        builtIn.erf.src = 'JXG.Math.erf';\r\n        builtIn.erfc.src = 'JXG.Math.erfc';\r\n        builtIn.erfi.src = 'JXG.Math.erfi';\r\n        builtIn.A.src = '$jc$.area';\r\n        builtIn.area.src = '$jc$.area';\r\n        builtIn.Area.src = '$jc$.area';\r\n        builtIn.perimeter.src = '$jc$.perimeter';\r\n        builtIn.Perimeter.src = '$jc$.perimeter';\r\n        builtIn.dist.src = '$jc$.dist';\r\n        builtIn.Dist.src = '$jc$.dist';\r\n        builtIn.R.src = '$jc$.radius';\r\n        builtIn.radius.src = '$jc$.radius';\r\n        builtIn.Radius.src = '$jc$.radius';\r\n        builtIn.factorial.src = 'JXG.Math.factorial';\r\n        builtIn.gcd.src = 'JXG.Math.gcd';\r\n        builtIn.lb.src = 'JXG.Math.log2';\r\n        builtIn.lcm.src = 'JXG.Math.lcm';\r\n        builtIn.ld.src = 'JXG.Math.log2';\r\n        builtIn.lg.src = 'JXG.Math.log10';\r\n        builtIn.ln.src = 'Math.log';\r\n        builtIn.log.src = 'JXG.Math.log';\r\n        builtIn.log10.src = 'JXG.Math.log10';\r\n        builtIn.log2.src = 'JXG.Math.log2';\r\n        builtIn.ndtr.src = 'JXG.Math.ndtr';\r\n        builtIn.ndtri.src = 'JXG.Math.ndtri';\r\n        builtIn.nthroot.src = 'JXG.Math.nthroot';\r\n        builtIn.pow.src = 'JXG.Math.pow';\r\n        builtIn.rad.src = 'JXG.Math.Geometry.rad';\r\n        builtIn.ratpow.src = 'JXG.Math.ratpow';\r\n        builtIn.trunc.src = 'JXG.trunc';\r\n        builtIn.sinh.src = 'JXG.Math.sinh';\r\n        builtIn.slope.src = '$jc$.slope';\r\n        builtIn.Slope.src = '$jc$.slope';\r\n\r\n        builtIn.randint.src = '$jc$.randint';\r\n\r\n        builtIn['import'].src = '$jc$.importModule';\r\n        builtIn.eval.src = '$jc$.eval';\r\n        builtIn.use.src = '$jc$.use';\r\n        builtIn.remove.src = '$jc$.del';\r\n        builtIn.IfThen.src = '$jc$.ifthen';\r\n        // usually unused, see node_op > op_execfun\r\n        builtIn.$.src = '(function (n) { return $jc$.board.select(n); })';\r\n        builtIn.$value.src = '(function (n) { return $jc$.board.select(n).Value(); })';\r\n        builtIn.getName.src = '$jc$.getName';\r\n        builtIn.name.src = '$jc$.getName';\r\n        if (builtIn.$board) {\r\n            builtIn.$board.src = '$jc$.board';\r\n        }\r\n        builtIn.$log.src = '$jc$.log';\r\n\r\n        builtIn = JXG.merge(builtIn, that._addedBuiltIn);\r\n\r\n        return builtIn;\r\n    },\r\n\r\n    _addedBuiltIn: {},\r\n\r\n    addBuiltIn: function (name, func) {\r\n        if (Type.exists(this.builtIn)) {\r\n            if (Type.exists(this.builtIn[name])) {\r\n                return;\r\n            }\r\n            this.builtIn[name] = func;\r\n            this.builtIn[name].src = '$jc$.' + name;\r\n        }\r\n\r\n        if (Type.exists(this._addedBuiltIn[name])) {\r\n            return;\r\n        }\r\n        this._addedBuiltIn[name] = func;\r\n        this._addedBuiltIn[name].src = '$jc$.' + name;\r\n\r\n        JXG.JessieCode.prototype[name] = func;\r\n    },\r\n\r\n    /**\r\n     * Returns information about the possible functions and constants.\r\n     * @returns {Object}\r\n     */\r\n    getPossibleOperands: function () {\r\n        var FORBIDDEN = ['E'],\r\n            jessiecode = this.builtIn || this.defineBuiltIn(),\r\n            math = Math,\r\n            jc, ma, merge,\r\n            i, j, p, len, e,\r\n            funcs, funcsJC, consts, operands,\r\n            sort, pack;\r\n\r\n        sort = function (a, b) {\r\n            return a.toLowerCase().localeCompare(b.toLowerCase());\r\n        };\r\n\r\n        pack = function (name, origin) {\r\n            var that = null;\r\n\r\n            if (origin === 'jc') that = jessiecode[name];\r\n            else if (origin === 'Math') that = math[name];\r\n            else return;\r\n\r\n            if (FORBIDDEN.indexOf(name) >= 0) {\r\n                return;\r\n            } else if (JXG.isFunction(that)) {\r\n                return {\r\n                    name: name,\r\n                    type: 'function',\r\n                    numParams: that.length,\r\n                    origin: origin,\r\n                };\r\n            } else if (JXG.isNumber(that)) {\r\n                return {\r\n                    name: name,\r\n                    type: 'constant',\r\n                    value: that,\r\n                    origin: origin,\r\n                };\r\n            } else if (name.startsWith('$')) {\r\n                // do nothing\r\n            } else if (that !== undefined) {\r\n                console.error('undefined type', that);\r\n            }\r\n        };\r\n\r\n        jc = Object.getOwnPropertyNames(jessiecode).sort(sort);\r\n        ma = Object.getOwnPropertyNames(math).sort(sort);\r\n        merge = [];\r\n        i = 0;\r\n        j = 0;\r\n\r\n        while (i < jc.length || j < ma.length) {\r\n            if (jc[i] === ma[j]) {\r\n                p = pack(ma[j], 'Math');\r\n                if (JXG.exists(p)) merge.push(p);\r\n                i++;\r\n                j++;\r\n            } else if (!JXG.exists(ma[j]) || jc[i].toLowerCase().localeCompare(ma[j].toLowerCase()) < 0) {\r\n                p = pack(jc[i], 'jc');\r\n                if (JXG.exists(p)) merge.push(p);\r\n                i++;\r\n            } else {\r\n                p = pack(ma[j], 'Math');\r\n                if (JXG.exists(p)) merge.push(p);\r\n                j++;\r\n            }\r\n        }\r\n\r\n        funcs = [];\r\n        funcsJC = [];\r\n        consts = [];\r\n        operands = {};\r\n        len = merge.length;\r\n        for (i = 0; i < len; i++) {\r\n            e = merge[i];\r\n            switch (e.type) {\r\n                case 'function':\r\n                    funcs.push(e.name);\r\n                    if (e.origin === 'jc')\r\n                        funcsJC.push(e.name);\r\n                    break;\r\n                case 'constant':\r\n                    consts.push(e.name);\r\n                    break;\r\n            }\r\n            operands[e.name] = e;\r\n        }\r\n\r\n        return {\r\n            all: operands,\r\n            list: merge,\r\n            functions: funcs,\r\n            functions_jessiecode: funcsJC,\r\n            constants: consts,\r\n        };\r\n    },\r\n\r\n    /**\r\n     * Output a debugging message. Uses debug console, if available. Otherwise an HTML element with the\r\n     * id \"debug\" and an innerText property is used.\r\n     * @param {String} log\r\n     * @private\r\n     */\r\n    _debug: function (log) {\r\n        if (typeof console === 'object' && console.log) {\r\n            console.log(log);\r\n        } else if (Env.isBrowser && document && document.getElementById('debug') !== null) {\r\n            document.getElementById('debug').innerText += log + '\\n';\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Throws an exception with the given error message.\r\n     * @param {String} msg Error message\r\n     */\r\n    _error: function (msg) {\r\n        var e = new Error('Error(' + this.line + '): ' + msg);\r\n        e.line = this.line;\r\n        throw e;\r\n    },\r\n\r\n    /**\r\n     * Output a warning message using {@link JXG#debug} and precedes the message with \"Warning: \".\r\n     * @param {String} msg\r\n     */\r\n    _warn: function (msg) {\r\n        if (typeof console === 'object' && console.log) {\r\n            console.log('Warning(' + this.line + '): ' + msg);\r\n        } else if (Env.isBrowser && document && document.getElementById(this.warnLog) !== null) {\r\n            document.getElementById(this.warnLog).innerText += 'Warning(' + this.line + '): ' + msg + '\\n';\r\n        }\r\n    },\r\n\r\n    _log: function (msg) {\r\n        if (typeof window !== 'object' && typeof self === 'object' && self.postMessage) {\r\n            self.postMessage({ type: 'log', msg: 'Log: ' + msg.toString() });\r\n        } else {\r\n            console.log('Log: ', arguments);\r\n        }\r\n    }\r\n\r\n});\r\n\r\n/* parser generated by jison 0.4.18 */\r\n/*\r\n  Returns a Parser object of the following structure:\r\n\r\n  Parser: {\r\n    yy: {}\r\n  }\r\n\r\n  Parser.prototype: {\r\n    yy: {},\r\n    trace: function(),\r\n    symbols_: {associative list: name ==> number},\r\n    terminals_: {associative list: number ==> name},\r\n    productions_: [...],\r\n    performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$),\r\n    table: [...],\r\n    defaultActions: {...},\r\n    parseError: function(str, hash),\r\n    parse: function(input),\r\n\r\n    lexer: {\r\n        EOF: 1,\r\n        parseError: function(str, hash),\r\n        setInput: function(input),\r\n        input: function(),\r\n        unput: function(str),\r\n        more: function(),\r\n        less: function(n),\r\n        pastInput: function(),\r\n        upcomingInput: function(),\r\n        showPosition: function(),\r\n        test_match: function(regex_match_array, rule_index),\r\n        next: function(),\r\n        lex: function(),\r\n        begin: function(condition),\r\n        popState: function(),\r\n        _currentRules: function(),\r\n        topState: function(),\r\n        pushState: function(condition),\r\n\r\n        options: {\r\n            ranges: boolean           (optional: true ==> token location info will include a .range[] member)\r\n            flex: boolean             (optional: true ==> flex-like lexing behaviour where the rules are tested exhaustively to find the longest match)\r\n            backtrack_lexer: boolean  (optional: true ==> lexer regexes are tested in order and for each matching regex the action code is invoked; the lexer terminates the scan when a token is returned by the action code)\r\n        },\r\n\r\n        performAction: function(yy, yy_, $avoiding_name_collisions, YY_START),\r\n        rules: [...],\r\n        conditions: {associative list: name ==> set},\r\n    }\r\n  }\r\n\r\n\r\n  token location info (@$, _$, etc.): {\r\n    first_line: n,\r\n    last_line: n,\r\n    first_column: n,\r\n    last_column: n,\r\n    range: [start_number, end_number]       (where the numbers are indexes into the input string, regular zero-based)\r\n  }\r\n\r\n\r\n  the parseError function receives a 'hash' object with these members for lexer and parser errors: {\r\n    text:        (matched text)\r\n    token:       (the produced terminal token, if any)\r\n    line:        (yylineno)\r\n  }\r\n  while parser (grammar) errors will also provide these members, i.e. parser errors deliver a superset of attributes: {\r\n    loc:         (yylloc)\r\n    expected:    (string describing the set of expected tokens)\r\n    recoverable: (boolean: TRUE when the parser has a error recovery rule available for this particular error)\r\n  }\r\n*/\r\n/**\r\n * @class\r\n * @ignore\r\n */\r\nvar parser = (function(){\r\nvar o=function(k,v,o,l){for(o=o||{},l=k.length;l--;o[k[l]]=v);return o},$V0=[2,14],$V1=[1,13],$V2=[1,37],$V3=[1,14],$V4=[1,15],$V5=[1,21],$V6=[1,16],$V7=[1,17],$V8=[1,33],$V9=[1,18],$Va=[1,19],$Vb=[1,12],$Vc=[1,59],$Vd=[1,60],$Ve=[1,58],$Vf=[1,46],$Vg=[1,48],$Vh=[1,49],$Vi=[1,50],$Vj=[1,51],$Vk=[1,52],$Vl=[1,53],$Vm=[1,54],$Vn=[1,45],$Vo=[1,38],$Vp=[1,39],$Vq=[5,7,8,14,15,16,17,19,20,21,23,26,27,50,51,58,65,74,75,76,77,78,79,80,82,91,93],$Vr=[5,7,8,12,14,15,16,17,19,20,21,23,26,27,50,51,58,65,74,75,76,77,78,79,80,82,91,93],$Vs=[8,10,16,32,34,35,37,39,41,42,43,45,46,47,48,50,51,53,54,55,57,64,65,66,83,86],$Vt=[2,48],$Vu=[1,72],$Vv=[10,16,32,34,35,37,39,41,42,43,45,46,47,48,50,51,53,54,55,57,66,83,86],$Vw=[1,78],$Vx=[8,10,16,32,34,35,37,41,42,43,45,46,47,48,50,51,53,54,55,57,64,65,66,83,86],$Vy=[1,82],$Vz=[8,10,16,32,34,35,37,39,45,46,47,48,50,51,53,54,55,57,64,65,66,83,86],$VA=[1,83],$VB=[1,84],$VC=[1,85],$VD=[8,10,16,32,34,35,37,39,41,42,43,50,51,53,54,55,57,64,65,66,83,86],$VE=[1,89],$VF=[1,90],$VG=[1,91],$VH=[1,92],$VI=[1,97],$VJ=[8,10,16,32,34,35,37,39,41,42,43,45,46,47,48,53,54,55,57,64,65,66,83,86],$VK=[1,103],$VL=[1,104],$VM=[8,10,16,32,34,35,37,39,41,42,43,45,46,47,48,50,51,57,64,65,66,83,86],$VN=[1,105],$VO=[1,106],$VP=[1,107],$VQ=[1,126],$VR=[1,139],$VS=[83,86],$VT=[1,150],$VU=[10,66,86],$VV=[8,10,16,20,32,34,35,37,39,41,42,43,45,46,47,48,50,51,53,54,55,57,64,65,66,82,83,86],$VW=[1,167],$VX=[10,86];\r\n/**\r\n * @class\r\n * @ignore\r\n */\r\nvar parser = {trace: function trace () { },\r\nyy: {},\r\nsymbols_: {\"error\":2,\"Program\":3,\"StatementList\":4,\"EOF\":5,\"IfStatement\":6,\"IF\":7,\"(\":8,\"Expression\":9,\")\":10,\"Statement\":11,\"ELSE\":12,\"LoopStatement\":13,\"WHILE\":14,\"FOR\":15,\";\":16,\"DO\":17,\"UnaryStatement\":18,\"USE\":19,\"IDENTIFIER\":20,\"DELETE\":21,\"ReturnStatement\":22,\"RETURN\":23,\"EmptyStatement\":24,\"StatementBlock\":25,\"{\":26,\"}\":27,\"ExpressionStatement\":28,\"AssignmentExpression\":29,\"ConditionalExpression\":30,\"LeftHandSideExpression\":31,\"=\":32,\"LogicalORExpression\":33,\"?\":34,\":\":35,\"LogicalANDExpression\":36,\"||\":37,\"EqualityExpression\":38,\"&&\":39,\"RelationalExpression\":40,\"==\":41,\"!=\":42,\"~=\":43,\"AdditiveExpression\":44,\"<\":45,\">\":46,\"<=\":47,\">=\":48,\"MultiplicativeExpression\":49,\"+\":50,\"-\":51,\"UnaryExpression\":52,\"*\":53,\"/\":54,\"%\":55,\"ExponentExpression\":56,\"^\":57,\"!\":58,\"MemberExpression\":59,\"CallExpression\":60,\"PrimaryExpression\":61,\"FunctionExpression\":62,\"MapExpression\":63,\".\":64,\"[\":65,\"]\":66,\"BasicLiteral\":67,\"ObjectLiteral\":68,\"ArrayLiteral\":69,\"NullLiteral\":70,\"BooleanLiteral\":71,\"StringLiteral\":72,\"NumberLiteral\":73,\"NULL\":74,\"TRUE\":75,\"FALSE\":76,\"STRING\":77,\"NUMBER\":78,\"NAN\":79,\"INFINITY\":80,\"ElementList\":81,\"<<\":82,\">>\":83,\"PropertyList\":84,\"Property\":85,\",\":86,\"PropertyName\":87,\"Arguments\":88,\"AttributeList\":89,\"Attribute\":90,\"FUNCTION\":91,\"ParameterDefinitionList\":92,\"MAP\":93,\"->\":94,\"$accept\":0,\"$end\":1},\r\nterminals_: {2:\"error\",5:\"EOF\",7:\"IF\",8:\"(\",10:\")\",12:\"ELSE\",14:\"WHILE\",15:\"FOR\",16:\";\",17:\"DO\",19:\"USE\",20:\"IDENTIFIER\",21:\"DELETE\",23:\"RETURN\",26:\"{\",27:\"}\",32:\"=\",34:\"?\",35:\":\",37:\"||\",39:\"&&\",41:\"==\",42:\"!=\",43:\"~=\",45:\"<\",46:\">\",47:\"<=\",48:\">=\",50:\"+\",51:\"-\",53:\"*\",54:\"/\",55:\"%\",57:\"^\",58:\"!\",64:\".\",65:\"[\",66:\"]\",74:\"NULL\",75:\"TRUE\",76:\"FALSE\",77:\"STRING\",78:\"NUMBER\",79:\"NAN\",80:\"INFINITY\",82:\"<<\",83:\">>\",86:\",\",91:\"FUNCTION\",93:\"MAP\",94:\"->\"},\r\nproductions_: [0,[3,2],[6,5],[6,7],[13,5],[13,9],[13,7],[18,2],[18,2],[22,2],[22,3],[24,1],[25,3],[4,2],[4,0],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[11,1],[28,2],[9,1],[29,1],[29,3],[30,1],[30,5],[33,1],[33,3],[36,1],[36,3],[38,1],[38,3],[38,3],[38,3],[40,1],[40,3],[40,3],[40,3],[40,3],[44,1],[44,3],[44,3],[49,1],[49,3],[49,3],[49,3],[56,1],[56,3],[52,1],[52,2],[52,2],[52,2],[31,1],[31,1],[59,1],[59,1],[59,1],[59,3],[59,4],[61,1],[61,1],[61,1],[61,1],[61,3],[67,1],[67,1],[67,1],[67,1],[70,1],[71,1],[71,1],[72,1],[73,1],[73,1],[73,1],[69,2],[69,3],[68,2],[68,3],[84,1],[84,3],[85,3],[87,1],[87,1],[87,1],[60,2],[60,3],[60,2],[60,4],[60,3],[88,2],[88,3],[89,1],[89,3],[90,1],[90,1],[81,1],[81,3],[62,4],[62,5],[63,5],[63,6],[92,1],[92,3]],\r\n/**\r\n * @class\r\n * @ignore\r\n */\r\nperformAction: function anonymous(yytext, yyleng, yylineno, yy, yystate /* action[1] */, $$ /* vstack */, _$ /* lstack */) {\r\n/* this == yyval */\r\n\r\nvar $0 = $$.length - 1;\r\nswitch (yystate) {\r\ncase 1:\r\n return $$[$0-1];\r\nbreak;\r\ncase 2:\r\n this.$ = AST.createNode(lc(_$[$0-4]), 'node_op', 'op_if', $$[$0-2], $$[$0]);\r\nbreak;\r\ncase 3:\r\n this.$ = AST.createNode(lc(_$[$0-6]), 'node_op', 'op_if_else', $$[$0-4], $$[$0-2], $$[$0]);\r\nbreak;\r\ncase 4:\r\n this.$ = AST.createNode(lc(_$[$0-4]), 'node_op', 'op_while', $$[$0-2], $$[$0]);\r\nbreak;\r\ncase 5:\r\n this.$ = AST.createNode(lc(_$[$0-8]), 'node_op', 'op_for', $$[$0-6], $$[$0-4], $$[$0-2], $$[$0]);\r\nbreak;\r\ncase 6:\r\n this.$ = AST.createNode(lc(_$[$0-6]), 'node_op', 'op_do', $$[$0-5], $$[$0-2]);\r\nbreak;\r\ncase 7:\r\n this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_use', $$[$0]);\r\nbreak;\r\ncase 8:\r\n this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_delete', $$[$0]);\r\nbreak;\r\ncase 9:\r\n this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_return', undefined);\r\nbreak;\r\ncase 10:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_return', $$[$0-1]);\r\nbreak;\r\ncase 11: case 14:\r\n this.$ = AST.createNode(lc(_$[$0]), 'node_op', 'op_none');\r\nbreak;\r\ncase 12:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_block', $$[$0-1]);\r\nbreak;\r\ncase 13:\r\n this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_none', $$[$0-1], $$[$0]);\r\nbreak;\r\ncase 15: case 16: case 17: case 18: case 19: case 20: case 21: case 23: case 24: case 26: case 28: case 30: case 32: case 36: case 41: case 44: case 48: case 50: case 52: case 54: case 55: case 56: case 58: case 62: case 81: case 84: case 85: case 86:\r\n this.$ = $$[$0];\r\nbreak;\r\ncase 22: case 65: case 93:\r\n this.$ = $$[$0-1];\r\nbreak;\r\ncase 25:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_assign', $$[$0-2], $$[$0]); this.$.isMath = false;\r\nbreak;\r\ncase 27:\r\n this.$ = AST.createNode(lc(_$[$0-4]), 'node_op', 'op_conditional', $$[$0-4], $$[$0-2], $$[$0]); this.$.isMath = false;\r\nbreak;\r\ncase 29:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_or', $$[$0-2], $$[$0]); this.$.isMath = false;\r\nbreak;\r\ncase 31:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_and', $$[$0-2], $$[$0]); this.$.isMath = false;\r\nbreak;\r\ncase 33:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_eq', $$[$0-2], $$[$0]); this.$.isMath = false;\r\nbreak;\r\ncase 34:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_neq', $$[$0-2], $$[$0]); this.$.isMath = false;\r\nbreak;\r\ncase 35:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_approx', $$[$0-2], $$[$0]); this.$.isMath = false;\r\nbreak;\r\ncase 37:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_lt', $$[$0-2], $$[$0]); this.$.isMath = false;\r\nbreak;\r\ncase 38:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_gt', $$[$0-2], $$[$0]); this.$.isMath = false;\r\nbreak;\r\ncase 39:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_leq', $$[$0-2], $$[$0]); this.$.isMath = false;\r\nbreak;\r\ncase 40:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_geq', $$[$0-2], $$[$0]); this.$.isMath = false;\r\nbreak;\r\ncase 42:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_add', $$[$0-2], $$[$0]); this.$.isMath = true;\r\nbreak;\r\ncase 43:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_sub', $$[$0-2], $$[$0]); this.$.isMath = true;\r\nbreak;\r\ncase 45:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_mul', $$[$0-2], $$[$0]); this.$.isMath = true;\r\nbreak;\r\ncase 46:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_div', $$[$0-2], $$[$0]); this.$.isMath = true;\r\nbreak;\r\ncase 47:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_mod', $$[$0-2], $$[$0]); this.$.isMath = true;\r\nbreak;\r\ncase 49:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_exp', $$[$0-2], $$[$0]); this.$.isMath = true;\r\nbreak;\r\ncase 51:\r\n this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_not', $$[$0]); this.$.isMath = false;\r\nbreak;\r\ncase 53:\r\n this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_neg', $$[$0]); this.$.isMath = true;\r\nbreak;\r\ncase 57: case 63: case 64: case 66: case 67: case 68: case 97:\r\n this.$ = $$[$0]; this.$.isMath = false;\r\nbreak;\r\ncase 59: case 91:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_property', $$[$0-2], $$[$0]); this.$.isMath = true;\r\nbreak;\r\ncase 60: case 90:\r\n this.$ = AST.createNode(lc(_$[$0-3]), 'node_op', 'op_extvalue', $$[$0-3], $$[$0-1]); this.$.isMath = true;\r\nbreak;\r\ncase 61:\r\n this.$ = AST.createNode(lc(_$[$0]), 'node_var', $$[$0]);\r\nbreak;\r\ncase 69:\r\n this.$ = $$[$0]; this.$.isMath = true;\r\nbreak;\r\ncase 70:\r\n this.$ = AST.createNode(lc(_$[$0]), 'node_const', null);\r\nbreak;\r\ncase 71:\r\n this.$ = AST.createNode(lc(_$[$0]), 'node_const_bool', true);\r\nbreak;\r\ncase 72:\r\n this.$ = AST.createNode(lc(_$[$0]), 'node_const_bool', false);\r\nbreak;\r\ncase 73:\r\n this.$ = AST.createNode(lc(_$[$0]), 'node_str', $$[$0].substring(1, $$[$0].length - 1));\r\nbreak;\r\ncase 74:\r\n this.$ = AST.createNode(lc(_$[$0]), 'node_const', parseFloat($$[$0]));\r\nbreak;\r\ncase 75:\r\n this.$ = AST.createNode(lc(_$[$0]), 'node_const', NaN);\r\nbreak;\r\ncase 76:\r\n this.$ = AST.createNode(lc(_$[$0]), 'node_const', Infinity);\r\nbreak;\r\ncase 77:\r\n this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_array', []);\r\nbreak;\r\ncase 78:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_array', $$[$0-1]);\r\nbreak;\r\ncase 79:\r\n this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_emptyobject', {}); this.$.needsAngleBrackets = true;\r\nbreak;\r\ncase 80:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_proplst_val', $$[$0-1]); this.$.needsAngleBrackets = true;\r\nbreak;\r\ncase 82:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_proplst', $$[$0-2], $$[$0]);\r\nbreak;\r\ncase 83:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_prop', $$[$0-2], $$[$0]);\r\nbreak;\r\ncase 87: case 89:\r\n this.$ = AST.createNode(lc(_$[$0-1]), 'node_op', 'op_execfun', $$[$0-1], $$[$0]); this.$.isMath = true;\r\nbreak;\r\ncase 88:\r\n this.$ = AST.createNode(lc(_$[$0-2]), 'node_op', 'op_execfun', $$[$0-2], $$[$0-1], $$[$0], true); this.$.isMath = false;\r\nbreak;\r\ncase 92:\r\n this.$ = [];\r\nbreak;\r\ncase 94: case 98: case 104:\r\n this.$ = [$$[$0]];\r\nbreak;\r\ncase 95: case 99: case 105:\r\n this.$ = $$[$0-2].concat($$[$0]);\r\nbreak;\r\ncase 96:\r\n this.$ = AST.createNode(lc(_$[$0]), 'node_var', $$[$0]); this.$.isMath = true;\r\nbreak;\r\ncase 100:\r\n this.$ = AST.createNode(lc(_$[$0-3]), 'node_op', 'op_function', [], $$[$0]); this.$.isMath = false;\r\nbreak;\r\ncase 101:\r\n this.$ = AST.createNode(lc(_$[$0-4]), 'node_op', 'op_function', $$[$0-2], $$[$0]); this.$.isMath = false;\r\nbreak;\r\ncase 102:\r\n this.$ = AST.createNode(lc(_$[$0-4]), 'node_op', 'op_map', [], $$[$0]);\r\nbreak;\r\ncase 103:\r\n this.$ = AST.createNode(lc(_$[$0-5]), 'node_op', 'op_map', $$[$0-3], $$[$0]);\r\nbreak;\r\n}\r\n},\r\ntable: [o([5,7,8,14,15,16,17,19,20,21,23,26,50,51,58,65,74,75,76,77,78,79,80,82,91,93],$V0,{3:1,4:2}),{1:[3]},{5:[1,3],6:6,7:$V1,8:$V2,9:20,11:4,13:7,14:$V3,15:$V4,16:$V5,17:$V6,18:8,19:$V7,20:$V8,21:$V9,22:9,23:$Va,24:11,25:5,26:$Vb,28:10,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{1:[2,1]},o($Vq,[2,13]),o($Vr,[2,15]),o($Vr,[2,16]),o($Vr,[2,17]),o($Vr,[2,18]),o($Vr,[2,19]),o($Vr,[2,20]),o($Vr,[2,21]),o([7,8,14,15,16,17,19,20,21,23,26,27,50,51,58,65,74,75,76,77,78,79,80,82,91,93],$V0,{4:61}),{8:[1,62]},{8:[1,63]},{8:[1,64]},{6:6,7:$V1,8:$V2,9:20,11:65,13:7,14:$V3,15:$V4,16:$V5,17:$V6,18:8,19:$V7,20:$V8,21:$V9,22:9,23:$Va,24:11,25:5,26:$Vb,28:10,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{20:[1,66]},{20:[1,67]},{8:$V2,9:69,16:[1,68],20:$V8,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{16:[1,70]},o($Vr,[2,11]),o($Vs,[2,23]),o($Vs,[2,24]),o([8,10,16,34,35,37,39,41,42,43,45,46,47,48,50,51,53,54,55,64,65,66,83,86],$Vt,{32:[1,71],57:$Vu}),o([8,10,16,32,35,39,41,42,43,45,46,47,48,50,51,53,54,55,57,64,65,66,83,86],[2,26],{34:[1,73],37:[1,74]}),o($Vv,[2,54],{88:77,8:$Vw,64:[1,75],65:[1,76]}),o($Vv,[2,55],{88:79,8:$Vw,64:[1,81],65:[1,80]}),o($Vx,[2,28],{39:$Vy}),o($Vs,[2,56]),o($Vs,[2,57]),o($Vs,[2,58]),o($Vz,[2,30],{41:$VA,42:$VB,43:$VC}),o($Vs,[2,61]),o($Vs,[2,62]),o($Vs,[2,63]),o($Vs,[2,64]),{8:$V2,9:86,20:$V8,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:[1,87]},{8:[1,88]},o($VD,[2,32],{45:$VE,46:$VF,47:$VG,48:$VH}),o($Vs,[2,66]),o($Vs,[2,67]),o($Vs,[2,68]),o($Vs,[2,69]),{20:$VI,72:98,73:99,77:$Vj,78:$Vk,79:$Vl,80:$Vm,83:[1,93],84:94,85:95,87:96},{8:$V2,20:$V8,29:102,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,66:[1,100],67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,81:101,82:$Vn,91:$Vo,93:$Vp},o($VJ,[2,36],{50:$VK,51:$VL}),o($Vs,[2,70]),o($Vs,[2,71]),o($Vs,[2,72]),o($Vs,[2,73]),o($Vs,[2,74]),o($Vs,[2,75]),o($Vs,[2,76]),o($VM,[2,41],{53:$VN,54:$VO,55:$VP}),o($Vs,[2,44]),o($Vs,[2,50]),{8:$V2,20:$V8,31:109,50:$Vc,51:$Vd,52:108,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,31:109,50:$Vc,51:$Vd,52:110,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,31:109,50:$Vc,51:$Vd,52:111,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{6:6,7:$V1,8:$V2,9:20,11:4,13:7,14:$V3,15:$V4,16:$V5,17:$V6,18:8,19:$V7,20:$V8,21:$V9,22:9,23:$Va,24:11,25:5,26:$Vb,27:[1,112],28:10,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,9:113,20:$V8,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,9:114,20:$V8,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,9:115,20:$V8,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{14:[1,116]},o($Vr,[2,7]),o($Vr,[2,8]),o($Vr,[2,9]),{16:[1,117]},o($Vr,[2,22]),{8:$V2,20:$V8,29:118,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,31:109,50:$Vc,51:$Vd,52:119,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,29:120,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,31:109,36:121,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{20:[1,122]},{8:$V2,9:123,20:$V8,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},o($Vs,[2,87],{89:124,90:125,68:127,20:$VQ,82:$Vn}),{8:$V2,10:[1,128],20:$V8,29:102,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,81:129,82:$Vn,91:$Vo,93:$Vp},o($Vs,[2,89]),{8:$V2,9:130,20:$V8,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{20:[1,131]},{8:$V2,20:$V8,31:109,38:132,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,31:109,40:133,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,31:109,40:134,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,31:109,40:135,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{10:[1,136]},{10:[1,137],20:$VR,92:138},{10:[1,140],20:$VR,92:141},{8:$V2,20:$V8,31:109,44:142,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,31:109,44:143,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,31:109,44:144,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,31:109,44:145,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},o($Vs,[2,79]),{83:[1,146],86:[1,147]},o($VS,[2,81]),{35:[1,148]},{35:[2,84]},{35:[2,85]},{35:[2,86]},o($Vs,[2,77]),{66:[1,149],86:$VT},o($VU,[2,98]),{8:$V2,20:$V8,31:109,49:151,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,31:109,49:152,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,31:109,50:$Vc,51:$Vd,52:153,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,31:109,50:$Vc,51:$Vd,52:154,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,31:109,50:$Vc,51:$Vd,52:155,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},o($Vs,[2,51]),o([8,10,16,32,34,35,37,39,41,42,43,45,46,47,48,50,51,53,54,55,64,65,66,83,86],$Vt,{57:$Vu}),o($Vs,[2,52]),o($Vs,[2,53]),o([5,7,8,10,12,14,15,16,17,19,20,21,23,26,27,32,34,35,37,39,41,42,43,45,46,47,48,50,51,53,54,55,57,58,64,65,66,74,75,76,77,78,79,80,82,83,86,91,93],[2,12]),{10:[1,156]},{10:[1,157]},{16:[1,158]},{8:[1,159]},o($Vr,[2,10]),o($Vs,[2,25]),o($Vs,[2,49]),{35:[1,160]},o($Vx,[2,29],{39:$Vy}),o($Vs,[2,59]),{66:[1,161]},o([8,10,16,32,34,35,37,39,41,42,43,45,46,47,48,50,51,53,54,55,57,64,65,66,83],[2,88],{86:[1,162]}),o($Vs,[2,94]),o($Vs,[2,96]),o($Vs,[2,97]),o($VV,[2,92]),{10:[1,163],86:$VT},{66:[1,164]},o($Vs,[2,91]),o($Vz,[2,31],{41:$VA,42:$VB,43:$VC}),o($VD,[2,33],{45:$VE,46:$VF,47:$VG,48:$VH}),o($VD,[2,34],{45:$VE,46:$VF,47:$VG,48:$VH}),o($VD,[2,35],{45:$VE,46:$VF,47:$VG,48:$VH}),o($Vs,[2,65]),{25:165,26:$Vb},{10:[1,166],86:$VW},o($VX,[2,104]),{94:[1,168]},{10:[1,169],86:$VW},o($VJ,[2,37],{50:$VK,51:$VL}),o($VJ,[2,38],{50:$VK,51:$VL}),o($VJ,[2,39],{50:$VK,51:$VL}),o($VJ,[2,40],{50:$VK,51:$VL}),o($Vs,[2,80]),{20:$VI,72:98,73:99,77:$Vj,78:$Vk,79:$Vl,80:$Vm,85:170,87:96},{8:$V2,20:$V8,29:171,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},o($Vs,[2,78]),{8:$V2,20:$V8,29:172,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},o($VM,[2,42],{53:$VN,54:$VO,55:$VP}),o($VM,[2,43],{53:$VN,54:$VO,55:$VP}),o($Vs,[2,45]),o($Vs,[2,46]),o($Vs,[2,47]),{6:6,7:$V1,8:$V2,9:20,11:173,13:7,14:$V3,15:$V4,16:$V5,17:$V6,18:8,19:$V7,20:$V8,21:$V9,22:9,23:$Va,24:11,25:5,26:$Vb,28:10,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{6:6,7:$V1,8:$V2,9:20,11:174,13:7,14:$V3,15:$V4,16:$V5,17:$V6,18:8,19:$V7,20:$V8,21:$V9,22:9,23:$Va,24:11,25:5,26:$Vb,28:10,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,9:175,20:$V8,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,9:176,20:$V8,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,20:$V8,29:177,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},o($Vs,[2,60]),{20:$VQ,68:127,82:$Vn,90:178},o($VV,[2,93]),o($Vs,[2,90]),o($Vs,[2,100]),{25:179,26:$Vb},{20:[1,180]},{8:$V2,9:181,20:$V8,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{94:[1,182]},o($VS,[2,82]),o($VS,[2,83]),o($VU,[2,99]),o($Vq,[2,2],{12:[1,183]}),o($Vr,[2,4]),{16:[1,184]},{10:[1,185]},o($Vs,[2,27]),o($Vs,[2,95]),o($Vs,[2,101]),o($VX,[2,105]),o($Vs,[2,102]),{8:$V2,9:186,20:$V8,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{6:6,7:$V1,8:$V2,9:20,11:187,13:7,14:$V3,15:$V4,16:$V5,17:$V6,18:8,19:$V7,20:$V8,21:$V9,22:9,23:$Va,24:11,25:5,26:$Vb,28:10,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{8:$V2,9:188,20:$V8,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},{16:[1,189]},o($Vs,[2,103]),o($Vr,[2,3]),{10:[1,190]},o($Vr,[2,6]),{6:6,7:$V1,8:$V2,9:20,11:191,13:7,14:$V3,15:$V4,16:$V5,17:$V6,18:8,19:$V7,20:$V8,21:$V9,22:9,23:$Va,24:11,25:5,26:$Vb,28:10,29:22,30:23,31:24,33:25,36:28,38:32,40:40,44:47,49:55,50:$Vc,51:$Vd,52:56,56:57,58:$Ve,59:26,60:27,61:29,62:30,63:31,65:$Vf,67:34,68:35,69:36,70:41,71:42,72:43,73:44,74:$Vg,75:$Vh,76:$Vi,77:$Vj,78:$Vk,79:$Vl,80:$Vm,82:$Vn,91:$Vo,93:$Vp},o($Vr,[2,5])],\r\ndefaultActions: {3:[2,1],97:[2,84],98:[2,85],99:[2,86]},\r\nparseError: function parseError (str, hash) {\r\n    if (hash.recoverable) {\r\n        this.trace(str);\r\n    } else {\r\n        var error = new Error(str);\r\n        error.hash = hash;\r\n        throw error;\r\n    }\r\n},\r\n/**\r\n * @class\r\n * @ignore\r\n */\r\nparse: function parse(input) {\r\n    var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = '', yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\r\n    var args = lstack.slice.call(arguments, 1);\r\n    var lexer = Object.create(this.lexer);\r\n    var sharedState = { yy: {} };\r\n    for (var k in this.yy) {\r\n        if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\r\n            sharedState.yy[k] = this.yy[k];\r\n        }\r\n    }\r\n    lexer.setInput(input, sharedState.yy);\r\n    sharedState.yy.lexer = lexer;\r\n    sharedState.yy.parser = this;\r\n    if (typeof lexer.yylloc == 'undefined') {\r\n        lexer.yylloc = {};\r\n    }\r\n    var yyloc = lexer.yylloc;\r\n    lstack.push(yyloc);\r\n    var ranges = lexer.options && lexer.options.ranges;\r\n    if (typeof sharedState.yy.parseError === 'function') {\r\n        this.parseError = sharedState.yy.parseError;\r\n    } else {\r\n        this.parseError = Object.getPrototypeOf(this).parseError;\r\n    }\r\n    function popStack(n) {\r\n        stack.length = stack.length - 2 * n;\r\n        vstack.length = vstack.length - n;\r\n        lstack.length = lstack.length - n;\r\n    }\r\n    _token_stack:\r\n        var lex = function () {\r\n            var token;\r\n            token = lexer.lex() || EOF;\r\n            if (typeof token !== 'number') {\r\n                token = self.symbols_[token] || token;\r\n            }\r\n            return token;\r\n        };\r\n    var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\r\n    while (true) {\r\n        state = stack[stack.length - 1];\r\n        if (this.defaultActions[state]) {\r\n            action = this.defaultActions[state];\r\n        } else {\r\n            if (symbol === null || typeof symbol == 'undefined') {\r\n                symbol = lex();\r\n            }\r\n            action = table[state] && table[state][symbol];\r\n        }\r\n                    if (typeof action === 'undefined' || !action.length || !action[0]) {\r\n                var errStr = '';\r\n                expected = [];\r\n                for (p in table[state]) {\r\n                    if (this.terminals_[p] && p > TERROR) {\r\n                        expected.push('\\'' + this.terminals_[p] + '\\'');\r\n                    }\r\n                }\r\n                if (lexer.showPosition) {\r\n                    errStr = 'Parse error on line ' + (yylineno + 1) + ':\\n' + lexer.showPosition() + '\\nExpecting ' + expected.join(', ') + ', got \\'' + (this.terminals_[symbol] || symbol) + '\\'';\r\n                } else {\r\n                    errStr = 'Parse error on line ' + (yylineno + 1) + ': Unexpected ' + (symbol == EOF ? 'end of input' : '\\'' + (this.terminals_[symbol] || symbol) + '\\'');\r\n                }\r\n                this.parseError(errStr, {\r\n                    text: lexer.match,\r\n                    token: this.terminals_[symbol] || symbol,\r\n                    line: lexer.yylineno,\r\n                    loc: yyloc,\r\n                    expected: expected\r\n                });\r\n            }\r\n        if (action[0] instanceof Array && action.length > 1) {\r\n            throw new Error('Parse Error: multiple actions possible at state: ' + state + ', token: ' + symbol);\r\n        }\r\n        switch (action[0]) {\r\n        case 1:\r\n            stack.push(symbol);\r\n            vstack.push(lexer.yytext);\r\n            lstack.push(lexer.yylloc);\r\n            stack.push(action[1]);\r\n            symbol = null;\r\n            if (!preErrorSymbol) {\r\n                yyleng = lexer.yyleng;\r\n                yytext = lexer.yytext;\r\n                yylineno = lexer.yylineno;\r\n                yyloc = lexer.yylloc;\r\n                if (recovering > 0) {\r\n                    recovering--;\r\n                }\r\n            } else {\r\n                symbol = preErrorSymbol;\r\n                preErrorSymbol = null;\r\n            }\r\n            break;\r\n        case 2:\r\n            len = this.productions_[action[1]][1];\r\n            yyval.$ = vstack[vstack.length - len];\r\n            yyval._$ = {\r\n                first_line: lstack[lstack.length - (len || 1)].first_line,\r\n                last_line: lstack[lstack.length - 1].last_line,\r\n                first_column: lstack[lstack.length - (len || 1)].first_column,\r\n                last_column: lstack[lstack.length - 1].last_column\r\n            };\r\n            if (ranges) {\r\n                yyval._$.range = [\r\n                    lstack[lstack.length - (len || 1)].range[0],\r\n                    lstack[lstack.length - 1].range[1]\r\n                ];\r\n            }\r\n            r = this.performAction.apply(yyval, [\r\n                yytext,\r\n                yyleng,\r\n                yylineno,\r\n                sharedState.yy,\r\n                action[1],\r\n                vstack,\r\n                lstack\r\n            ].concat(args));\r\n            if (typeof r !== 'undefined') {\r\n                return r;\r\n            }\r\n            if (len) {\r\n                stack = stack.slice(0, -1 * len * 2);\r\n                vstack = vstack.slice(0, -1 * len);\r\n                lstack = lstack.slice(0, -1 * len);\r\n            }\r\n            stack.push(this.productions_[action[1]][0]);\r\n            vstack.push(yyval.$);\r\n            lstack.push(yyval._$);\r\n            newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\r\n            stack.push(newState);\r\n            break;\r\n        case 3:\r\n            return true;\r\n        }\r\n    }\r\n    return true;\r\n}};\r\n\r\n\r\n    var AST = {\r\n        node: function (type, value, children) {\r\n            return {\r\n                type: type,\r\n                value: value,\r\n                children: children\r\n            };\r\n        },\r\n\r\n        createNode: function (pos, type, value, children) {\r\n            var i,\r\n                n = this.node(type, value, []);\r\n\r\n            for (i = 3; i < arguments.length; i++) {\r\n                n.children.push(arguments[i]);\r\n            }\r\n\r\n            n.line = pos[0];\r\n            n.col = pos[1];\r\n            n.eline = pos[2];\r\n            n.ecol = pos[3];\r\n\r\n            return n;\r\n        }\r\n    };\r\n\r\n    var lc = function (lc1) {\r\n        return [lc1.first_line, lc1.first_column, lc1.last_line, lc1.last_column];\r\n    };\r\n\r\n/* generated by jison-lex 0.3.4 */\r\nvar lexer = (function(){\r\nvar lexer = ({\r\n\r\nEOF:1,\r\n\r\nparseError:function parseError(str, hash) {\r\n        if (this.yy.parser) {\r\n            this.yy.parser.parseError(str, hash);\r\n        } else {\r\n            throw new Error(str);\r\n        }\r\n    },\r\n\r\n// resets the lexer, sets new input\r\nsetInput:function (input, yy) {\r\n        this.yy = yy || this.yy || {};\r\n        this._input = input;\r\n        this._more = this._backtrack = this.done = false;\r\n        this.yylineno = this.yyleng = 0;\r\n        this.yytext = this.matched = this.match = '';\r\n        this.conditionStack = ['INITIAL'];\r\n        this.yylloc = {\r\n            first_line: 1,\r\n            first_column: 0,\r\n            last_line: 1,\r\n            last_column: 0\r\n        };\r\n        if (this.options.ranges) {\r\n            this.yylloc.range = [0,0];\r\n        }\r\n        this.offset = 0;\r\n        return this;\r\n    },\r\n\r\n// consumes and returns one char from the input\r\ninput:function () {\r\n        var ch = this._input[0];\r\n        this.yytext += ch;\r\n        this.yyleng++;\r\n        this.offset++;\r\n        this.match += ch;\r\n        this.matched += ch;\r\n        var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\r\n        if (lines) {\r\n            this.yylineno++;\r\n            this.yylloc.last_line++;\r\n        } else {\r\n            this.yylloc.last_column++;\r\n        }\r\n        if (this.options.ranges) {\r\n            this.yylloc.range[1]++;\r\n        }\r\n\r\n        this._input = this._input.slice(1);\r\n        return ch;\r\n    },\r\n\r\n// unshifts one char (or a string) into the input\r\nunput:function (ch) {\r\n        var len = ch.length;\r\n        var lines = ch.split(/(?:\\r\\n?|\\n)/g);\r\n\r\n        this._input = ch + this._input;\r\n        this.yytext = this.yytext.substr(0, this.yytext.length - len);\r\n        //this.yyleng -= len;\r\n        this.offset -= len;\r\n        var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\r\n        this.match = this.match.substr(0, this.match.length - 1);\r\n        this.matched = this.matched.substr(0, this.matched.length - 1);\r\n\r\n        if (lines.length - 1) {\r\n            this.yylineno -= lines.length - 1;\r\n        }\r\n        var r = this.yylloc.range;\r\n\r\n        this.yylloc = {\r\n            first_line: this.yylloc.first_line,\r\n            last_line: this.yylineno + 1,\r\n            first_column: this.yylloc.first_column,\r\n            last_column: lines ?\r\n                (lines.length === oldLines.length ? this.yylloc.first_column : 0)\r\n                 + oldLines[oldLines.length - lines.length].length - lines[0].length :\r\n              this.yylloc.first_column - len\r\n        };\r\n\r\n        if (this.options.ranges) {\r\n            this.yylloc.range = [r[0], r[0] + this.yyleng - len];\r\n        }\r\n        this.yyleng = this.yytext.length;\r\n        return this;\r\n    },\r\n\r\n// When called from action, caches matched text and appends it on next action\r\nmore:function () {\r\n        this._more = true;\r\n        return this;\r\n    },\r\n\r\n// When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.\r\nreject:function () {\r\n        if (this.options.backtrack_lexer) {\r\n            this._backtrack = true;\r\n        } else {\r\n            return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\\n' + this.showPosition(), {\r\n                text: \"\",\r\n                token: null,\r\n                line: this.yylineno\r\n            });\r\n\r\n        }\r\n        return this;\r\n    },\r\n\r\n// retain first n characters of the match\r\nless:function (n) {\r\n        this.unput(this.match.slice(n));\r\n    },\r\n\r\n// displays already matched input, i.e. for error messages\r\npastInput:function () {\r\n        var past = this.matched.substr(0, this.matched.length - this.match.length);\r\n        return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\\n/g, \"\");\r\n    },\r\n\r\n// displays upcoming input, i.e. for error messages\r\nupcomingInput:function () {\r\n        var next = this.match;\r\n        if (next.length < 20) {\r\n            next += this._input.substr(0, 20-next.length);\r\n        }\r\n        return (next.substr(0,20) + (next.length > 20 ? '...' : '')).replace(/\\n/g, \"\");\r\n    },\r\n\r\n// displays the character position where the lexing error occurred, i.e. for error messages\r\nshowPosition:function () {\r\n        var pre = this.pastInput();\r\n        var c = new Array(pre.length + 1).join(\"-\");\r\n        return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\r\n    },\r\n\r\n// test the lexed token: return FALSE when not a match, otherwise return token\r\ntest_match:function(match, indexed_rule) {\r\n        var token,\r\n            lines,\r\n            backup;\r\n\r\n        if (this.options.backtrack_lexer) {\r\n            // save context\r\n            backup = {\r\n                yylineno: this.yylineno,\r\n                yylloc: {\r\n                    first_line: this.yylloc.first_line,\r\n                    last_line: this.last_line,\r\n                    first_column: this.yylloc.first_column,\r\n                    last_column: this.yylloc.last_column\r\n                },\r\n                yytext: this.yytext,\r\n                match: this.match,\r\n                matches: this.matches,\r\n                matched: this.matched,\r\n                yyleng: this.yyleng,\r\n                offset: this.offset,\r\n                _more: this._more,\r\n                _input: this._input,\r\n                yy: this.yy,\r\n                conditionStack: this.conditionStack.slice(0),\r\n                done: this.done\r\n            };\r\n            if (this.options.ranges) {\r\n                backup.yylloc.range = this.yylloc.range.slice(0);\r\n            }\r\n        }\r\n\r\n        lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\r\n        if (lines) {\r\n            this.yylineno += lines.length;\r\n        }\r\n        this.yylloc = {\r\n            first_line: this.yylloc.last_line,\r\n            last_line: this.yylineno + 1,\r\n            first_column: this.yylloc.last_column,\r\n            last_column: lines ?\r\n                         lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length :\r\n                         this.yylloc.last_column + match[0].length\r\n        };\r\n        this.yytext += match[0];\r\n        this.match += match[0];\r\n        this.matches = match;\r\n        this.yyleng = this.yytext.length;\r\n        if (this.options.ranges) {\r\n            this.yylloc.range = [this.offset, this.offset += this.yyleng];\r\n        }\r\n        this._more = false;\r\n        this._backtrack = false;\r\n        this._input = this._input.slice(match[0].length);\r\n        this.matched += match[0];\r\n        token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\r\n        if (this.done && this._input) {\r\n            this.done = false;\r\n        }\r\n        if (token) {\r\n            return token;\r\n        } else if (this._backtrack) {\r\n            // recover context\r\n            for (var k in backup) {\r\n                this[k] = backup[k];\r\n            }\r\n            return false; // rule action called reject() implying the next rule should be tested instead.\r\n        }\r\n        return false;\r\n    },\r\n\r\n// return next match in input\r\nnext:function () {\r\n        if (this.done) {\r\n            return this.EOF;\r\n        }\r\n        if (!this._input) {\r\n            this.done = true;\r\n        }\r\n\r\n        var token,\r\n            match,\r\n            tempMatch,\r\n            index;\r\n        if (!this._more) {\r\n            this.yytext = '';\r\n            this.match = '';\r\n        }\r\n        var rules = this._currentRules();\r\n        for (var i = 0; i < rules.length; i++) {\r\n            tempMatch = this._input.match(this.rules[rules[i]]);\r\n            if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\r\n                match = tempMatch;\r\n                index = i;\r\n                if (this.options.backtrack_lexer) {\r\n                    token = this.test_match(tempMatch, rules[i]);\r\n                    if (token !== false) {\r\n                        return token;\r\n                    } else if (this._backtrack) {\r\n                        match = false;\r\n                        continue; // rule action called reject() implying a rule MISmatch.\r\n                    } else {\r\n                        // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)\r\n                        return false;\r\n                    }\r\n                } else if (!this.options.flex) {\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n        if (match) {\r\n            token = this.test_match(match, rules[index]);\r\n            if (token !== false) {\r\n                return token;\r\n            }\r\n            // else: this is a lexer rule which consumes input without producing a token (e.g. whitespace)\r\n            return false;\r\n        }\r\n        if (this._input === \"\") {\r\n            return this.EOF;\r\n        } else {\r\n            return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\\n' + this.showPosition(), {\r\n                text: \"\",\r\n                token: null,\r\n                line: this.yylineno\r\n            });\r\n        }\r\n    },\r\n\r\n// return next match that has a token\r\nlex:function lex () {\r\n        var r = this.next();\r\n        if (r) {\r\n            return r;\r\n        } else {\r\n            return this.lex();\r\n        }\r\n    },\r\n\r\n// activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\r\nbegin:function begin (condition) {\r\n        this.conditionStack.push(condition);\r\n    },\r\n\r\n// pop the previously active lexer condition state off the condition stack\r\npopState:function popState () {\r\n        var n = this.conditionStack.length - 1;\r\n        if (n > 0) {\r\n            return this.conditionStack.pop();\r\n        } else {\r\n            return this.conditionStack[0];\r\n        }\r\n    },\r\n\r\n// produce the lexer rule set which is active for the currently active lexer condition state\r\n_currentRules:function _currentRules () {\r\n        if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\r\n            return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\r\n        } else {\r\n            return this.conditions[\"INITIAL\"].rules;\r\n        }\r\n    },\r\n\r\n// return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\r\ntopState:function topState (n) {\r\n        n = this.conditionStack.length - 1 - Math.abs(n || 0);\r\n        if (n >= 0) {\r\n            return this.conditionStack[n];\r\n        } else {\r\n            return \"INITIAL\";\r\n        }\r\n    },\r\n\r\n// alias for begin(condition)\r\npushState:function pushState (condition) {\r\n        this.begin(condition);\r\n    },\r\n\r\n// return the number of states currently on the stack\r\nstateStackSize:function stateStackSize() {\r\n        return this.conditionStack.length;\r\n    },\r\noptions: {},\r\n/**\r\n * @class\r\n * @ignore\r\n */\r\nperformAction: function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {\r\nvar YYSTATE=YY_START;\r\nswitch($avoiding_name_collisions) {\r\ncase 0:/* ignore */\r\nbreak;\r\ncase 1:return 78  /* New 123.1234e+-12 */\r\nbreak;\r\ncase 2:return 78  /* Old 123.1234 or .1234 */\r\nbreak;\r\ncase 3:return 78  /* Old 123 */\r\nbreak;\r\ncase 4: return 77;\r\nbreak;\r\ncase 5: return 77;\r\nbreak;\r\ncase 6:/* ignore comment */\r\nbreak;\r\ncase 7:/* ignore multiline comment */\r\nbreak;\r\ncase 8:return 7\r\nbreak;\r\ncase 9:return 12\r\nbreak;\r\ncase 10:return 14\r\nbreak;\r\ncase 11:return 17\r\nbreak;\r\ncase 12:return 15\r\nbreak;\r\ncase 13:return 91\r\nbreak;\r\ncase 14:return 93\r\nbreak;\r\ncase 15:return 19\r\nbreak;\r\ncase 16:return 23\r\nbreak;\r\ncase 17:return 21\r\nbreak;\r\ncase 18:return 75\r\nbreak;\r\ncase 19:return 76\r\nbreak;\r\ncase 20:return 74\r\nbreak;\r\ncase 21:return 80\r\nbreak;\r\ncase 22:return 94\r\nbreak;\r\ncase 23:return 94\r\nbreak;\r\ncase 24:return 82\r\nbreak;\r\ncase 25:return 83\r\nbreak;\r\ncase 26:return 26\r\nbreak;\r\ncase 27:return 27\r\nbreak;\r\ncase 28:return 16\r\nbreak;\r\ncase 29:return '#'\r\nbreak;\r\ncase 30:return 34\r\nbreak;\r\ncase 31:return 35\r\nbreak;\r\ncase 32:return 79\r\nbreak;\r\ncase 33:return 64\r\nbreak;\r\ncase 34:return 65\r\nbreak;\r\ncase 35:return 66\r\nbreak;\r\ncase 36:return 8\r\nbreak;\r\ncase 37:return 10\r\nbreak;\r\ncase 38:return 58\r\nbreak;\r\ncase 39:return 57\r\nbreak;\r\ncase 40:return 57\r\nbreak;\r\ncase 41:return 53\r\nbreak;\r\ncase 42:return 54\r\nbreak;\r\ncase 43:return 55\r\nbreak;\r\ncase 44:return 50\r\nbreak;\r\ncase 45:return 51\r\nbreak;\r\ncase 46:return 47\r\nbreak;\r\ncase 47:return 45\r\nbreak;\r\ncase 48:return 48\r\nbreak;\r\ncase 49:return 46\r\nbreak;\r\ncase 50:return 41\r\nbreak;\r\ncase 51:return 43\r\nbreak;\r\ncase 52:return 42\r\nbreak;\r\ncase 53:return 39\r\nbreak;\r\ncase 54:return 37\r\nbreak;\r\ncase 55:return 32\r\nbreak;\r\ncase 56:return 86\r\nbreak;\r\ncase 57:return 5\r\nbreak;\r\ncase 58:return 20\r\nbreak;\r\ncase 59:return 'INVALID'\r\nbreak;\r\n}\r\n},\r\nrules: [/^(?:\\s+)/,/^(?:[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+))/,/^(?:[0-9]+\\.[0-9]*|[0-9]*\\.[0-9]+\\b)/,/^(?:[0-9]+)/,/^(?:\"(\\\\[\"]|[^\"])*\")/,/^(?:'(\\\\[']|[^'])*')/,/^(?:\\/\\/.*)/,/^(?:\\/\\*(.|\\n|\\r)*?\\*\\/)/,/^(?:if\\b)/,/^(?:else\\b)/,/^(?:while\\b)/,/^(?:do\\b)/,/^(?:for\\b)/,/^(?:function\\b)/,/^(?:map\\b)/,/^(?:use\\b)/,/^(?:return\\b)/,/^(?:delete\\b)/,/^(?:true\\b)/,/^(?:false\\b)/,/^(?:null\\b)/,/^(?:Infinity\\b)/,/^(?:->)/,/^(?:=>)/,/^(?:<<)/,/^(?:>>)/,/^(?:\\{)/,/^(?:\\})/,/^(?:;)/,/^(?:#)/,/^(?:\\?)/,/^(?::)/,/^(?:NaN\\b)/,/^(?:\\.)/,/^(?:\\[)/,/^(?:\\])/,/^(?:\\()/,/^(?:\\))/,/^(?:!)/,/^(?:\\^)/,/^(?:\\*\\*)/,/^(?:\\*)/,/^(?:\\/)/,/^(?:%)/,/^(?:\\+)/,/^(?:-)/,/^(?:<=)/,/^(?:<)/,/^(?:>=)/,/^(?:>)/,/^(?:==)/,/^(?:~=)/,/^(?:!=)/,/^(?:&&)/,/^(?:\\|\\|)/,/^(?:=)/,/^(?:,)/,/^(?:$)/,/^(?:[A-Za-z_\\$][A-Za-z0-9_]*)/,/^(?:.)/],\r\nconditions: {\"INITIAL\":{\"rules\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59],\"inclusive\":true}}\r\n});\r\nreturn lexer;\r\n})();\r\nparser.lexer = lexer;\r\n/**\r\n * @class\r\n * @ignore\r\n */\r\nfunction Parser () {\r\n  this.yy = {};\r\n}\r\nParser.prototype = parser;parser.Parser = Parser;\r\nreturn new Parser;\r\n})();\r\n// Work around an issue with browsers that don't support Object.getPrototypeOf()\r\nparser.yy.parseError = parser.parseError;\r\n\r\nexport default JXG.JessieCode;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Andreas Walter,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph and JSXCompressor.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n    JSXCompressor is free software dual licensed under the GNU LGPL or Apache License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n      OR\r\n      * Apache License Version 2.0\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License, Apache\r\n    License, and the MIT License along with JSXGraph. If not, see\r\n    <https://www.gnu.org/licenses/>, <https://www.apache.org/licenses/LICENSE-2.0.html>,\r\n    and <https://opensource.org/licenses/MIT/>.\r\n\r\n */\r\n\r\n/*global JXG: true, define: true, jQuery: true, window: true, document: true, navigator: true, require: true, module: true, console: true */\r\n/*jslint nomen:true, plusplus:true, forin:true*/\r\n\r\n/**\r\n * @fileoverview The JSXGraph object is defined in this file. JXG.JSXGraph controls all boards.\r\n * It has methods to create, save, load and free boards. Additionally some helper functions are\r\n * defined in this file directly in the JXG namespace.\r\n */\r\n\r\n/**\r\n * JXG is the top object of JSXGraph and defines the namespace\r\n *\r\n * @name JXG\r\n * @exports jxg as JXG\r\n * @namespace\r\n */\r\nvar jxg = {};\r\n\r\n// Make sure JXG.extend is not defined.\r\n// If JSXGraph is compiled as an amd module, it is possible that another JSXGraph version is already loaded and we\r\n// therefore must not re-use the global JXG variable. But in this case JXG.extend will already be defined.\r\n// This is the reason for this check.\r\n// The try-statement is necessary, otherwise an error is thrown in certain imports, e.g. in deno.\r\ntry {\r\n    if (typeof JXG === \"object\" && !JXG.extend) {\r\n        jxg = JXG;\r\n    }\r\n} catch (e) {}\r\n\r\n// We need the following two methods \"extend\" and \"shortcut\" to create the JXG object via JXG.extend.\r\n\r\n/**\r\n * Copy all properties of the <tt>extension</tt> object to <tt>object</tt>.\r\n * @param {Object} object\r\n * @param {Object} extension\r\n * @param {Boolean} [onlyOwn=false] Only consider properties that belong to extension itself, not any inherited properties.\r\n * @param {Boolean} [toLower=false] If true the keys are convert to lower case. This is needed for visProp, see JXG#copyAttributes\r\n */\r\njxg.extend = function (object, extension, onlyOwn, toLower) {\r\n    var e, e2;\r\n\r\n    onlyOwn = onlyOwn || false;\r\n    toLower = toLower || false;\r\n\r\n    // the purpose of this for...in loop is indeed to use hasOwnProperty only if the caller\r\n    // explicitly wishes so.\r\n    for (e in extension) {\r\n        if (!onlyOwn || (onlyOwn && extension.hasOwnProperty(e))) {\r\n            if (toLower) {\r\n                e2 = e.toLowerCase();\r\n            } else {\r\n                e2 = e;\r\n            }\r\n\r\n            object[e2] = extension[e];\r\n        }\r\n    }\r\n};\r\n\r\n/**\r\n * Set a constant <tt>name</tt> in <tt>object</tt> to <tt>value</tt>. The value can't be changed after declaration.\r\n * @param {Object} object\r\n * @param {String} name\r\n * @param {Number|String|Boolean} value\r\n * @param {Boolean} ignoreRedefine This should be left at its default: false.\r\n */\r\njxg.defineConstant = function (object, name, value, ignoreRedefine) {\r\n    ignoreRedefine = ignoreRedefine || false;\r\n\r\n    if (ignoreRedefine && jxg.exists(object[name])) {\r\n        return;\r\n    }\r\n\r\n    Object.defineProperty(object, name, {\r\n        value: value,\r\n        writable: false,\r\n        enumerable: true,\r\n        configurable: false\r\n    });\r\n};\r\n\r\n/**\r\n * Copy all properties of the <tt>constants</tt> object in <tt>object</tt> as a constant.\r\n * @param {Object} object\r\n * @param {Object} constants\r\n * @param {Boolean} [onlyOwn=false] Only consider properties that belong to extension itself, not any inherited properties.\r\n * @param {Boolean} [toUpper=false] If true the keys are convert to lower case. This is needed for visProp, see JXG#copyAttributes\r\n */\r\njxg.extendConstants = function (object, constants, onlyOwn, toUpper) {\r\n    var e, e2;\r\n\r\n    onlyOwn = onlyOwn || false;\r\n    toUpper = toUpper || false;\r\n\r\n    // The purpose of this for...in loop is indeed to use hasOwnProperty only if the caller explicitly wishes so.\r\n    for (e in constants) {\r\n        if (!onlyOwn || (onlyOwn && constants.hasOwnProperty(e))) {\r\n            if (toUpper) {\r\n                e2 = e.toUpperCase();\r\n            } else {\r\n                e2 = e;\r\n            }\r\n\r\n            this.defineConstant(object, e2, constants[e]);\r\n        }\r\n    }\r\n};\r\n\r\njxg.extend(\r\n    jxg,\r\n    /** @lends JXG */ {\r\n        /**\r\n         * Store a reference to every board in this central list. This will at some point\r\n         * replace JXG.JSXGraph.boards.\r\n         * @type Object\r\n         */\r\n        boards: {},\r\n\r\n        /**\r\n         * Store the available file readers in this structure.\r\n         * @type Object\r\n         */\r\n        readers: {},\r\n\r\n        /**\r\n         * Associative array that keeps track of all constructable elements registered\r\n         * via {@link JXG.registerElement}.\r\n         * @type Object\r\n         */\r\n        elements: {},\r\n\r\n        /**\r\n         * This registers a new construction element to JSXGraph for the construction via the {@link JXG.Board.create}\r\n         * interface.\r\n         * @param {String} element The elements name. This is case-insensitive, existing elements with the same name\r\n         * will be overwritten.\r\n         * @param {Function} creator A reference to a function taking three parameters: First the board, the element is\r\n         * to be created on, a parent element array, and an attributes object. See {@link JXG.createPoint} or any other\r\n         * <tt>JXG.create...</tt> function for an example.\r\n         */\r\n        registerElement: function (element, creator) {\r\n            element = element.toLowerCase();\r\n            this.elements[element] = creator;\r\n        },\r\n\r\n        /**\r\n         * Register a file reader.\r\n         * @param {function} reader A file reader. This object has to provide two methods: <tt>prepareString()</tt>\r\n         * and <tt>read()</tt>.\r\n         * @param {Array} ext\r\n         */\r\n        registerReader: function (reader, ext) {\r\n            var i, e;\r\n\r\n            for (i = 0; i < ext.length; i++) {\r\n                e = ext[i].toLowerCase();\r\n\r\n                if (typeof this.readers[e] !== 'function') {\r\n                    this.readers[e] = reader;\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Creates a shortcut to a method, e.g. {@link JXG.Board#createElement} is a shortcut to {@link JXG.Board#create}.\r\n         * Sometimes the target is undefined by the time you want to define the shortcut so we need this little helper.\r\n         * @param {Object} object The object the method we want to create a shortcut for belongs to.\r\n         * @param {String} fun The method we want to create a shortcut for.\r\n         * @returns {Function} A function that calls the given method.\r\n         */\r\n        shortcut: function (object, fun) {\r\n            return function () {\r\n                return object[fun].apply(this, arguments);\r\n            };\r\n        },\r\n\r\n        /**\r\n         * s may be a string containing the name or id of an element or even a reference\r\n         * to the element itself. This function returns a reference to the element. Search order: id, name.\r\n         * @param {JXG.Board} board Reference to the board the element belongs to.\r\n         * @param {String} s String or reference to a JSXGraph element.\r\n         * @returns {Object} Reference to the object given in parameter object\r\n         * @deprecated Use {@link JXG.Board#select}\r\n         */\r\n        getRef: function (board, s) {\r\n            jxg.deprecated(\"JXG.getRef()\", \"Board.select()\");\r\n            return board.select(s);\r\n        },\r\n\r\n        /**\r\n         * This is just a shortcut to {@link JXG.getRef}.\r\n         * @deprecated Use {@link JXG.Board#select}.\r\n         */\r\n        getReference: function (board, s) {\r\n            jxg.deprecated(\"JXG.getReference()\", \"Board.select()\");\r\n            return board.select(s);\r\n        },\r\n\r\n        /**\r\n         * s may be the string containing the id of an HTML tag that hosts a JSXGraph board.\r\n         * This function returns the reference to the board.\r\n         * @param  {String} s String of an HTML tag that hosts a JSXGraph board\r\n         * @returns {Object} Reference to the board or null.\r\n         */\r\n        getBoardByContainerId: function (s) {\r\n            var b;\r\n            for (b in JXG.boards) {\r\n                if (JXG.boards.hasOwnProperty(b) && JXG.boards[b].container === s) {\r\n                    return JXG.boards[b];\r\n                }\r\n            }\r\n\r\n            return null;\r\n        },\r\n\r\n        /**\r\n         * This method issues a warning to the developer that the given function is deprecated\r\n         * and, if available, offers an alternative to the deprecated function.\r\n         * @param {String} what Describes the function that is deprecated\r\n         * @param {String} [replacement] The replacement that should be used instead.\r\n         */\r\n        deprecated: function (what, replacement) {\r\n            var warning = what + \" is deprecated.\";\r\n\r\n            if (replacement) {\r\n                warning += \" Please use \" + replacement + \" instead.\";\r\n            }\r\n\r\n            jxg.warn(warning);\r\n        },\r\n\r\n        /**\r\n         * Outputs a warning via console.warn(), if available. If console.warn() is\r\n         * unavailable this function will look for an HTML element with the id 'warning'\r\n         * and append the warning to this element's innerText.\r\n         * @param {String} warning The warning text\r\n         */\r\n        warn: function (warning) {\r\n            if (typeof window === \"object\" && window.console && console.warn) {\r\n                console.warn(\"WARNING:\", warning);\r\n            } else if (typeof document === \"object\" && document.getElementById('warning')) {\r\n                document.getElementById('debug').innerText += \"WARNING: \" + warning + '\\n';\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Add something to the debug log. If available a JavaScript debug console is used. Otherwise\r\n         * we're looking for a HTML div with id \"debug\". If this doesn't exist, too, the output is omitted.\r\n         * @param s An arbitrary number of parameters.\r\n         * @see JXG.debugWST\r\n         */\r\n        debugInt: function (s) {\r\n            var i, p;\r\n\r\n            for (i = 0; i < arguments.length; i++) {\r\n                p = arguments[i];\r\n                if (typeof window === \"object\" && window.console && console.log) {\r\n                    console.log(p);\r\n                } else if (typeof document === \"object\" && document.getElementById('debug')) {\r\n                    document.getElementById('debug').innerText += p + '\\n';\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Add something to the debug log. If available a JavaScript debug console is used. Otherwise\r\n         * we're looking for a HTML div with id \"debug\". If this doesn't exist, too, the output is omitted.\r\n         * This method adds a stack trace (if available).\r\n         * @param s An arbitrary number of parameters.\r\n         * @see JXG.debug\r\n         */\r\n        debugWST: function (s) {\r\n            var e = new Error();\r\n\r\n            jxg.debugInt.apply(this, arguments);\r\n\r\n            if (e && e.stack) {\r\n                jxg.debugInt('stacktrace');\r\n                jxg.debugInt(e.stack.split(\"\\n\").slice(1).join(\"\\n\"));\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Add something to the debug log. If available a JavaScript debug console is used. Otherwise\r\n         * we're looking for a HTML div with id \"debug\". If this doesn't exist, too, the output is omitted.\r\n         * This method adds a line of the stack trace (if available).\r\n         *\r\n         * @param s An arbitrary number of parameters.\r\n         * @see JXG.debug\r\n         */\r\n        debugLine: function (s) {\r\n            var e = new Error();\r\n\r\n            jxg.debugInt.apply(this, arguments);\r\n\r\n            if (e && e.stack) {\r\n                jxg.debugInt(\"Called from\", e.stack.split(\"\\n\").slice(2, 3).join(\"\\n\"));\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Add something to the debug log. If available a JavaScript debug console is used. Otherwise\r\n         * we're looking for a HTML div with id \"debug\". If this doesn't exist, too, the output is omitted.\r\n         * @param s An arbitrary number of parameters.\r\n         * @see JXG.debugWST\r\n         * @see JXG.debugLine\r\n         * @see JXG.debugInt\r\n         */\r\n        debug: function (s) {\r\n            jxg.debugInt.apply(this, arguments);\r\n        },\r\n\r\n        themes: {}\r\n    }\r\n);\r\n\r\nexport default jxg;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview In this file the EventEmitter interface is defined.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"./type.js\";\r\n\r\n/**\r\n * Event namespace\r\n * @namespace\r\n */\r\nJXG.EventEmitter = {\r\n    /**\r\n     * Holds the registered event handlers.\r\n     * @type Object\r\n     */\r\n    eventHandlers: {},\r\n\r\n    /**\r\n     * Events can be suspended to prevent endless loops.\r\n     * @type Object\r\n     */\r\n    suspended: {},\r\n\r\n    /**\r\n     * Triggers all event handlers of this element for a given event.\r\n     * @param {Array} event\r\n     * @param {Array} args The arguments passed onto the event handler\r\n     * @returns Reference to the object.\r\n     */\r\n    trigger: function (event, args) {\r\n        var i, j, h, evt, len1, len2;\r\n\r\n        len1 = event.length;\r\n        for (j = 0; j < len1; j++) {\r\n            evt = this.eventHandlers[event[j]];\r\n            if (!this.suspended[event[j]]) {\r\n                this.suspended[event[j]] = true;\r\n                if (evt) {\r\n                    len2 = evt.length;\r\n                    for (i = 0; i < len2; i++) {\r\n                        h = evt[i];\r\n                        h.handler.apply(h.context, args);\r\n                    }\r\n                }\r\n\r\n                this.suspended[event[j]] = false;\r\n            }\r\n        }\r\n\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * Register a new event handler. For a list of possible events see documentation\r\n     * of the elements and objects implementing\r\n     * the {@link EventEmitter} interface.\r\n     *\r\n     * As of version 1.5.0, it is only possible to access the element via \"this\" if the event listener\r\n     * is supplied as regular JavaScript function and not as arrow function.\r\n     *\r\n     * @param {String} event\r\n     * @param {Function} handler\r\n     * @param {Object} [context] The context the handler will be called in, default is the element itself.\r\n     * @returns Reference to the object.\r\n     */\r\n    on: function (event, handler, context) {\r\n        if (!Type.isArray(this.eventHandlers[event])) {\r\n            this.eventHandlers[event] = [];\r\n        }\r\n\r\n        context = Type.def(context, this);\r\n\r\n        this.eventHandlers[event].push({\r\n            handler: handler,\r\n            context: context\r\n        });\r\n\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * Unregister an event handler.\r\n     * @param {String} event\r\n     * @param {Function} [handler]\r\n     * @returns Reference to the object.\r\n     */\r\n    off: function (event, handler) {\r\n        var i;\r\n\r\n        if (!event || !Type.isArray(this.eventHandlers[event])) {\r\n            return this;\r\n        }\r\n\r\n        if (handler) {\r\n            i = Type.indexOf(this.eventHandlers[event], handler, 'handler');\r\n            if (i > -1) {\r\n                this.eventHandlers[event].splice(i, 1);\r\n            }\r\n\r\n            if (this.eventHandlers[event].length === 0) {\r\n                delete this.eventHandlers[event];\r\n            }\r\n        } else {\r\n            delete this.eventHandlers[event];\r\n        }\r\n\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * @description Implements the functionality from this interface in the given object.\r\n     * All objects getting their event handling\r\n     * capabilities from this method should document it by adding\r\n     * the <tt>on, off, triggerEventHandlers</tt> via the\r\n     * borrows tag as methods to their documentation:\r\n     * <pre>@borrows JXG.EventEmitter#on as this.on</pre>\r\n     * @param {Object} o\r\n     */\r\n    eventify: function (o) {\r\n        o.eventHandlers = {\r\n            clicks: 0 // Needed to handle dblclicks\r\n        };\r\n        o.on = this.on;\r\n        o.off = this.off;\r\n        o.triggerEventHandlers = this.trigger;\r\n        o.trigger = this.trigger;\r\n        o.suspended = {};\r\n    }\r\n};\r\n\r\nexport default JXG.EventEmitter;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, Float32Array: true */\r\n/*jslint nomen: true, plusplus: true, bitwise: true*/\r\n\r\n/**\r\n * @fileoverview In this file the namespace JXG.Math is defined, which is the base namespace\r\n * for namespaces like JXG.Math.Numerics, JXG.Math.Plot, JXG.Math.Statistics, JXG.Math.Clip etc.\r\n */\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\nvar undef,\r\n    /*\r\n     * Dynamic programming approach for recursive functions.\r\n     * From \"Speed up your JavaScript, Part 3\" by Nicholas C. Zakas.\r\n     * @see JXG.Math.factorial\r\n     * @see JXG.Math.binomial\r\n     * http://blog.thejit.org/2008/09/05/memoization-in-javascript/\r\n     *\r\n     * This method is hidden, because it is only used in JXG.Math. If someone wants\r\n     * to use it in JSXGraph outside of JXG.Math, it should be moved to jsxgraph.js\r\n     */\r\n    memoizer = function (f) {\r\n        var cache, join;\r\n\r\n        if (f.memo) {\r\n            return f.memo;\r\n        }\r\n\r\n        cache = {};\r\n        join = Array.prototype.join;\r\n\r\n        f.memo = function () {\r\n            var key = join.call(arguments);\r\n\r\n            // Seems to be a bit faster than \"if (a in b)\"\r\n            return cache[key] !== undef ? cache[key] : (cache[key] = f.apply(this, arguments));\r\n        };\r\n\r\n        return f.memo;\r\n    };\r\n\r\n/**\r\n * Math namespace. Contains mathematics related methods which are\r\n * specific to JSXGraph or which extend the JavaScript Math class.\r\n * @namespace\r\n */\r\nJXG.Math = {\r\n    /**\r\n     * eps defines the closeness to zero. If the absolute value of a given number is smaller\r\n     * than eps, it is considered to be equal to zero.\r\n     * @type Number\r\n     */\r\n    eps: 0.000001,\r\n\r\n    /**\r\n     * Determine the relative difference between two numbers.\r\n     * @param  {Number} a First number\r\n     * @param  {Number} b Second number\r\n     * @returns {Number}  Relative difference between a and b: |a-b| / max(|a|, |b|)\r\n     */\r\n    relDif: function (a, b) {\r\n        var c = Math.abs(a),\r\n            d = Math.abs(b);\r\n\r\n        d = Math.max(c, d);\r\n\r\n        return d === 0.0 ? 0.0 : Math.abs(a - b) / d;\r\n    },\r\n\r\n    /**\r\n     * The JavaScript implementation of the % operator returns the symmetric modulo.\r\n     * mod and \"%\" are both identical if a >= 0 and m >= 0 but the results differ if a or m < 0.\r\n     * @param {Number} a\r\n     * @param {Number} m\r\n     * @returns {Number} Mathematical modulo <tt>a mod m</tt>\r\n     */\r\n    mod: function (a, m) {\r\n        return a - Math.floor(a / m) * m;\r\n    },\r\n\r\n    /**\r\n     * Translate <code>x</code> into the interval <code>[a, b)</code> by adding\r\n     * a multiple of <code>b - a</code>.\r\n     * @param {Number} x\r\n     * @param {Number} a\r\n     * @param {Number} b\r\n     */\r\n    wrap: function (x, a, b) {\r\n        return a + this.mod(x - a, b - a);\r\n    },\r\n\r\n    /**\r\n     * Clamp <code>x</code> within the interval <code>[a, b]</code>. If\r\n     * <code>x</code> is below <code>a</code>, increase it to <code>a</code>. If\r\n     * it's above <code>b</code>, decrease it to <code>b</code>.\r\n     */\r\n    clamp: function (x, a, b) {\r\n        return Math.min(Math.max(x, a), b);\r\n    },\r\n\r\n    /**\r\n     * A way of clamping a periodic variable. If <code>x</code> is congruent mod\r\n     * <code>period</code> to a point in <code>[a, b]</code>, return that point.\r\n     * Otherwise, wrap it into <code>[mid - period/2, mid + period/2]</code>,\r\n     * where <code>mid</code> is the mean of <code>a</code> and <code>b</code>,\r\n     * and then clamp it to <code>[a, b]</code> from there.\r\n     */\r\n    wrapAndClamp: function (x, a, b, period) {\r\n        var mid = 0.5 * (a + b),\r\n            half_period = 0.5 * period;\r\n\r\n        return this.clamp(\r\n            this.wrap(\r\n                x,\r\n                mid - half_period,\r\n                mid + half_period\r\n            ),\r\n            a,\r\n            b\r\n        );\r\n    },\r\n\r\n    /**\r\n     * Initializes a vector of size <tt>n</tt> wih coefficients set to the init value (default 0)\r\n     * @param {Number} n Length of the vector\r\n     * @param {Number} [init=0] Initial value for each coefficient\r\n     * @returns {Array} An array of length <tt>n</tt>\r\n     */\r\n    vector: function (n, init) {\r\n        var r, i;\r\n\r\n        init = init || 0;\r\n        r = [];\r\n\r\n        for (i = 0; i < n; i++) {\r\n            r[i] = init;\r\n        }\r\n\r\n        return r;\r\n    },\r\n\r\n    /**\r\n     * Initializes a matrix as an array of rows with the given value.\r\n     * @param {Number} n Number of rows\r\n     * @param {Number} [m=n] Number of columns\r\n     * @param {Number} [init=0] Initial value for each coefficient\r\n     * @returns {Array} A <tt>n</tt> times <tt>m</tt>-matrix represented by a\r\n     * two-dimensional array. The inner arrays hold the columns, the outer array holds the rows.\r\n     */\r\n    matrix: function (n, m, init) {\r\n        var r, i, j;\r\n\r\n        init = init || 0;\r\n        m = m || n;\r\n        r = [];\r\n\r\n        for (i = 0; i < n; i++) {\r\n            r[i] = [];\r\n\r\n            for (j = 0; j < m; j++) {\r\n                r[i][j] = init;\r\n            }\r\n        }\r\n\r\n        return r;\r\n    },\r\n\r\n    /**\r\n     * Generates an identity matrix. If n is a number and m is undefined or not a number, a square matrix is generated,\r\n     * if n and m are both numbers, an nxm matrix is generated.\r\n     * @param {Number} n Number of rows\r\n     * @param {Number} [m=n] Number of columns\r\n     * @returns {Array} A square matrix of length <tt>n</tt> with all coefficients equal to 0 except a_(i,i), i out of (1, ..., n), if <tt>m</tt> is undefined or not a number\r\n     * or a <tt>n</tt> times <tt>m</tt>-matrix with a_(i,j) = 0 and a_(i,i) = 1 if m is a number.\r\n     */\r\n    identity: function (n, m) {\r\n        var r, i;\r\n\r\n        if (m === undef && typeof m !== 'number') {\r\n            m = n;\r\n        }\r\n\r\n        r = this.matrix(n, m);\r\n\r\n        for (i = 0; i < Math.min(n, m); i++) {\r\n            r[i][i] = 1;\r\n        }\r\n\r\n        return r;\r\n    },\r\n\r\n    /**\r\n     * Generates a 4x4 matrix for 3D to 2D projections.\r\n     * @param {Number} l Left\r\n     * @param {Number} r Right\r\n     * @param {Number} t Top\r\n     * @param {Number} b Bottom\r\n     * @param {Number} n Near\r\n     * @param {Number} f Far\r\n     * @returns {Array} 4x4 Matrix\r\n     */\r\n    frustum: function (l, r, b, t, n, f) {\r\n        var ret = this.matrix(4, 4);\r\n\r\n        ret[0][0] = (n * 2) / (r - l);\r\n        ret[0][1] = 0;\r\n        ret[0][2] = (r + l) / (r - l);\r\n        ret[0][3] = 0;\r\n\r\n        ret[1][0] = 0;\r\n        ret[1][1] = (n * 2) / (t - b);\r\n        ret[1][2] = (t + b) / (t - b);\r\n        ret[1][3] = 0;\r\n\r\n        ret[2][0] = 0;\r\n        ret[2][1] = 0;\r\n        ret[2][2] = -(f + n) / (f - n);\r\n        ret[2][3] = -(f * n * 2) / (f - n);\r\n\r\n        ret[3][0] = 0;\r\n        ret[3][1] = 0;\r\n        ret[3][2] = -1;\r\n        ret[3][3] = 0;\r\n\r\n        return ret;\r\n    },\r\n\r\n    /**\r\n     * Generates a 4x4 matrix for 3D to 2D projections.\r\n     * @param {Number} fov Field of view in vertical direction, given in rad.\r\n     * @param {Number} ratio Aspect ratio of the projection plane.\r\n     * @param {Number} n Near\r\n     * @param {Number} f Far\r\n     * @returns {Array} 4x4 Projection Matrix\r\n     */\r\n    projection: function (fov, ratio, n, f) {\r\n        var t = n * Math.tan(fov / 2),\r\n            r = t * ratio;\r\n\r\n        return this.frustum(-r, r, -t, t, n, f);\r\n    },\r\n\r\n    /**\r\n     * Multiplies a vector vec to a matrix mat: mat * vec. The matrix is interpreted by this function as an array of rows.\r\n     * Please note: This\r\n     * function does not check if the dimensions match.\r\n     * @param {Array} mat Two-dimensional array of numbers. The inner arrays describe the columns, the outer ones the matrix' rows.\r\n     * @param {Array} vec Array of numbers\r\n     * @returns {Array} Array of numbers containing the result\r\n     * @example\r\n     * var A = [[2, 1],\r\n     *          [2, 3]],\r\n     *     b = [4, 5],\r\n     *     c;\r\n     * c = JXG.Math.matVecMult(A, b);\r\n     * // c === [13, 23];\r\n     */\r\n    matVecMult: function (mat, vec) {\r\n        var i, k, s,\r\n            m = mat.length,\r\n            n = vec.length,\r\n            res = [];\r\n\r\n        if (n === 3) {\r\n            for (i = 0; i < m; i++) {\r\n                res[i] = mat[i][0] * vec[0] + mat[i][1] * vec[1] + mat[i][2] * vec[2];\r\n            }\r\n        } else {\r\n            for (i = 0; i < m; i++) {\r\n                s = 0;\r\n                for (k = 0; k < n; k++) {\r\n                    s += mat[i][k] * vec[k];\r\n                }\r\n                res[i] = s;\r\n            }\r\n        }\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Multiplies a vector vec to a matrix mat from the left: vec * mat.\r\n     * The matrix is interpreted by this function as an array of rows.\r\n     * Please note: This function does not check if the dimensions match.\r\n     * @param {Array} vec Array of numbers\r\n     * @param {Array} mat Two-dimensional array of numbers. The inner arrays describe the columns,\r\n     *  the outer ones the matrix' rows.\r\n     * @returns {Array} Array of numbers containing the result\r\n     * @example\r\n     * var A = [[2, 1],\r\n     *          [2, 3]],\r\n     *     b = [4, 5],\r\n     *     c;\r\n     * c = JXG.Math.vecMatMult(b, A);\r\n     * // c === [18, 16];\r\n     */\r\n    vecMatMult: function (vec, mat) {\r\n        var i, k, s,\r\n            m = mat.length,\r\n            n = vec.length,\r\n            res = [];\r\n\r\n        if (n === 3) {\r\n            for (i = 0; i < m; i++) {\r\n                res[i] = vec[0] * mat[0][i] + vec[1] * mat[1][i] + vec[2] * mat[2][i];\r\n            }\r\n        } else {\r\n            for (i = 0; i < n; i++) {\r\n                s = 0;\r\n                for (k = 0; k < m; k++) {\r\n                    s += vec[k] * mat[k][i];\r\n                }\r\n                res[i] = s;\r\n            }\r\n        }\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Computes the product of the two matrices: mat1 * mat2.\r\n     * Returns a new matrix array.\r\n     *\r\n     * @param {Array} mat1 Two-dimensional array of numbers\r\n     * @param {Array} mat2 Two-dimensional array of numbers\r\n     * @returns {Array} Two-dimensional Array of numbers containing result\r\n     */\r\n    matMatMult: function (mat1, mat2) {\r\n        var i, j, s, k,\r\n            m = mat1.length,\r\n            n = m > 0 ? mat2[0].length : 0,\r\n            m2 = mat2.length,\r\n            res = this.matrix(m, n);\r\n\r\n        for (i = 0; i < m; i++) {\r\n            for (j = 0; j < n; j++) {\r\n                s = 0;\r\n                for (k = 0; k < m2; k++) {\r\n                    s += mat1[i][k] * mat2[k][j];\r\n                }\r\n                res[i][j] = s;\r\n            }\r\n        }\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Multiply a matrix mat by a scalar alpha: mat * scalar\r\n     *\r\n     * @param {Array} mat Two-dimensional array of numbers\r\n     * @param {Number} alpha Scalar\r\n     * @returns {Array} Two-dimensional Array of numbers containing result\r\n     */\r\n    matNumberMult: function (mat, alpha) {\r\n        var i, j,\r\n            m = mat.length,\r\n            n = m > 0 ? mat[0].length : 0,\r\n            res = this.matrix(m, n);\r\n\r\n        for (i = 0; i < m; i++) {\r\n            for (j = 0; j < n; j++) {\r\n                res[i][j] = mat[i][j] * alpha;\r\n            }\r\n        }\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Compute the sum of two matrices: mat1 + mat2.\r\n     * Returns a new matrix object.\r\n     *\r\n     * @param {Array} mat1 Two-dimensional array of numbers\r\n     * @param {Array} mat2 Two-dimensional array of numbers\r\n     * @returns {Array} Two-dimensional Array of numbers containing result\r\n     */\r\n    matMatAdd: function (mat1, mat2) {\r\n        var i, j,\r\n            m = mat1.length,\r\n            n = m > 0 ? mat1[0].length : 0,\r\n            res = this.matrix(m, n);\r\n\r\n        for (i = 0; i < m; i++) {\r\n            for (j = 0; j < n; j++) {\r\n                res[i][j] = mat1[i][j] + mat2[i][j];\r\n            }\r\n        }\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Transposes a matrix given as a two-dimensional array.\r\n     * @param {Array} M The matrix to be transposed\r\n     * @returns {Array} The transpose of M\r\n     */\r\n    transpose: function (M) {\r\n        var MT, i, j, m, n;\r\n\r\n        // number of rows of M\r\n        m = M.length;\r\n        // number of columns of M\r\n        n = M.length > 0 ? M[0].length : 0;\r\n        MT = this.matrix(n, m);\r\n\r\n        for (i = 0; i < n; i++) {\r\n            for (j = 0; j < m; j++) {\r\n                MT[i][j] = M[j][i];\r\n            }\r\n        }\r\n\r\n        return MT;\r\n    },\r\n\r\n    /**\r\n     * Compute the inverse of an <i>(n x n)</i>-matrix by Gauss elimination.\r\n     *\r\n     * @param {Array} A matrix\r\n     * @returns {Array} Inverse matrix of A or empty array (i.e. []) in case A is singular.\r\n     */\r\n    inverse: function (Ain) {\r\n        var i, j, k, r, s,\r\n            eps = this.eps * this.eps,\r\n            ma, swp,\r\n            n = Ain.length,\r\n            A = [],\r\n            p = [],\r\n            hv = [];\r\n\r\n        for (i = 0; i < n; i++) {\r\n            A[i] = [];\r\n            for (j = 0; j < n; j++) {\r\n                A[i][j] = Ain[i][j];\r\n            }\r\n            p[i] = i;\r\n        }\r\n\r\n        for (j = 0; j < n; j++) {\r\n            // Pivot search\r\n            ma = Math.abs(A[j][j]);\r\n            r = j;\r\n\r\n            for (i = j + 1; i < n; i++) {\r\n                if (Math.abs(A[i][j]) > ma) {\r\n                    ma = Math.abs(A[i][j]);\r\n                    r = i;\r\n                }\r\n            }\r\n\r\n            // Singular matrix\r\n            if (ma <= eps) {\r\n                JXG.warn('JXG.Math.inverse: singular matrix');\r\n                return [];\r\n            }\r\n\r\n            // swap rows:\r\n            if (r > j) {\r\n                for (k = 0; k < n; k++) {\r\n                    swp = A[j][k];\r\n                    A[j][k] = A[r][k];\r\n                    A[r][k] = swp;\r\n                }\r\n\r\n                swp = p[j];\r\n                p[j] = p[r];\r\n                p[r] = swp;\r\n            }\r\n\r\n            // transformation:\r\n            s = 1.0 / A[j][j];\r\n            for (i = 0; i < n; i++) {\r\n                A[i][j] *= s;\r\n            }\r\n            A[j][j] = s;\r\n\r\n            for (k = 0; k < n; k++) {\r\n                if (k !== j) {\r\n                    for (i = 0; i < n; i++) {\r\n                        if (i !== j) {\r\n                            A[i][k] -= A[i][j] * A[j][k];\r\n                        }\r\n                    }\r\n                    A[j][k] = -s * A[j][k];\r\n                }\r\n            }\r\n        }\r\n\r\n        // swap columns:\r\n        for (i = 0; i < n; i++) {\r\n            for (k = 0; k < n; k++) {\r\n                hv[p[k]] = A[i][k];\r\n            }\r\n            for (k = 0; k < n; k++) {\r\n                A[i][k] = hv[k];\r\n            }\r\n        }\r\n\r\n        return A;\r\n    },\r\n\r\n    /**\r\n     * Trace of a square matrix, given as a two-dimensional array.\r\n     * @param {Array} M Square matrix\r\n     * @returns {Number} The trace of M, NaN if M is not square.\r\n     */\r\n    trace: function (M) {\r\n        var i, m, n,\r\n            t = 0.0;\r\n\r\n        // number of rows of M\r\n        m = M.length;\r\n        // number of columns of M\r\n        n = M.length > 0 ? M[0].length : 0;\r\n        if (m !== n) {\r\n            return NaN;\r\n        }\r\n        for (i = 0; i < n; i++) {\r\n            t += M[i][i];\r\n        }\r\n\r\n        return t;\r\n    },\r\n\r\n    /**\r\n     * Inner product of two vectors a and b. n is the length of the vectors.\r\n     * @param {Array} a Vector\r\n     * @param {Array} b Vector\r\n     * @param {Number} [n] Length of the Vectors. If not given the length of the first vector is taken.\r\n     * @returns {Number} The inner product of a and b.\r\n     */\r\n    innerProduct: function (a, b, n) {\r\n        var i,\r\n            s = 0;\r\n\r\n        if (n === undef || !Type.isNumber(n)) {\r\n            n = a.length;\r\n        }\r\n\r\n        for (i = 0; i < n; i++) {\r\n            s += a[i] * b[i];\r\n        }\r\n\r\n        return s;\r\n    },\r\n\r\n    /**\r\n     * Calculates the cross product of two vectors both of length three.\r\n     * In case of homogeneous coordinates this is either\r\n     * <ul>\r\n     * <li>the intersection of two lines</li>\r\n     * <li>the line through two points</li>\r\n     * </ul>\r\n     * @param {Array} c1 Homogeneous coordinates of line or point 1\r\n     * @param {Array} c2 Homogeneous coordinates of line or point 2\r\n     * @returns {Array} vector of length 3: homogeneous coordinates of the resulting point / line.\r\n     */\r\n    crossProduct: function (c1, c2) {\r\n        return [\r\n            c1[1] * c2[2] - c1[2] * c2[1],\r\n            c1[2] * c2[0] - c1[0] * c2[2],\r\n            c1[0] * c2[1] - c1[1] * c2[0]\r\n        ];\r\n    },\r\n\r\n    /**\r\n     * Euclidean norm of a vector.\r\n     *\r\n     * @param {Array} a Array containing a vector.\r\n     * @param {Number} n (Optional) length of the array.\r\n     * @returns {Number} Euclidean norm of the vector.\r\n     */\r\n    norm: function (a, n) {\r\n        var i,\r\n            sum = 0.0;\r\n\r\n        if (n === undef || !Type.isNumber(n)) {\r\n            n = a.length;\r\n        }\r\n\r\n        for (i = 0; i < n; i++) {\r\n            sum += a[i] * a[i];\r\n        }\r\n\r\n        return Math.sqrt(sum);\r\n    },\r\n\r\n    /**\r\n     * Compute a * x + y for a scalar a and vectors x and y.\r\n     *\r\n     * @param {Number} a\r\n     * @param {Array} x\r\n     * @param {Array} y\r\n     * @returns {Array}\r\n     */\r\n    axpy: function (a, x, y) {\r\n        var i,\r\n            le = x.length,\r\n            p = [];\r\n        for (i = 0; i < le; i++) {\r\n            p[i] = a * x[i] + y[i];\r\n        }\r\n        return p;\r\n    },\r\n\r\n    /**\r\n     * Compute the factorial of a positive integer. If a non-integer value\r\n     * is given, the fraction will be ignored.\r\n     * @function\r\n     * @param {Number} n\r\n     * @returns {Number} n! = n*(n-1)*...*2*1\r\n     */\r\n    factorial: memoizer(function (n) {\r\n        if (n < 0) {\r\n            return NaN;\r\n        }\r\n\r\n        n = Math.floor(n);\r\n\r\n        if (n === 0 || n === 1) {\r\n            return 1;\r\n        }\r\n\r\n        return n * this.factorial(n - 1);\r\n    }),\r\n\r\n    /**\r\n     * Computes the binomial coefficient n over k.\r\n     * @function\r\n     * @param {Number} n Fraction will be ignored\r\n     * @param {Number} k Fraction will be ignored\r\n     * @returns {Number} The binomial coefficient n over k\r\n     */\r\n    binomial: memoizer(function (n, k) {\r\n        var b, i;\r\n\r\n        if (k > n || k < 0) {\r\n            return NaN;\r\n        }\r\n\r\n        k = Math.round(k);\r\n        n = Math.round(n);\r\n\r\n        if (k === 0 || k === n) {\r\n            return 1;\r\n        }\r\n\r\n        b = 1;\r\n\r\n        for (i = 0; i < k; i++) {\r\n            b *= n - i;\r\n            b /= i + 1;\r\n        }\r\n\r\n        return b;\r\n    }),\r\n\r\n    /**\r\n     * Calculates the cosine hyperbolicus of x.\r\n     * @function\r\n     * @param {Number} x The number the cosine hyperbolicus will be calculated of.\r\n     * @returns {Number} Cosine hyperbolicus of the given value.\r\n     */\r\n    cosh:\r\n        Math.cosh ||\r\n        function (x) {\r\n            return (Math.exp(x) + Math.exp(-x)) * 0.5;\r\n        },\r\n\r\n    /**\r\n     * Sine hyperbolicus of x.\r\n     * @function\r\n     * @param {Number} x The number the sine hyperbolicus will be calculated of.\r\n     * @returns {Number} Sine hyperbolicus of the given value.\r\n     */\r\n    sinh:\r\n        Math.sinh ||\r\n        function (x) {\r\n            return (Math.exp(x) - Math.exp(-x)) * 0.5;\r\n        },\r\n\r\n    /**\r\n     * Hyperbolic arc-cosine of a number.\r\n     * @function\r\n     * @param {Number} x\r\n     * @returns {Number}\r\n     */\r\n    acosh:\r\n        Math.acosh ||\r\n        function (x) {\r\n            return Math.log(x + Math.sqrt(x * x - 1));\r\n        },\r\n\r\n    /**\r\n     * Hyperbolic arcsine of a number\r\n     * @function\r\n     * @param {Number} x\r\n     * @returns {Number}\r\n     */\r\n    asinh:\r\n        Math.asinh ||\r\n        function (x) {\r\n            if (x === -Infinity) {\r\n                return x;\r\n            }\r\n            return Math.log(x + Math.sqrt(x * x + 1));\r\n        },\r\n\r\n    /**\r\n     * Computes the cotangent of x.\r\n     * @function\r\n     * @param {Number} x The number the cotangent will be calculated of.\r\n     * @returns {Number} Cotangent of the given value.\r\n     */\r\n    cot: function (x) {\r\n        return 1 / Math.tan(x);\r\n    },\r\n\r\n    /**\r\n     * Computes the inverse cotangent of x.\r\n     * @param {Number} x The number the inverse cotangent will be calculated of.\r\n     * @returns {Number} Inverse cotangent of the given value.\r\n     */\r\n    acot: function (x) {\r\n        return (x >= 0 ? 0.5 : -0.5) * Math.PI - Math.atan(x);\r\n    },\r\n\r\n    /**\r\n     * Compute n-th real root of a real number. n must be strictly positive integer.\r\n     * If n is odd, the real n-th root exists and is negative.\r\n     * For n even, for negative valuees of x NaN is returned\r\n     * @param  {Number} x radicand. Must be non-negative, if n even.\r\n     * @param  {Number} n index of the root. must be strictly positive integer.\r\n     * @returns {Number} returns real root or NaN\r\n     *\r\n     * @example\r\n     * nthroot(16, 4): 2\r\n     * nthroot(-27, 3): -3\r\n     * nthroot(-4, 2): NaN\r\n     */\r\n    nthroot: function (x, n) {\r\n        var inv = 1 / n;\r\n\r\n        if (n <= 0 || Math.floor(n) !== n) {\r\n            return NaN;\r\n        }\r\n\r\n        if (x === 0.0) {\r\n            return 0.0;\r\n        }\r\n\r\n        if (x > 0) {\r\n            return Math.exp(inv * Math.log(x));\r\n        }\r\n\r\n        // From here on, x is negative\r\n        if (n % 2 === 1) {\r\n            return -Math.exp(inv * Math.log(-x));\r\n        }\r\n\r\n        // x negative, even root\r\n        return NaN;\r\n    },\r\n\r\n    /**\r\n     * Computes cube root of real number\r\n     * Polyfill for Math.cbrt().\r\n     *\r\n     * @function\r\n     * @param  {Number} x Radicand\r\n     * @returns {Number} Cube root of x.\r\n     */\r\n    cbrt:\r\n        Math.cbrt ||\r\n        function (x) {\r\n            return this.nthroot(x, 3);\r\n        },\r\n\r\n    /**\r\n     * Compute base to the power of exponent.\r\n     * @param {Number} base\r\n     * @param {Number} exponent\r\n     * @returns {Number} base to the power of exponent.\r\n     */\r\n    pow: function (base, exponent) {\r\n        if (base === 0) {\r\n            if (exponent === 0) {\r\n                return 1;\r\n            }\r\n            return 0;\r\n        }\r\n\r\n        // exponent is an integer\r\n        if (Math.floor(exponent) === exponent) {\r\n            return Math.pow(base, exponent);\r\n        }\r\n\r\n        // exponent is not an integer\r\n        if (base > 0) {\r\n            return Math.exp(exponent * Math.log(base));\r\n        }\r\n\r\n        return NaN;\r\n    },\r\n\r\n    /**\r\n     * Compute base to the power of the rational exponent m / n.\r\n     * This function first reduces the fraction m/n and then computes\r\n     * JXG.Math.pow(base, m/n).\r\n     *\r\n     * This function is necessary to have the same results for e.g.\r\n     * (-8)^(1/3) = (-8)^(2/6) = -2\r\n     * @param {Number} base\r\n     * @param {Number} m numerator of exponent\r\n     * @param {Number} n denominator of exponent\r\n     * @returns {Number} base to the power of exponent.\r\n     */\r\n    ratpow: function (base, m, n) {\r\n        var g;\r\n        if (m === 0) {\r\n            return 1;\r\n        }\r\n        if (n === 0) {\r\n            return NaN;\r\n        }\r\n\r\n        g = this.gcd(m, n);\r\n        return this.nthroot(this.pow(base, m / g), n / g);\r\n    },\r\n\r\n    /**\r\n     * Logarithm to base 10.\r\n     * @param {Number} x\r\n     * @returns {Number} log10(x) Logarithm of x to base 10.\r\n     */\r\n    log10: function (x) {\r\n        return Math.log(x) / Math.log(10.0);\r\n    },\r\n\r\n    /**\r\n     * Logarithm to base 2.\r\n     * @param {Number} x\r\n     * @returns {Number} log2(x) Logarithm of x to base 2.\r\n     */\r\n    log2: function (x) {\r\n        return Math.log(x) / Math.log(2.0);\r\n    },\r\n\r\n    /**\r\n     * Logarithm to arbitrary base b. If b is not given, natural log is taken, i.e. b = e.\r\n     * @param {Number} x\r\n     * @param {Number} b base\r\n     * @returns {Number} log(x, b) Logarithm of x to base b, that is log(x)/log(b).\r\n     */\r\n    log: function (x, b) {\r\n        if (b !== undefined && Type.isNumber(b)) {\r\n            return Math.log(x) / Math.log(b);\r\n        }\r\n\r\n        return Math.log(x);\r\n    },\r\n\r\n    /**\r\n     * The sign() function returns the sign of a number, indicating whether the number is positive, negative or zero.\r\n     *\r\n     * @function\r\n     * @param  {Number} x A Number\r\n     * @returns {Number}  This function has 5 kinds of return values,\r\n     *    1, -1, 0, -0, NaN, which represent \"positive number\", \"negative number\", \"positive zero\", \"negative zero\"\r\n     *    and NaN respectively.\r\n     */\r\n    sign:\r\n        Math.sign ||\r\n        function (x) {\r\n            x = +x; // convert to a number\r\n            if (x === 0 || isNaN(x)) {\r\n                return x;\r\n            }\r\n            return x > 0 ? 1 : -1;\r\n        },\r\n\r\n    /**\r\n     * A square & multiply algorithm to compute base to the power of exponent.\r\n     * Implementated by Wolfgang Riedl.\r\n     *\r\n     * @param {Number} base\r\n     * @param {Number} exponent\r\n     * @returns {Number} Base to the power of exponent\r\n     */\r\n    squampow: function (base, exponent) {\r\n        var result;\r\n\r\n        if (Math.floor(exponent) === exponent) {\r\n            // exponent is integer (could be zero)\r\n            result = 1;\r\n\r\n            if (exponent < 0) {\r\n                // invert: base\r\n                base = 1.0 / base;\r\n                exponent *= -1;\r\n            }\r\n\r\n            while (exponent !== 0) {\r\n                if (exponent & 1) {\r\n                    result *= base;\r\n                }\r\n\r\n                exponent >>= 1;\r\n                base *= base;\r\n            }\r\n            return result;\r\n        }\r\n\r\n        return this.pow(base, exponent);\r\n    },\r\n\r\n    /**\r\n     * Greatest common divisor (gcd) of two numbers.\r\n     * See {@link <a href=\"https://rosettacode.org/wiki/Greatest_common_divisor#JavaScript\">rosettacode.org</a>}.\r\n     *\r\n     * @param  {Number} a First number\r\n     * @param  {Number} b Second number\r\n     * @returns {Number}   gcd(a, b) if a and b are numbers, NaN else.\r\n     */\r\n    gcd: function (a, b) {\r\n        var tmp,\r\n            endless = true;\r\n\r\n        a = Math.abs(a);\r\n        b = Math.abs(b);\r\n\r\n        if (!(Type.isNumber(a) && Type.isNumber(b))) {\r\n            return NaN;\r\n        }\r\n        if (b > a) {\r\n            tmp = a;\r\n            a = b;\r\n            b = tmp;\r\n        }\r\n\r\n        while (endless) {\r\n            a %= b;\r\n            if (a === 0) {\r\n                return b;\r\n            }\r\n            b %= a;\r\n            if (b === 0) {\r\n                return a;\r\n            }\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Least common multiple (lcm) of two numbers.\r\n     *\r\n     * @param  {Number} a First number\r\n     * @param  {Number} b Second number\r\n     * @returns {Number}   lcm(a, b) if a and b are numbers, NaN else.\r\n     */\r\n    lcm: function (a, b) {\r\n        var ret;\r\n\r\n        if (!(Type.isNumber(a) && Type.isNumber(b))) {\r\n            return NaN;\r\n        }\r\n\r\n        ret = a * b;\r\n        if (ret !== 0) {\r\n            return ret / this.gcd(a, b);\r\n        }\r\n\r\n        return 0;\r\n    },\r\n\r\n    /**\r\n     * Special use of Math.round function to round not only to integers but also to chosen decimal values.\r\n     *\r\n     * @param {Number} value Value to be rounded.\r\n     * @param {Number} step Distance between the values to be rounded to. (default: 1.0)\r\n     * @param {Number} [min] If set, it will be returned the maximum of value and min.\r\n     * @param {Number} [max] If set, it will be returned the minimum of value and max.\r\n     * @returns {Number} Fitted value.\r\n     */\r\n    roundToStep: function (value, step, min, max) {\r\n        var n = value,\r\n            tmp, minOr0;\r\n\r\n        // for performance\r\n        if (!Type.exists(step) && !Type.exists(min) && !Type.exists(max)) {\r\n            return n;\r\n        }\r\n\r\n        if (JXG.exists(max)) {\r\n            n = Math.min(n, max);\r\n        }\r\n        if (JXG.exists(min)) {\r\n            n = Math.max(n, min);\r\n        }\r\n\r\n        minOr0 = min || 0;\r\n\r\n        if (JXG.exists(step)) {\r\n            tmp = (n - minOr0) / step;\r\n            if (Number.isInteger(tmp)) {\r\n                return n;\r\n            }\r\n\r\n            tmp = Math.round(tmp);\r\n            n = minOr0 + tmp * step;\r\n        }\r\n\r\n        if (JXG.exists(max)) {\r\n            n = Math.min(n, max);\r\n        }\r\n        if (JXG.exists(min)) {\r\n            n = Math.max(n, min);\r\n        }\r\n\r\n        return n;\r\n    },\r\n\r\n    /**\r\n     *  Error function, see {@link https://en.wikipedia.org/wiki/Error_function}.\r\n     *\r\n     * @see JXG.Math.ProbFuncs.erf\r\n     * @param  {Number} x\r\n     * @returns {Number}\r\n     */\r\n    erf: function (x) {\r\n        return this.ProbFuncs.erf(x);\r\n    },\r\n\r\n    /**\r\n     * Complementary error function, i.e. 1 - erf(x).\r\n     *\r\n     * @see JXG.Math.erf\r\n     * @see JXG.Math.ProbFuncs.erfc\r\n     * @param  {Number} x\r\n     * @returns {Number}\r\n     */\r\n    erfc: function (x) {\r\n        return this.ProbFuncs.erfc(x);\r\n    },\r\n\r\n    /**\r\n     * Inverse of error function\r\n     *\r\n     * @see JXG.Math.erf\r\n     * @see JXG.Math.ProbFuncs.erfi\r\n     * @param  {Number} x\r\n     * @returns {Number}\r\n     */\r\n    erfi: function (x) {\r\n        return this.ProbFuncs.erfi(x);\r\n    },\r\n\r\n    /**\r\n     * Normal distribution function\r\n     *\r\n     * @see JXG.Math.ProbFuncs.ndtr\r\n     * @param  {Number} x\r\n     * @returns {Number}\r\n     */\r\n    ndtr: function (x) {\r\n        return this.ProbFuncs.ndtr(x);\r\n    },\r\n\r\n    /**\r\n     * Inverse of normal distribution function\r\n     *\r\n     * @see JXG.Math.ndtr\r\n     * @see JXG.Math.ProbFuncs.ndtri\r\n     * @param  {Number} x\r\n     * @returns {Number}\r\n     */\r\n    ndtri: function (x) {\r\n        return this.ProbFuncs.ndtri(x);\r\n    },\r\n\r\n    /**\r\n     * Returns sqrt(a * a + b * b) for a variable number of arguments.\r\n     * This is a naive implementation which might be faster than Math.hypot.\r\n     * The latter is numerically more stable.\r\n     *\r\n     * @param {Number} a Variable number of arguments.\r\n     * @returns Number\r\n     */\r\n    hypot: function () {\r\n        var i, le, a, sum;\r\n\r\n        le = arguments.length;\r\n        for (i = 0, sum = 0.0; i < le; i++) {\r\n            a = arguments[i];\r\n            sum += a * a;\r\n        }\r\n        return Math.sqrt(sum);\r\n    },\r\n\r\n    /**\r\n     * Heaviside unit step function. Returns 0 for x &lt;, 1 for x &gt; 0, and 0.5 for x == 0.\r\n     *\r\n     * @param {Number} x\r\n     * @returns Number\r\n     */\r\n    hstep: function (x) {\r\n        return (x > 0.0) ? 1 :\r\n            ((x < 0.0) ? 0.0 : 0.5);\r\n    },\r\n\r\n    /**\r\n     * Gamma function for real parameters by Lanczos approximation.\r\n     * Implementation straight from {@link https://en.wikipedia.org/wiki/Lanczos_approximation}.\r\n     *\r\n     * @param {Number} z\r\n     * @returns Number\r\n     */\r\n    gamma: function (z) {\r\n        var x, y, t, i, le,\r\n            g = 7,\r\n            // n = 9,\r\n            p = [\r\n                1.0,\r\n                676.5203681218851,\r\n                -1259.1392167224028,\r\n                771.32342877765313,\r\n                -176.61502916214059,\r\n                12.507343278686905,\r\n                -0.13857109526572012,\r\n                9.9843695780195716e-6,\r\n                1.5056327351493116e-7\r\n            ];\r\n\r\n        if (z < 0.5) {\r\n            y = Math.PI / (Math.sin(Math.PI * z) * this.gamma(1 - z));  // Reflection formula\r\n        } else {\r\n            z -= 1;\r\n            x = p[0];\r\n            le = p.length;\r\n            for (i = 1; i < le; i++) {\r\n                x += p[i] / (z + i);\r\n            }\r\n            t = z + g + 0.5;\r\n            y = Math.sqrt(2 * Math.PI) * Math.pow(t, z + 0.5) * Math.exp(-t) * x;\r\n        }\r\n        return y;\r\n    },\r\n\r\n    /* ********************  Comparisons and logical operators ************** */\r\n\r\n    /**\r\n     * Logical test: a < b?\r\n     *\r\n     * @param {Number} a\r\n     * @param {Number} b\r\n     * @returns {Boolean}\r\n     */\r\n    lt: function (a, b) {\r\n        return a < b;\r\n    },\r\n\r\n    /**\r\n     * Logical test: a <= b?\r\n     *\r\n     * @param {Number} a\r\n     * @param {Number} b\r\n     * @returns {Boolean}\r\n     */\r\n    leq: function (a, b) {\r\n        return a <= b;\r\n    },\r\n\r\n    /**\r\n     * Logical test: a > b?\r\n     *\r\n     * @param {Number} a\r\n     * @param {Number} b\r\n     * @returns {Boolean}\r\n     */\r\n    gt: function (a, b) {\r\n        return a > b;\r\n    },\r\n\r\n    /**\r\n     * Logical test: a >= b?\r\n     *\r\n     * @param {Number} a\r\n     * @param {Number} b\r\n     * @returns {Boolean}\r\n     */\r\n    geq: function (a, b) {\r\n        return a >= b;\r\n    },\r\n\r\n    /**\r\n     * Logical test: a === b?\r\n     *\r\n     * @param {Number} a\r\n     * @param {Number} b\r\n     * @returns {Boolean}\r\n     */\r\n    eq: function (a, b) {\r\n        return a === b;\r\n    },\r\n\r\n    /**\r\n     * Logical test: a !== b?\r\n     *\r\n     * @param {Number} a\r\n     * @param {Number} b\r\n     * @returns {Boolean}\r\n     */\r\n    neq: function (a, b) {\r\n        return a !== b;\r\n    },\r\n\r\n    /**\r\n     * Logical operator: a && b?\r\n     *\r\n     * @param {Boolean} a\r\n     * @param {Boolean} b\r\n     * @returns {Boolean}\r\n     */\r\n    and: function (a, b) {\r\n        return a && b;\r\n    },\r\n\r\n    /**\r\n     * Logical operator: !a?\r\n     *\r\n     * @param {Boolean} a\r\n     * @returns {Boolean}\r\n     */\r\n    not: function (a) {\r\n        return !a;\r\n    },\r\n\r\n    /**\r\n     * Logical operator: a || b?\r\n     *\r\n     * @param {Boolean} a\r\n     * @param {Boolean} b\r\n     * @returns {Boolean}\r\n     */\r\n    or: function (a, b) {\r\n        return a || b;\r\n    },\r\n\r\n    /**\r\n     * Logical operator: either a or b?\r\n     *\r\n     * @param {Boolean} a\r\n     * @param {Boolean} b\r\n     * @returns {Boolean}\r\n     */\r\n    xor: function (a, b) {\r\n        return (a || b) && !(a && b);\r\n    },\r\n\r\n    /**\r\n     *\r\n     * Convert a floating point number to sign + integer + fraction.\r\n     * fraction is given as nominator and denominator.\r\n     * <p>\r\n     * Algorithm: approximate the floating point number\r\n     * by a continued fraction and simultaneously keep track\r\n     * of its convergents.\r\n     * Inspired by {@link https://kevinboone.me/rationalize.html}.\r\n     *\r\n     * @param {Number} x Number which is to be converted\r\n     * @param {Number} [order=0.001] Small number determining the approximation precision.\r\n     * @returns {Array} [sign, leading, nominator, denominator] where sign is 1 or -1.\r\n     * @see JXG.toFraction\r\n     *\r\n     * @example\r\n     * JXG.Math.decToFraction(0.33333333);\r\n     * // Result: [ 1, 0, 1, 3 ]\r\n     *\r\n     * JXG.Math.decToFraction(0);\r\n     * // Result: [ 1, 0, 0, 1 ]\r\n     *\r\n     * JXG.Math.decToFraction(-10.66666666666667);\r\n     * // Result: [-1, 10, 2, 3 ]\r\n    */\r\n    decToFraction: function (x, order) {\r\n        var lead, sign, a,\r\n            n, n1, n2,\r\n            d, d1, d2,\r\n            it = 0,\r\n            maxit = 20;\r\n\r\n        order = Type.def(order, 0.001);\r\n\r\n        // Round the number.\r\n        // Otherwise, 0.999999999 would result in [0, 1, 1].\r\n        x = Math.round(x * 1.e12) * 1.e-12;\r\n\r\n        // Negative numbers:\r\n        // The minus sign is handled in sign.\r\n        sign = (x < 0) ? -1 : 1;\r\n        x = Math.abs(x);\r\n\r\n        // From now on we consider x to be nonnegative.\r\n        lead = Math.floor(x);\r\n        x -= Math.floor(x);\r\n        a = 0.0;\r\n        n2 = 1.0;\r\n        n = n1 = a;\r\n        d2 = 0.0;\r\n        d = d1 = 1.0;\r\n\r\n        while (x - Math.floor(x) > order && it < maxit) {\r\n            x = 1 / (x - a);\r\n            a = Math.floor(x);\r\n            n = n2 + a * n1;\r\n            d = d2 + a * d1;\r\n            n2 = n1;\r\n            d2 = d1;\r\n            n1 = n;\r\n            d1 = d;\r\n            it++;\r\n        }\r\n        return [sign, lead, n, d];\r\n    },\r\n\r\n    /* *************************** Normalize *************************** */\r\n\r\n    /**\r\n     * Normalize the standard form [c, b0, b1, a, k, r, q0, q1].\r\n     * @private\r\n     * @param {Array} stdform The standard form to be normalized.\r\n     * @returns {Array} The normalized standard form.\r\n     */\r\n    normalize: function (stdform) {\r\n        var n,\r\n            signr,\r\n            a2 = 2 * stdform[3],\r\n            r = stdform[4] / a2;\r\n\r\n        stdform[5] = r;\r\n        stdform[6] = -stdform[1] / a2;\r\n        stdform[7] = -stdform[2] / a2;\r\n\r\n        if (!isFinite(r)) {\r\n            n = this.hypot(stdform[1], stdform[2]);\r\n\r\n            stdform[0] /= n;\r\n            stdform[1] /= n;\r\n            stdform[2] /= n;\r\n            stdform[3] = 0;\r\n            stdform[4] = 1;\r\n        } else if (Math.abs(r) >= 1) {\r\n            stdform[0] = (stdform[6] * stdform[6] + stdform[7] * stdform[7] - r * r) / (2 * r);\r\n            stdform[1] = -stdform[6] / r;\r\n            stdform[2] = -stdform[7] / r;\r\n            stdform[3] = 1 / (2 * r);\r\n            stdform[4] = 1;\r\n        } else {\r\n            signr = r <= 0 ? -1 : 1;\r\n            stdform[0] =\r\n                signr * (stdform[6] * stdform[6] + stdform[7] * stdform[7] - r * r) * 0.5;\r\n            stdform[1] = -signr * stdform[6];\r\n            stdform[2] = -signr * stdform[7];\r\n            stdform[3] = signr / 2;\r\n            stdform[4] = signr * r;\r\n        }\r\n\r\n        return stdform;\r\n    },\r\n\r\n    /**\r\n     * Converts a two-dimensional array to a one-dimensional Float32Array that can be processed by WebGL.\r\n     * @param {Array} m A matrix in a two-dimensional array.\r\n     * @returns {Float32Array} A one-dimensional array containing the matrix in column wise notation. Provides a fall\r\n     * back to the default JavaScript Array if Float32Array is not available.\r\n     */\r\n    toGL: function (m) {\r\n        var v, i, j;\r\n\r\n        if (typeof Float32Array === 'function') {\r\n            v = new Float32Array(16);\r\n        } else {\r\n            v = new Array(16);\r\n        }\r\n\r\n        if (m.length !== 4 && m[0].length !== 4) {\r\n            return v;\r\n        }\r\n\r\n        for (i = 0; i < 4; i++) {\r\n            for (j = 0; j < 4; j++) {\r\n                v[i + 4 * j] = m[i][j];\r\n            }\r\n        }\r\n\r\n        return v;\r\n    },\r\n\r\n    /**\r\n     * Theorem of Vieta: Given a set of simple zeroes x_0, ..., x_n\r\n     * of a polynomial f, compute the coefficients s_k, (k=0,...,n-1)\r\n     * of the polynomial of the form. See {@link https://de.wikipedia.org/wiki/Elementarsymmetrisches_Polynom}.\r\n     * <p>\r\n     *  f(x) = (x-x_0)*...*(x-x_n) =\r\n     *  x^n + sum_{k=1}^{n} (-1)^(k) s_{k-1} x^(n-k)\r\n     * </p>\r\n     * @param {Array} x Simple zeroes of the polynomial.\r\n     * @returns {Array} Coefficients of the polynomial.\r\n     *\r\n     */\r\n    Vieta: function (x) {\r\n        var n = x.length,\r\n            s = [],\r\n            m,\r\n            k,\r\n            y;\r\n\r\n        s = x.slice();\r\n        for (m = 1; m < n; ++m) {\r\n            y = s[m];\r\n            s[m] *= s[m - 1];\r\n            for (k = m - 1; k >= 1; --k) {\r\n                s[k] += s[k - 1] * y;\r\n            }\r\n            s[0] += y;\r\n        }\r\n        return s;\r\n    }\r\n};\r\n\r\nexport default JXG.Math;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Andreas Walter,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\n\r\nvar major = 1,\r\n    minor = 12,\r\n    patch = 2,\r\n    add = '', // 'dev' 'beta'\r\n    version = major + '.' + minor + '.' + patch + (add ? '-' + add : ''),\r\n    constants;\r\n\r\nconstants =\r\n    /** @lends JXG */ {\r\n    /**\r\n     * Constant: the currently used JSXGraph version.\r\n     *\r\n     * @name JXG.version\r\n     * @type String\r\n     */\r\n    version: version,\r\n\r\n    /**\r\n     * Constant: the small gray version indicator in the top left corner of every JSXGraph board (if\r\n     * showCopyright is not set to false on board creation).\r\n     *\r\n     * @name JXG.licenseText\r\n     * @type String\r\n     */\r\n    licenseText: \"JSXGraph v\" + version + \" \\u00A9 jsxgraph.org\",\r\n\r\n    /**\r\n     * JSXGraph logo: base64 data-URL of img/png/screen/jsxgraph-logo_black-square-solid.png\r\n     *\r\n     * @name JXG.licenseLogo\r\n     * @type String\r\n     */\r\n    licenseLogo: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAJ8AAACfCAYAAADnGwvgAAAACXBIWXMAAAsSAAALEgHS3X78AAAIPklEQVR4nO2d21XjSBCG/96z75ABzgBPBHgiWDLARDCeCBAZeCMYO4KFCEbOwM7AZIAjqH1QiTHGF7XUF7X6/87xw4APqodv+qaqaiMiICQGf8UOgOQL5SPRoHwkGpSPROPv2AH4whhzDWCs/xwDuI4YTu4sRGR7+MPByGeMGQG4BzBBJdtNxHDIZ0oA28MfJi2fCjfVD2VLjCTlU+kKAA9RAyGdSEo+SjcskpHPGFMAmAG4ihwKcUTv5dPR7gXAbdxIiGt6fc5njJkAWIPiDZLeymeMmQL4DU6zg6WX8ql4v2LHQfzSO/koXj70Sj6Klxd92+2uAXyPHQS5yBQOzlp7JZ+IrGPHQC6jpxCd6dW0S/KC8pFoUD4SDcpHokH5SDQoH4kG5SPRoHwkGpSPRCPaGw5jzBjACFWl2Ug/JB4LEVmEfGAw+bSO9h5/yhuZp9cvytAP9C6fvgecAfjH97NIWniTT9OjCrCelpzAuXw60hUA7lz/bTIsnMmna7oCwA9Xf5MMGyfy6c51AVaZEQs6n/Pp2q4ExSOWdBr5WHNButB65KN4pCut5KN4xAXW8ulRCsUjnbGSb69pDyGdsR35XsB3ssQRjeXT/ng8TiHOaCSfTrczr5GQ7Gg68hXgdEscc/GQWUc99kC+zArAO6p+M4fU94Aw2WKPJm84Ct9BJMorqteKpU2PGX0PPkGVVJu1jGfl46j3hTcAc1Qp5+9t/oCKugYwz/0ekUtrvmmIIBLgDcCjiIxEZN5WvENEZCsihYiMADzqc7KB8p1nB+BZpVv4fJD+/TGAZ5/P6RMn5dMpIbupYI8NgLGIFKEeKCLv+rxv+vxBc27kuw8WRf9Yisj42E2JIdB14QTAMsbzQ3FOvkmoIHrGTxGZxg5CR8EpBizgud3u+Mzvhspj6MLpS4jI1BgDDPDU4ejIp8VAua33nvsmXs1QR8BT025uo94y5MaiDSrga+w4XNKrbvSR2MBR0oS+vbjG5/VyCeDdUaf9KaoD6kHMSqfky2nkm3Y5NDbG1P1n7nE8+eJJv7dDlQ+5EJGyzbNE5H3vTrrkOTXtXgeNIh7PbUckY8y9MWYL4D9Um4FLWT9X+r3fxph127ssVNxBrP9y7s+3Q/We1gpjzLUx5gWVdG2nv1tUEi50c2fLDFX8SZOzfDPb6VbXdCXcddx6AFDaCqhxW//H6Ru5ylevvxqzJ57rUoJbtBAQlC9ZrFKiVIwF/GVz38KyOaPGn/TaL1f5bEeNAv6Lp261SMuGhYc4gpGjfG82CQO6Kw3V9u1Js4kaoTvfZDceOcpnW/Re+AjC4fOSLeLPUb6y6Rd1kxG6zuLBZvRDhEberqB855l6iuESNrmUyV6QnZ18lmd7E19xXKCxfCnfzp6bfCvL78dqD2I71Se56chNvsa0ffcaiSRHP8rXUxKTvxWUj0SD8vUXJ4XpfYbynWYb8+GWu9gk8y9zk2/U9Iv6Ci7WLtK2bUaSTTtzk882+bP0EYTL57ZMRu0FuclXvzJrSqz3pjbPTbbeJjv5YPfW4gXhp96diNjIN/EViG9ClU6+oXnu2Qh+q/MnaJjPp9Vic2gFWiBscw0nPoIIQSj5tk2LsvVw1bd8NsxRFeyE6EldN59shK73ku1umuO0e6W1to3QRISpv3A+YVtDnHQnsRzlAyw7FOga7F9PsdT8bFFMnvT1FLnKd2eZsAkRmcFfwc5SRKzWero8SfJ8ryZX+YAW6fHarMd129rHlv0AC8dxBCdn+R7aZI7oxuk7ujfv3gD41qYtm8ad7EajJmf5gJaF1yJSduggX3e2H7fJQt6rIU6e3OVrUyv7gYgsVMJvqKbjFb4eSr/pz59RjXRdO9sXGHiLtJx4Msa8dKmF2LvYxSuBa4i9k/vIV9OmV0pQ9J10sjW6x6B8FVfosYAa1+Au2qZ8f2jbLcorGk+Jgazz9qF8n6kFHEWOA8DHVLtG4ofJp6B8X7kF0LptrSv0/XOJAY54NZTvOFeo2tbOQ0/D2nZ3jqrt7qDWeIdQvvP8QDUKBske0U7zawzoOOUclO8yNwD+M8aUviQ0xky1s/0vDHiaPYSHzM25Q5UNU2dlL7rcSqmbiSmqnLxshNuH8tlzgyqt/klFLPWzBbA+lgyq68bx3meCTIXbh/J14wZVyv9H2r/eEEkawDUfiQblIyHYHvsh5SPeObUxo3zENyeL7ikf8c3JPEfKR3xD+Ug0KB+JRnnqF5SP+GRz7hUk5SM+WZz7JeUjPjlb8ET5iC9Wl7J+KB/xRXHpC5SP+GDVpN0b5SM+KJp8ifIR17w2bXJJ+YhLdrBoIUz5iEusekpTPuKKpeX9IZSPOGHTprUv5SNd2aDlRTSUj3RhA2BieXfIB70rndRtehL1h8aYEgNozN2STuIBHPlIOxboKB7Qw5GP9J8ubUL24chHasrQD6R8JBqUjwD42OgFhfIRoNq5BofyESDABTbHoHwEiLDZACgfqYhysxHlI69dD4vbEuqQ+c4YI4GeReyIdp8bR768eet4/WonKF/eLGI+nPLlyw4tb1p3BeXLl1msjUYN5cuTVcy1Xg3ly5NZ7AAAypcjP0Ukyuu0QyhfXixFJOomYx/Klw8b9GS6raF8edC52McHlG/49FI8gPINnd6KB1C+IbMUkXFfxQNYOjlEdqi6RUXLVmkKR75h8QpglIJ4AOUbCisA30Xkvs/T7CGcdtNmBaCIUfboAsqXHhtUeXgvrtpWxILy9ZsdqrLG+lOmLtw+RuRraYUxZgRgFDgW8oftkCQ7xVH5CAkBd7skGpSPRIPykWhQPhKN/wEKYnCiOMadyQAAAABJRU5ErkJggg==',\r\n\r\n    /**\r\n     *  Constant: user coordinates relative to the coordinates system defined by the bounding box.\r\n     *  @name JXG.COORDS_BY_USER\r\n     *  @type Number\r\n     */\r\n    COORDS_BY_USER: 0x0001,\r\n\r\n    /**\r\n     *  Constant: screen coordinates in pixel relative to the upper left corner of the div element.\r\n     *  @name JXG.COORDS_BY_SCREEN\r\n     *  @type Number\r\n     */\r\n    COORDS_BY_SCREEN: 0x0002,\r\n\r\n    // object types\r\n    OBJECT_TYPE_ARC: 1,\r\n    OBJECT_TYPE_ARROW: 2,\r\n    OBJECT_TYPE_AXIS: 3,\r\n    OBJECT_TYPE_AXISPOINT: 4,\r\n    OBJECT_TYPE_TICKS: 5,\r\n    OBJECT_TYPE_CIRCLE: 6,\r\n    OBJECT_TYPE_CONIC: 7,\r\n    OBJECT_TYPE_CURVE: 8,\r\n    OBJECT_TYPE_GLIDER: 9,\r\n    OBJECT_TYPE_IMAGE: 10,\r\n    OBJECT_TYPE_LINE: 11,\r\n    OBJECT_TYPE_POINT: 12,\r\n    OBJECT_TYPE_SLIDER: 13,// unused\r\n    OBJECT_TYPE_CAS: 14,\r\n    OBJECT_TYPE_GXTCAS: 15,\r\n    OBJECT_TYPE_POLYGON: 16,\r\n    OBJECT_TYPE_SECTOR: 17,\r\n    OBJECT_TYPE_TEXT: 18,\r\n    OBJECT_TYPE_ANGLE: 19,\r\n    OBJECT_TYPE_INTERSECTION: 20,\r\n    OBJECT_TYPE_TURTLE: 21,\r\n    OBJECT_TYPE_VECTOR: 22,\r\n    OBJECT_TYPE_OPROJECT: 23,\r\n    OBJECT_TYPE_GRID: 24,\r\n    OBJECT_TYPE_TANGENT: 25,\r\n    OBJECT_TYPE_HTMLSLIDER: 26,\r\n    OBJECT_TYPE_CHECKBOX: 27,\r\n    OBJECT_TYPE_INPUT: 28,\r\n    OBJECT_TYPE_BUTTON: 29,\r\n    OBJECT_TYPE_TRANSFORMATION: 30,\r\n    OBJECT_TYPE_FOREIGNOBJECT: 31,\r\n\r\n    OBJECT_TYPE_VIEW3D: 32,\r\n    OBJECT_TYPE_POINT3D: 33,\r\n    OBJECT_TYPE_LINE3D: 34,\r\n    OBJECT_TYPE_PLANE3D: 35,\r\n    OBJECT_TYPE_CURVE3D: 36,\r\n    OBJECT_TYPE_SURFACE3D: 37,\r\n\r\n    OBJECT_TYPE_MEASUREMENT: 38,\r\n\r\n    OBJECT_TYPE_INTERSECTION_LINE3D: 39,\r\n    OBJECT_TYPE_SPHERE3D: 40,\r\n    OBJECT_TYPE_CIRCLE3D: 41,\r\n    OBJECT_TYPE_INTERSECTION_CIRCLE3D: 42,\r\n    OBJECT_TYPE_TEXT3D: 43,\r\n    OBJECT_TYPE_FACE3D: 44,\r\n    OBJECT_TYPE_POLYHEDRON3D: 45,\r\n    OBJECT_TYPE_POLYGON3D: 46,\r\n\r\n    // IMPORTANT:\r\n    // ----------\r\n    // For being able to differentiate between the (sketchometry specific) SPECIAL_OBJECT_TYPEs and\r\n    // (core specific) OBJECT_TYPEs, the non-sketchometry types MUST NOT be changed\r\n    // to values > 100.\r\n\r\n    // object classes\r\n    OBJECT_CLASS_POINT: 1,\r\n    OBJECT_CLASS_LINE: 2,\r\n    OBJECT_CLASS_CIRCLE: 3,\r\n    OBJECT_CLASS_CURVE: 4,\r\n    OBJECT_CLASS_AREA: 5,\r\n    OBJECT_CLASS_OTHER: 6,\r\n    OBJECT_CLASS_TEXT: 7,\r\n    OBJECT_CLASS_3D: 8\r\n};\r\n\r\nJXG.extendConstants(JXG, constants);\r\n\r\nexport default constants;\r\n// const COORDS_BY_SCREEN = constants.COORDS_BY_SCREEN;\r\n// export {constants as default,\r\n//         COORDS_BY_SCREEN};\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Andreas Walter,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview This file contains the Math.Geometry namespace for calculating algebraic/geometric\r\n * stuff like intersection points, angles, midpoint, and so on.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Coords from \"../base/coords.js\";\r\nimport Mat from \"./math.js\";\r\nimport Stat from \"../math/statistics.js\";\r\nimport Numerics from \"./numerics.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Expect from \"../utils/expect.js\";\r\n\r\n/**\r\n * Math.Geometry namespace definition. This namespace holds geometrical algorithms,\r\n * especially intersection algorithms.\r\n * @name JXG.Math.Geometry\r\n * @exports Mat.Geometry as JXG.Math.Geometry\r\n * @namespace\r\n */\r\nMat.Geometry = {};\r\n\r\n// the splitting is necessary due to the shortcut for the circumcircleMidpoint method to circumcenter.\r\n\r\nJXG.extend(\r\n    Mat.Geometry,\r\n    /** @lends JXG.Math.Geometry */ {\r\n        /* ***************************************/\r\n        /* *** GENERAL GEOMETRIC CALCULATIONS ****/\r\n        /* ***************************************/\r\n\r\n        /**\r\n         * Calculates the angle defined by the points A, B, C.\r\n         * @param {JXG.Point|Array} A A point  or [x,y] array.\r\n         * @param {JXG.Point|Array} B Another point or [x,y] array.\r\n         * @param {JXG.Point|Array} C A circle - no, of course the third point or [x,y] array.\r\n         * @deprecated Use {@link JXG.Math.Geometry.rad} instead.\r\n         * @see JXG.Math.Geometry.rad\r\n         * @see JXG.Math.Geometry.trueAngle\r\n         * @returns {Number} The angle in radian measure.\r\n         */\r\n        angle: function (A, B, C) {\r\n            var u,\r\n                v,\r\n                s,\r\n                t,\r\n                a = [],\r\n                b = [],\r\n                c = [];\r\n\r\n            JXG.deprecated(\"Geometry.angle()\", \"Geometry.rad()\");\r\n            if (A.coords) {\r\n                a[0] = A.coords.usrCoords[1];\r\n                a[1] = A.coords.usrCoords[2];\r\n            } else {\r\n                a[0] = A[0];\r\n                a[1] = A[1];\r\n            }\r\n\r\n            if (B.coords) {\r\n                b[0] = B.coords.usrCoords[1];\r\n                b[1] = B.coords.usrCoords[2];\r\n            } else {\r\n                b[0] = B[0];\r\n                b[1] = B[1];\r\n            }\r\n\r\n            if (C.coords) {\r\n                c[0] = C.coords.usrCoords[1];\r\n                c[1] = C.coords.usrCoords[2];\r\n            } else {\r\n                c[0] = C[0];\r\n                c[1] = C[1];\r\n            }\r\n\r\n            u = a[0] - b[0];\r\n            v = a[1] - b[1];\r\n            s = c[0] - b[0];\r\n            t = c[1] - b[1];\r\n\r\n            return Math.atan2(u * t - v * s, u * s + v * t);\r\n        },\r\n\r\n        /**\r\n         * Calculates the angle defined by the three points A, B, C if you're going from A to C around B counterclockwise.\r\n         * @param {JXG.Point|Array} A Point or [x,y] array\r\n         * @param {JXG.Point|Array} B Point or [x,y] array\r\n         * @param {JXG.Point|Array} C Point or [x,y] array\r\n         * @see JXG.Math.Geometry.rad\r\n         * @returns {Number} The angle in degrees.\r\n         */\r\n        trueAngle: function (A, B, C) {\r\n            return this.rad(A, B, C) * 57.295779513082323; // *180.0/Math.PI;\r\n        },\r\n\r\n        /**\r\n         * Calculates the internal angle defined by the three points A, B, C if you're going from A to C around B counterclockwise.\r\n         * @param {JXG.Point|Array} A Point or [x,y] array\r\n         * @param {JXG.Point|Array} B Point or [x,y] array\r\n         * @param {JXG.Point|Array} C Point or [x,y] array\r\n         * @see JXG.Math.Geometry.trueAngle\r\n         * @returns {Number} Angle in radians.\r\n         */\r\n        rad: function (A, B, C) {\r\n            var ax, ay, bx, by, cx, cy, phi;\r\n\r\n            if (A.coords) {\r\n                ax = A.coords.usrCoords[1];\r\n                ay = A.coords.usrCoords[2];\r\n            } else {\r\n                ax = A[0];\r\n                ay = A[1];\r\n            }\r\n\r\n            if (B.coords) {\r\n                bx = B.coords.usrCoords[1];\r\n                by = B.coords.usrCoords[2];\r\n            } else {\r\n                bx = B[0];\r\n                by = B[1];\r\n            }\r\n\r\n            if (C.coords) {\r\n                cx = C.coords.usrCoords[1];\r\n                cy = C.coords.usrCoords[2];\r\n            } else {\r\n                cx = C[0];\r\n                cy = C[1];\r\n            }\r\n\r\n            phi = Math.atan2(cy - by, cx - bx) - Math.atan2(ay - by, ax - bx);\r\n\r\n            if (phi < 0) {\r\n                phi += 6.2831853071795862;\r\n            }\r\n\r\n            return phi;\r\n        },\r\n\r\n        /**\r\n         * Calculates a point on the bisection line between the three points A, B, C.\r\n         * As a result, the bisection line is defined by two points:\r\n         * Parameter B and the point with the coordinates calculated in this function.\r\n         * Does not work for ideal points.\r\n         * @param {JXG.Point} A Point\r\n         * @param {JXG.Point} B Point\r\n         * @param {JXG.Point} C Point\r\n         * @param [board=A.board] Reference to the board\r\n         * @returns {JXG.Coords} Coordinates of the second point defining the bisection.\r\n         */\r\n        angleBisector: function (A, B, C, board) {\r\n            var phiA,\r\n                phiC,\r\n                phi,\r\n                Ac = A.coords.usrCoords,\r\n                Bc = B.coords.usrCoords,\r\n                Cc = C.coords.usrCoords,\r\n                x,\r\n                y;\r\n\r\n            if (!Type.exists(board)) {\r\n                board = A.board;\r\n            }\r\n\r\n            // Parallel lines\r\n            if (Bc[0] === 0) {\r\n                return new Coords(\r\n                    Const.COORDS_BY_USER,\r\n                    [1, (Ac[1] + Cc[1]) * 0.5, (Ac[2] + Cc[2]) * 0.5],\r\n                    board\r\n                );\r\n            }\r\n\r\n            // Non-parallel lines\r\n            x = Ac[1] - Bc[1];\r\n            y = Ac[2] - Bc[2];\r\n            phiA = Math.atan2(y, x);\r\n\r\n            x = Cc[1] - Bc[1];\r\n            y = Cc[2] - Bc[2];\r\n            phiC = Math.atan2(y, x);\r\n\r\n            phi = (phiA + phiC) * 0.5;\r\n\r\n            if (phiA > phiC) {\r\n                phi += Math.PI;\r\n            }\r\n\r\n            x = Math.cos(phi) + Bc[1];\r\n            y = Math.sin(phi) + Bc[2];\r\n\r\n            return new Coords(Const.COORDS_BY_USER, [1, x, y], board);\r\n        },\r\n\r\n        // /**\r\n        //  * Calculates a point on the m-section line between the three points A, B, C.\r\n        //  * As a result, the m-section line is defined by two points:\r\n        //  * Parameter B and the point with the coordinates calculated in this function.\r\n        //  * The m-section generalizes the bisector to any real number.\r\n        //  * For example, the trisectors of an angle are simply the 1/3-sector and the 2/3-sector.\r\n        //  * Does not work for ideal points.\r\n        //  * @param {JXG.Point} A Point\r\n        //  * @param {JXG.Point} B Point\r\n        //  * @param {JXG.Point} C Point\r\n        //  * @param {Number} m Number\r\n        //  * @param [board=A.board] Reference to the board\r\n        //  * @returns {JXG.Coords} Coordinates of the second point defining the bisection.\r\n        //  */\r\n        // angleMsector: function (A, B, C, m, board) {\r\n        //     var phiA, phiC, phi,\r\n        //         Ac = A.coords.usrCoords,\r\n        //         Bc = B.coords.usrCoords,\r\n        //         Cc = C.coords.usrCoords,\r\n        //         x, y;\r\n\r\n        //     if (!Type.exists(board)) {\r\n        //         board = A.board;\r\n        //     }\r\n\r\n        //     // Parallel lines\r\n        //     if (Bc[0] === 0) {\r\n        //         return new Coords(Const.COORDS_BY_USER,\r\n        //             [1, (Ac[1] + Cc[1]) * m, (Ac[2] + Cc[2]) * m], board);\r\n        //     }\r\n\r\n        //     // Non-parallel lines\r\n        //     x = Ac[1] - Bc[1];\r\n        //     y = Ac[2] - Bc[2];\r\n        //     phiA =  Math.atan2(y, x);\r\n\r\n        //     x = Cc[1] - Bc[1];\r\n        //     y = Cc[2] - Bc[2];\r\n        //     phiC =  Math.atan2(y, x);\r\n\r\n        //     phi = phiA + ((phiC - phiA) * m);\r\n\r\n        //     if (phiA - phiC > Math.PI) {\r\n        //         phi += 2*m*Math.PI;\r\n        //     }\r\n\r\n        //     x = Math.cos(phi) + Bc[1];\r\n        //     y = Math.sin(phi) + Bc[2];\r\n\r\n        //     return new Coords(Const.COORDS_BY_USER, [1, x, y], board);\r\n        // },\r\n\r\n        /**\r\n         * Reflects the point along the line.\r\n         * @param {JXG.Line} line Axis of reflection.\r\n         * @param {JXG.Point} point Point to reflect.\r\n         * @param [board=point.board] Reference to the board\r\n         * @returns {JXG.Coords} Coordinates of the reflected point.\r\n         */\r\n        reflection: function (line, point, board) {\r\n            // (v,w) defines the slope of the line\r\n            var x0,\r\n                y0,\r\n                x1,\r\n                y1,\r\n                v,\r\n                w,\r\n                mu,\r\n                pc = point.coords.usrCoords,\r\n                p1c = line.point1.coords.usrCoords,\r\n                p2c = line.point2.coords.usrCoords;\r\n\r\n            if (!Type.exists(board)) {\r\n                board = point.board;\r\n            }\r\n\r\n            v = p2c[1] - p1c[1];\r\n            w = p2c[2] - p1c[2];\r\n\r\n            x0 = pc[1] - p1c[1];\r\n            y0 = pc[2] - p1c[2];\r\n\r\n            mu = (v * y0 - w * x0) / (v * v + w * w);\r\n\r\n            // point + mu*(-y,x) is the perpendicular foot\r\n            x1 = pc[1] + 2 * mu * w;\r\n            y1 = pc[2] - 2 * mu * v;\r\n\r\n            return new Coords(Const.COORDS_BY_USER, [x1, y1], board);\r\n        },\r\n\r\n        /**\r\n         * Computes the new position of a point which is rotated\r\n         * around a second point (called rotpoint) by the angle phi.\r\n         * @param {JXG.Point} rotpoint Center of the rotation\r\n         * @param {JXG.Point} point point to be rotated\r\n         * @param {Number} phi rotation angle in arc length\r\n         * @param {JXG.Board} [board=point.board] Reference to the board\r\n         * @returns {JXG.Coords} Coordinates of the new position.\r\n         */\r\n        rotation: function (rotpoint, point, phi, board) {\r\n            var x0,\r\n                y0,\r\n                c,\r\n                s,\r\n                x1,\r\n                y1,\r\n                pc = point.coords.usrCoords,\r\n                rotpc = rotpoint.coords.usrCoords;\r\n\r\n            if (!Type.exists(board)) {\r\n                board = point.board;\r\n            }\r\n\r\n            x0 = pc[1] - rotpc[1];\r\n            y0 = pc[2] - rotpc[2];\r\n\r\n            c = Math.cos(phi);\r\n            s = Math.sin(phi);\r\n\r\n            x1 = x0 * c - y0 * s + rotpc[1];\r\n            y1 = x0 * s + y0 * c + rotpc[2];\r\n\r\n            return new Coords(Const.COORDS_BY_USER, [x1, y1], board);\r\n        },\r\n\r\n        /**\r\n         * Calculates the coordinates of a point on the perpendicular to the given line through\r\n         * the given point.\r\n         * @param {JXG.Line} line A line.\r\n         * @param {JXG.Point} point Point which is projected to the line.\r\n         * @param {JXG.Board} [board=point.board] Reference to the board\r\n         * @returns {Array} Array of length two containing coordinates of a point on the perpendicular to the given line\r\n         *                  through the given point and boolean flag \"change\".\r\n         */\r\n        perpendicular: function (line, point, board) {\r\n            var x,\r\n                y,\r\n                change,\r\n                c,\r\n                z,\r\n                A = line.point1.coords.usrCoords,\r\n                B = line.point2.coords.usrCoords,\r\n                C = point.coords.usrCoords;\r\n\r\n            if (!Type.exists(board)) {\r\n                board = point.board;\r\n            }\r\n\r\n            // special case: point is the first point of the line\r\n            if (point === line.point1) {\r\n                x = A[1] + B[2] - A[2];\r\n                y = A[2] - B[1] + A[1];\r\n                z = A[0] * B[0];\r\n\r\n                if (Math.abs(z) < Mat.eps) {\r\n                    x = B[2];\r\n                    y = -B[1];\r\n                }\r\n                c = [z, x, y];\r\n                change = true;\r\n\r\n                // special case: point is the second point of the line\r\n            } else if (point === line.point2) {\r\n                x = B[1] + A[2] - B[2];\r\n                y = B[2] - A[1] + B[1];\r\n                z = A[0] * B[0];\r\n\r\n                if (Math.abs(z) < Mat.eps) {\r\n                    x = A[2];\r\n                    y = -A[1];\r\n                }\r\n                c = [z, x, y];\r\n                change = false;\r\n\r\n                // special case: point lies somewhere else on the line\r\n            } else if (Math.abs(Mat.innerProduct(C, line.stdform, 3)) < Mat.eps) {\r\n                x = C[1] + B[2] - C[2];\r\n                y = C[2] - B[1] + C[1];\r\n                z = B[0];\r\n\r\n                if (Math.abs(z) < Mat.eps) {\r\n                    x = B[2];\r\n                    y = -B[1];\r\n                }\r\n\r\n                change = true;\r\n                if (\r\n                    Math.abs(z) > Mat.eps &&\r\n                    Math.abs(x - C[1]) < Mat.eps &&\r\n                    Math.abs(y - C[2]) < Mat.eps\r\n                ) {\r\n                    x = C[1] + A[2] - C[2];\r\n                    y = C[2] - A[1] + C[1];\r\n                    change = false;\r\n                }\r\n                c = [z, x, y];\r\n\r\n                // general case: point does not lie on the line\r\n                // -> calculate the foot of the dropped perpendicular\r\n            } else {\r\n                c = [0, line.stdform[1], line.stdform[2]];\r\n                c = Mat.crossProduct(c, C); // perpendicuar to line\r\n                c = Mat.crossProduct(c, line.stdform); // intersection of line and perpendicular\r\n                change = true;\r\n            }\r\n\r\n            return [new Coords(Const.COORDS_BY_USER, c, board), change];\r\n        },\r\n\r\n        /**\r\n         * @deprecated Please use {@link JXG.Math.Geometry.circumcenter} instead.\r\n         */\r\n        circumcenterMidpoint: function () {\r\n            JXG.deprecated(\"Geometry.circumcenterMidpoint()\", \"Geometry.circumcenter()\");\r\n            this.circumcenter.apply(this, arguments);\r\n        },\r\n\r\n        /**\r\n         * Calculates the center of the circumcircle of the three given points.\r\n         * @param {JXG.Point} point1 Point\r\n         * @param {JXG.Point} point2 Point\r\n         * @param {JXG.Point} point3 Point\r\n         * @param {JXG.Board} [board=point1.board] Reference to the board\r\n         * @returns {JXG.Coords} Coordinates of the center of the circumcircle of the given points.\r\n         */\r\n        circumcenter: function (point1, point2, point3, board) {\r\n            var u,\r\n                v,\r\n                m1,\r\n                m2,\r\n                A = point1.coords.usrCoords,\r\n                B = point2.coords.usrCoords,\r\n                C = point3.coords.usrCoords;\r\n\r\n            if (!Type.exists(board)) {\r\n                board = point1.board;\r\n            }\r\n\r\n            u = [B[0] - A[0], -B[2] + A[2], B[1] - A[1]];\r\n            v = [(A[0] + B[0]) * 0.5, (A[1] + B[1]) * 0.5, (A[2] + B[2]) * 0.5];\r\n            m1 = Mat.crossProduct(u, v);\r\n\r\n            u = [C[0] - B[0], -C[2] + B[2], C[1] - B[1]];\r\n            v = [(B[0] + C[0]) * 0.5, (B[1] + C[1]) * 0.5, (B[2] + C[2]) * 0.5];\r\n            m2 = Mat.crossProduct(u, v);\r\n\r\n            return new Coords(Const.COORDS_BY_USER, Mat.crossProduct(m1, m2), board);\r\n        },\r\n\r\n        /**\r\n         * Calculates the Euclidean distance for two given arrays of the same length.\r\n         * @param {Array} array1 Array of Number\r\n         * @param {Array} array2 Array of Number\r\n         * @param {Number} [n] Length of the arrays. Default is the minimum length of the given arrays.\r\n         * @returns {Number} Euclidean distance of the given vectors.\r\n         */\r\n        distance: function (array1, array2, n) {\r\n            var i,\r\n                sum = 0;\r\n\r\n            if (!n) {\r\n                n = Math.min(array1.length, array2.length);\r\n            }\r\n\r\n            for (i = 0; i < n; i++) {\r\n                sum += (array1[i] - array2[i]) * (array1[i] - array2[i]);\r\n            }\r\n\r\n            return Math.sqrt(sum);\r\n        },\r\n\r\n        /**\r\n         * Calculates Euclidean distance for two given arrays of the same length.\r\n         * If one of the arrays contains a zero in the first coordinate, and the Euclidean distance\r\n         * is different from zero it is a point at infinity and we return Infinity.\r\n         * @param {Array} array1 Array containing elements of type number.\r\n         * @param {Array} array2 Array containing elements of type number.\r\n         * @param {Number} [n] Length of the arrays. Default is the minimum length of the given arrays.\r\n         * @returns {Number} Euclidean (affine) distance of the given vectors.\r\n         */\r\n        affineDistance: function (array1, array2, n) {\r\n            var d;\r\n\r\n            d = this.distance(array1, array2, n);\r\n\r\n            if (\r\n                d > Mat.eps &&\r\n                (Math.abs(array1[0]) < Mat.eps || Math.abs(array2[0]) < Mat.eps)\r\n            ) {\r\n                return Infinity;\r\n            }\r\n\r\n            return d;\r\n        },\r\n\r\n        /**\r\n         * Affine ratio of three collinear points a, b, c: (c - a) / (b - a).\r\n         * If r > 1 or r < 0 then c is outside of the segment ab.\r\n         *\r\n         * @param {Array|JXG.Coords} a\r\n         * @param {Array|JXG.Coords} b\r\n         * @param {Array|JXG.Coords} c\r\n         * @returns {Number} affine ratio (c - a) / (b - a)\r\n         */\r\n        affineRatio: function (a, b, c) {\r\n            var r = 0.0,\r\n                dx;\r\n\r\n            if (Type.exists(a.usrCoords)) {\r\n                a = a.usrCoords;\r\n            }\r\n            if (Type.exists(b.usrCoords)) {\r\n                b = b.usrCoords;\r\n            }\r\n            if (Type.exists(c.usrCoords)) {\r\n                c = c.usrCoords;\r\n            }\r\n\r\n            dx = b[1] - a[1];\r\n\r\n            if (Math.abs(dx) > Mat.eps) {\r\n                r = (c[1] - a[1]) / dx;\r\n            } else {\r\n                r = (c[2] - a[2]) / (b[2] - a[2]);\r\n            }\r\n            return r;\r\n        },\r\n\r\n        /**\r\n         * Sort vertices counter clockwise starting with the first point.\r\n         * Used in Polygon.sutherlandHodgman, Geometry.signedPolygon.\r\n         *\r\n         * @param {Array} p An array containing {@link JXG.Point}, {@link JXG.Coords}, and/or arrays.\r\n         *\r\n         * @returns {Array}\r\n         */\r\n        sortVertices: function (p) {\r\n            var ll,\r\n                ps = Expect.each(p, Expect.coordsArray),\r\n                N = ps.length,\r\n                lastPoint = null;\r\n\r\n            // If the last point equals the first point, we take the last point out of the array.\r\n            // It may be that the several points at the end of the array are equal to the first point.\r\n            // The polygonal chain is been closed by JSXGraph, but this may also have been done by the user.\r\n            // Therefore, we use a while loop to pop the last points.\r\n            while (\r\n                ps[0][0] === ps[N - 1][0] &&\r\n                ps[0][1] === ps[N - 1][1] &&\r\n                ps[0][2] === ps[N - 1][2]\r\n            ) {\r\n                lastPoint = ps.pop();\r\n                N--;\r\n            }\r\n\r\n            ll = ps[0];\r\n            // Sort ps in increasing order of the angle between a point and the first point ll.\r\n            // If a point is equal to the first point ll, the angle is defined to be -Infinity.\r\n            // Otherwise, atan2 would return zero, which is a value which also attained by points\r\n            // on the same horizontal line.\r\n            ps.sort(function (a, b) {\r\n                var rad1 =\r\n                        (a[2] === ll[2] && a[1] === ll[1])\r\n                            ? -Infinity\r\n                            : Math.atan2(a[2] - ll[2], a[1] - ll[1]),\r\n                    rad2 =\r\n                        (b[2] === ll[2] && b[1] === ll[1])\r\n                            ? -Infinity\r\n                            : Math.atan2(b[2] - ll[2], b[1] - ll[1]);\r\n                return rad1 - rad2;\r\n            });\r\n\r\n            // If the last point has been taken out of the array, we put it in again.\r\n            if (lastPoint !== null) {\r\n                ps.push(lastPoint);\r\n            }\r\n\r\n            return ps;\r\n        },\r\n\r\n        /**\r\n         * Signed triangle area of the three points given. It can also be used\r\n         * to test the orientation of the triangle.\r\n         * <ul>\r\n         * <li> If the return value is < 0, then the point p2 is left of the line [p1, p3] (i.e p3 is right from [p1, p2]).\r\n         * <li> If the return value is > 0, then the point p2 is right of the line [p1, p3] (i.e p3 is left from [p1, p2]).\r\n         * <li> If the return value is = 0, then the points p1, p2, p3 are collinear.\r\n         * </ul>\r\n         *\r\n         * @param {JXG.Point|JXG.Coords|Array} p1\r\n         * @param {JXG.Point|JXG.Coords|Array} p2\r\n         * @param {JXG.Point|JXG.Coords|Array} p3\r\n         *\r\n         * @returns {Number}\r\n         */\r\n        signedTriangle: function (p1, p2, p3) {\r\n            var A = Expect.coordsArray(p1),\r\n                B = Expect.coordsArray(p2),\r\n                C = Expect.coordsArray(p3);\r\n            return 0.5 * ((B[1] - A[1]) * (C[2] - A[2]) - (B[2] - A[2]) * (C[1] - A[1]));\r\n        },\r\n\r\n        /**\r\n         * Determine the signed area of a non-self-intersecting polygon.\r\n         * Surveyor's Formula\r\n         *\r\n         * @param {Array} p An array containing {@link JXG.Point}, {@link JXG.Coords}, and/or arrays.\r\n         * @param {Boolean} [sort=true]\r\n         *\r\n         * @returns {Number}\r\n         */\r\n        signedPolygon: function (p, sort) {\r\n            var i,\r\n                N,\r\n                A = 0,\r\n                ps = Expect.each(p, Expect.coordsArray);\r\n\r\n            if (sort === undefined) {\r\n                sort = true;\r\n            }\r\n\r\n            if (!sort) {\r\n                ps = this.sortVertices(ps);\r\n            } else {\r\n                // Make sure the polygon is closed. If it is already closed this won't change the sum because the last\r\n                // summand will be 0.\r\n                ps.unshift(ps[ps.length - 1]);\r\n            }\r\n\r\n            N = ps.length;\r\n\r\n            for (i = 1; i < N; i++) {\r\n                A += ps[i - 1][1] * ps[i][2] - ps[i][1] * ps[i - 1][2];\r\n            }\r\n\r\n            return 0.5 * A;\r\n        },\r\n\r\n        /**\r\n         * Calculate the complex hull of a point cloud by the Graham scan algorithm.\r\n         *\r\n         * @param {Array} points An array containing {@link JXG.Point}, {@link JXG.Coords}, and/or arrays.\r\n         *\r\n         * @returns {Array} List of objects <pre>{i: index, c: coords}</pre> containing the convex hull points\r\n         *  in form of the index in the original input array and a coords array.\r\n         *\r\n         * @example\r\n         *     // Static example\r\n         *\r\n         *     var i, hull,\r\n         *       p = [],\r\n         *       q = [];\r\n         *\r\n         *     p.push( board.create('point', [4, 0], {withLabel:false }) );\r\n         *     p.push( board.create('point', [0, 4], {withLabel:false }) );\r\n         *     p.push( board.create('point', [0, 0], {withLabel:false }) );\r\n         *     p.push([-1, 0]);\r\n         *     p.push([-3, -3]);\r\n         *\r\n         *     hull = JXG.Math.Geometry.GrahamScan(p);\r\n         *     for (i = 0; i < hull.length; i++) {\r\n         *       console.log(hull[i]);\r\n         *       q.push(hull[i].c);\r\n         *     }\r\n         *     board.create('polygon', q);\r\n         *     // Output:\r\n         *     // { i: 4, c: [1, -3, 3]}\r\n         *     // { i: 0, c: [1, 4, 0]}\r\n         *     // { i: 1, c: [1, 0, 4]}\r\n         *\r\n         * </pre><div id=\"JXGb310b874-595e-4020-b0c2-566482797836\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGb310b874-595e-4020-b0c2-566482797836',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *         var i, hull,\r\n         *           p = [],\r\n         *           q = [];\r\n         *\r\n         *         p.push( board.create('point', [4, 0], {withLabel:false }) );\r\n         *         p.push( board.create('point', [0, 4], {withLabel:false }) );\r\n         *         p.push( board.create('point', [0, 0], {withLabel:false }) );\r\n         *         p.push([-1, 0]);\r\n         *         p.push([-3, -3]);\r\n         *\r\n         *         hull = JXG.Math.Geometry.GrahamScan(p);\r\n         *         for (i = 0; i < hull.length; i++) {\r\n         *           console.log(hull[i]);\r\n         *           q.push(hull[i].c);\r\n         *         }\r\n         *         board.create('polygon', q);\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        GrahamScan: function (points) {\r\n            var i, M, o,\r\n                mi_idx,\r\n                mi_x, mi_y, ma_x, ma_y,\r\n                mi_xpy, mi_xmy, ma_xpy, ma_xmy,\r\n                mi_x_i, ma_x_i, mi_y_i, ma_y_i,\r\n                mi_xpy_i, mi_xmy_i, ma_xpy_i, ma_xmy_i,\r\n                v, c,\r\n                eps = Mat.eps * Mat.eps,\r\n                that = this,\r\n                ps_idx = [],\r\n                stack = [],\r\n                ps = Expect.each(points, Expect.coordsArray), // New array object, i.e. a copy of the input array.\r\n                N,\r\n                AklToussaint = 1024;  // This is a rough threshold where the heuristic pays off.\r\n\r\n            N = ps.length;\r\n            if (N === 0) {\r\n                return [];\r\n            }\r\n\r\n            if (N > AklToussaint) {\r\n                //\r\n                // Akl-Toussaint heuristic\r\n                // Determine an irregular convex octagon whose inside can be discarded.\r\n                //\r\n                mi_x = ps[0][1];\r\n                ma_x = mi_x;\r\n                mi_y = ps[0][2];\r\n                ma_y = mi_y;\r\n\r\n                mi_xmy = ps[0][1] - ps[0][2];\r\n                ma_xmy = mi_xmy;\r\n                mi_xpy = ps[0][1] + ps[0][2];\r\n                ma_xpy = mi_xpy;\r\n\r\n                mi_x_i = 0;\r\n                ma_x_i = 0;\r\n                mi_y_i = 0;\r\n                ma_y_i = 0;\r\n\r\n                mi_xmy_i = 0;\r\n                ma_xmy_i = 0;\r\n                mi_xpy_i = 0;\r\n                ma_xpy_i = 0;\r\n                for (i = 1; i < N; i++) {\r\n                    v = ps[i][1];\r\n                    if (v < mi_x) {\r\n                        mi_x = v;\r\n                        mi_x_i = i;\r\n                    } else if (v > ma_x) {\r\n                        ma_x = v;\r\n                        ma_x_i = i;\r\n                    }\r\n\r\n                    v = ps[i][2];\r\n                    if (v < mi_y) {\r\n                        mi_y = v;\r\n                        mi_y_i = i;\r\n                    } else if (v > ma_y) {\r\n                        ma_y = v;\r\n                        ma_y_i = i;\r\n                    }\r\n\r\n                    v = ps[i][1] - ps[i][2];\r\n                    if (v < mi_xmy) {\r\n                        mi_xmy = v;\r\n                        mi_xmy_i = i;\r\n                    } else if (v > ma_xmy) {\r\n                        ma_xmy = v;\r\n                        ma_xmy_i = i;\r\n                    }\r\n\r\n                    v = ps[i][1] + ps[i][2];\r\n                    if (v < mi_xpy) {\r\n                        mi_xpy = v;\r\n                        mi_xpy_i = i;\r\n                    } else if (v > ma_xpy) {\r\n                        ma_xpy = v;\r\n                        ma_xpy_i = i;\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Keep track of the indices of the input points.\r\n            for (i = 0; i < N; i++) {\r\n                c = ps[i];\r\n                if (N <= AklToussaint ||\r\n                    // Discard inside of the octagon according to the Akl-Toussaint heuristic\r\n                    i in [mi_x_i, ma_x_i, mi_y_i, ma_y_i, mi_xpy_i, mi_xmy_i, ma_xpy_i, ma_xmy_i] ||\r\n                    (mi_x_i !== mi_xmy_i && this.signedTriangle(ps[mi_x_i], ps[mi_xmy_i], c) >= -eps) ||\r\n                    (mi_xmy_i !== ma_y_i && this.signedTriangle(ps[mi_xmy_i], ps[ma_y_i], c) >= -eps) ||\r\n                    (ma_y_i !== ma_xpy_i && this.signedTriangle(ps[ma_y_i], ps[ma_xpy_i], c) >= -eps) ||\r\n                    (ma_xpy_i !== ma_x_i && this.signedTriangle(ps[ma_xpy_i], ps[ma_x_i], c) >= -eps) ||\r\n                    (ma_x_i !== ma_xmy_i && this.signedTriangle(ps[ma_x_i], ps[ma_xmy_i], c) >= -eps) ||\r\n                    (ma_xmy_i !== mi_y_i && this.signedTriangle(ps[ma_xmy_i], ps[mi_y_i], c) >= -eps) ||\r\n                    (mi_y_i !== mi_xpy_i && this.signedTriangle(ps[mi_y_i], ps[mi_xpy_i], c) >= -eps) ||\r\n                    (mi_xpy_i !== mi_x_i && this.signedTriangle(ps[mi_xpy_i], ps[mi_x_i], c) >= -eps)\r\n                ) {\r\n                    ps_idx.push({\r\n                        i: i,\r\n                        c: c\r\n                    });\r\n                }\r\n            }\r\n            N = ps_idx.length;\r\n\r\n            // Find the point with the lowest y value\r\n            mi_idx = 0;\r\n            mi_x = ps_idx[0].c[1];\r\n            mi_y = ps_idx[0].c[2];\r\n            for (i = 1; i < N; i++) {\r\n                if ((ps_idx[i].c[2] < mi_y) || (ps_idx[i].c[2] === mi_y && ps_idx[i].c[1] < mi_x)) {\r\n                    mi_x = ps_idx[i].c[1];\r\n                    mi_y = ps_idx[i].c[2];\r\n                    mi_idx = i;\r\n                }\r\n            }\r\n            ps_idx = Type.swap(ps_idx, mi_idx, 0);\r\n\r\n            // Our origin o, i.e. the first point.\r\n            o = ps_idx[0].c;\r\n\r\n            // Sort according to the angle around o.\r\n            ps_idx.sort(function(a_obj, b_obj) {\r\n                var a = a_obj.c,\r\n                    b = b_obj.c,\r\n                    v = that.signedTriangle(o, a, b);\r\n\r\n                if (v === 0) {\r\n                    // if o, a, b are collinear, the point which is further away\r\n                    // from o is considered greater.\r\n                    return Mat.hypot(a[1] - o[1], a[2] - o[2]) - Mat.hypot(b[1] - o[1], b[2] - o[2]);\r\n                }\r\n\r\n                // if v < 0, a is to the left of [o, b], i.e. angle(a) > angle(b)\r\n                return -v;\r\n            });\r\n\r\n            // Do the Graham scan.\r\n            M = 0;\r\n            for (i = 0; i < N; i++) {\r\n                while (M > 1 && this.signedTriangle(stack[M - 2].c, stack[M - 1].c, ps_idx[i].c) <= 0) {\r\n                    // stack[M - 1] is to the left of stack[M - 1], ps[i]: discard it\r\n                    stack.pop();\r\n                    M--;\r\n                }\r\n                stack.push(ps_idx[i]);\r\n                M++;\r\n            }\r\n\r\n            return stack;\r\n        },\r\n\r\n        // Original method\r\n        // GrahamScan: function (points, indices) {\r\n        //     var i,\r\n        //         M = 1,\r\n        //         ps = Expect.each(points, Expect.coordsArray),\r\n        //         N = ps.length;\r\n        //     ps = this.sortVertices(ps);\r\n        //     N = ps.length;\r\n        //     for (i = 2; i < N; i++) {\r\n        //         while (this.signedTriangle(ps[M - 1], ps[M], ps[i]) <= 0) {\r\n        //             if (M > 1) {\r\n        //                 M -= 1;\r\n        //             } else if (i === N - 1) {\r\n        //                 break;\r\n        //             }\r\n        //             i += 1;\r\n        //         }\r\n        //         M += 1;\r\n        //         ps = Type.swap(ps, M, i);\r\n        //         indices = Type.swap(indices, M, i);\r\n        //     }\r\n        //     return ps.slice(0, M);\r\n        // },\r\n\r\n        /**\r\n         * Calculate the complex hull of a point cloud by the Graham scan algorithm.\r\n         *\r\n         * @param {Array} points An array containing {@link JXG.Point}, {@link JXG.Coords}, and/or arrays.\r\n         * @param {Boolean} [returnCoords=false] If true, return an array of coords. Otherwise return a list of pointers\r\n         * to the input list elements. That is, if the input is a list of {@link JXG.Point} elements, the returned list\r\n         * will contain the points that form the convex hull.\r\n         * @returns {Array} List containing the convex hull. Format depends on returnCoords.\r\n         * @see JXG.Math.Geometry.GrahamScan\r\n         *\r\n         * @example\r\n         *     // Static example\r\n         *     var i, hull,\r\n         *         p = [];\r\n         *\r\n         *     p.push( board.create('point', [4, 0], {withLabel:false }) );\r\n         *     p.push( board.create('point', [0, 4], {withLabel:false }) );\r\n         *     p.push( board.create('point', [0, 0], {withLabel:false }) );\r\n         *     p.push( board.create('point', [1, 1], {withLabel:false }) );\r\n         *     hull = JXG.Math.Geometry.convexHull(p);\r\n         *     for (i = 0; i < hull.length; i++) {\r\n         *       hull[i].setAttribute({color: 'blue'});\r\n         *     }\r\n         *\r\n         * </pre><div id=\"JXGdfc76123-81b8-4250-96f9-419253bd95dd\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGdfc76123-81b8-4250-96f9-419253bd95dd',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *         var i, hull,\r\n         *             p = [];\r\n         *\r\n         *         p.push( board.create('point', [4, 0], {withLabel:false }) );\r\n         *         p.push( board.create('point', [0, 4], {withLabel:false }) );\r\n         *         p.push( board.create('point', [0, 0], {withLabel:false }) );\r\n         *         p.push( board.create('point', [1, 1], {withLabel:false }) );\r\n         *         hull = JXG.Math.Geometry.convexHull(p);\r\n         *         for (i = 0; i < hull.length; i++) {\r\n         *           hull[i].setAttribute({color: 'blue'});\r\n         *         }\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         *     // Dynamic version using returnCoords==true: drag the points\r\n         *     var p = [];\r\n         *\r\n         *     p.push( board.create('point', [4, 0], {withLabel:false }) );\r\n         *     p.push( board.create('point', [0, 4], {withLabel:false }) );\r\n         *     p.push( board.create('point', [0, 0], {withLabel:false }) );\r\n         *     p.push( board.create('point', [1, 1], {withLabel:false }) );\r\n         *\r\n         *     var c = board.create('curve', [[], []], {fillColor: 'yellow', fillOpacity: 0.3});\r\n         *     c.updateDataArray = function() {\r\n         *       var i,\r\n         *         hull = JXG.Math.Geometry.convexHull(p, true);\r\n         *\r\n         *       this.dataX = [];\r\n         *       this.dataY = [];\r\n         *\r\n         *       for (i = 0; i < hull.length; i ++) {\r\n         *         this.dataX.push(hull[i][1]);\r\n         *         this.dataY.push(hull[i][2]);\r\n         *       }\r\n         *       this.dataX.push(hull[0][1]);\r\n         *       this.dataY.push(hull[0][2]);\r\n         *     };\r\n         *     board.update();\r\n         *\r\n         * </pre><div id=\"JXG61e51909-da0b-432f-9aa7-9fb0c8bb01c9\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG61e51909-da0b-432f-9aa7-9fb0c8bb01c9',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *         var p = [];\r\n         *\r\n         *         p.push( board.create('point', [4, 0], {withLabel:false }) );\r\n         *         p.push( board.create('point', [0, 4], {withLabel:false }) );\r\n         *         p.push( board.create('point', [0, 0], {withLabel:false }) );\r\n         *         p.push( board.create('point', [1, 1], {withLabel:false }) );\r\n         *\r\n         *         var c = board.create('curve', [[], []], {fillColor: 'yellow', fillOpacity: 0.3});\r\n         *         c.updateDataArray = function() {\r\n         *           var i,\r\n         *             hull = JXG.Math.Geometry.convexHull(p, true);\r\n         *\r\n         *           this.dataX = [];\r\n         *           this.dataY = [];\r\n         *\r\n         *           for (i = 0; i < hull.length; i ++) {\r\n         *             this.dataX.push(hull[i][1]);\r\n         *             this.dataY.push(hull[i][2]);\r\n         *           }\r\n         *           this.dataX.push(hull[0][1]);\r\n         *           this.dataY.push(hull[0][2]);\r\n         *         };\r\n         *         board.update();\r\n         *\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        convexHull: function(points, returnCoords) {\r\n            var i, hull,\r\n                res = [];\r\n\r\n            hull = this.GrahamScan(points);\r\n            for (i = 0; i < hull.length; i++) {\r\n                if (returnCoords) {\r\n                    res.push(hull[i].c);\r\n                } else {\r\n                    res.push(points[hull[i].i]);\r\n                }\r\n            }\r\n            return res;\r\n        },\r\n\r\n        // /**\r\n        //  * Determine if a polygon or a path element is convex, non-convex or complex which are defined like this:\r\n        //  * <ul>\r\n        //  * <li> A polygon is convex if for every pair of points, the line segment connecting them does not intersect\r\n        //  * an edge of the polygon in one point.\r\n        //  * A single line segment or a a single point is considered as convex. A necessary condition for a polygon\r\n        //  * to be convex that the angle sum of its interior angles equals &plusmn; 2 &pi;.\r\n        //  * <li> A polygon is non-convex, if it does not self-intersect, but is not convex.\r\n        //  * <li> A polygon is complex if its the angle sum is not equal to &plusmn; 2 &pi;.\r\n        //  * That is, there must be self-intersection (contiguous coincident points in the path are not treated as self-intersection).\r\n        //  * </ul>\r\n        //  * A path  element might be specified as an array of coordinate arrays or {@link JXG.Coords}.\r\n        //  *\r\n        //  * @param {Array|Polygon|PolygonalChain} points Polygon or list of coordinates\r\n        //  * @returns {Number} -1: if complex, 0: if non-convex, 1: if convex\r\n        //  */\r\n        /**\r\n         * Determine if a polygon or a path element is convex:\r\n         * <p>\r\n         * A polygon is convex if for every pair of points, the line segment connecting them does not intersect\r\n         * an edge of the polygon in one point.\r\n         * A single line segment, a single point, or the empty set is considered as convex. A necessary condition for a polygon\r\n         * to be convex that the angle sum of its interior angles equals &plusmn; 2 &pi;.\r\n         * <p>\r\n         * A path  element might be specified as an array of coordinate arrays or {@link JXG.Coords}.\r\n         * See the discussion at <a href=\"https://stackoverflow.com/questions/471962/how-do-i-efficiently-determine-if-a-polygon-is-convex-non-convex-or-complex\">stackoverflow</a>.\r\n         *\r\n         * @param {Array|Polygon|PolygonalChain} points Polygon or list of coordinates\r\n         * @returns {Boolean} true if convex\r\n         *\r\n         * @example\r\n         * var pol = board.create('polygon', [\r\n         *     [-1, -1],\r\n         *     [3, -1],\r\n         *     [4, 2],\r\n         *     [3, 3],\r\n         *     [0, 4],\r\n         *     [-3, 1]\r\n         * ], {\r\n         *     vertices: {\r\n         *         color: 'blue',\r\n         *         snapToGrid: true\r\n         *     }\r\n         * });\r\n         *\r\n         * console.log(JXG.Math.Geometry.isConvex(pol));\r\n         * // > true\r\n         *\r\n         *\r\n         *\r\n         * </pre><div id=\"JXG9b43cc53-15b4-49be-92cc-2a1dfc06665b\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG9b43cc53-15b4-49be-92cc-2a1dfc06665b',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var pol = board.create('polygon', [\r\n         *         [-1, -1],\r\n         *         [3, -1],\r\n         *         [4, 2],\r\n         *         [3, 3],\r\n         *         [0, 4],\r\n         *         [-3, 1]\r\n         *     ], {\r\n         *         vertices: {\r\n         *             color: 'blue',\r\n         *             snapToGrid: true\r\n         *         }\r\n         *     });\r\n         *\r\n         *     console.log(JXG.Math.Geometry.isConvex(pol));\r\n         *\r\n         *\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        isConvex: function(points) {\r\n            var ps, le, i,\r\n                eps = Mat.eps * Mat.eps,\r\n                old_x, old_y, old_dir,\r\n                new_x, new_y, new_dir,\r\n                angle,\r\n                orient,\r\n                angle_sum = 0.0;\r\n\r\n            if (Type.isArray(points)) {\r\n                ps = Expect.each(points, Expect.coordsArray);\r\n            } else if (Type.exists(points.type) && points.type === Const.OBJECT_TYPE_POLYGON) {\r\n                ps = Expect.each(points.vertices, Expect.coordsArray);\r\n            }\r\n            le = ps.length;\r\n            if (le === 0) {\r\n                // Empty set is convex\r\n                return true;\r\n            }\r\n            if (le < 3) {\r\n                // Segments and points are convex\r\n                return true;\r\n            }\r\n\r\n            orient = null;\r\n            old_x = ps[le - 2][1];\r\n            old_y = ps[le - 2][2];\r\n            new_x = ps[le - 1][1];\r\n            new_y = ps[le - 1][2];\r\n            new_dir = Math.atan2(new_y - old_y, new_x - old_x);\r\n            for (i = 0; i < le; i++) {\r\n                old_x = new_x;\r\n                old_y = new_y;\r\n                old_dir = new_dir;\r\n                new_x = ps[i][1];\r\n                new_y = ps[i][2];\r\n                if (old_x === new_x && old_y === new_y) {\r\n                    // Repeated consecutive points are ignored\r\n                    continue;\r\n                }\r\n                new_dir = Math.atan2(new_y - old_y, new_x - old_x);\r\n                angle = new_dir - old_dir;\r\n                if (angle <= -Math.PI) {\r\n                    angle += 2 * Math.PI;\r\n                } else if (angle > Math.PI) {\r\n                    angle -= 2 * Math.PI;\r\n                }\r\n                if (orient === null) {\r\n                    if (angle === 0.0) {\r\n                        continue;\r\n                    }\r\n                    orient = (angle > 0) ? 1 : -1;\r\n                } else {\r\n                    if (orient * angle < -eps) {\r\n                        return false;\r\n                    }\r\n                }\r\n                angle_sum += angle;\r\n            }\r\n\r\n            if ((Math.abs(angle_sum / (2 * Math.PI)) - 1) < eps) {\r\n                return true;\r\n            }\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * A line can be a segment, a straight, or a ray. So it is not always delimited by point1 and point2\r\n         * calcStraight determines the visual start point and end point of the line. A segment is only drawn\r\n         * from start to end point, a straight line is drawn until it meets the boards boundaries.\r\n         * @param {JXG.Line} el Reference to a line object, that needs calculation of start and end point.\r\n         * @param {JXG.Coords} point1 Coordinates of the point where line drawing begins. This value is calculated and\r\n         * set by this method.\r\n         * @param {JXG.Coords} point2 Coordinates of the point where line drawing ends. This value is calculated and set\r\n         * by this method.\r\n         * @param {Number} margin Optional margin, to avoid the display of the small sides of lines.\r\n         * @returns null\r\n         * @see Line\r\n         * @see JXG.Line\r\n         */\r\n        calcStraight: function (el, point1, point2, margin) {\r\n            var takePoint1,\r\n                takePoint2,\r\n                intersection,\r\n                intersect1,\r\n                intersect2,\r\n                straightFirst,\r\n                straightLast,\r\n                c, p1, p2;\r\n\r\n            if (!Type.exists(margin)) {\r\n                // Enlarge the drawable region slightly. This hides the small sides\r\n                // of thick lines in most cases.\r\n                margin = 10;\r\n            }\r\n\r\n            straightFirst = el.evalVisProp('straightfirst');\r\n            straightLast = el.evalVisProp('straightlast');\r\n\r\n            // If one of the point is an ideal point in homogeneous coordinates\r\n            // drawing of line segments or rays are not possible.\r\n            if (Math.abs(point1.scrCoords[0]) < Mat.eps) {\r\n                straightFirst = true;\r\n            }\r\n            if (Math.abs(point2.scrCoords[0]) < Mat.eps) {\r\n                straightLast = true;\r\n            }\r\n\r\n            // Do nothing in case of line segments (inside or outside of the board)\r\n            if (!straightFirst && !straightLast) {\r\n                return;\r\n            }\r\n\r\n            // Compute the stdform of the line in screen coordinates.\r\n            c = [];\r\n            c[0] =\r\n                el.stdform[0] -\r\n                (el.stdform[1] * el.board.origin.scrCoords[1]) / el.board.unitX +\r\n                (el.stdform[2] * el.board.origin.scrCoords[2]) / el.board.unitY;\r\n            c[1] = el.stdform[1] / el.board.unitX;\r\n            c[2] = -el.stdform[2] / el.board.unitY;\r\n\r\n            // If p1=p2\r\n            if (isNaN(c[0] + c[1] + c[2])) {\r\n                return;\r\n            }\r\n\r\n            takePoint1 = false;\r\n            takePoint2 = false;\r\n\r\n            // Line starts at point1 and point1 is inside the board\r\n            takePoint1 =\r\n                !straightFirst &&\r\n                Math.abs(point1.usrCoords[0]) >= Mat.eps &&\r\n                point1.scrCoords[1] >= 0.0 &&\r\n                point1.scrCoords[1] <= el.board.canvasWidth &&\r\n                point1.scrCoords[2] >= 0.0 &&\r\n                point1.scrCoords[2] <= el.board.canvasHeight;\r\n\r\n            // Line ends at point2 and point2 is inside the board\r\n            takePoint2 =\r\n                !straightLast &&\r\n                Math.abs(point2.usrCoords[0]) >= Mat.eps &&\r\n                point2.scrCoords[1] >= 0.0 &&\r\n                point2.scrCoords[1] <= el.board.canvasWidth &&\r\n                point2.scrCoords[2] >= 0.0 &&\r\n                point2.scrCoords[2] <= el.board.canvasHeight;\r\n\r\n            // Intersect the line with the four borders of the board.\r\n            intersection = this.meetLineBoard(c, el.board, margin);\r\n            intersect1 = intersection[0];\r\n            intersect2 = intersection[1];\r\n\r\n            /**\r\n             * At this point we have four points:\r\n             * point1 and point2 are the first and the second defining point on the line,\r\n             * intersect1, intersect2 are the intersections of the line with border around the board.\r\n             */\r\n\r\n            /*\r\n             * Here we handle rays where both defining points are outside of the board.\r\n             */\r\n            // If both points are outside and the complete ray is outside we do nothing\r\n            if (!takePoint1 && !takePoint2) {\r\n                // Ray starting at point 1\r\n                if (\r\n                    !straightFirst &&\r\n                    straightLast &&\r\n                    !this.isSameDirection(point1, point2, intersect1) &&\r\n                    !this.isSameDirection(point1, point2, intersect2)\r\n                ) {\r\n                    return;\r\n                }\r\n\r\n                // Ray starting at point 2\r\n                if (\r\n                    straightFirst &&\r\n                    !straightLast &&\r\n                    !this.isSameDirection(point2, point1, intersect1) &&\r\n                    !this.isSameDirection(point2, point1, intersect2)\r\n                ) {\r\n                    return;\r\n                }\r\n            }\r\n\r\n            /*\r\n             * If at least one of the defining points is outside of the board\r\n             * we take intersect1 or intersect2 as one of the end points\r\n             * The order is also important for arrows of axes\r\n             */\r\n            if (!takePoint1) {\r\n                if (!takePoint2) {\r\n                    // Two border intersection points are used\r\n                    if (this.isSameDir(point1, point2, intersect1, intersect2)) {\r\n                        p1 = intersect1;\r\n                        p2 = intersect2;\r\n                    } else {\r\n                        p2 = intersect1;\r\n                        p1 = intersect2;\r\n                    }\r\n                } else {\r\n                    // One border intersection points is used\r\n                    if (this.isSameDir(point1, point2, intersect1, intersect2)) {\r\n                        p1 = intersect1;\r\n                    } else {\r\n                        p1 = intersect2;\r\n                    }\r\n                }\r\n            } else {\r\n                if (!takePoint2) {\r\n                    // One border intersection points is used\r\n                    if (this.isSameDir(point1, point2, intersect1, intersect2)) {\r\n                        p2 = intersect2;\r\n                    } else {\r\n                        p2 = intersect1;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (p1) {\r\n                //point1.setCoordinates(Const.COORDS_BY_USER, p1.usrCoords.slice(1));\r\n                point1.setCoordinates(Const.COORDS_BY_USER, p1.usrCoords);\r\n            }\r\n\r\n            if (p2) {\r\n                //point2.setCoordinates(Const.COORDS_BY_USER, p2.usrCoords.slice(1));\r\n                point2.setCoordinates(Const.COORDS_BY_USER, p2.usrCoords);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * A line can be a segment, a straight, or a ray. so it is not always delimited by point1 and point2.\r\n         *\r\n         * This method adjusts the line's delimiting points taking into account its nature, the viewport defined\r\n         * by the board.\r\n         *\r\n         * A segment is delimited by start and end point, a straight line or ray is delimited until it meets the\r\n         * boards boundaries. However, if the line has infinite ticks, it will be delimited by the projection of\r\n         * the boards vertices onto itself.\r\n         *\r\n         * @param {JXG.Line} el Reference to a line object, that needs calculation of start and end point.\r\n         * @param {JXG.Coords} point1 Coordinates of the point where line drawing begins. This value is calculated and\r\n         * set by this method.\r\n         * @param {JXG.Coords} point2 Coordinates of the point where line drawing ends. This value is calculated and set\r\n         * by this method.\r\n         * @see Line\r\n         * @see JXG.Line\r\n         */\r\n        calcLineDelimitingPoints: function (el, point1, point2) {\r\n            var distP1P2,\r\n                boundingBox,\r\n                lineSlope,\r\n                intersect1,\r\n                intersect2,\r\n                straightFirst,\r\n                straightLast,\r\n                c,\r\n                p1,\r\n                p2,\r\n                takePoint1 = false,\r\n                takePoint2 = false;\r\n\r\n            straightFirst = el.evalVisProp('straightfirst');\r\n            straightLast = el.evalVisProp('straightlast');\r\n\r\n            // If one of the point is an ideal point in homogeneous coordinates\r\n            // drawing of line segments or rays are not possible.\r\n            if (Math.abs(point1.scrCoords[0]) < Mat.eps) {\r\n                straightFirst = true;\r\n            }\r\n            if (Math.abs(point2.scrCoords[0]) < Mat.eps) {\r\n                straightLast = true;\r\n            }\r\n\r\n            // Compute the stdform of the line in screen coordinates.\r\n            c = [];\r\n            c[0] =\r\n                el.stdform[0] -\r\n                (el.stdform[1] * el.board.origin.scrCoords[1]) / el.board.unitX +\r\n                (el.stdform[2] * el.board.origin.scrCoords[2]) / el.board.unitY;\r\n            c[1] = el.stdform[1] / el.board.unitX;\r\n            c[2] = -el.stdform[2] / el.board.unitY;\r\n\r\n            // p1=p2\r\n            if (isNaN(c[0] + c[1] + c[2])) {\r\n                return;\r\n            }\r\n\r\n            takePoint1 = !straightFirst;\r\n            takePoint2 = !straightLast;\r\n            // Intersect the board vertices on the line to establish the available visual space for the infinite ticks\r\n            // Based on the slope of the line we can optimise and only project the two outer vertices\r\n\r\n            // boundingBox = [x1, y1, x2, y2] upper left, lower right vertices\r\n            boundingBox = el.board.getBoundingBox();\r\n            lineSlope = el.getSlope();\r\n            if (lineSlope >= 0) {\r\n                // project vertices (x2,y1) (x1, y2)\r\n                intersect1 = this.projectPointToLine(\r\n                    { coords: { usrCoords: [1, boundingBox[2], boundingBox[1]] } },\r\n                    el,\r\n                    el.board\r\n                );\r\n                intersect2 = this.projectPointToLine(\r\n                    { coords: { usrCoords: [1, boundingBox[0], boundingBox[3]] } },\r\n                    el,\r\n                    el.board\r\n                );\r\n            } else {\r\n                // project vertices (x1, y1) (x2, y2)\r\n                intersect1 = this.projectPointToLine(\r\n                    { coords: { usrCoords: [1, boundingBox[0], boundingBox[1]] } },\r\n                    el,\r\n                    el.board\r\n                );\r\n                intersect2 = this.projectPointToLine(\r\n                    { coords: { usrCoords: [1, boundingBox[2], boundingBox[3]] } },\r\n                    el,\r\n                    el.board\r\n                );\r\n            }\r\n\r\n            /**\r\n             * we have four points:\r\n             * point1 and point2 are the first and the second defining point on the line,\r\n             * intersect1, intersect2 are the intersections of the line with border around the board.\r\n             */\r\n\r\n            /*\r\n             * Here we handle rays/segments where both defining points are outside of the board.\r\n             */\r\n            if (!takePoint1 && !takePoint2) {\r\n                // Segment, if segment does not cross the board, do nothing\r\n                if (!straightFirst && !straightLast) {\r\n                    distP1P2 = point1.distance(Const.COORDS_BY_USER, point2);\r\n                    // if  intersect1 not between point1 and point2\r\n                    if (\r\n                        Math.abs(\r\n                            point1.distance(Const.COORDS_BY_USER, intersect1) +\r\n                            intersect1.distance(Const.COORDS_BY_USER, point2) -\r\n                            distP1P2\r\n                        ) > Mat.eps\r\n                    ) {\r\n                        return;\r\n                    }\r\n                    // if insersect2 not between point1 and point2\r\n                    if (\r\n                        Math.abs(\r\n                            point1.distance(Const.COORDS_BY_USER, intersect2) +\r\n                            intersect2.distance(Const.COORDS_BY_USER, point2) -\r\n                            distP1P2\r\n                        ) > Mat.eps\r\n                    ) {\r\n                        return;\r\n                    }\r\n                }\r\n\r\n                // If both points are outside and the complete ray is outside we do nothing\r\n                // Ray starting at point 1\r\n                if (\r\n                    !straightFirst &&\r\n                    straightLast &&\r\n                    !this.isSameDirection(point1, point2, intersect1) &&\r\n                    !this.isSameDirection(point1, point2, intersect2)\r\n                ) {\r\n                    return;\r\n                }\r\n\r\n                // Ray starting at point 2\r\n                if (\r\n                    straightFirst &&\r\n                    !straightLast &&\r\n                    !this.isSameDirection(point2, point1, intersect1) &&\r\n                    !this.isSameDirection(point2, point1, intersect2)\r\n                ) {\r\n                    return;\r\n                }\r\n            }\r\n\r\n            /*\r\n             * If at least one of the defining points is outside of the board\r\n             * we take intersect1 or intersect2 as one of the end points\r\n             * The order is also important for arrows of axes\r\n             */\r\n            if (!takePoint1) {\r\n                if (!takePoint2) {\r\n                    // Two border intersection points are used\r\n                    if (this.isSameDir(point1, point2, intersect1, intersect2)) {\r\n                        p1 = intersect1;\r\n                        p2 = intersect2;\r\n                    } else {\r\n                        p2 = intersect1;\r\n                        p1 = intersect2;\r\n                    }\r\n                } else {\r\n                    // One border intersection points is used\r\n                    if (this.isSameDir(point1, point2, intersect1, intersect2)) {\r\n                        p1 = intersect1;\r\n                    } else {\r\n                        p1 = intersect2;\r\n                    }\r\n                }\r\n            } else {\r\n                if (!takePoint2) {\r\n                    // One border intersection points is used\r\n                    if (this.isSameDir(point1, point2, intersect1, intersect2)) {\r\n                        p2 = intersect2;\r\n                    } else {\r\n                        p2 = intersect1;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (p1) {\r\n                //point1.setCoordinates(Const.COORDS_BY_USER, p1.usrCoords.slice(1));\r\n                point1.setCoordinates(Const.COORDS_BY_USER, p1.usrCoords);\r\n            }\r\n\r\n            if (p2) {\r\n                //point2.setCoordinates(Const.COORDS_BY_USER, p2.usrCoords.slice(1));\r\n                point2.setCoordinates(Const.COORDS_BY_USER, p2.usrCoords);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Calculates the visProp.position corresponding to a given angle.\r\n         * @param {number} angle angle in radians. Must be in range (-2pi,2pi).\r\n         */\r\n        calcLabelQuadrant: function (angle) {\r\n            var q;\r\n            if (angle < 0) {\r\n                angle += 2 * Math.PI;\r\n            }\r\n            q = Math.floor((angle + Math.PI / 8) / (Math.PI / 4)) % 8;\r\n            return [\"rt\", \"urt\", \"top\", \"ulft\", \"lft\", \"llft\", \"lrt\"][q];\r\n        },\r\n\r\n        /**\r\n         * The vectors <tt>p2-p1</tt> and <tt>i2-i1</tt> are supposed to be collinear. If their cosine is positive\r\n         * they point into the same direction otherwise they point in opposite direction.\r\n         * @param {JXG.Coords} p1\r\n         * @param {JXG.Coords} p2\r\n         * @param {JXG.Coords} i1\r\n         * @param {JXG.Coords} i2\r\n         * @returns {Boolean} True, if <tt>p2-p1</tt> and <tt>i2-i1</tt> point into the same direction\r\n         */\r\n        isSameDir: function (p1, p2, i1, i2) {\r\n            var dpx = p2.usrCoords[1] - p1.usrCoords[1],\r\n                dpy = p2.usrCoords[2] - p1.usrCoords[2],\r\n                dix = i2.usrCoords[1] - i1.usrCoords[1],\r\n                diy = i2.usrCoords[2] - i1.usrCoords[2];\r\n\r\n            if (Math.abs(p2.usrCoords[0]) < Mat.eps) {\r\n                dpx = p2.usrCoords[1];\r\n                dpy = p2.usrCoords[2];\r\n            }\r\n\r\n            if (Math.abs(p1.usrCoords[0]) < Mat.eps) {\r\n                dpx = -p1.usrCoords[1];\r\n                dpy = -p1.usrCoords[2];\r\n            }\r\n\r\n            return dpx * dix + dpy * diy >= 0;\r\n        },\r\n\r\n        /**\r\n         * If you're looking from point \"start\" towards point \"s\" and you can see the point \"p\", return true.\r\n         * Otherwise return false.\r\n         * @param {JXG.Coords} start The point you're standing on.\r\n         * @param {JXG.Coords} p The point in which direction you're looking.\r\n         * @param {JXG.Coords} s The point that should be visible.\r\n         * @returns {Boolean} True, if from start the point p is in the same direction as s is, that means s-start = k*(p-start) with k>=0.\r\n         */\r\n        isSameDirection: function (start, p, s) {\r\n            var dx,\r\n                dy,\r\n                sx,\r\n                sy,\r\n                r = false;\r\n\r\n            dx = p.usrCoords[1] - start.usrCoords[1];\r\n            dy = p.usrCoords[2] - start.usrCoords[2];\r\n\r\n            sx = s.usrCoords[1] - start.usrCoords[1];\r\n            sy = s.usrCoords[2] - start.usrCoords[2];\r\n\r\n            if (Math.abs(dx) < Mat.eps) {\r\n                dx = 0;\r\n            }\r\n\r\n            if (Math.abs(dy) < Mat.eps) {\r\n                dy = 0;\r\n            }\r\n\r\n            if (Math.abs(sx) < Mat.eps) {\r\n                sx = 0;\r\n            }\r\n\r\n            if (Math.abs(sy) < Mat.eps) {\r\n                sy = 0;\r\n            }\r\n\r\n            if (dx >= 0 && sx >= 0) {\r\n                r = (dy >= 0 && sy >= 0) || (dy <= 0 && sy <= 0);\r\n            } else if (dx <= 0 && sx <= 0) {\r\n                r = (dy >= 0 && sy >= 0) || (dy <= 0 && sy <= 0);\r\n            }\r\n\r\n            return r;\r\n        },\r\n\r\n        /**\r\n         * Determinant of three points in the Euclidean plane.\r\n         * Zero, if the points are collinear. Used to determine of a point q is left or\r\n         * right to a segment defined by points p1 and p2.\r\n         * <p>\r\n         * Non-homogeneous version.\r\n         *\r\n         * @param  {Array|JXG.Point} p1 First point or its coordinates of the segment. Point object or array of length 3. First (homogeneous) coordinate is equal to 1.\r\n         * @param  {Array|JXG.Point} p2 Second point or its coordinates of the segment. Point object or array of length 3. First (homogeneous) coordinate is equal to 1.\r\n         * @param  {Array|JXG.Point} q Point or its coordinates. Point object or array of length 3. First (homogeneous) coordinate is equal to 1.\r\n         * @return {Number} Signed area of the triangle formed by these three points.\r\n         *\r\n         * @see JXG.Math.Geometry.windingNumber\r\n         */\r\n        det3p: function (p1, p2, q) {\r\n            var pp1, pp2, qq;\r\n\r\n            if (Type.isPoint(p1)) {\r\n                pp1 = p1.Coords(true);\r\n            } else {\r\n                pp1 = p1;\r\n            }\r\n            if (Type.isPoint(p2)) {\r\n                pp2 = p2.Coords(true);\r\n            } else {\r\n                pp2 = p2;\r\n            }\r\n            if (Type.isPoint(q)) {\r\n                qq = q.Coords(true);\r\n            } else {\r\n                qq = q;\r\n            }\r\n\r\n            return (pp1[1] - qq[1]) * (pp2[2] - qq[2]) - (pp2[1] - qq[1]) * (pp1[2] - qq[2]);\r\n        },\r\n\r\n        /**\r\n         * Winding number of a point in respect to a polygon path.\r\n         *\r\n         * The point is regarded outside if the winding number is zero,\r\n         * inside otherwise. The algorithm tries to find degenerate cases, i.e.\r\n         * if the point is on the path. This is regarded as \"outside\".\r\n         * If the point is a vertex of the path, it is regarded as \"inside\".\r\n         *\r\n         * Implementation of algorithm 7 from \"The point in polygon problem for\r\n         * arbitrary polygons\" by Kai Hormann and Alexander Agathos, Computational Geometry,\r\n         * Volume 20, Issue 3, November 2001, Pages 131-144.\r\n         *\r\n         * @param  {Array} usrCoords Homogenous coordinates of the point\r\n         * @param  {Array} path      Array of points / coords determining a path, i.e. the vertices of the polygon / path. The array elements\r\n         * do not have to be full points, but have to have a subobject \"coords\" or should be of type JXG.Coords.\r\n         * @param  {Boolean} [doNotClosePath=false] If true the last point of the path is not connected to the first point.\r\n         * This is necessary if the path consists of two or more closed subpaths, e.g. if the figure has a hole.\r\n         *\r\n         * @return {Number}          Winding number of the point. The point is\r\n         *                           regarded outside if the winding number is zero,\r\n         *                           inside otherwise.\r\n         */\r\n        windingNumber: function (usrCoords, path, doNotClosePath) {\r\n            var wn = 0,\r\n                le = path.length,\r\n                x = usrCoords[1],\r\n                y = usrCoords[2],\r\n                p0,\r\n                p1,\r\n                p2,\r\n                d,\r\n                sign,\r\n                i,\r\n                off = 0;\r\n\r\n            if (le === 0) {\r\n                return 0;\r\n            }\r\n\r\n            doNotClosePath = doNotClosePath || false;\r\n            if (doNotClosePath) {\r\n                off = 1;\r\n            }\r\n\r\n            // Infinite points are declared outside\r\n            if (isNaN(x) || isNaN(y)) {\r\n                return 1;\r\n            }\r\n\r\n            if (Type.exists(path[0].coords)) {\r\n                p0 = path[0].coords;\r\n                p1 = path[le - 1].coords;\r\n            } else {\r\n                p0 = path[0];\r\n                p1 = path[le - 1];\r\n            }\r\n            // Handle the case if the point is the first vertex of the path, i.e. inside.\r\n            if (p0.usrCoords[1] === x && p0.usrCoords[2] === y) {\r\n                return 1;\r\n            }\r\n\r\n            for (i = 0; i < le - off; i++) {\r\n                // Consider the edge from p1 = path[i] to p2 = path[i+1]isClosedPath\r\n                if (Type.exists(path[i].coords)) {\r\n                    p1 = path[i].coords.usrCoords;\r\n                    p2 = path[(i + 1) % le].coords.usrCoords;\r\n                } else {\r\n                    p1 = path[i].usrCoords;\r\n                    p2 = path[(i + 1) % le].usrCoords;\r\n                }\r\n\r\n                // If one of the two points p1, p2 is undefined or infinite,\r\n                // move on.\r\n                if (\r\n                    p1[0] === 0 ||\r\n                    p2[0] === 0 ||\r\n                    isNaN(p1[1]) ||\r\n                    isNaN(p2[1]) ||\r\n                    isNaN(p1[2]) ||\r\n                    isNaN(p2[2])\r\n                ) {\r\n                    continue;\r\n                }\r\n\r\n                if (p2[2] === y) {\r\n                    if (p2[1] === x) {\r\n                        return 1;\r\n                    }\r\n                    if (p1[2] === y && p2[1] > x === p1[1] < x) {\r\n                        return 0;\r\n                    }\r\n                }\r\n\r\n                if (p1[2] < y !== p2[2] < y) {\r\n                    // Crossing\r\n                    sign = 2 * (p2[2] > p1[2] ? 1 : 0) - 1;\r\n                    if (p1[1] >= x) {\r\n                        if (p2[1] > x) {\r\n                            wn += sign;\r\n                        } else {\r\n                            d = this.det3p(p1, p2, usrCoords);\r\n                            if (d === 0) {\r\n                                // Point is on line, i.e. outside\r\n                                return 0;\r\n                            }\r\n                            if (d > 0 + Mat.eps === p2[2] > p1[2]) {\r\n                                // Right crossing\r\n                                wn += sign;\r\n                            }\r\n                        }\r\n                    } else {\r\n                        if (p2[1] > x) {\r\n                            d = this.det3p(p1, p2, usrCoords);\r\n                            if (d > 0 + Mat.eps === p2[2] > p1[2]) {\r\n                                // Right crossing\r\n                                wn += sign;\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            return wn;\r\n        },\r\n\r\n        /**\r\n         * Decides if a point (x,y) is inside of a path / polygon.\r\n         * Does not work correct if the path has hole. In this case, windingNumber is the preferred method.\r\n         * Implements W. Randolf Franklin's pnpoly method.\r\n         *\r\n         * See <a href=\"https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html\">https://wrf.ecse.rpi.edu/Research/Short_Notes/pnpoly.html</a>.\r\n         *\r\n         * @param {Number} x_in x-coordinate (screen or user coordinates)\r\n         * @param {Number} y_in y-coordinate (screen or user coordinates)\r\n         * @param  {Array} path  Array of points / coords determining a path, i.e. the vertices of the polygon / path. The array elements\r\n         * do not have to be full points, but have to have a subobject \"coords\" or should be of type JXG.Coords.\r\n         * @param {Number} [coord_type=JXG.COORDS_BY_SCREEN] Type of coordinates used here.\r\n         *   Possible values are <b>JXG.COORDS_BY_USER</b> and <b>JXG.COORDS_BY_SCREEN</b>.\r\n         *   Default value is JXG.COORDS_BY_SCREEN.\r\n         * @param {JXG.Board} board Board object\r\n         *\r\n         * @returns {Boolean} if (x_in, y_in) is inside of the polygon.\r\n         * @see JXG.Polygon#hasPoint\r\n         * @see JXG.Polygon#pnpoly\r\n         * @see JXG.Math.Geometry.windingNumber\r\n         *\r\n         * @example\r\n         * var pol = board.create('polygon', [[-1,2], [2,2], [-1,4]]);\r\n         * var p = board.create('point', [4, 3]);\r\n         * var txt = board.create('text', [-1, 0.5, function() {\r\n         *   return 'Point A is inside of the polygon = ' +\r\n         *     JXG.Math.Geometry.pnpoly(p.X(), p.Y(), pol.vertices, JXG.COORDS_BY_USER, board);\r\n         * }]);\r\n         *\r\n         * </pre><div id=\"JXG4656ed42-f965-4e35-bb66-c334a4529683\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG4656ed42-f965-4e35-bb66-c334a4529683',\r\n         *             {boundingbox: [-2, 5, 5,-2], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var pol = board.create('polygon', [[-1,2], [2,2], [-1,4]]);\r\n         *     var p = board.create('point', [4, 3]);\r\n         *     var txt = board.create('text', [-1, 0.5, function() {\r\n         *     \t\treturn 'Point A is inside of the polygon = ' + JXG.Math.Geometry.pnpoly(p.X(), p.Y(), pol.vertices, JXG.COORDS_BY_USER, board);\r\n         *     }]);\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        pnpoly: function (x_in, y_in, path, coord_type, board) {\r\n            var i, j, vi, vj, len,\r\n                x, y, crds,\r\n                v = path,\r\n                isIn = false;\r\n\r\n            if (coord_type === Const.COORDS_BY_USER) {\r\n                crds = new Coords(Const.COORDS_BY_USER, [x_in, y_in], board);\r\n                x = crds.scrCoords[1];\r\n                y = crds.scrCoords[2];\r\n            } else {\r\n                x = x_in;\r\n                y = y_in;\r\n            }\r\n\r\n            len = path.length;\r\n            for (i = 0, j = len - 2; i < len - 1; j = i++) {\r\n                vi = Type.exists(v[i].coords) ? v[i].coords : v[i];\r\n                vj = Type.exists(v[j].coords) ? v[j].coords : v[j];\r\n\r\n                if (\r\n                    vi.scrCoords[2] > y !== vj.scrCoords[2] > y &&\r\n                    x <\r\n                    ((vj.scrCoords[1] - vi.scrCoords[1]) * (y - vi.scrCoords[2])) /\r\n                    (vj.scrCoords[2] - vi.scrCoords[2]) +\r\n                    vi.scrCoords[1]\r\n                ) {\r\n                    isIn = !isIn;\r\n                }\r\n            }\r\n\r\n            return isIn;\r\n        },\r\n\r\n        /****************************************/\r\n        /****          INTERSECTIONS         ****/\r\n        /****************************************/\r\n\r\n        /**\r\n         * Generate the function which computes the coordinates of the intersection point.\r\n         * Primarily used in {@link JXG.Point.createIntersectionPoint}.\r\n         * @param {JXG.Board} board object\r\n         * @param {JXG.Line,JXG.Circle_JXG.Line,JXG.Circle_Number|Function} el1,el2,i The result will be a intersection point on el1 and el2.\r\n         * i determines the intersection point if two points are available: <ul>\r\n         *   <li>i==0: use the positive square root,</li>\r\n         *   <li>i==1: use the negative square root.</li></ul>\r\n         * @param {Boolean} alwaysintersect. Flag that determines if segments and arc can have an outer intersection point\r\n         * on their defining line or circle.\r\n         * @returns {Function} Function returning a {@link JXG.Coords} object that determines\r\n         * the intersection point.\r\n         *\r\n         * @see JXG.Point.createIntersectionPoint\r\n         */\r\n        intersectionFunction: function (board, el1, el2, i, j, alwaysintersect) {\r\n            var func,\r\n                that = this,\r\n                el1_isArcType = false,\r\n                el2_isArcType = false;\r\n\r\n            el1_isArcType =\r\n                el1.elementClass === Const.OBJECT_CLASS_CURVE &&\r\n                    (el1.type === Const.OBJECT_TYPE_ARC || el1.type === Const.OBJECT_TYPE_SECTOR)\r\n                    ? true\r\n                    : false;\r\n            el2_isArcType =\r\n                el2.elementClass === Const.OBJECT_CLASS_CURVE &&\r\n                    (el2.type === Const.OBJECT_TYPE_ARC || el2.type === Const.OBJECT_TYPE_SECTOR)\r\n                    ? true\r\n                    : false;\r\n\r\n            if (\r\n                (el1.elementClass === Const.OBJECT_CLASS_CURVE ||\r\n                    el2.elementClass === Const.OBJECT_CLASS_CURVE) &&\r\n                (el1.elementClass === Const.OBJECT_CLASS_CURVE ||\r\n                    el1.elementClass === Const.OBJECT_CLASS_CIRCLE) &&\r\n                (el2.elementClass === Const.OBJECT_CLASS_CURVE ||\r\n                    el2.elementClass === Const.OBJECT_CLASS_CIRCLE) /*&&\r\n                !(el1_isArcType && el2_isArcType)*/\r\n            ) {\r\n                // curve - curve\r\n                // with the exception that both elements are arc types\r\n                /** @ignore */\r\n                func = function () {\r\n                    return that.meetCurveCurve(el1, el2, i, j, el1.board);\r\n                };\r\n            } else if (\r\n                (el1.elementClass === Const.OBJECT_CLASS_CURVE &&\r\n                    !el1_isArcType &&\r\n                    el2.elementClass === Const.OBJECT_CLASS_LINE) ||\r\n                (el2.elementClass === Const.OBJECT_CLASS_CURVE &&\r\n                    !el2_isArcType &&\r\n                    el1.elementClass === Const.OBJECT_CLASS_LINE)\r\n            ) {\r\n                // curve - line (this includes intersections between conic sections and lines)\r\n                // with the exception that the curve is of arc type\r\n                /** @ignore */\r\n                func = function () {\r\n                    return that.meetCurveLine(el1, el2, i, el1.board, Type.evaluate(alwaysintersect));\r\n                };\r\n            } else if (\r\n                el1.type === Const.OBJECT_TYPE_POLYGON ||\r\n                el2.type === Const.OBJECT_TYPE_POLYGON\r\n            ) {\r\n                // polygon - other\r\n                // Uses the Greiner-Hormann clipping algorithm\r\n                // Not implemented: polygon - point\r\n\r\n                if (el1.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                    // line - path\r\n                    /** @ignore */\r\n                    func = function () {\r\n                        var first1 = el1.evalVisProp('straightfirst'),\r\n                            last1 = el1.evalVisProp('straightlast'),\r\n                            first2 = el2.evalVisProp('straightfirst'),\r\n                            last2 = el2.evalVisProp('straightlast'),\r\n                            a_not;\r\n\r\n                        a_not = (!Type.evaluate(alwaysintersect) && (!first1 || !last1 || !first2 || !last2));\r\n                        return that.meetPolygonLine(el2, el1, i, el1.board, a_not);\r\n                    };\r\n                } else if (el2.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                    // path - line\r\n                    /** @ignore */\r\n                    func = function () {\r\n                        var first1 = el1.evalVisProp('straightfirst'),\r\n                            last1 = el1.evalVisProp('straightlast'),\r\n                            first2 = el2.evalVisProp('straightfirst'),\r\n                            last2 = el2.evalVisProp('straightlast'),\r\n                            a_not;\r\n\r\n                        a_not = (!Type.evaluate(alwaysintersect) && (!first1 || !last1 || !first2 || !last2));\r\n                        return that.meetPolygonLine(el1, el2, i, el1.board, a_not);\r\n                    };\r\n                } else {\r\n                    // path - path\r\n                    /** @ignore */\r\n                    func = function () {\r\n                        return that.meetPathPath(el1, el2, i, el1.board);\r\n                    };\r\n                }\r\n            } else if (\r\n                el1.elementClass === Const.OBJECT_CLASS_LINE &&\r\n                el2.elementClass === Const.OBJECT_CLASS_LINE\r\n            ) {\r\n                // line - line, lines may also be segments.\r\n                /** @ignore */\r\n                func = function () {\r\n                    var res,\r\n                        c,\r\n                        first1 = el1.evalVisProp('straightfirst'),\r\n                        last1 = el1.evalVisProp('straightlast'),\r\n                        first2 = el2.evalVisProp('straightfirst'),\r\n                        last2 = el2.evalVisProp('straightlast');\r\n\r\n                    /**\r\n                     * If one of the lines is a segment or ray and\r\n                     * the intersection point should disappear if outside\r\n                     * of the segment or ray we call\r\n                     * meetSegmentSegment\r\n                     */\r\n                    if (\r\n                        !Type.evaluate(alwaysintersect) &&\r\n                        (!first1 || !last1 || !first2 || !last2)\r\n                    ) {\r\n                        res = that.meetSegmentSegment(\r\n                            el1.point1.coords.usrCoords,\r\n                            el1.point2.coords.usrCoords,\r\n                            el2.point1.coords.usrCoords,\r\n                            el2.point2.coords.usrCoords\r\n                        );\r\n\r\n                        if (\r\n                            (!first1 && res[1] < 0) ||\r\n                            (!last1 && res[1] > 1) ||\r\n                            (!first2 && res[2] < 0) ||\r\n                            (!last2 && res[2] > 1)\r\n                        ) {\r\n                            // Non-existent\r\n                            c = [0, NaN, NaN];\r\n                        } else {\r\n                            c = res[0];\r\n                        }\r\n\r\n                        return new Coords(Const.COORDS_BY_USER, c, el1.board);\r\n                    }\r\n\r\n                    return that.meet(el1.stdform, el2.stdform, i, el1.board);\r\n                };\r\n            } else {\r\n                // All other combinations of circles and lines,\r\n                // Arc types are treated as circles.\r\n                /** @ignore */\r\n                func = function () {\r\n                    var res = that.meet(el1.stdform, el2.stdform, i, el1.board),\r\n                        has = true,\r\n                        first,\r\n                        last,\r\n                        r;\r\n\r\n                    if (Type.evaluate(alwaysintersect)) {\r\n                        return res;\r\n                    }\r\n                    if (el1.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                        first = el1.evalVisProp('straightfirst');\r\n                        last = el1.evalVisProp('straightlast');\r\n                        if (!first || !last) {\r\n                            r = that.affineRatio(el1.point1.coords, el1.point2.coords, res);\r\n                            if ((!last && r > 1 + Mat.eps) || (!first && r < 0 - Mat.eps)) {\r\n                                return new Coords(JXG.COORDS_BY_USER, [0, NaN, NaN], el1.board);\r\n                            }\r\n                        }\r\n                    }\r\n                    if (el2.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                        first = el2.evalVisProp('straightfirst');\r\n                        last = el2.evalVisProp('straightlast');\r\n                        if (!first || !last) {\r\n                            r = that.affineRatio(el2.point1.coords, el2.point2.coords, res);\r\n                            if ((!last && r > 1 + Mat.eps) || (!first && r < 0 - Mat.eps)) {\r\n                                return new Coords(JXG.COORDS_BY_USER, [0, NaN, NaN], el1.board);\r\n                            }\r\n                        }\r\n                    }\r\n                    if (el1_isArcType) {\r\n                        has = that.coordsOnArc(el1, res);\r\n                        if (has && el2_isArcType) {\r\n                            has = that.coordsOnArc(el2, res);\r\n                        }\r\n                        if (!has) {\r\n                            return new Coords(JXG.COORDS_BY_USER, [0, NaN, NaN], el1.board);\r\n                        }\r\n                    }\r\n                    return res;\r\n                };\r\n            }\r\n\r\n            return func;\r\n        },\r\n\r\n        otherIntersectionFunction: function (input, others, alwaysintersect, precision) {\r\n            var func, board,\r\n                el1, el2,\r\n                that = this;\r\n\r\n            el1 = input[0];\r\n            el2 = input[1];\r\n            board = el1.board;\r\n            /** @ignore */\r\n            func = function () {\r\n                var i, k, c, d,\r\n                    isClose,\r\n                    le = others.length,\r\n                    eps = Type.evaluate(precision);\r\n\r\n                for (i = le; i >= 0; i--) {\r\n                    if (el1.elementClass === Const.OBJECT_CLASS_CIRCLE &&\r\n                        [Const.OBJECT_CLASS_CIRCLE, Const.OBJECT_CLASS_LINE].indexOf(el2.elementClass) >= 0) {\r\n                        // circle, circle|line\r\n                        c = that.meet(el1.stdform, el2.stdform, i, board);\r\n                    } else if (el1.elementClass === Const.OBJECT_CLASS_CURVE &&\r\n                        [Const.OBJECT_CLASS_CURVE, Const.OBJECT_CLASS_CIRCLE].indexOf(el2.elementClass) >= 0) {\r\n                        // curve, circle|curve\r\n                        c = that.meetCurveCurve(el1, el2, i, 0, board);\r\n                    } else if (el1.elementClass === Const.OBJECT_CLASS_CURVE && el2.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                        // curve, line\r\n                        if (Type.exists(el1.dataX)) {\r\n                            c = JXG.Math.Geometry.meetCurveLine(el1, el2, i, el1.board, Type.evaluate(alwaysintersect));\r\n                        } else {\r\n                            c = JXG.Math.Geometry.meetCurveLineContinuous(el1, el2, i, el1.board);\r\n                        }\r\n                    }\r\n\r\n                    if (c === undefined) {\r\n                        // Intersection point does not exist\r\n                        continue;\r\n                    }\r\n\r\n                    // If the intersection is close to one of the points in other\r\n                    // we have to search for another intersection point.\r\n                    isClose = false;\r\n                    for (k = 0; !isClose && k < le; k++) {\r\n                        if (Type.exists(c) && Type.exists(c.distance)) {\r\n                            d = c.distance(JXG.COORDS_BY_USER, others[k].coords);\r\n                            if (d < eps) {\r\n                                isClose = true;\r\n                            }\r\n                        }\r\n                    }\r\n                    if (!isClose) {\r\n                        // We are done, the intersection is away from any other\r\n                        // intersection point.\r\n                        return c;\r\n                    }\r\n                }\r\n                // Otherwise we return the last intersection point\r\n                return c;\r\n            };\r\n            return func;\r\n        },\r\n\r\n        /**\r\n         * Returns true if the coordinates are on the arc element,\r\n         * false otherwise. Usually, coords is an intersection\r\n         * on the circle line. Now it is decided if coords are on the\r\n         * circle restricted to the arc line.\r\n         * @param  {Arc} arc arc or sector element\r\n         * @param  {JXG.Coords} coords Coords object of an intersection\r\n         * @returns {Boolean}\r\n         * @private\r\n         */\r\n        coordsOnArc: function (arc, coords) {\r\n            var angle = this.rad(arc.radiuspoint, arc.center, coords.usrCoords.slice(1)),\r\n                alpha = 0.0,\r\n                beta = this.rad(arc.radiuspoint, arc.center, arc.anglepoint),\r\n                ev_s = arc.evalVisProp('selection');\r\n\r\n            if ((ev_s === \"minor\" && beta > Math.PI) || (ev_s === \"major\" && beta < Math.PI)) {\r\n                alpha = beta;\r\n                beta = 2 * Math.PI;\r\n            }\r\n            if (angle < alpha || angle > beta) {\r\n                return false;\r\n            }\r\n            return true;\r\n        },\r\n\r\n        /**\r\n         * Computes the intersection of a pair of lines, circles or both.\r\n         * It uses the internal data array stdform of these elements.\r\n         * @param {Array} el1 stdform of the first element (line or circle)\r\n         * @param {Array} el2 stdform of the second element (line or circle)\r\n         * @param {Number|Function} i Index of the intersection point that should be returned.\r\n         * @param board Reference to the board.\r\n         * @returns {JXG.Coords} Coordinates of one of the possible two or more intersection points.\r\n         * Which point will be returned is determined by i.\r\n         */\r\n        meet: function (el1, el2, i, board) {\r\n            var result,\r\n                eps = Mat.eps;\r\n\r\n            if (Math.abs(el1[3]) < eps && Math.abs(el2[3]) < eps) {\r\n                // line line\r\n                result = this.meetLineLine(el1, el2, i, board);\r\n            } else if (Math.abs(el1[3]) >= eps && Math.abs(el2[3]) < eps) {\r\n                // circle line\r\n                result = this.meetLineCircle(el2, el1, i, board);\r\n            } else if (Math.abs(el1[3]) < eps && Math.abs(el2[3]) >= eps) {\r\n                // line circle\r\n                result = this.meetLineCircle(el1, el2, i, board);\r\n            } else {\r\n                // circle circle\r\n                result = this.meetCircleCircle(el1, el2, i, board);\r\n            }\r\n\r\n            return result;\r\n        },\r\n\r\n        /**\r\n         * Intersection of the line with the board\r\n         * @param  {Array}     line   stdform of the line in screen coordinates\r\n         * @param  {JXG.Board} board  reference to a board.\r\n         * @param  {Number}    margin optional margin, to avoid the display of the small sides of lines.\r\n         * @returns {Array}            [intersection coords 1, intersection coords 2]\r\n         */\r\n        meetLineBoard: function (line, board, margin) {\r\n            // Intersect the line with the four borders of the board.\r\n            var s = [],\r\n                intersect1,\r\n                intersect2,\r\n                i, j;\r\n\r\n            if (!Type.exists(margin)) {\r\n                margin = 0;\r\n            }\r\n\r\n            // top\r\n            s[0] = Mat.crossProduct(line, [margin, 0, 1]);\r\n            // left\r\n            s[1] = Mat.crossProduct(line, [margin, 1, 0]);\r\n            // bottom\r\n            s[2] = Mat.crossProduct(line, [-margin - board.canvasHeight, 0, 1]);\r\n            // right\r\n            s[3] = Mat.crossProduct(line, [-margin - board.canvasWidth, 1, 0]);\r\n\r\n            // Normalize the intersections\r\n            for (i = 0; i < 4; i++) {\r\n                if (Math.abs(s[i][0]) > Mat.eps) {\r\n                    for (j = 2; j > 0; j--) {\r\n                        s[i][j] /= s[i][0];\r\n                    }\r\n                    s[i][0] = 1.0;\r\n                }\r\n            }\r\n\r\n            // line is parallel to \"left\", take \"top\" and \"bottom\"\r\n            if (Math.abs(s[1][0]) < Mat.eps) {\r\n                intersect1 = s[0]; // top\r\n                intersect2 = s[2]; // bottom\r\n                // line is parallel to \"top\", take \"left\" and \"right\"\r\n            } else if (Math.abs(s[0][0]) < Mat.eps) {\r\n                intersect1 = s[1]; // left\r\n                intersect2 = s[3]; // right\r\n                // left intersection out of board (above)\r\n            } else if (s[1][2] < 0) {\r\n                intersect1 = s[0]; // top\r\n\r\n                // right intersection out of board (below)\r\n                if (s[3][2] > board.canvasHeight) {\r\n                    intersect2 = s[2]; // bottom\r\n                } else {\r\n                    intersect2 = s[3]; // right\r\n                }\r\n                // left intersection out of board (below)\r\n            } else if (s[1][2] > board.canvasHeight) {\r\n                intersect1 = s[2]; // bottom\r\n\r\n                // right intersection out of board (above)\r\n                if (s[3][2] < 0) {\r\n                    intersect2 = s[0]; // top\r\n                } else {\r\n                    intersect2 = s[3]; // right\r\n                }\r\n            } else {\r\n                intersect1 = s[1]; // left\r\n\r\n                // right intersection out of board (above)\r\n                if (s[3][2] < 0) {\r\n                    intersect2 = s[0]; // top\r\n                    // right intersection out of board (below)\r\n                } else if (s[3][2] > board.canvasHeight) {\r\n                    intersect2 = s[2]; // bottom\r\n                } else {\r\n                    intersect2 = s[3]; // right\r\n                }\r\n            }\r\n\r\n            return [\r\n                new Coords(Const.COORDS_BY_SCREEN, intersect1.slice(1), board),\r\n                new Coords(Const.COORDS_BY_SCREEN, intersect2.slice(1), board)\r\n            ];\r\n        },\r\n\r\n        /**\r\n         * Intersection of two lines.\r\n         * @param {Array} l1 stdform of the first line\r\n         * @param {Array} l2 stdform of the second line\r\n         * @param {number} i unused\r\n         * @param {JXG.Board} board Reference to the board.\r\n         * @returns {JXG.Coords} Coordinates of the intersection point.\r\n         */\r\n        meetLineLine: function (l1, l2, i, board) {\r\n            var s = isNaN(l1[5] + l2[5]) ? [0, 0, 0] : Mat.crossProduct(l1, l2);\r\n\r\n            // Make intersection of parallel lines more robust:\r\n            if (Math.abs(s[0]) < 1.0e-14) {\r\n                s[0] = 0;\r\n            }\r\n            return new Coords(Const.COORDS_BY_USER, s, board);\r\n        },\r\n\r\n        /**\r\n         * Intersection of line and circle.\r\n         * @param {Array} lin stdform of the line\r\n         * @param {Array} circ stdform of the circle\r\n         * @param {number|function} i number of the returned intersection point.\r\n         *   i==0: use the positive square root,\r\n         *   i==1: use the negative square root.\r\n         * @param {JXG.Board} board Reference to a board.\r\n         * @returns {JXG.Coords} Coordinates of the intersection point\r\n         */\r\n        meetLineCircle: function (lin, circ, i, board) {\r\n            var a, b, c, d, n, A, B, C, k, t;\r\n\r\n            // Radius is zero, return center of circle\r\n            if (circ[4] < Mat.eps) {\r\n                if (Math.abs(Mat.innerProduct([1, circ[6], circ[7]], lin, 3)) < Mat.eps) {\r\n                    return new Coords(Const.COORDS_BY_USER, circ.slice(6, 8), board);\r\n                }\r\n\r\n                return new Coords(Const.COORDS_BY_USER, [NaN, NaN], board);\r\n            }\r\n            c = circ[0];\r\n            b = circ.slice(1, 3);\r\n            a = circ[3];\r\n            d = lin[0];\r\n            n = lin.slice(1, 3);\r\n\r\n            // Line is assumed to be normalized. Therefore, nn==1 and we can skip some operations:\r\n            /*\r\n             var nn = n[0]*n[0]+n[1]*n[1];\r\n             A = a*nn;\r\n             B = (b[0]*n[1]-b[1]*n[0])*nn;\r\n             C = a*d*d - (b[0]*n[0]+b[1]*n[1])*d + c*nn;\r\n             */\r\n            A = a;\r\n            B = b[0] * n[1] - b[1] * n[0];\r\n            C = a * d * d - (b[0] * n[0] + b[1] * n[1]) * d + c;\r\n\r\n            k = B * B - 4 * A * C;\r\n            if (k > -Mat.eps * Mat.eps) {\r\n                k = Math.sqrt(Math.abs(k));\r\n                t = [(-B + k) / (2 * A), (-B - k) / (2 * A)];\r\n\r\n                return Type.evaluate(i) === 0\r\n                    ? new Coords(\r\n                        Const.COORDS_BY_USER,\r\n                        [-t[0] * -n[1] - d * n[0], -t[0] * n[0] - d * n[1]],\r\n                        board\r\n                    )\r\n                    : new Coords(\r\n                        Const.COORDS_BY_USER,\r\n                        [-t[1] * -n[1] - d * n[0], -t[1] * n[0] - d * n[1]],\r\n                        board\r\n                    );\r\n            }\r\n\r\n            return new Coords(Const.COORDS_BY_USER, [0, 0, 0], board);\r\n        },\r\n\r\n        /**\r\n         * Intersection of two circles.\r\n         * @param {Array} circ1 stdform of the first circle\r\n         * @param {Array} circ2 stdform of the second circle\r\n         * @param {number|function} i number of the returned intersection point.\r\n         *   i==0: use the positive square root,\r\n         *   i==1: use the negative square root.\r\n         * @param {JXG.Board} board Reference to the board.\r\n         * @returns {JXG.Coords} Coordinates of the intersection point\r\n         */\r\n        meetCircleCircle: function (circ1, circ2, i, board) {\r\n            var radicalAxis;\r\n\r\n            // Radius is zero, return center of circle, if on other circle\r\n            if (circ1[4] < Mat.eps) {\r\n                if (\r\n                    Math.abs(this.distance(circ1.slice(6, 2), circ2.slice(6, 8)) - circ2[4]) <\r\n                    Mat.eps\r\n                ) {\r\n                    return new Coords(Const.COORDS_BY_USER, circ1.slice(6, 8), board);\r\n                }\r\n\r\n                return new Coords(Const.COORDS_BY_USER, [0, 0, 0], board);\r\n            }\r\n\r\n            // Radius is zero, return center of circle, if on other circle\r\n            if (circ2[4] < Mat.eps) {\r\n                if (\r\n                    Math.abs(this.distance(circ2.slice(6, 2), circ1.slice(6, 8)) - circ1[4]) <\r\n                    Mat.eps\r\n                ) {\r\n                    return new Coords(Const.COORDS_BY_USER, circ2.slice(6, 8), board);\r\n                }\r\n\r\n                return new Coords(Const.COORDS_BY_USER, [0, 0, 0], board);\r\n            }\r\n\r\n            radicalAxis = [\r\n                circ2[3] * circ1[0] - circ1[3] * circ2[0],\r\n                circ2[3] * circ1[1] - circ1[3] * circ2[1],\r\n                circ2[3] * circ1[2] - circ1[3] * circ2[2],\r\n                0,\r\n                1,\r\n                Infinity,\r\n                Infinity,\r\n                Infinity\r\n            ];\r\n            radicalAxis = Mat.normalize(radicalAxis);\r\n\r\n            return this.meetLineCircle(radicalAxis, circ1, i, board);\r\n        },\r\n\r\n        /**\r\n         * Segment-wise search for the nr-th intersection of two curves.\r\n         * testSegment is always assumed to be true.\r\n         *\r\n         * @param {JXG.Curve} c1 Curve, Line or Circle\r\n         * @param {JXG.Curve} c2 Curve, Line or Circle\r\n         * @param {Number} nr the nr-th intersection point will be returned\r\n         * @param {JXG.Board} [board=c1.board] Reference to a board object\r\n         * @returns {JXG.Coords} intersection as Coords object\r\n         *\r\n         * @private\r\n         * @see JXG.Math.Geometry.meetCurveCurve\r\n         */\r\n        meetCurveCurveDiscrete: function (c1, c2, nr, board) {\r\n            var co,\r\n                i = Type.evaluate(nr);\r\n\r\n            if (c1.bezierDegree === 3 || c2.bezierDegree === 3) {\r\n                co = this.meetBezierCurveRedBlueSegments(c1, c2, i);\r\n            } else {\r\n                co = this.meetCurveRedBlueSegments(c1, c2, i);\r\n            }\r\n            return new Coords(Const.COORDS_BY_USER, co, board);\r\n        },\r\n\r\n        /**\r\n         * Apply Newton-Raphson to search for an intersection of two curves\r\n         * in a given range of the first curve.\r\n         *\r\n         * @param {JXG.Curve} c1 Curve, Line or Circle\r\n         * @param {JXG.Curve} c2 Curve, Line or Circle\r\n         * @param {Array} range Domain for the search of an intersection. The start value\r\n         * for the search is chosen to be inside of that range.\r\n         * @param {Boolean} testSegment If true require that t1 and t2 are inside of the allowed bounds.\r\n         * @returns {Array} [[z, x, y], t1, t2, t, ||c1[t1]-c2[t2]||**2]. The last entry is set to\r\n         * 10000 if the intersection is outside of the given domain (range) for the first curve.\r\n         * @private\r\n         * @see JXG.Math.Geometry._meetCurveCurveRecursive\r\n         * @see JXG.Math.Geometry._meetCurveCurveIterative\r\n         * @see JXG.Math.Numerics.generalizedDampedNewton\r\n         * @see JXG.Math.Geometry.meetCurveCurveCobyla\r\n         */\r\n        meetCurveCurveNewton: function (c1, c2, range1, range2, testSegment) {\r\n            var t1, t2,\r\n                co, r,\r\n                inphi = (Math.sqrt(5) - 1) * 0.5,\r\n                damp = 0.85, // (\r\n                eps3 = Mat.eps * Mat.eps * Mat.eps,\r\n                eps2 = Mat.eps * Mat.eps,\r\n\r\n                ma1 = c1.maxX(),\r\n                mi1 = c1.minX(),\r\n                ma2 = c2.maxX(),\r\n                mi2 = c2.minX(),\r\n\r\n                F = function(t, n) {\r\n                    var f1 = c1.Ft(t[0]),\r\n                        f2 = c2.Ft(t[1]),\r\n                        e = f1[1] - f2[1],\r\n                        f = f1[2] - f2[2];\r\n\r\n                    return [e, f];\r\n                },\r\n                D = function(t, n) {\r\n                    var h = Mat.eps,\r\n                        h2 = 2 * h,\r\n                        f1_1 = c1.Ft(t[0] - h),\r\n                        f1_2 = c1.Ft(t[0] + h),\r\n                        f2_1 = c2.Ft(t[1] - h),\r\n                        f2_2 = c2.Ft(t[1] + h);\r\n                    return [\r\n                        [ (f1_2[1] - f1_1[1]) / h2,\r\n                         -(f2_2[1] - f2_1[1]) / h2],\r\n                        [ (f1_2[2] - f1_1[2]) / h2,\r\n                         -(f2_2[2] - f2_1[2]) / h2]\r\n                    ];\r\n                };\r\n\r\n            t1 = range1[0] + (range1[1] - range1[0]) * (1 - inphi);\r\n            t2 = range2[0] + (range2[1] - range2[0]) * (1 - inphi);\r\n\r\n            // Use damped Newton\r\n            // r = Numerics.generalizedDampedNewtonCurves(c1, c2, t1, t2, damp, eps3);\r\n            r = Numerics.generalizedDampedNewton(F, D, 2, [t1, t2], damp, eps3, 40);\r\n            // r: [t1, t2, F2]\r\n\r\n            t1 = r[0][0];\r\n            t2 = r[0][1];\r\n            co = c1.Ft(t1);\r\n\r\n            if (\r\n                t1 < range1[0] - Mat.eps || t1 > range1[1] + Mat.eps ||\r\n                t2 < range2[0] - Mat.eps || t2 > range2[1] + Mat.eps ||\r\n                (testSegment &&\r\n                    (t1 < mi1 - eps2 || t1 > ma1 + eps2 ||\r\n                     t2 < mi2 - eps2 || t2 > ma2 + eps2)\r\n                )\r\n            ) {\r\n                // Damped-Newton found solution outside of range\r\n                return [co, t1, t2, 10000];\r\n            }\r\n// console.log(t1, r[3])\r\n\r\n            return [co, t1, t2, r[1]];\r\n        },\r\n\r\n        /**\r\n         * Return a list of the (at most) first i intersection points of two curves.\r\n         * Computed iteratively.\r\n         *\r\n         * @param {JXG.Curve} c1 Curve, Line or Circle\r\n         * @param {JXG.Curve} c2 Curve, Line or Circle\r\n         * @param {Number} low Lower bound of the search domain (between [0, 1])\r\n         * @param {Number} up Upper bound of the search domain (between [0, 1])\r\n         * @param {Number} i Return a list of the first i intersection points\r\n         * @param {Boolean} testSegment If true require that t1 and t2 are inside of the allowed bounds.\r\n         * @returns {Array} List of the first i intersection points, given by the parameter t.\r\n         * @private\r\n         * @see JXG.Math.Geometry.meetCurveCurveNewton\r\n         * @see JXG.Math.Geometry.meetCurveCurve\r\n         */\r\n        _meetCurveCurveIterative: function(c1, c2, range1, range2, i, testSegment) {\r\n            var ret,\r\n                t1,// t2,\r\n                low1, low2, up1, up2,\r\n                eps = Mat.eps * 100, // Minimum difference between zeros\r\n                j1, j2,\r\n                steps = 20,\r\n                d1, d2,\r\n                zeros = [];\r\n\r\n            low1 = range1[0];\r\n            up1 = range1[1];\r\n            low2 = range2[0];\r\n            up2 = range2[1];\r\n            if (up1 < low1 || up2 < low2) {\r\n                return [];\r\n            }\r\n\r\n            // console.log('DO iterative', [low1, up1], [low2, up2])\r\n\r\n            d1 = (up1 - low1) / steps;\r\n            d2 = (up2 - low2) / steps;\r\n            for (j1 = 0; j1 < steps; j1++) {\r\n                for (j2 = 0; j2 < steps; j2++) {\r\n\r\n                    ret = this.meetCurveCurveNewton(c1, c2,\r\n                        [low1 + j1 * d1, low1 + (j1 + 1) * d1],\r\n                        [low2 + j2 * d2, low2 + (j2 + 1) * d2],\r\n                        testSegment);\r\n\r\n                    if (ret[3] < Mat.eps) {\r\n                        t1 = ret[1];\r\n                        // t2 = ret[2];\r\n                        // console.log(\"\\tFOUND\", t1, t2, c1.Ft(t1)[2])\r\n                        zeros = zeros.concat([t1]);\r\n                        zeros = Type.toUniqueArrayFloat(zeros, eps);\r\n                        // console.log(zeros, i)\r\n                        if (zeros.length > i) {\r\n                            return zeros;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            return zeros;\r\n        },\r\n\r\n        /**\r\n         * Compute an intersection of the curves c1 and c2.\r\n         * We want to find values t1, t2 such that\r\n         * c1(t1) = c2(t2), i.e. (c1_x(t1) - c2_x(t2), c1_y(t1) - c2_y(t2)) = (0, 0).\r\n         *\r\n         * Available methods:\r\n         * <ul>\r\n         *  <li> discrete, segment-wise intersections\r\n         *  <li> generalized damped Newton-Raphson\r\n         * </ul>\r\n         *\r\n         * Segment-wise intersection is more stable, but has problems with tangent points.\r\n         * Damped Newton-Raphson converges very rapidly but sometimes behaves chaotic.\r\n         *\r\n         * @param {JXG.Curve} c1 Curve, Line or Circle\r\n         * @param {JXG.Curve} c2 Curve, Line or Circle\r\n         * @param {Number|Function} nr the nr-th intersection point will be returned. For backwards compatibility:\r\n         * if method='newton' and nr is not an integer, {@link JXG.Math.Numerics.generalizedNewton} is called\r\n         * directly with nr as start value (not recommended).\r\n         * @param {Number} t2ini not longer used. Must be supplied and is ignored.\r\n         * @param {JXG.Board} [board=c1.board] Reference to a board object.\r\n         * @param {String} [method] Intersection method, possible values are 'newton' and 'segment'.\r\n         * If both curves are given by functions (assumed to be continuous), 'newton' is the default, otherwise\r\n         * 'segment' is the default.\r\n         * @returns {JXG.Coords} intersection point\r\n         *\r\n         * @see JXG.Math.Geometry.meetCurveCurveDiscrete\r\n         * @see JXG.Math.Geometry._meetCurveCurveRecursive\r\n         * @see JXG.Math.Geometry.meetCurveCurveIterative\r\n         */\r\n        meetCurveCurve: function (c1, c2, nr, t2ini, board, method, testSegment) {\r\n            var co,\r\n                zeros,\r\n                mi1, ma1, mi2, ma2,\r\n                i = Type.evaluate(nr);\r\n\r\n            board = board || c1.board;\r\n            if (method === 'segment' || Type.exists(c1.dataX) || Type.exists(c2.dataX)) {\r\n                // Discrete data points, i.e. x-coordinates of c1 or c2 are given in an array)\r\n                return this.meetCurveCurveDiscrete(c1, c2, i, board);\r\n            }\r\n\r\n            // Outdated:\r\n            // Backwards compatibility if nr is not a positive integer then\r\n            // generalizedNewton is still used.\r\n            if (Type.exists(method) && method === 'newton' && i < 0 || parseInt(i) !== i) {\r\n                co = Numerics.generalizedNewton(c1, c2, i, t2ini);\r\n                return new Coords(Const.COORDS_BY_USER, co, board);\r\n            }\r\n\r\n            // Method 'newton'\r\n            mi1 = c1.minX();\r\n            ma1 = c1.maxX();\r\n            mi2 = c2.minX();\r\n            ma2 = c2.maxX();\r\n\r\n            // console.time('curvecurve')\r\n            zeros = this._meetCurveCurveIterative(c1, c2, [mi1, ma1], [mi2, ma2], i, testSegment);\r\n            // console.timeEnd('curvecurve')\r\n\r\n            if (zeros.length > i) {\r\n                co = c1.Ft(zeros[i]);\r\n            } else {\r\n                return [0, NaN, NaN];\r\n            }\r\n\r\n            return new Coords(Const.COORDS_BY_USER, co, board);\r\n        },\r\n\r\n        /**\r\n         * Intersection of curve with line,\r\n         * Order of input does not matter for el1 and el2.\r\n         * From version 0.99.7 on this method calls\r\n         * {@link JXG.Math.Geometry.meetCurveLineDiscrete}.\r\n         * If higher precision is needed, {@link JXG.Math.Geometry.meetCurveLineContinuous}\r\n         * has to be used.\r\n         *\r\n         * @param {JXG.Curve|JXG.Line} el1 Curve or Line\r\n         * @param {JXG.Curve|JXG.Line} el2 Curve or Line\r\n         * @param {Number|Function} nr the nr-th intersection point will be returned.\r\n         * @param {JXG.Board} [board=el1.board] Reference to a board object.\r\n         * @param {Boolean} alwaysIntersect If false just the segment between the two defining points are tested for intersection\r\n         * @returns {JXG.Coords} Intersection point. In case no intersection point is detected,\r\n         * the ideal point [0,1,0] is returned.\r\n         */\r\n        meetCurveLine: function (el1, el2, nr, board, alwaysIntersect) {\r\n            var v = [0, NaN, NaN],\r\n                cu,\r\n                li;\r\n\r\n            if (!Type.exists(board)) {\r\n                board = el1.board;\r\n            }\r\n\r\n            if (el1.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n                cu = el1;\r\n                li = el2;\r\n            } else {\r\n                cu = el2;\r\n                li = el1;\r\n            }\r\n\r\n            if (Type.exists(cu.dataX)) {\r\n                // We use the discrete version if\r\n                //   the curve is not a parametric curve, e.g. implicit plots\r\n                v = this.meetCurveLineDiscrete(cu, li, nr, board, !alwaysIntersect);\r\n            } else {\r\n                v = this.meetCurveCurve(cu, li, nr, 0, board, 'newton', !alwaysIntersect);\r\n            }\r\n\r\n            return v;\r\n        },\r\n\r\n        /**\r\n         * Intersection of line and curve, continuous case.\r\n         * Finds the nr-th intersection point\r\n         * Uses {@link JXG.Math.Geometry.meetCurveLineDiscrete} as a first approximation.\r\n         * A more exact solution is then found with {@link JXG.Math.Numerics.root}.\r\n         *\r\n         * @param {JXG.Curve} cu Curve\r\n         * @param {JXG.Line} li Line\r\n         * @param {NumberFunction} nr Will return the nr-th intersection point.\r\n         * @param {JXG.Board} board\r\n         * @param {Boolean} testSegment Test if intersection has to be inside of the segment or somewhere on the\r\n         * line defined by the segment\r\n         * @returns {JXG.Coords} Coords object containing the intersection.\r\n         */\r\n        meetCurveLineContinuous: function (cu, li, nr, board, testSegment) {\r\n            var func0, func1,\r\n                t, v, x, y, z,\r\n                eps = Mat.eps,\r\n                epsLow = Mat.eps,\r\n                steps,\r\n                delta,\r\n                tnew, tmin, fmin,\r\n                i, ft;\r\n\r\n            v = this.meetCurveLineDiscrete(cu, li, nr, board, testSegment);\r\n            x = v.usrCoords[1];\r\n            y = v.usrCoords[2];\r\n\r\n            func0 = function (t) {\r\n                var c1, c2;\r\n\r\n                if (t > cu.maxX() || t < cu.minX()) {\r\n                    return Infinity;\r\n                }\r\n                c1 = cu.X(t) - x;\r\n                c2 = cu.Y(t) - y;\r\n                return c1 * c1 + c2 * c2;\r\n                // return c1 * (cu.X(t + h) - cu.X(t - h)) + c2 * (cu.Y(t + h) - cu.Y(t - h)) / h;\r\n            };\r\n\r\n            func1 = function (t) {\r\n                var v = li.stdform[0] + li.stdform[1] * cu.X(t) + li.stdform[2] * cu.Y(t);\r\n                return v * v;\r\n            };\r\n\r\n            // Find t\r\n            steps = 50;\r\n            delta = (cu.maxX() - cu.minX()) / steps;\r\n            tnew = cu.minX();\r\n            fmin = 0.0001; //eps;\r\n            tmin = NaN;\r\n            for (i = 0; i < steps; i++) {\r\n                t = Numerics.root(func0, [\r\n                    Math.max(tnew, cu.minX()),\r\n                    Math.min(tnew + delta, cu.maxX())\r\n                ]);\r\n                ft = Math.abs(func0(t));\r\n                if (ft <= fmin) {\r\n                    fmin = ft;\r\n                    tmin = t;\r\n                    if (fmin < eps) {\r\n                        break;\r\n                    }\r\n                }\r\n\r\n                tnew += delta;\r\n            }\r\n            t = tmin;\r\n            // Compute \"exact\" t\r\n            t = Numerics.root(func1, [\r\n                Math.max(t - delta, cu.minX()),\r\n                Math.min(t + delta, cu.maxX())\r\n            ]);\r\n\r\n            ft = func1(t);\r\n            // Is the point on the line?\r\n            if (isNaN(ft) || Math.abs(ft) > epsLow) {\r\n                z = 0.0; //NaN;\r\n            } else {\r\n                z = 1.0;\r\n            }\r\n\r\n            return new Coords(Const.COORDS_BY_USER, [z, cu.X(t), cu.Y(t)], board);\r\n        },\r\n\r\n        /**\r\n         * Intersection of line and curve, discrete case.\r\n         * Segments are treated as lines.\r\n         * Finding the nr-th intersection point should work for all nr.\r\n         * @param {JXG.Curve} cu\r\n         * @param {JXG.Line} li\r\n         * @param {Number|Function} nr\r\n         * @param {JXG.Board} board\r\n         * @param {Boolean} testSegment Test if intersection has to be inside of the segment or somewhere on the\r\n         * line defined by the segment\r\n         *\r\n         * @returns {JXG.Coords} Intersection point. In case no intersection point is detected,\r\n         * the ideal point [0,1,0] is returned.\r\n         */\r\n        meetCurveLineDiscrete: function (cu, li, nr, board, testSegment) {\r\n            var i, j,\r\n                n = Type.evaluate(nr),\r\n                p1, p2,\r\n                p, q,\r\n                lip1 = li.point1.coords.usrCoords,\r\n                lip2 = li.point2.coords.usrCoords,\r\n                d, res,\r\n                cnt = 0,\r\n                len = cu.numberPoints,\r\n                ev_sf = li.evalVisProp('straightfirst'),\r\n                ev_sl = li.evalVisProp('straightlast');\r\n\r\n            // In case, no intersection will be found we will take this\r\n            q = new Coords(Const.COORDS_BY_USER, [0, NaN, NaN], board);\r\n\r\n            if (lip1[0] === 0.0) {\r\n                lip1 = [1, lip2[1] + li.stdform[2], lip2[2] - li.stdform[1]];\r\n            } else if (lip2[0] === 0.0) {\r\n                lip2 = [1, lip1[1] + li.stdform[2], lip1[2] - li.stdform[1]];\r\n            }\r\n\r\n            p2 = cu.points[0].usrCoords;\r\n            for (i = 1; i < len; i += cu.bezierDegree) {\r\n                p1 = p2.slice(0);\r\n                p2 = cu.points[i].usrCoords;\r\n                d = this.distance(p1, p2);\r\n\r\n                // The defining points are not identical\r\n                if (d > Mat.eps) {\r\n                    if (cu.bezierDegree === 3) {\r\n                        res = this.meetBeziersegmentBeziersegment(\r\n                            [\r\n                                cu.points[i - 1].usrCoords.slice(1),\r\n                                cu.points[i].usrCoords.slice(1),\r\n                                cu.points[i + 1].usrCoords.slice(1),\r\n                                cu.points[i + 2].usrCoords.slice(1)\r\n                            ],\r\n                            [lip1.slice(1), lip2.slice(1)],\r\n                            testSegment\r\n                        );\r\n                    } else {\r\n                        res = [this.meetSegmentSegment(p1, p2, lip1, lip2)];\r\n                    }\r\n\r\n                    for (j = 0; j < res.length; j++) {\r\n                        p = res[j];\r\n                        if (0 <= p[1] && p[1] <= 1) {\r\n                            if (cnt === n) {\r\n                                /**\r\n                                 * If the intersection point is not part of the segment,\r\n                                 * this intersection point is set to non-existent.\r\n                                 * This prevents jumping behavior of the intersection points.\r\n                                 * But it may be discussed if it is the desired behavior.\r\n                                 */\r\n                                if (\r\n                                    testSegment &&\r\n                                    ((!ev_sf && p[2] < 0) || (!ev_sl && p[2] > 1))\r\n                                ) {\r\n                                    return q; // break;\r\n                                }\r\n\r\n                                q = new Coords(Const.COORDS_BY_USER, p[0], board);\r\n                                return q; // break;\r\n                            }\r\n                            cnt += 1;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            return q;\r\n        },\r\n\r\n        /**\r\n         * Find the n-th intersection point of two curves named red (first parameter) and blue (second parameter).\r\n         * We go through each segment of the red curve and search if there is an intersection with a segment of the blue curve.\r\n         * This double loop, i.e. the outer loop runs along the red curve and the inner loop runs along the blue curve, defines\r\n         * the n-th intersection point. The segments are either line segments or Bezier curves of degree 3. This depends on\r\n         * the property bezierDegree of the curves.\r\n         * <p>\r\n         * This method works also for transformed curves, since only the already\r\n         * transformed points are used.\r\n         *\r\n         * @param {JXG.Curve} red\r\n         * @param {JXG.Curve} blue\r\n         * @param {Number|Function} nr\r\n         */\r\n        meetCurveRedBlueSegments: function (red, blue, nr) {\r\n            var i,\r\n                j,\r\n                n = Type.evaluate(nr),\r\n                red1,\r\n                red2,\r\n                blue1,\r\n                blue2,\r\n                m,\r\n                minX,\r\n                maxX,\r\n                iFound = 0,\r\n                lenBlue = blue.numberPoints,\r\n                lenRed = red.numberPoints;\r\n\r\n            if (lenBlue <= 1 || lenRed <= 1) {\r\n                return [0, NaN, NaN];\r\n            }\r\n\r\n            for (i = 1; i < lenRed; i++) {\r\n                red1 = red.points[i - 1].usrCoords;\r\n                red2 = red.points[i].usrCoords;\r\n                minX = Math.min(red1[1], red2[1]);\r\n                maxX = Math.max(red1[1], red2[1]);\r\n\r\n                blue2 = blue.points[0].usrCoords;\r\n                for (j = 1; j < lenBlue; j++) {\r\n                    blue1 = blue2;\r\n                    blue2 = blue.points[j].usrCoords;\r\n                    if (\r\n                        Math.min(blue1[1], blue2[1]) < maxX &&\r\n                        Math.max(blue1[1], blue2[1]) > minX\r\n                    ) {\r\n                        m = this.meetSegmentSegment(red1, red2, blue1, blue2);\r\n                        if (\r\n                            m[1] >= 0.0 && m[2] >= 0.0 &&\r\n                            // The two segments meet in the interior or at the start points\r\n                            ((m[1] < 1.0 && m[2] < 1.0) ||\r\n                              // One of the curve is intersected in the very last point\r\n                                (i === lenRed - 1 && m[1] === 1.0) ||\r\n                                (j === lenBlue - 1 && m[2] === 1.0))\r\n                        ) {\r\n                            if (iFound === n) {\r\n                                return m[0];\r\n                            }\r\n\r\n                            iFound++;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            return [0, NaN, NaN];\r\n        },\r\n\r\n        /**\r\n         * (Virtual) Intersection of two segments.\r\n         * @param {Array} p1 First point of segment 1 using normalized homogeneous coordinates [1,x,y]\r\n         * @param {Array} p2 Second point or direction of segment 1 using normalized homogeneous coordinates [1,x,y] or point at infinity [0,x,y], respectively\r\n         * @param {Array} q1 First point of segment 2 using normalized homogeneous coordinates [1,x,y]\r\n         * @param {Array} q2 Second point or direction of segment 2 using normalized homogeneous coordinates [1,x,y] or point at infinity [0,x,y], respectively\r\n         * @returns {Array} [Intersection point, t, u] The first entry contains the homogeneous coordinates\r\n         * of the intersection point. The second and third entry give the position of the intersection with respect\r\n         * to the definiting parameters. For example, the second entry t is defined by: intersection point = p1 + t * deltaP, where\r\n         * deltaP = (p2 - p1) when both parameters are coordinates, and deltaP = p2 if p2 is a point at infinity.\r\n         * If the two segments are collinear, [[0,0,0], Infinity, Infinity] is returned.\r\n         **/\r\n        meetSegmentSegment: function (p1, p2, q1, q2) {\r\n            var t,\r\n                u,\r\n                i,\r\n                d,\r\n                li1 = Mat.crossProduct(p1, p2),\r\n                li2 = Mat.crossProduct(q1, q2),\r\n                c = Mat.crossProduct(li1, li2);\r\n\r\n            if (Math.abs(c[0]) < Mat.eps) {\r\n                return [c, Infinity, Infinity];\r\n            }\r\n\r\n            // Normalize the intersection coordinates\r\n            c[1] /= c[0];\r\n            c[2] /= c[0];\r\n            c[0] /= c[0];\r\n\r\n            // Now compute in principle:\r\n            //    t = dist(c - p1) / dist(p2 - p1) and\r\n            //    u = dist(c - q1) / dist(q2 - q1)\r\n            // However: the points q1, q2, p1, p2 might be ideal points - or in general - the\r\n            // coordinates might be not normalized.\r\n            // Note that the z-coordinates of p2 and q2 are used to determine whether it should be interpreted\r\n            // as a segment coordinate or a direction.\r\n            i = Math.abs(p2[1] - p2[0] * p1[1]) < Mat.eps ? 2 : 1;\r\n            d = p1[i] / p1[0];\r\n            t = (c[i] - d) / (p2[0] !== 0 ? p2[i] / p2[0] - d : p2[i]);\r\n\r\n            i = Math.abs(q2[1] - q2[0] * q1[1]) < Mat.eps ? 2 : 1;\r\n            d = q1[i] / q1[0];\r\n            u = (c[i] - d) / (q2[0] !== 0 ? q2[i] / q2[0] - d : q2[i]);\r\n\r\n            return [c, t, u];\r\n        },\r\n\r\n        /**\r\n         * Find the n-th intersection point of two pathes, usually given by polygons. Uses parts of the\r\n         * Greiner-Hormann algorithm in JXG.Math.Clip.\r\n         *\r\n         * @param {JXG.Circle|JXG.Curve|JXG.Polygon} path1\r\n         * @param {JXG.Circle|JXG.Curve|JXG.Polygon} path2\r\n         * @param {Number|Function} n\r\n         * @param {JXG.Board} board\r\n         *\r\n         * @returns {JXG.Coords} Intersection point. In case no intersection point is detected,\r\n         * the ideal point [0,0,0] is returned.\r\n         *\r\n         */\r\n        meetPathPath: function (path1, path2, nr, board) {\r\n            var S, C, len, intersections,\r\n                n = Type.evaluate(nr);\r\n\r\n            S = JXG.Math.Clip._getPath(path1, board);\r\n            len = S.length;\r\n            if (\r\n                len > 0 &&\r\n                this.distance(S[0].coords.usrCoords, S[len - 1].coords.usrCoords, 3) < Mat.eps\r\n            ) {\r\n                S.pop();\r\n            }\r\n\r\n            C = JXG.Math.Clip._getPath(path2, board);\r\n            len = C.length;\r\n            if (\r\n                len > 0 &&\r\n                this.distance(C[0].coords.usrCoords, C[len - 1].coords.usrCoords, 3) <\r\n                Mat.eps * Mat.eps\r\n            ) {\r\n                C.pop();\r\n            }\r\n\r\n            // Handle cases where at least one of the paths is empty\r\n            if (nr < 0 || JXG.Math.Clip.isEmptyCase(S, C, 'intersection')) {\r\n                return new Coords(Const.COORDS_BY_USER, [0, 0, 0], board);\r\n            }\r\n\r\n            JXG.Math.Clip.makeDoublyLinkedList(S);\r\n            JXG.Math.Clip.makeDoublyLinkedList(C);\r\n\r\n            intersections = JXG.Math.Clip.findIntersections(S, C, board)[0];\r\n            if (n < intersections.length) {\r\n                return intersections[n].coords;\r\n            }\r\n            return new Coords(Const.COORDS_BY_USER, [0, 0, 0], board);\r\n        },\r\n\r\n        /**\r\n         * Find the n-th intersection point between a polygon and a line.\r\n         * @param {JXG.Polygon} path\r\n         * @param {JXG.Line} line\r\n         * @param {Number|Function} nr\r\n         * @param {JXG.Board} board\r\n         * @param {Boolean} alwaysIntersect If false just the segment between the two defining points of the line are tested for intersection.\r\n         *\r\n         * @returns {JXG.Coords} Intersection point. In case no intersection point is detected,\r\n         * the ideal point [0,0,0] is returned.\r\n         */\r\n        meetPolygonLine: function (path, line, nr, board, alwaysIntersect) {\r\n            var i,\r\n                n = Type.evaluate(nr),\r\n                res,\r\n                border,\r\n                crds = [0, 0, 0],\r\n                len = path.borders.length,\r\n                intersections = [];\r\n\r\n            for (i = 0; i < len; i++) {\r\n                border = path.borders[i];\r\n                res = this.meetSegmentSegment(\r\n                    border.point1.coords.usrCoords,\r\n                    border.point2.coords.usrCoords,\r\n                    line.point1.coords.usrCoords,\r\n                    line.point2.coords.usrCoords\r\n                );\r\n\r\n                if (\r\n                    (!alwaysIntersect || (res[2] >= 0 && res[2] < 1)) &&\r\n                    res[1] >= 0 &&\r\n                    res[1] < 1\r\n                ) {\r\n                    intersections.push(res[0]);\r\n                }\r\n            }\r\n\r\n            if (n >= 0 && n < intersections.length) {\r\n                crds = intersections[n];\r\n            }\r\n            return new Coords(Const.COORDS_BY_USER, crds, board);\r\n        },\r\n\r\n        /****************************************/\r\n        /****   BEZIER CURVE ALGORITHMS      ****/\r\n        /****************************************/\r\n\r\n        /**\r\n         * Splits a Bezier curve segment defined by four points into\r\n         * two Bezier curve segments. Dissection point is t=1/2.\r\n         * @param {Array} curve Array of four coordinate arrays of length 2 defining a\r\n         * Bezier curve segment, i.e. [[x0,y0], [x1,y1], [x2,y2], [x3,y3]].\r\n         * @returns {Array} Array consisting of two coordinate arrays for Bezier curves.\r\n         */\r\n        _bezierSplit: function (curve) {\r\n            var p0, p1, p2, p00, p22, p000;\r\n\r\n            p0 = [(curve[0][0] + curve[1][0]) * 0.5, (curve[0][1] + curve[1][1]) * 0.5];\r\n            p1 = [(curve[1][0] + curve[2][0]) * 0.5, (curve[1][1] + curve[2][1]) * 0.5];\r\n            p2 = [(curve[2][0] + curve[3][0]) * 0.5, (curve[2][1] + curve[3][1]) * 0.5];\r\n\r\n            p00 = [(p0[0] + p1[0]) * 0.5, (p0[1] + p1[1]) * 0.5];\r\n            p22 = [(p1[0] + p2[0]) * 0.5, (p1[1] + p2[1]) * 0.5];\r\n\r\n            p000 = [(p00[0] + p22[0]) * 0.5, (p00[1] + p22[1]) * 0.5];\r\n\r\n            return [\r\n                [curve[0], p0, p00, p000],\r\n                [p000, p22, p2, curve[3]]\r\n            ];\r\n        },\r\n\r\n        /**\r\n         * Computes the bounding box [minX, maxY, maxX, minY] of a Bezier curve segment\r\n         * from its control points.\r\n         * @param {Array} curve Array of four coordinate arrays of length 2 defining a\r\n         * Bezier curve segment, i.e. [[x0,y0], [x1,y1], [x2,y2], [x3,y3]].\r\n         * @returns {Array} Bounding box [minX, maxY, maxX, minY]\r\n         */\r\n        _bezierBbox: function (curve) {\r\n            var bb = [];\r\n\r\n            if (curve.length === 4) {\r\n                // bezierDegree == 3\r\n                bb[0] = Math.min(curve[0][0], curve[1][0], curve[2][0], curve[3][0]); // minX\r\n                bb[1] = Math.max(curve[0][1], curve[1][1], curve[2][1], curve[3][1]); // maxY\r\n                bb[2] = Math.max(curve[0][0], curve[1][0], curve[2][0], curve[3][0]); // maxX\r\n                bb[3] = Math.min(curve[0][1], curve[1][1], curve[2][1], curve[3][1]); // minY\r\n            } else {\r\n                // bezierDegree == 1\r\n                bb[0] = Math.min(curve[0][0], curve[1][0]); // minX\r\n                bb[1] = Math.max(curve[0][1], curve[1][1]); // maxY\r\n                bb[2] = Math.max(curve[0][0], curve[1][0]); // maxX\r\n                bb[3] = Math.min(curve[0][1], curve[1][1]); // minY\r\n            }\r\n\r\n            return bb;\r\n        },\r\n\r\n        /**\r\n         * Decide if two Bezier curve segments overlap by comparing their bounding boxes.\r\n         * @param {Array} bb1 Bounding box of the first Bezier curve segment\r\n         * @param {Array} bb2 Bounding box of the second Bezier curve segment\r\n         * @returns {Boolean} true if the bounding boxes overlap, false otherwise.\r\n         */\r\n        _bezierOverlap: function (bb1, bb2) {\r\n            return bb1[2] >= bb2[0] && bb1[0] <= bb2[2] && bb1[1] >= bb2[3] && bb1[3] <= bb2[1];\r\n        },\r\n\r\n        /**\r\n         * Append list of intersection points to a list.\r\n         * @private\r\n         */\r\n        _bezierListConcat: function (L, Lnew, t1, t2) {\r\n            var i,\r\n                t2exists = Type.exists(t2),\r\n                start = 0,\r\n                len = Lnew.length,\r\n                le = L.length;\r\n\r\n            if (\r\n                le > 0 &&\r\n                len > 0 &&\r\n                ((L[le - 1][1] === 1 && Lnew[0][1] === 0) ||\r\n                    (t2exists && L[le - 1][2] === 1 && Lnew[0][2] === 0))\r\n            ) {\r\n                start = 1;\r\n            }\r\n\r\n            for (i = start; i < len; i++) {\r\n                if (t2exists) {\r\n                    Lnew[i][2] *= 0.5;\r\n                    Lnew[i][2] += t2;\r\n                }\r\n\r\n                Lnew[i][1] *= 0.5;\r\n                Lnew[i][1] += t1;\r\n\r\n                L.push(Lnew[i]);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Find intersections of two Bezier curve segments by recursive subdivision.\r\n         * Below maxlevel determine intersections by intersection line segments.\r\n         * @param {Array} red Array of four coordinate arrays of length 2 defining the first\r\n         * Bezier curve segment, i.e. [[x0,y0], [x1,y1], [x2,y2], [x3,y3]].\r\n         * @param {Array} blue Array of four coordinate arrays of length 2 defining the second\r\n         * Bezier curve segment, i.e. [[x0,y0], [x1,y1], [x2,y2], [x3,y3]].\r\n         * @param {Number} level Recursion level\r\n         * @returns {Array} List of intersection points (up to nine). Each intersection point is an\r\n         * array of length three (homogeneous coordinates) plus preimages.\r\n         */\r\n        _bezierMeetSubdivision: function (red, blue, level) {\r\n            var bbb,\r\n                bbr,\r\n                ar,\r\n                b0,\r\n                b1,\r\n                r0,\r\n                r1,\r\n                m,\r\n                p0,\r\n                p1,\r\n                q0,\r\n                q1,\r\n                L = [],\r\n                maxLev = 5; // Maximum recursion level\r\n\r\n            bbr = this._bezierBbox(blue);\r\n            bbb = this._bezierBbox(red);\r\n\r\n            if (!this._bezierOverlap(bbr, bbb)) {\r\n                return [];\r\n            }\r\n\r\n            if (level < maxLev) {\r\n                ar = this._bezierSplit(red);\r\n                r0 = ar[0];\r\n                r1 = ar[1];\r\n\r\n                ar = this._bezierSplit(blue);\r\n                b0 = ar[0];\r\n                b1 = ar[1];\r\n\r\n                this._bezierListConcat(\r\n                    L,\r\n                    this._bezierMeetSubdivision(r0, b0, level + 1),\r\n                    0.0,\r\n                    0.0\r\n                );\r\n                this._bezierListConcat(\r\n                    L,\r\n                    this._bezierMeetSubdivision(r0, b1, level + 1),\r\n                    0,\r\n                    0.5\r\n                );\r\n                this._bezierListConcat(\r\n                    L,\r\n                    this._bezierMeetSubdivision(r1, b0, level + 1),\r\n                    0.5,\r\n                    0.0\r\n                );\r\n                this._bezierListConcat(\r\n                    L,\r\n                    this._bezierMeetSubdivision(r1, b1, level + 1),\r\n                    0.5,\r\n                    0.5\r\n                );\r\n\r\n                return L;\r\n            }\r\n\r\n            // Make homogeneous coordinates\r\n            q0 = [1].concat(red[0]);\r\n            q1 = [1].concat(red[3]);\r\n            p0 = [1].concat(blue[0]);\r\n            p1 = [1].concat(blue[3]);\r\n\r\n            m = this.meetSegmentSegment(q0, q1, p0, p1);\r\n\r\n            if (m[1] >= 0.0 && m[2] >= 0.0 && m[1] <= 1.0 && m[2] <= 1.0) {\r\n                return [m];\r\n            }\r\n\r\n            return [];\r\n        },\r\n\r\n        /**\r\n         * @param {Boolean} testSegment Test if intersection has to be inside of the segment or somewhere on the line defined by the segment\r\n         */\r\n        _bezierLineMeetSubdivision: function (red, blue, level, testSegment) {\r\n            var bbb, bbr, ar,\r\n                r0, r1,\r\n                m,\r\n                p0, p1, q0, q1,\r\n                L = [],\r\n                maxLev = 5; // Maximum recursion level\r\n\r\n            bbb = this._bezierBbox(blue);\r\n            bbr = this._bezierBbox(red);\r\n\r\n            if (testSegment && !this._bezierOverlap(bbr, bbb)) {\r\n                return [];\r\n            }\r\n\r\n            if (level < maxLev) {\r\n                ar = this._bezierSplit(red);\r\n                r0 = ar[0];\r\n                r1 = ar[1];\r\n\r\n                this._bezierListConcat(\r\n                    L,\r\n                    this._bezierLineMeetSubdivision(r0, blue, level + 1),\r\n                    0.0\r\n                );\r\n                this._bezierListConcat(\r\n                    L,\r\n                    this._bezierLineMeetSubdivision(r1, blue, level + 1),\r\n                    0.5\r\n                );\r\n\r\n                return L;\r\n            }\r\n\r\n            // Make homogeneous coordinates\r\n            q0 = [1].concat(red[0]);\r\n            q1 = [1].concat(red[3]);\r\n            p0 = [1].concat(blue[0]);\r\n            p1 = [1].concat(blue[1]);\r\n\r\n            m = this.meetSegmentSegment(q0, q1, p0, p1);\r\n\r\n            if (m[1] >= 0.0 && m[1] <= 1.0) {\r\n                if (!testSegment || (m[2] >= 0.0 && m[2] <= 1.0)) {\r\n                    return [m];\r\n                }\r\n            }\r\n\r\n            return [];\r\n        },\r\n\r\n        /**\r\n         * Find the nr-th intersection point of two Bezier curve segments.\r\n         * @param {Array} red Array of four coordinate arrays of length 2 defining the first\r\n         * Bezier curve segment, i.e. [[x0,y0], [x1,y1], [x2,y2], [x3,y3]].\r\n         * @param {Array} blue Array of four coordinate arrays of length 2 defining the second\r\n         * Bezier curve segment, i.e. [[x0,y0], [x1,y1], [x2,y2], [x3,y3]].\r\n         * @param {Boolean} testSegment Test if intersection has to be inside of the segment or somewhere on the line defined by the segment\r\n         * @returns {Array} Array containing the list of all intersection points as homogeneous coordinate arrays plus\r\n         * preimages [x,y], t_1, t_2] of the two Bezier curve segments.\r\n         *\r\n         */\r\n        meetBeziersegmentBeziersegment: function (red, blue, testSegment) {\r\n            var L, L2, i;\r\n\r\n            if (red.length === 4 && blue.length === 4) {\r\n                L = this._bezierMeetSubdivision(red, blue, 0);\r\n            } else {\r\n                L = this._bezierLineMeetSubdivision(red, blue, 0, testSegment);\r\n            }\r\n\r\n            L.sort(function (a, b) {\r\n                return (a[1] - b[1]) * 10000000.0 + (a[2] - b[2]);\r\n            });\r\n\r\n            L2 = [];\r\n            for (i = 0; i < L.length; i++) {\r\n                // Only push entries different from their predecessor\r\n                if (i === 0 || L[i][1] !== L[i - 1][1] || L[i][2] !== L[i - 1][2]) {\r\n                    L2.push(L[i]);\r\n                }\r\n            }\r\n            return L2;\r\n        },\r\n\r\n        /**\r\n         * Find the nr-th intersection point of two Bezier curves, i.e. curves with bezierDegree == 3.\r\n         * @param {JXG.Curve} red Curve with bezierDegree == 3\r\n         * @param {JXG.Curve} blue Curve with bezierDegree == 3\r\n         * @param {Number|Function} nr The number of the intersection point which should be returned.\r\n         * @returns {Array} The homogeneous coordinates of the nr-th intersection point.\r\n         */\r\n        meetBezierCurveRedBlueSegments: function (red, blue, nr) {\r\n            var p, i, j, k,\r\n                n = Type.evaluate(nr),\r\n                po, tmp,\r\n                redArr,\r\n                blueArr,\r\n                bbr,\r\n                bbb,\r\n                intersections,\r\n                startRed = 0,\r\n                startBlue = 0,\r\n                lenBlue, lenRed,\r\n                L = [];\r\n\r\n            if (blue.numberPoints < blue.bezierDegree + 1 || red.numberPoints < red.bezierDegree + 1) {\r\n                return [0, NaN, NaN];\r\n            }\r\n            if (red.bezierDegree === 1 && blue.bezierDegree === 3) {\r\n                tmp = red;\r\n                red = blue;\r\n                blue = tmp;\r\n            }\r\n\r\n            lenBlue = blue.numberPoints - blue.bezierDegree;\r\n            lenRed = red.numberPoints - red.bezierDegree;\r\n\r\n            // For sectors, we ignore the \"legs\"\r\n            if (red.type === Const.OBJECT_TYPE_SECTOR) {\r\n                startRed = 3;\r\n                lenRed -= 3;\r\n            }\r\n            if (blue.type === Const.OBJECT_TYPE_SECTOR) {\r\n                startBlue = 3;\r\n                lenBlue -= 3;\r\n            }\r\n\r\n            for (i = startRed; i < lenRed; i += red.bezierDegree) {\r\n                p = red.points;\r\n                redArr = [p[i].usrCoords.slice(1), p[i + 1].usrCoords.slice(1)];\r\n                if (red.bezierDegree === 3) {\r\n                    redArr[2] = p[i + 2].usrCoords.slice(1);\r\n                    redArr[3] = p[i + 3].usrCoords.slice(1);\r\n                }\r\n\r\n                bbr = this._bezierBbox(redArr);\r\n\r\n                for (j = startBlue; j < lenBlue; j += blue.bezierDegree) {\r\n                    p = blue.points;\r\n                    blueArr = [p[j].usrCoords.slice(1), p[j + 1].usrCoords.slice(1)];\r\n                    if (blue.bezierDegree === 3) {\r\n                        blueArr[2] = p[j + 2].usrCoords.slice(1);\r\n                        blueArr[3] = p[j + 3].usrCoords.slice(1);\r\n                    }\r\n\r\n                    bbb = this._bezierBbox(blueArr);\r\n                    if (this._bezierOverlap(bbr, bbb)) {\r\n                        intersections = this.meetBeziersegmentBeziersegment(redArr, blueArr);\r\n                        if (intersections.length === 0) {\r\n                            continue;\r\n                        }\r\n                        for (k = 0; k < intersections.length; k++) {\r\n                            po = intersections[k];\r\n                            if (\r\n                                po[1] < -Mat.eps ||\r\n                                po[1] > 1 + Mat.eps ||\r\n                                po[2] < -Mat.eps ||\r\n                                po[2] > 1 + Mat.eps\r\n                            ) {\r\n                                continue;\r\n                            }\r\n                            L.push(po);\r\n                        }\r\n                        if (L.length > n) {\r\n                            return L[n][0];\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            if (L.length > n) {\r\n                return L[n][0];\r\n            }\r\n\r\n            return [0, NaN, NaN];\r\n        },\r\n\r\n        bezierSegmentEval: function (t, curve) {\r\n            var f,\r\n                x,\r\n                y,\r\n                t1 = 1.0 - t;\r\n\r\n            x = 0;\r\n            y = 0;\r\n\r\n            f = t1 * t1 * t1;\r\n            x += f * curve[0][0];\r\n            y += f * curve[0][1];\r\n\r\n            f = 3.0 * t * t1 * t1;\r\n            x += f * curve[1][0];\r\n            y += f * curve[1][1];\r\n\r\n            f = 3.0 * t * t * t1;\r\n            x += f * curve[2][0];\r\n            y += f * curve[2][1];\r\n\r\n            f = t * t * t;\r\n            x += f * curve[3][0];\r\n            y += f * curve[3][1];\r\n\r\n            return [1.0, x, y];\r\n        },\r\n\r\n        /**\r\n         * Generate the defining points of a 3rd degree bezier curve that approximates\r\n         * a circle sector defined by three coordinate points A, B, C, each defined by an array of length three.\r\n         * The coordinate arrays are given in homogeneous coordinates.\r\n         * @param {Array} A First point\r\n         * @param {Array} B Second point (intersection point)\r\n         * @param {Array} C Third point\r\n         * @param {Boolean} withLegs Flag. If true the legs to the intersection point are part of the curve.\r\n         * @param {Number} sgn Wither 1 or -1. Needed for minor and major arcs. In case of doubt, use 1.\r\n         */\r\n        bezierArc: function (A, B, C, withLegs, sgn) {\r\n            var p1, p2, p3, p4,\r\n                r,\r\n                phi, beta, delta,\r\n                // PI2 = Math.PI * 0.5,\r\n                x = B[1],\r\n                y = B[2],\r\n                z = B[0],\r\n                dataX = [],\r\n                dataY = [],\r\n                co, si,\r\n                ax, ay,\r\n                bx, by,\r\n                k, v, d,\r\n                matrix;\r\n\r\n            r = this.distance(B, A);\r\n\r\n            // x,y, z is intersection point. Normalize it.\r\n            x /= z;\r\n            y /= z;\r\n\r\n            phi = this.rad(A.slice(1), B.slice(1), C.slice(1));\r\n            if (sgn === -1) {\r\n                phi = 2 * Math.PI - phi;\r\n            }\r\n\r\n            // Always divide the arc into four Bezier arcs.\r\n            // Otherwise, the position of gliders on this arc\r\n            // will be wrong.\r\n            delta = phi / 4;\r\n\r\n\r\n            p1 = A;\r\n            p1[1] /= p1[0];\r\n            p1[2] /= p1[0];\r\n            p1[0] /= p1[0];\r\n\r\n            p4 = p1.slice(0);\r\n\r\n            if (withLegs) {\r\n                dataX = [x, x + 0.333 * (p1[1] - x), x + 0.666 * (p1[1] - x), p1[1]];\r\n                dataY = [y, y + 0.333 * (p1[2] - y), y + 0.666 * (p1[2] - y), p1[2]];\r\n            } else {\r\n                dataX = [p1[1]];\r\n                dataY = [p1[2]];\r\n            }\r\n\r\n            while (phi > Mat.eps) {\r\n                // if (phi > PI2) {\r\n                //     beta = PI2;\r\n                //     phi -= PI2;\r\n                // } else {\r\n                //     beta = phi;\r\n                //     phi = 0;\r\n                // }\r\n                if (phi > delta) {\r\n                    beta = delta;\r\n                    phi -= delta;\r\n                } else {\r\n                    beta = phi;\r\n                    phi = 0;\r\n                }\r\n\r\n                co = Math.cos(sgn * beta);\r\n                si = Math.sin(sgn * beta);\r\n\r\n                matrix = [\r\n                    [1, 0, 0],\r\n                    [x * (1 - co) + y * si, co, -si],\r\n                    [y * (1 - co) - x * si, si, co]\r\n                ];\r\n                v = Mat.matVecMult(matrix, p1);\r\n                p4 = [v[0] / v[0], v[1] / v[0], v[2] / v[0]];\r\n\r\n                ax = p1[1] - x;\r\n                ay = p1[2] - y;\r\n                bx = p4[1] - x;\r\n                by = p4[2] - y;\r\n                d = Mat.hypot(ax + bx, ay + by);\r\n\r\n                if (Math.abs(by - ay) > Mat.eps) {\r\n                    k = ((((ax + bx) * (r / d - 0.5)) / (by - ay)) * 8) / 3;\r\n                } else {\r\n                    k = ((((ay + by) * (r / d - 0.5)) / (ax - bx)) * 8) / 3;\r\n                }\r\n\r\n                p2 = [1, p1[1] - k * ay, p1[2] + k * ax];\r\n                p3 = [1, p4[1] + k * by, p4[2] - k * bx];\r\n\r\n                Type.concat(dataX, [p2[1], p3[1], p4[1]]);\r\n                Type.concat(dataY, [p2[2], p3[2], p4[2]]);\r\n                p1 = p4.slice(0);\r\n            }\r\n\r\n            if (withLegs) {\r\n                Type.concat(dataX, [\r\n                    p4[1] + 0.333 * (x - p4[1]),\r\n                    p4[1] + 0.666 * (x - p4[1]),\r\n                    x\r\n                ]);\r\n                Type.concat(dataY, [\r\n                    p4[2] + 0.333 * (y - p4[2]),\r\n                    p4[2] + 0.666 * (y - p4[2]),\r\n                    y\r\n                ]);\r\n            }\r\n\r\n            return [dataX, dataY];\r\n        },\r\n\r\n        /****************************************/\r\n        /****           PROJECTIONS          ****/\r\n        /****************************************/\r\n\r\n        /**\r\n         * Calculates the coordinates of the projection of a given point on a given circle. I.o.w. the\r\n         * nearest one of the two intersection points of the line through the given point and the circles\r\n         * center.\r\n         * @param {JXG.Point|JXG.Coords} point Point to project or coords object to project.\r\n         * @param {JXG.Circle} circle Circle on that the point is projected.\r\n         * @param {JXG.Board} [board=point.board] Reference to the board\r\n         * @returns {JXG.Coords} The coordinates of the projection of the given point on the given circle.\r\n         */\r\n        projectPointToCircle: function (point, circle, board) {\r\n            var dist,\r\n                P,\r\n                x,\r\n                y,\r\n                factor,\r\n                M = circle.center.coords.usrCoords;\r\n\r\n            if (!Type.exists(board)) {\r\n                board = point.board;\r\n            }\r\n\r\n            // gave us a point\r\n            if (Type.isPoint(point)) {\r\n                dist = point.coords.distance(Const.COORDS_BY_USER, circle.center.coords);\r\n                P = point.coords.usrCoords;\r\n                // gave us coords\r\n            } else {\r\n                dist = point.distance(Const.COORDS_BY_USER, circle.center.coords);\r\n                P = point.usrCoords;\r\n            }\r\n\r\n            if (Math.abs(dist) < Mat.eps) {\r\n                dist = Mat.eps;\r\n            }\r\n\r\n            factor = circle.Radius() / dist;\r\n            x = M[1] + factor * (P[1] - M[1]);\r\n            y = M[2] + factor * (P[2] - M[2]);\r\n\r\n            return new Coords(Const.COORDS_BY_USER, [x, y], board);\r\n        },\r\n\r\n        /**\r\n         * Calculates the coordinates of the orthogonal projection of a given point on a given line. I.o.w. the\r\n         * intersection point of the given line and its perpendicular through the given point.\r\n         * @param {JXG.Point|JXG.Coords} point Point to project.\r\n         * @param {JXG.Line} line Line on that the point is projected.\r\n         * @param {JXG.Board} [board=point.board|board=line.board] Reference to a board.\r\n         * @returns {JXG.Coords} The coordinates of the projection of the given point on the given line.\r\n         */\r\n        projectPointToLine: function (point, line, board) {\r\n            var v = [0, line.stdform[1], line.stdform[2]],\r\n                coords;\r\n\r\n            if (!Type.exists(board)) {\r\n                if (Type.exists(point.coords)) {\r\n                    board = point.board;\r\n                } else {\r\n                    board = line.board;\r\n                }\r\n            }\r\n\r\n            if (Type.exists(point.coords)) {\r\n                coords = point.coords.usrCoords;\r\n            } else {\r\n                coords = point.usrCoords;\r\n            }\r\n\r\n            v = Mat.crossProduct(v, coords);\r\n            return new Coords(Const.COORDS_BY_USER, Mat.crossProduct(v, line.stdform), board);\r\n        },\r\n\r\n        /**\r\n         * Calculates the coordinates of the orthogonal projection of a given coordinate array on a given line\r\n         * segment defined by two coordinate arrays.\r\n         * @param {Array} p Point to project.\r\n         * @param {Array} q1 Start point of the line segment on that the point is projected.\r\n         * @param {Array} q2 End point of the line segment on that the point is projected.\r\n         * @returns {Array} The coordinates of the projection of the given point on the given segment\r\n         * and the factor that determines the projected point as a convex combination of the\r\n         * two endpoints q1 and q2 of the segment.\r\n         */\r\n        projectCoordsToSegment: function (p, q1, q2) {\r\n            var t,\r\n                denom,\r\n                s = [q2[1] - q1[1], q2[2] - q1[2]],\r\n                v = [p[1] - q1[1], p[2] - q1[2]];\r\n\r\n            /**\r\n             * If the segment has length 0, i.e. is a point,\r\n             * the projection is equal to that point.\r\n             */\r\n            if (Math.abs(s[0]) < Mat.eps && Math.abs(s[1]) < Mat.eps) {\r\n                return [q1, 0];\r\n            }\r\n\r\n            t = Mat.innerProduct(v, s);\r\n            denom = Mat.innerProduct(s, s);\r\n            t /= denom;\r\n\r\n            return [[1, t * s[0] + q1[1], t * s[1] + q1[2]], t];\r\n        },\r\n\r\n        /**\r\n         * Finds the coordinates of the closest point on a Bezier segment of a\r\n         * {@link JXG.Curve} to a given coordinate array.\r\n         * @param {Array} pos Point to project in homogeneous coordinates.\r\n         * @param {JXG.Curve} curve Curve of type \"plot\" having Bezier degree 3.\r\n         * @param {Number} start Number of the Bezier segment of the curve.\r\n         * @returns {Array} The coordinates of the projection of the given point\r\n         * on the given Bezier segment and the preimage of the curve which\r\n         * determines the closest point.\r\n         */\r\n        projectCoordsToBeziersegment: function (pos, curve, start) {\r\n            var t0,\r\n                /** @ignore */\r\n                minfunc = function (t) {\r\n                    var z = [1, curve.X(start + t), curve.Y(start + t)];\r\n\r\n                    z[1] -= pos[1];\r\n                    z[2] -= pos[2];\r\n\r\n                    return z[1] * z[1] + z[2] * z[2];\r\n                };\r\n\r\n            t0 = JXG.Math.Numerics.fminbr(minfunc, [0.0, 1.0]);\r\n\r\n            return [[1, curve.X(t0 + start), curve.Y(t0 + start)], t0];\r\n        },\r\n\r\n        /**\r\n         * Calculates the coordinates of the projection of a given point on a given curve.\r\n         * Uses {@link JXG.Math.Geometry.projectCoordsToCurve}.\r\n         *\r\n         * @param {JXG.Point} point Point to project.\r\n         * @param {JXG.Curve} curve Curve on that the point is projected.\r\n         * @param {JXG.Board} [board=point.board] Reference to a board.\r\n         * @see JXG.Math.Geometry.projectCoordsToCurve\r\n         * @returns {Array} [JXG.Coords, position] The coordinates of the projection of the given\r\n         * point on the given graph and the relative position on the curve (real number).\r\n         */\r\n        projectPointToCurve: function (point, curve, board) {\r\n            if (!Type.exists(board)) {\r\n                board = point.board;\r\n            }\r\n\r\n            var x = point.X(),\r\n                y = point.Y(),\r\n                t = point.position,\r\n                result;\r\n\r\n            if (!Type.exists(t)) {\r\n                t = curve.evalVisProp('curvetype') === 'functiongraph' ? x : 0.0;\r\n            }\r\n            result = this.projectCoordsToCurve(x, y, t, curve, board);\r\n            // point.position = result[1];\r\n\r\n            return result;\r\n        },\r\n\r\n        /**\r\n         * Calculates the coordinates of the projection of a coordinates pair on a given curve. In case of\r\n         * function graphs this is the\r\n         * intersection point of the curve and the parallel to y-axis through the given point.\r\n         * @param {Number} x coordinate to project.\r\n         * @param {Number} y coordinate to project.\r\n         * @param {Number} t start value for newtons method\r\n         * @param {JXG.Curve} curve Curve on that the point is projected.\r\n         * @param {JXG.Board} [board=curve.board] Reference to a board.\r\n         * @see JXG.Math.Geometry.projectPointToCurve\r\n         * @returns {JXG.Coords} Array containing the coordinates of the projection of the given point on the given curve and\r\n         * the position on the curve.\r\n         */\r\n        projectCoordsToCurve: function (x, y, t, curve, board) {\r\n            var newCoords, newCoordsObj,\r\n                i, j, mindist, dist, lbda,\r\n                v, coords, d, p1, p2, res, minfunc,\r\n                t_new, f_new, f_old, dy,\r\n                delta, delta1, delta2, steps,\r\n                minX, maxX, minX_glob, maxX_glob,\r\n                infty = Number.POSITIVE_INFINITY;\r\n\r\n            if (!Type.exists(board)) {\r\n                board = curve.board;\r\n            }\r\n\r\n            if (curve.evalVisProp('curvetype') === 'plot') {\r\n                t = 0;\r\n                mindist = infty;\r\n                if (curve.numberPoints === 0) {\r\n                    newCoords = [0, 1, 1];\r\n                } else {\r\n                    newCoords = [curve.Z(0), curve.X(0), curve.Y(0)];\r\n                }\r\n\r\n                if (curve.numberPoints > 1) {\r\n                    v = [1, x, y];\r\n                    if (curve.bezierDegree === 3) {\r\n                        j = 0;\r\n                    } else {\r\n                        p1 = [curve.Z(0), curve.X(0), curve.Y(0)];\r\n                    }\r\n                    for (i = 0; i < curve.numberPoints - 1; i++) {\r\n                        if (curve.bezierDegree === 3) {\r\n                            res = this.projectCoordsToBeziersegment(v, curve, j);\r\n                        } else {\r\n                            p2 = [curve.Z(i + 1), curve.X(i + 1), curve.Y(i + 1)];\r\n                            res = this.projectCoordsToSegment(v, p1, p2);\r\n                        }\r\n                        lbda = res[1];\r\n                        coords = res[0];\r\n\r\n                        if (0.0 <= lbda && lbda <= 1.0) {\r\n                            dist = this.distance(coords, v);\r\n                            d = i + lbda;\r\n                        } else if (lbda < 0.0) {\r\n                            coords = p1;\r\n                            dist = this.distance(p1, v);\r\n                            d = i;\r\n                        } else if (lbda > 1.0 && i === curve.numberPoints - 2) {\r\n                            coords = p2;\r\n                            dist = this.distance(coords, v);\r\n                            d = curve.numberPoints - 1;\r\n                        }\r\n\r\n                        if (dist < mindist) {\r\n                            mindist = dist;\r\n                            t = d;\r\n                            newCoords = coords;\r\n                        }\r\n\r\n                        if (curve.bezierDegree === 3) {\r\n                            j++;\r\n                            i += 2;\r\n                        } else {\r\n                            p1 = p2;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                newCoordsObj = new Coords(Const.COORDS_BY_USER, newCoords, board);\r\n            } else {\r\n                // 'parameter', 'polar', 'functiongraph'\r\n\r\n                minX_glob = curve.minX();\r\n                maxX_glob = curve.maxX();\r\n                minX = minX_glob;\r\n                maxX = maxX_glob;\r\n\r\n                if (curve.evalVisProp('curvetype') === 'functiongraph') {\r\n                    // Restrict the possible position of t\r\n                    // to the projection of a circle to the x-axis (= t-axis)\r\n                    dy = Math.abs(y - curve.Y(x));\r\n                    if (!isNaN(dy)) {\r\n                        minX = x - dy;\r\n                        maxX = x + dy;\r\n                    }\r\n                }\r\n\r\n                /**\r\n                 * @ignore\r\n                 * Find t such that the Euclidean distance between\r\n                 * [x, y] and [curve.X(t), curve.Y(t)]\r\n                 * is minimized.\r\n                 */\r\n                minfunc = function (t) {\r\n                    var dx, dy;\r\n\r\n                    if (t < minX_glob || t > curve.maxX_glob) {\r\n                        return Infinity;\r\n                    }\r\n                    dx = x - curve.X(t);\r\n                    dy = y - curve.Y(t);\r\n                    return dx * dx + dy * dy;\r\n                };\r\n\r\n                // Search t which minimizes minfunc(t)\r\n                // in discrete steps\r\n                f_old = minfunc(t);\r\n                steps = 50;\r\n                delta = (maxX - minX) / steps;\r\n                t_new = minX;\r\n                for (i = 0; i < steps; i++) {\r\n                    f_new = minfunc(t_new);\r\n\r\n                    if (f_new < f_old || f_old === Infinity || isNaN(f_old)) {\r\n                        t = t_new;\r\n                        f_old = f_new;\r\n                    }\r\n\r\n                    t_new += delta;\r\n                }\r\n\r\n                // t = Numerics.root(Numerics.D(minfunc), t);\r\n\r\n                // Ensure that minfunc is defined on the\r\n                // enclosing interval [t-delta1, t+delta2]\r\n                delta1 = delta;\r\n                for (i = 0; i < 20 && isNaN(minfunc(t - delta1)); i++, delta1 *= 0.5);\r\n                if (isNaN(minfunc(t - delta1))) {\r\n                    delta1 = 0.0;\r\n                }\r\n                delta2 = delta;\r\n                for (i = 0; i < 20 && isNaN(minfunc(t + delta2)); i++, delta2 *= 0.5);\r\n                if (isNaN(minfunc(t + delta2))) {\r\n                    delta2 = 0.0;\r\n                }\r\n\r\n                // Finally, apply mathemetical optimization in the determined interval\r\n                t = Numerics.fminbr(minfunc, [\r\n                    Math.max(t - delta1, minX),\r\n                    Math.min(t + delta2, maxX)\r\n                ]);\r\n\r\n                // Distinction between closed and open curves is not necessary.\r\n                // If closed, the cyclic projection shift will work anyhow\r\n                // if (Math.abs(curve.X(minX) - curve.X(maxX)) < Mat.eps &&\r\n                //     Math.abs(curve.Y(minX) - curve.Y(maxX)) < Mat.eps) {\r\n                //     // Cyclically\r\n                //     if (t < minX) {console.log(t)\r\n                //         t = maxX + t - minX;\r\n                //     }\r\n                //     if (t > maxX) {\r\n                //         t = minX + t - maxX;\r\n                //     }\r\n                // } else {\r\n\r\n                t = t < minX_glob ? minX_glob : t;\r\n                t = t > maxX_glob ? maxX_glob : t;\r\n                // }\r\n\r\n                newCoordsObj = new Coords(\r\n                    Const.COORDS_BY_USER,\r\n                    [curve.X(t), curve.Y(t)],\r\n                    board\r\n                );\r\n            }\r\n\r\n            return [curve.updateTransform(newCoordsObj), t];\r\n        },\r\n\r\n        /**\r\n         * Calculates the coordinates of the closest orthogonal projection of a given coordinate array onto the\r\n         * border of a polygon.\r\n         * @param {Array} p Point to project.\r\n         * @param {JXG.Polygon} pol Polygon element\r\n         * @returns {Array} The coordinates of the closest projection of the given point to the border of the polygon.\r\n         */\r\n        projectCoordsToPolygon: function (p, pol) {\r\n            var i,\r\n                len = pol.vertices.length,\r\n                d_best = Infinity,\r\n                d,\r\n                projection,\r\n                proj,\r\n                bestprojection;\r\n\r\n            for (i = 0; i < len - 1; i++) {\r\n                projection = JXG.Math.Geometry.projectCoordsToSegment(\r\n                    p,\r\n                    pol.vertices[i].coords.usrCoords,\r\n                    pol.vertices[i + 1].coords.usrCoords\r\n                );\r\n\r\n                if (0 <= projection[1] && projection[1] <= 1) {\r\n                    d = JXG.Math.Geometry.distance(projection[0], p, 3);\r\n                    proj = projection[0];\r\n                } else if (projection[1] < 0) {\r\n                    d = JXG.Math.Geometry.distance(pol.vertices[i].coords.usrCoords, p, 3);\r\n                    proj = pol.vertices[i].coords.usrCoords;\r\n                } else {\r\n                    d = JXG.Math.Geometry.distance(pol.vertices[i + 1].coords.usrCoords, p, 3);\r\n                    proj = pol.vertices[i + 1].coords.usrCoords;\r\n                }\r\n                if (d < d_best) {\r\n                    bestprojection = proj.slice(0);\r\n                    d_best = d;\r\n                }\r\n            }\r\n            return bestprojection;\r\n        },\r\n\r\n        /**\r\n         * Calculates the coordinates of the projection of a given point on a given turtle. A turtle consists of\r\n         * one or more curves of curveType 'plot'. Uses {@link JXG.Math.Geometry.projectPointToCurve}.\r\n         * @param {JXG.Point} point Point to project.\r\n         * @param {JXG.Turtle} turtle on that the point is projected.\r\n         * @param {JXG.Board} [board=point.board] Reference to a board.\r\n         * @returns {Array} [JXG.Coords, position] Array containing the coordinates of the projection of the given point on the turtle and\r\n         * the position on the turtle.\r\n         */\r\n        projectPointToTurtle: function (point, turtle, board) {\r\n            var newCoords,\r\n                t,\r\n                x,\r\n                y,\r\n                i,\r\n                dist,\r\n                el,\r\n                minEl,\r\n                res,\r\n                newPos,\r\n                np = 0,\r\n                npmin = 0,\r\n                mindist = Number.POSITIVE_INFINITY,\r\n                len = turtle.objects.length;\r\n\r\n            if (!Type.exists(board)) {\r\n                board = point.board;\r\n            }\r\n\r\n            // run through all curves of this turtle\r\n            for (i = 0; i < len; i++) {\r\n                el = turtle.objects[i];\r\n\r\n                if (el.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n                    res = this.projectPointToCurve(point, el);\r\n                    newCoords = res[0];\r\n                    newPos = res[1];\r\n                    dist = this.distance(newCoords.usrCoords, point.coords.usrCoords);\r\n\r\n                    if (dist < mindist) {\r\n                        x = newCoords.usrCoords[1];\r\n                        y = newCoords.usrCoords[2];\r\n                        t = newPos;\r\n                        mindist = dist;\r\n                        minEl = el;\r\n                        npmin = np;\r\n                    }\r\n                    np += el.numberPoints;\r\n                }\r\n            }\r\n\r\n            newCoords = new Coords(Const.COORDS_BY_USER, [x, y], board);\r\n            // point.position = t + npmin;\r\n            // return minEl.updateTransform(newCoords);\r\n            return [minEl.updateTransform(newCoords), t + npmin];\r\n        },\r\n\r\n        /**\r\n         * Trivial projection of a point to another point.\r\n         * @param {JXG.Point} point Point to project (not used).\r\n         * @param {JXG.Point} dest Point on that the point is projected.\r\n         * @returns {JXG.Coords} The coordinates of the projection of the given point on the given circle.\r\n         */\r\n        projectPointToPoint: function (point, dest) {\r\n            return dest.coords;\r\n        },\r\n\r\n        /**\r\n         *\r\n         * @param {JXG.Point|JXG.Coords} point\r\n         * @param {JXG.Board} [board]\r\n         */\r\n        projectPointToBoard: function (point, board) {\r\n            var i,\r\n                l,\r\n                c,\r\n                brd = board || point.board,\r\n                // comparison factor, point coord idx, bbox idx, 1st bbox corner x & y idx, 2nd bbox corner x & y idx\r\n                config = [\r\n                    // left\r\n                    [1, 1, 0, 0, 3, 0, 1],\r\n                    // top\r\n                    [-1, 2, 1, 0, 1, 2, 1],\r\n                    // right\r\n                    [-1, 1, 2, 2, 1, 2, 3],\r\n                    // bottom\r\n                    [1, 2, 3, 0, 3, 2, 3]\r\n                ],\r\n                coords = point.coords || point,\r\n                bbox = brd.getBoundingBox();\r\n\r\n            for (i = 0; i < 4; i++) {\r\n                c = config[i];\r\n                if (c[0] * coords.usrCoords[c[1]] < c[0] * bbox[c[2]]) {\r\n                    // define border\r\n                    l = Mat.crossProduct(\r\n                        [1, bbox[c[3]], bbox[c[4]]],\r\n                        [1, bbox[c[5]], bbox[c[6]]]\r\n                    );\r\n                    l[3] = 0;\r\n                    l = Mat.normalize(l);\r\n\r\n                    // project point\r\n                    coords = this.projectPointToLine({ coords: coords }, { stdform: l }, brd);\r\n                }\r\n            }\r\n\r\n            return coords;\r\n        },\r\n\r\n        /**\r\n         * Calculates the distance of a point to a line. The point and the line are given by homogeneous\r\n         * coordinates. For lines this can be line.stdform.\r\n         * @param {Array} point Homogeneous coordinates of a point.\r\n         * @param {Array} line Homogeneous coordinates of a line ([C,A,B] where A*x+B*y+C*z=0).\r\n         * @returns {Number} Distance of the point to the line.\r\n         */\r\n        distPointLine: function (point, line) {\r\n            var a = line[1],\r\n                b = line[2],\r\n                c = line[0],\r\n                nom;\r\n\r\n            if (Math.abs(a) + Math.abs(b) < Mat.eps) {\r\n                return Number.POSITIVE_INFINITY;\r\n            }\r\n\r\n            nom = a * point[1] + b * point[2] + c;\r\n            a *= a;\r\n            b *= b;\r\n\r\n            return Math.abs(nom) / Math.sqrt(a + b);\r\n        },\r\n\r\n        /**\r\n         * Determine the (Euclidean) distance between a point q and a line segment\r\n         * defined by two points p1 and p2. In case p1 equals p2, the distance to this\r\n         * point is returned.\r\n         *\r\n         * @param {Array} q Homogeneous coordinates of q\r\n         * @param {Array} p1 Homogeneous coordinates of p1\r\n         * @param {Array} p2 Homogeneous coordinates of p2\r\n         * @returns {Number} Distance of q to line segment [p1, p2]\r\n         */\r\n        distPointSegment: function (q, p1, p2) {\r\n            var x, y, dx, dy,\r\n                den, lbda,\r\n                eps = Mat.eps * Mat.eps,\r\n                huge = 1000000;\r\n\r\n            // Difference q - p1\r\n            x = q[1] - p1[1];\r\n            y = q[2] - p1[2];\r\n            x = (x === Infinity) ? huge : (x === -Infinity) ? -huge : x;\r\n            y = (y === Infinity) ? huge : (y === -Infinity) ? -huge : y;\r\n\r\n            // Difference p2 - p1\r\n            dx = p2[1] - p1[1];\r\n            dy = p2[2] - p1[2];\r\n            dx = (dx === Infinity) ? huge : (dx === -Infinity) ? -huge : dx;\r\n            dy = (dy === Infinity) ? huge : (dy === -Infinity) ? -huge : dy;\r\n\r\n            // If den==0 then p1 and p2 are identical\r\n            // In this case the distance to p1 is returned\r\n            den = dx * dx + dy * dy;\r\n            if (den > eps) {\r\n                lbda = (x * dx + y * dy) / den;\r\n                if (lbda < 0.0) {\r\n                    lbda = 0.0;\r\n                } else if (lbda > 1.0) {\r\n                    lbda = 1.0;\r\n                }\r\n                x -= lbda * dx;\r\n                y -= lbda * dy;\r\n            }\r\n\r\n            return Mat.hypot(x, y);\r\n        },\r\n\r\n        /* ***************************************/\r\n        /* *** 3D CALCULATIONS ****/\r\n        /* ***************************************/\r\n\r\n        /**\r\n         * Generate the function which computes the data of the intersection between\r\n         * <ul>\r\n         * <li> plane3d, plane3d,\r\n         * <li> plane3d, sphere3d,\r\n         * <li> sphere3d, plane3d,\r\n         * <li> sphere3d, sphere3d\r\n         * </ul>\r\n         *\r\n         * @param {JXG.GeometryElement3D} el1 Plane or sphere element\r\n         * @param {JXG.GeometryElement3D} el2 Plane or sphere element\r\n         * @returns {Array} of functions needed as input to create the intersecting line or circle.\r\n         *\r\n         */\r\n        intersectionFunction3D: function (view, el1, el2) {\r\n            var func,\r\n                that = this;\r\n\r\n            if (el1.type === Const.OBJECT_TYPE_PLANE3D) {\r\n                if (el2.type === Const.OBJECT_TYPE_PLANE3D) {\r\n                    // func = () => view.intersectionPlanePlane(el1, el2)[i];\r\n                    func = view.intersectionPlanePlane(el1, el2);\r\n                } else if (el2.type === Const.OBJECT_TYPE_SPHERE3D) {\r\n                    func = that.meetPlaneSphere(el1, el2);\r\n                }\r\n            } else if (el1.type === Const.OBJECT_TYPE_SPHERE3D) {\r\n                if (el2.type === Const.OBJECT_TYPE_PLANE3D) {\r\n                    func = that.meetPlaneSphere(el2, el1);\r\n                } else if (el2.type === Const.OBJECT_TYPE_SPHERE3D) {\r\n                    func = that.meetSphereSphere(el1, el2);\r\n                }\r\n            }\r\n\r\n            return func;\r\n        },\r\n\r\n        /**\r\n         * Intersecting point of three planes in 3D. The planes\r\n         * are given in Hesse normal form.\r\n         *\r\n         * @param {Array} n1 Hesse normal form vector of plane 1\r\n         * @param {Number} d1 Hesse normal form right hand side of plane 1\r\n         * @param {Array} n2 Hesse normal form vector of plane 2\r\n         * @param {Number} d2 Hesse normal form right hand side of plane 2\r\n         * @param {Array} n3 Hesse normal form vector of plane 1\r\n         * @param {Number} d3 Hesse normal form right hand side of plane 3\r\n         * @returns {Array} Coordinates array of length 4 of the intersecting point\r\n         */\r\n        meet3Planes: function (n1, d1, n2, d2, n3, d3) {\r\n            var p = [1, 0, 0, 0],\r\n                n31, n12, n23,\r\n                denom,\r\n                i;\r\n\r\n            n31 = Mat.crossProduct(n3.slice(1), n1.slice(1));\r\n            n12 = Mat.crossProduct(n1.slice(1), n2.slice(1));\r\n            n23 = Mat.crossProduct(n2.slice(1), n3.slice(1));\r\n\r\n            denom = Mat.innerProduct(n1.slice(1), n23, 3);\r\n            for (i = 0; i < 3; i++) {\r\n                p[i + 1] = (d1 * n23[i] + d2 * n31[i] + d3 * n12[i]) / denom;\r\n            }\r\n\r\n            return p;\r\n        },\r\n\r\n        /**\r\n         * Direction of intersecting line of two planes in 3D.\r\n         *\r\n         * @param {Array} v11 First vector spanning plane 1 (homogeneous coordinates)\r\n         * @param {Array} v12 Second vector spanning plane 1 (homogeneous coordinates)\r\n         * @param {Array} v21 First vector spanning plane 2 (homogeneous coordinates)\r\n         * @param {Array} v22 Second vector spanning plane 2 (homogeneous coordinates)\r\n         * @returns {Array} Coordinates array of length 4 of the direction  (homogeneous coordinates)\r\n         */\r\n        meetPlanePlane: function (v11, v12, v21, v22) {\r\n            var no1,\r\n                no2,\r\n                v, w;\r\n\r\n            v = v11.slice(1);\r\n            w = v12.slice(1);\r\n            no1 = Mat.crossProduct(v, w);\r\n\r\n            v = v21.slice(1);\r\n            w = v22.slice(1);\r\n            no2 = Mat.crossProduct(v, w);\r\n\r\n            w = Mat.crossProduct(no1, no2);\r\n            w.unshift(0);\r\n            return w;\r\n        },\r\n\r\n        meetPlaneSphere: function (el1, el2) {\r\n            var dis = function () {\r\n                    return Mat.innerProduct(el1.normal, el2.center.coords, 4) - el1.d;\r\n                };\r\n\r\n            return [\r\n                // Center\r\n                function() {\r\n                    return Mat.axpy(-dis(), el1.normal, el2.center.coords);\r\n                },\r\n                // Normal\r\n                el1.normal,\r\n                // Radius\r\n                function () {\r\n                    // Radius (returns NaN if spheres don't touch)\r\n                    var r = el2.Radius(),\r\n                        s = dis();\r\n                    return Math.sqrt(r * r - s * s);\r\n                }\r\n            ];\r\n        },\r\n\r\n        meetSphereSphere: function (el1, el2) {\r\n            var skew = function () {\r\n                    var dist = el1.center.distance(el2.center),\r\n                        r1 = el1.Radius(),\r\n                        r2 = el2.Radius();\r\n                    return (r1 - r2) * (r1 + r2) / (dist * dist);\r\n                };\r\n            return [\r\n                // Center\r\n                function () {\r\n                    var s = skew();\r\n                    return [\r\n                        1,\r\n                        0.5 * ((1 - s) * el1.center.coords[1] + (1 + s) * el2.center.coords[1]),\r\n                        0.5 * ((1 - s) * el1.center.coords[2] + (1 + s) * el2.center.coords[2]),\r\n                        0.5 * ((1 - s) * el1.center.coords[3] + (1 + s) * el2.center.coords[3])\r\n                    ];\r\n                },\r\n                // Normal\r\n                function() {\r\n                    return Stat.subtract(el2.center.coords, el1.center.coords);\r\n                },\r\n                // Radius\r\n                function () {\r\n                    // Radius (returns NaN if spheres don't touch)\r\n                    var dist = el1.center.distance(el2.center),\r\n                        r1 = el1.Radius(),\r\n                        r2 = el2.Radius(),\r\n                        s = skew(),\r\n                        rIxnSq = 0.5 * (r1 * r1 + r2 * r2 - 0.5 * dist * dist * (1 + s * s));\r\n                    return Math.sqrt(rIxnSq);\r\n                }\r\n            ];\r\n        },\r\n\r\n        /**\r\n         * Test if parameters are inside of allowed ranges\r\n         *\r\n         * @param {Array} params Array of length 1 or 2\r\n         * @param {Array} r_u First range\r\n         * @param {Array} [r_v] Second range\r\n         * @returns Boolean\r\n         * @private\r\n         */\r\n        _paramsOutOfRange: function(params, r_u, r_v) {\r\n            return params[0] < r_u[0] || params[0] > r_u[1] ||\r\n                (params.length > 1 && (params[1] < r_v[0] || params[1] > r_v[1]));\r\n        },\r\n\r\n        /**\r\n         * Given the 2D screen coordinates of a point, finds the nearest point on the given\r\n         * parametric curve or surface, and returns its view-space coordinates.\r\n         * @param {Array} p 3D coordinates for which the closest point on the curve point is searched.\r\n         * @param {JXG.Curve3D|JXG.Surface3D} target Parametric curve or surface to project to.\r\n         * @param {Array} params New position of point on the target (i.e. it is a return value),\r\n         * modified in place during the search, ending up at the nearest point.\r\n         * Usually, point.position is supplied for params.\r\n         *\r\n         * @returns {Array} Array of length 4 containing the coordinates of the nearest point on the curve or surface.\r\n         */\r\n        projectCoordsToParametric: function (p, target, n, params) {\r\n            // The variables and parameters for the Cobyla constrained\r\n            // minimization algorithm are explained in the Cobyla.js comments\r\n            var rhobeg,                // initial size of simplex (Cobyla)\r\n                rhoend,                // finial size of simplex (Cobyla)\r\n                iprint = 0,            // no console output (Cobyla)\r\n                maxfun = 200,          // call objective function at most 200 times (Cobyla)\r\n                _minFunc,              // Objective function for Cobyla\r\n                f = Math.random() * 0.01 + 0.5,\r\n                r_u, r_v,\r\n                m = 2 * n;\r\n\r\n            // adapt simplex size to parameter range\r\n            if (n === 1) {\r\n                r_u = [Type.evaluate(target.range[0]), Type.evaluate(target.range[1])];\r\n\r\n                rhobeg = 0.1 * (r_u[1] - r_u[0]);\r\n            } else if (n === 2) {\r\n                r_u = [Type.evaluate(target.range_u[0]), Type.evaluate(target.range_u[1])];\r\n                r_v = [Type.evaluate(target.range_v[0]), Type.evaluate(target.range_v[1])];\r\n\r\n                rhobeg = 0.1 * Math.min(\r\n                    r_u[1] - r_u[0],\r\n                    r_v[1] - r_v[0]\r\n                );\r\n            }\r\n            rhoend = rhobeg / 5e6;\r\n\r\n            // Minimize distance of the new position to the original position\r\n            _minFunc = function (n, m, w, con) {\r\n                var p_new = [\r\n                        target.X.apply(target, w),\r\n                        target.Y.apply(target, w),\r\n                        target.Z.apply(target, w)\r\n                    ],\r\n                    xDiff = p[0] - p_new[0],\r\n                    yDiff = p[1] - p_new[1],\r\n                    zDiff = p[2] - p_new[2];\r\n\r\n                if (m >= 2) {\r\n                    con[0] =  w[0] - r_u[0];\r\n                    con[1] = -w[0] + r_u[1];\r\n                }\r\n                if (m >= 4) {\r\n                    con[2] =  w[1] - r_v[0];\r\n                    con[3] = -w[1] + r_v[1];\r\n                }\r\n\r\n                return xDiff * xDiff + yDiff * yDiff + zDiff * zDiff;\r\n            };\r\n\r\n            // First optimization without range constraints to give a smooth draag experience on\r\n            // cyclic structures.\r\n\r\n            // Set the start values\r\n            if (params.length === 0) {\r\n                // If length > 0: take the previous position as start values for the optimization\r\n                params[0] = f * (r_u[0] + r_u[1]);\r\n                if (n === 2) { params[1] = f * (r_v[0] + r_v[1]); }\r\n            }\r\n            Mat.Nlp.FindMinimum(_minFunc, n, 0, params, rhobeg, rhoend, iprint, maxfun);\r\n            // Update p which is used subsequently in _minFunc\r\n            p = [target.X.apply(target, params),\r\n                target.Y.apply(target, params),\r\n                target.Z.apply(target, params)\r\n            ];\r\n\r\n            // If the optimal params are outside of the rang\r\n            // Second optimization to obey the range constraints\r\n\r\n            if (this._paramsOutOfRange(params, r_u, r_v)) {\r\n                // Set the start values again\r\n                params[0] = f * (r_u[0] + r_u[1]);\r\n                if (n === 2) { params[1] = f * (r_v[0] + r_v[1]); }\r\n\r\n                Mat.Nlp.FindMinimum(_minFunc, n, m, params, rhobeg, rhoend, iprint, maxfun);\r\n            }\r\n\r\n            return [1,\r\n                target.X.apply(target, params),\r\n                target.Y.apply(target, params),\r\n                target.Z.apply(target, params)\r\n            ];\r\n        },\r\n\r\n        // /**\r\n        //  * Given a the screen coordinates of a point, finds the point on the\r\n        //  * given parametric curve or surface which is nearest in screen space,\r\n        //  * and returns its view-space coordinates.\r\n        //  * @param {Array} pScr Screen coordinates to project.\r\n        //  * @param {JXG.Curve3D|JXG.Surface3D} target Parametric curve or surface to project to.\r\n        //  * @param {Array} params Parameters of point on the target, initially specifying the starting point of\r\n        //  * the search. The parameters are modified in place during the search, ending up at the nearest point.\r\n        //  * @returns {Array} Array of length 4 containing the coordinates of the nearest point on the curve or surface.\r\n        //  */\r\n        // projectScreenCoordsToParametric: function (pScr, target, params) {\r\n        //     // The variables and parameters for the Cobyla constrained\r\n        //     // minimization algorithm are explained in the Cobyla.js comments\r\n        //     var rhobeg, // initial size of simplex (Cobyla)\r\n        //         rhoend, // finial size of simplex (Cobyla)\r\n        //         iprint = 0, // no console output (Cobyla)\r\n        //         maxfun = 200, // call objective function at most 200 times (Cobyla)\r\n        //         dim = params.length,\r\n        //         _minFunc; // objective function (Cobyla)\r\n\r\n        //     // adapt simplex size to parameter range\r\n        //     if (dim === 1) {\r\n        //         rhobeg = 0.1 * (target.range[1] - target.range[0]);\r\n        //     } else if (dim === 2) {\r\n        //         rhobeg = 0.1 * Math.min(\r\n        //             target.range_u[1] - target.range_u[0],\r\n        //             target.range_v[1] - target.range_v[0]\r\n        //         );\r\n        //     }\r\n        //     rhoend = rhobeg / 5e6;\r\n\r\n        //     // minimize screen distance to cursor\r\n        //     _minFunc = function (n, m, w, con) {\r\n        //         var c3d = [\r\n        //             1,\r\n        //             target.X.apply(target, w),\r\n        //             target.Y.apply(target, w),\r\n        //             target.Z.apply(target, w)\r\n        //         ],\r\n        //         c2d = target.view.project3DTo2D(c3d),\r\n        //         xDiff = pScr[0] - c2d[1],\r\n        //         yDiff = pScr[1] - c2d[2];\r\n\r\n        //         if (n === 1) {\r\n        //             con[0] = w[0] - target.range[0];\r\n        //             con[1] = -w[0] + target.range[1];\r\n        //         } else if (n === 2) {\r\n        //             con[0] = w[0] - target.range_u[0];\r\n        //             con[1] = -w[0] + target.range_u[1];\r\n        //             con[2] = w[1] - target.range_v[0];\r\n        //             con[3] = -w[1] + target.range_v[1];\r\n        //         }\r\n\r\n        //         return xDiff * xDiff + yDiff * yDiff;\r\n        //     };\r\n\r\n        //     Mat.Nlp.FindMinimum(_minFunc, dim, 2 * dim, params, rhobeg, rhoend, iprint, maxfun);\r\n\r\n        //     return [1, target.X.apply(target, params), target.Y.apply(target, params), target.Z.apply(target, params)];\r\n        // },\r\n\r\n        project3DTo3DPlane: function (point, normal, foot) {\r\n            // TODO: homogeneous 3D coordinates\r\n            var sol = [0, 0, 0],\r\n                le,\r\n                d1,\r\n                d2,\r\n                lbda;\r\n\r\n            foot = foot || [0, 0, 0];\r\n\r\n            le = Mat.norm(normal);\r\n            d1 = Mat.innerProduct(point, normal, 3);\r\n            d2 = Mat.innerProduct(foot, normal, 3);\r\n            // (point - lbda * normal / le) * normal / le == foot * normal / le\r\n            // => (point * normal - foot * normal) ==  lbda * le\r\n            lbda = (d1 - d2) / le;\r\n            sol = Mat.axpy(-lbda, normal, point);\r\n\r\n            return sol;\r\n        },\r\n\r\n        getPlaneBounds: function (v1, v2, q, s, e) {\r\n            var s1, s2, e1, e2, mat, rhs, sol;\r\n\r\n            if (v1[2] + v2[0] !== 0) {\r\n                mat = [\r\n                    [v1[0], v2[0]],\r\n                    [v1[1], v2[1]]\r\n                ];\r\n                rhs = [s - q[0], s - q[1]];\r\n\r\n                sol = Numerics.Gauss(mat, rhs);\r\n                s1 = sol[0];\r\n                s2 = sol[1];\r\n\r\n                rhs = [e - q[0], e - q[1]];\r\n                sol = Numerics.Gauss(mat, rhs);\r\n                e1 = sol[0];\r\n                e2 = sol[1];\r\n                return [s1, e1, s2, e2];\r\n            }\r\n            return null;\r\n        },\r\n\r\n        /* ***************************************/\r\n        /* *** Various ****/\r\n        /* ***************************************/\r\n\r\n        /**\r\n         * Helper function to create curve which displays a Reuleaux polygons.\r\n         * @param {Array} points Array of points which should be the vertices of the Reuleaux polygon. Typically,\r\n         * these point list is the array vertices of a regular polygon.\r\n         * @param {Number} nr Number of vertices\r\n         * @returns {Array} An array containing the two functions defining the Reuleaux polygon and the two values\r\n         * for the start and the end of the paramtric curve. array may be used as parent array of a\r\n         * {@link JXG.Curve}.\r\n         *\r\n         * @example\r\n         * var A = brd.create('point',[-2,-2]);\r\n         * var B = brd.create('point',[0,1]);\r\n         * var pol = brd.create('regularpolygon',[A,B,3], {withLines:false, fillColor:'none', highlightFillColor:'none', fillOpacity:0.0});\r\n         * var reuleauxTriangle = brd.create('curve', JXG.Math.Geometry.reuleauxPolygon(pol.vertices, 3),\r\n         *                          {strokeWidth:6, strokeColor:'#d66d55', fillColor:'#ad5544', highlightFillColor:'#ad5544'});\r\n         *\r\n         * </pre><div class=\"jxgbox\" id=\"JXG2543a843-46a9-4372-abc1-94d9ad2db7ac\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         * var brd = JXG.JSXGraph.initBoard('JXG2543a843-46a9-4372-abc1-94d9ad2db7ac', {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright:false, shownavigation: false});\r\n         * var A = brd.create('point',[-2,-2]);\r\n         * var B = brd.create('point',[0,1]);\r\n         * var pol = brd.create('regularpolygon',[A,B,3], {withLines:false, fillColor:'none', highlightFillColor:'none', fillOpacity:0.0});\r\n         * var reuleauxTriangle = brd.create('curve', JXG.Math.Geometry.reuleauxPolygon(pol.vertices, 3),\r\n         *                          {strokeWidth:6, strokeColor:'#d66d55', fillColor:'#ad5544', highlightFillColor:'#ad5544'});\r\n         * </script><pre>\r\n         */\r\n        reuleauxPolygon: function (points, nr) {\r\n            var beta,\r\n                pi2 = Math.PI * 2,\r\n                pi2_n = pi2 / nr,\r\n                diag = (nr - 1) / 2,\r\n                d = 0,\r\n                makeFct = function (which, trig) {\r\n                    return function (t, suspendUpdate) {\r\n                        var t1 = ((t % pi2) + pi2) % pi2,\r\n                            j = Math.floor(t1 / pi2_n) % nr;\r\n\r\n                        if (!suspendUpdate) {\r\n                            d = points[0].Dist(points[diag]);\r\n                            beta = Mat.Geometry.rad(\r\n                                [points[0].X() + 1, points[0].Y()],\r\n                                points[0],\r\n                                points[diag % nr]\r\n                            );\r\n                        }\r\n\r\n                        if (isNaN(j)) {\r\n                            return j;\r\n                        }\r\n\r\n                        t1 = t1 * 0.5 + j * pi2_n * 0.5 + beta;\r\n\r\n                        return points[j][which]() + d * Math[trig](t1);\r\n                    };\r\n                };\r\n\r\n            return [makeFct(\"X\", 'cos'), makeFct(\"Y\", 'sin'), 0, pi2];\r\n        }\r\n\r\n    }\r\n);\r\n\r\nexport default Mat.Geometry;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Mat from \"./math.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Functions for mathematical statistics. Most functions are like in the statistics package R.\r\n * @name JXG.Math.Statistics\r\n * @exports Mat.Statistics as JXG.Math.Statistics\r\n * @namespace\r\n */\r\nMat.Statistics = {\r\n    /**\r\n     * Sums up all elements of the given array.\r\n     * @param {Array} arr An array of numbers.\r\n     * @returns {Number}\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    sum: function (arr) {\r\n        var i,\r\n            len = arr.length,\r\n            res = 0;\r\n\r\n        for (i = 0; i < len; i++) {\r\n            res += arr[i];\r\n        }\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Multiplies all elements of the given array.\r\n     * @param {Array} arr An array of numbers.\r\n     * @returns {Number}\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    prod: function (arr) {\r\n        var i,\r\n            len = arr.length,\r\n            res = 1;\r\n\r\n        for (i = 0; i < len; i++) {\r\n            res *= arr[i];\r\n        }\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Determines the mean value of the values given in an array.\r\n     * @param {Array} arr\r\n     * @returns {Number}\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    mean: function (arr) {\r\n        if (arr.length > 0) {\r\n            return this.sum(arr) / arr.length;\r\n        }\r\n\r\n        return 0.0;\r\n    },\r\n\r\n    /**\r\n     * The median of a finite set of values is the value that divides the set\r\n     * into two equal sized subsets.\r\n     * @param {Array} arr The set of values.\r\n     * @returns {Number}\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    median: function (arr) {\r\n        var tmp, len;\r\n\r\n        if (arr.length > 0) {\r\n            if (ArrayBuffer.isView(arr)) {\r\n                tmp = new Float64Array(arr);\r\n                tmp.sort();\r\n            } else {\r\n                tmp = arr.slice(0);\r\n                tmp.sort(function (a, b) {\r\n                    return a - b;\r\n                });\r\n            }\r\n            len = tmp.length;\r\n\r\n            if (len & 1) {\r\n                // odd\r\n                return tmp[parseInt(len * 0.5, 10)];\r\n            }\r\n\r\n            return (tmp[len * 0.5 - 1] + tmp[len * 0.5]) * 0.5;\r\n        }\r\n\r\n        return 0.0;\r\n    },\r\n\r\n    /**\r\n     * The P-th percentile ( <i>0 < P ≤ 100</i> ) of a list of <i>N</i> ordered values (sorted from least to greatest)\r\n     * is the smallest value in the list such that no more than <i>P</i> percent of the data is strictly less\r\n     * than the value and at least <i>P</i> percent of the data is less than or equal to that value.\r\n     * See <a href=\"https://en.wikipedia.org/wiki/Percentile\">https://en.wikipedia.org/wiki/Percentile</a>.\r\n     *\r\n     * Here, the <i>linear interpolation between closest ranks</i> method is used.\r\n     * @param {Array} arr The set of values, need not be ordered.\r\n     * @param {Number|Array} percentile One or several percentiles\r\n     * @returns {Number|Array} Depending if a number or an array is the input for percentile, a number or an array containing the percentiles\r\n     * is returned.\r\n     */\r\n    percentile: function (arr, percentile) {\r\n        var tmp,\r\n            len,\r\n            i,\r\n            p,\r\n            res = [],\r\n            per;\r\n\r\n        if (arr.length > 0) {\r\n            if (ArrayBuffer.isView(arr)) {\r\n                tmp = new Float64Array(arr);\r\n                tmp.sort();\r\n            } else {\r\n                tmp = arr.slice(0);\r\n                tmp.sort(function (a, b) {\r\n                    return a - b;\r\n                });\r\n            }\r\n            len = tmp.length;\r\n\r\n            if (Type.isArray(percentile)) {\r\n                p = percentile;\r\n            } else {\r\n                p = [percentile];\r\n            }\r\n\r\n            for (i = 0; i < p.length; i++) {\r\n                per = len * p[i] * 0.01;\r\n                if (parseInt(per, 10) === per) {\r\n                    res.push((tmp[per - 1] + tmp[per]) * 0.5);\r\n                } else {\r\n                    res.push(tmp[parseInt(per, 10)]);\r\n                }\r\n            }\r\n\r\n            if (Type.isArray(percentile)) {\r\n                return res;\r\n            } else {\r\n                return res[0];\r\n            }\r\n        }\r\n\r\n        return 0.0;\r\n    },\r\n\r\n    /**\r\n     * Bias-corrected sample variance. A variance is a measure of how far a\r\n     * set of numbers are spread out from each other.\r\n     * @param {Array} arr\r\n     * @returns {Number}\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    variance: function (arr) {\r\n        var m,\r\n            res,\r\n            i,\r\n            len = arr.length;\r\n\r\n        if (len > 1) {\r\n            m = this.mean(arr);\r\n            res = 0;\r\n            for (i = 0; i < len; i++) {\r\n                res += (arr[i] - m) * (arr[i] - m);\r\n            }\r\n            return res / (arr.length - 1);\r\n        }\r\n\r\n        return 0.0;\r\n    },\r\n\r\n    /**\r\n     * Determines the <strong>s</strong>tandard <strong>d</strong>eviation which shows how much\r\n     * variation there is from the average value of a set of numbers.\r\n     * @param {Array} arr\r\n     * @returns {Number}\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    sd: function (arr) {\r\n        return Math.sqrt(this.variance(arr));\r\n    },\r\n\r\n    /**\r\n     * Weighted mean value is basically the same as {@link JXG.Math.Statistics.mean} but here the values\r\n     * are weighted, i.e. multiplied with another value called <em>weight</em>. The weight values are given\r\n     * as a second array with the same length as the value array..\r\n     * @throws {Error} If the dimensions of the arrays don't match.\r\n     * @param {Array} arr Set of alues.\r\n     * @param {Array} w Weight values.\r\n     * @returns {Number}\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    weightedMean: function (arr, w) {\r\n        if (arr.length !== w.length) {\r\n            throw new Error(\r\n                \"JSXGraph error (Math.Statistics.weightedMean): Array dimension mismatch.\"\r\n            );\r\n        }\r\n\r\n        if (arr.length > 0) {\r\n            return this.mean(this.multiply(arr, w));\r\n        }\r\n\r\n        return 0.0;\r\n    },\r\n\r\n    /**\r\n     * Extracts the maximum value from the array.\r\n     * @param {Array} arr\r\n     * @returns {Number} The highest number from the array. It returns <tt>NaN</tt> if not every element could be\r\n     * interpreted as a number and <tt>-Infinity</tt> if an empty array is given or no element could be interpreted\r\n     * as a number.\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    max: function (arr) {\r\n        return Math.max.apply(this, arr);\r\n    },\r\n\r\n    /**\r\n     * Extracts the minimum value from the array.\r\n     * @param {Array} arr\r\n     * @returns {Number} The lowest number from the array. It returns <tt>NaN</tt> if not every element could be\r\n     * interpreted as a number and <tt>Infinity</tt> if an empty array is given or no element could be interpreted\r\n     * as a number.\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    min: function (arr) {\r\n        return Math.min.apply(this, arr);\r\n    },\r\n\r\n    /**\r\n     * Determines the lowest and the highest value from the given array.\r\n     * @param {Array} arr\r\n     * @returns {Array} The minimum value as the first and the maximum value as the second value.\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    range: function (arr) {\r\n        return [this.min(arr), this.max(arr)];\r\n    },\r\n\r\n    /**\r\n     * Determines the absolute value of every given value.\r\n     * @param {Array|Number} arr\r\n     * @returns {Array|Number}\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    abs: function (arr) {\r\n        var i, len, res;\r\n\r\n        if (Type.isArray(arr)) {\r\n            if (arr.map) {\r\n                res = arr.map(Math.abs);\r\n            } else {\r\n                len = arr.length;\r\n                res = [];\r\n\r\n                for (i = 0; i < len; i++) {\r\n                    res[i] = Math.abs(arr[i]);\r\n                }\r\n            }\r\n        } else if (ArrayBuffer.isView(arr)) {\r\n            res = arr.map(Math.abs);\r\n        } else {\r\n            res = Math.abs(arr);\r\n        }\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Adds up two (sequences of) values. If one value is an array and the other one is a number the number\r\n     * is added to every element of the array. If two arrays are given and the lengths don't match the shortest\r\n     * length is taken.\r\n     * @param {Array|Number} arr1\r\n     * @param {Array|Number} arr2\r\n     * @returns {Array|Number}\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    add: function (arr1, arr2) {\r\n        var i,\r\n            len,\r\n            res = [];\r\n\r\n        arr1 = Type.evalSlider(arr1);\r\n        arr2 = Type.evalSlider(arr2);\r\n\r\n        if (Type.isArray(arr1) && Type.isNumber(arr2)) {\r\n            len = arr1.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = arr1[i] + arr2;\r\n            }\r\n        } else if (Type.isNumber(arr1) && Type.isArray(arr2)) {\r\n            len = arr2.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = arr1 + arr2[i];\r\n            }\r\n        } else if (Type.isArray(arr1) && Type.isArray(arr2)) {\r\n            len = Math.min(arr1.length, arr2.length);\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = arr1[i] + arr2[i];\r\n            }\r\n        } else {\r\n            res = arr1 + arr2;\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Divides two (sequences of) values. If two arrays are given and the lengths don't match the shortest length\r\n     * is taken.\r\n     * @param {Array|Number} arr1 Dividend\r\n     * @param {Array|Number} arr2 Divisor\r\n     * @returns {Array|Number}\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    div: function (arr1, arr2) {\r\n        var i,\r\n            len,\r\n            res = [];\r\n\r\n        arr1 = Type.evalSlider(arr1);\r\n        arr2 = Type.evalSlider(arr2);\r\n\r\n        if (Type.isArray(arr1) && Type.isNumber(arr2)) {\r\n            len = arr1.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = arr1[i] / arr2;\r\n            }\r\n        } else if (Type.isNumber(arr1) && Type.isArray(arr2)) {\r\n            len = arr2.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = arr1 / arr2[i];\r\n            }\r\n        } else if (Type.isArray(arr1) && Type.isArray(arr2)) {\r\n            len = Math.min(arr1.length, arr2.length);\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = arr1[i] / arr2[i];\r\n            }\r\n        } else {\r\n            res = arr1 / arr2;\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * @function\r\n     * @deprecated Use {@link JXG.Math.Statistics.div} instead.\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    divide: function () {\r\n        JXG.deprecated(\"Statistics.divide()\", \"Statistics.div()\");\r\n        Mat.Statistics.div.apply(Mat.Statistics, arguments);\r\n    },\r\n\r\n    /**\r\n     * Divides two (sequences of) values and returns the remainder. If two arrays are given and the lengths don't\r\n     * match the shortest length is taken.\r\n     * @param {Array|Number} arr1 Dividend\r\n     * @param {Array|Number} arr2 Divisor\r\n     * @param {Boolean} [math=false] Mathematical mod or symmetric mod? Default is symmetric, the JavaScript <tt>%</tt> operator.\r\n     * @returns {Array|Number}\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    mod: function (arr1, arr2, math) {\r\n        var i,\r\n            len,\r\n            res = [],\r\n            mod = function (a, m) {\r\n                return a % m;\r\n            };\r\n\r\n        math = Type.def(math, false);\r\n\r\n        if (math) {\r\n            mod = Mat.mod;\r\n        }\r\n\r\n        arr1 = Type.evalSlider(arr1);\r\n        arr2 = Type.evalSlider(arr2);\r\n\r\n        if (Type.isArray(arr1) && Type.isNumber(arr2)) {\r\n            len = arr1.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = mod(arr1[i], arr2);\r\n            }\r\n        } else if (Type.isNumber(arr1) && Type.isArray(arr2)) {\r\n            len = arr2.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = mod(arr1, arr2[i]);\r\n            }\r\n        } else if (Type.isArray(arr1) && Type.isArray(arr2)) {\r\n            len = Math.min(arr1.length, arr2.length);\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = mod(arr1[i], arr2[i]);\r\n            }\r\n        } else {\r\n            res = mod(arr1, arr2);\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Multiplies two (sequences of) values. If one value is an array and the other one is a number the number\r\n     * is multiplied to every element of the array. If two arrays are given and the lengths don't match the shortest\r\n     * length is taken.\r\n     * @param {Array|Number} arr1\r\n     * @param {Array|Number} arr2\r\n     * @returns {Array|Number}\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    multiply: function (arr1, arr2) {\r\n        var i,\r\n            len,\r\n            res = [];\r\n\r\n        arr1 = Type.evalSlider(arr1);\r\n        arr2 = Type.evalSlider(arr2);\r\n\r\n        if (Type.isArray(arr1) && Type.isNumber(arr2)) {\r\n            len = arr1.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = arr1[i] * arr2;\r\n            }\r\n        } else if (Type.isNumber(arr1) && Type.isArray(arr2)) {\r\n            len = arr2.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = arr1 * arr2[i];\r\n            }\r\n        } else if (Type.isArray(arr1) && Type.isArray(arr2)) {\r\n            len = Math.min(arr1.length, arr2.length);\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = arr1[i] * arr2[i];\r\n            }\r\n        } else {\r\n            res = arr1 * arr2;\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Subtracts two (sequences of) values. If two arrays are given and the lengths don't match the shortest\r\n     * length is taken.\r\n     * @param {Array|Number} arr1 Minuend\r\n     * @param {Array|Number} arr2 Subtrahend\r\n     * @returns {Array|Number}\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    subtract: function (arr1, arr2) {\r\n        var i,\r\n            len,\r\n            res = [];\r\n\r\n        arr1 = Type.evalSlider(arr1);\r\n        arr2 = Type.evalSlider(arr2);\r\n\r\n        if (Type.isArray(arr1) && Type.isNumber(arr2)) {\r\n            len = arr1.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = arr1[i] - arr2;\r\n            }\r\n        } else if (Type.isNumber(arr1) && Type.isArray(arr2)) {\r\n            len = arr2.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = arr1 - arr2[i];\r\n            }\r\n        } else if (Type.isArray(arr1) && Type.isArray(arr2)) {\r\n            len = Math.min(arr1.length, arr2.length);\r\n\r\n            for (i = 0; i < len; i++) {\r\n                res[i] = arr1[i] - arr2[i];\r\n            }\r\n        } else {\r\n            res = arr1 - arr2;\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * The Theil-Sen estimator can be used to determine a more robust linear regression of a set of sample\r\n     * points than least squares regression in {@link JXG.Math.Numerics.regressionPolynomial}.\r\n     *\r\n     * If the function should be applied to an array a of points, a the coords array can be generated with\r\n     * JavaScript array.map:\r\n     *\r\n     * <pre>\r\n     * JXG.Math.Statistics.TheilSenRegression(a.map(el => el.coords));\r\n     * </pre>\r\n     *\r\n     * @param {Array} coords Array of {@link JXG.Coords}.\r\n     * @returns {Array} A stdform array of the regression line.\r\n     * @memberof JXG.Math.Statistics\r\n     *\r\n     * @example\r\n     * var board = JXG.JSXGraph.initBoard('jxgbox', { boundingbox: [-6,6,6,-6], axis : true });\r\n     * var a=[];\r\n     * a[0]=board.create('point', [0,0]);\r\n     * a[1]=board.create('point', [3,0]);\r\n     * a[2]=board.create('point', [0,3]);\r\n     *\r\n     * board.create('line', [\r\n     *     () => JXG.Math.Statistics.TheilSenRegression(a.map(el => el.coords))\r\n     *   ],\r\n     *   {strokeWidth:1, strokeColor:'black'});\r\n     *\r\n     * </pre><div id=\"JXG0a28be85-91c5-44d3-aae6-114e81217cf0\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXG0a28be85-91c5-44d3-aae6-114e81217cf0',\r\n     *             {boundingbox: [-6,6,6,-6], axis: true, showcopyright: false, shownavigation: false});\r\n     *     var a=[];\r\n     *     a[0]=board.create('point', [0,0]);\r\n     *     a[1]=board.create('point', [3,0]);\r\n     *     a[2]=board.create('point', [0,3]);\r\n     *\r\n     *     board.create('line', [\r\n     *         () => JXG.Math.Statistics.TheilSenRegression(a.map(el => el.coords))\r\n     *       ],\r\n     *       {strokeWidth:1, strokeColor:'black'});\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     */\r\n    TheilSenRegression: function (coords) {\r\n        var i,\r\n            j,\r\n            slopes = [],\r\n            tmpslopes = [],\r\n            yintercepts = [];\r\n\r\n        for (i = 0; i < coords.length; i++) {\r\n            tmpslopes.length = 0;\r\n\r\n            for (j = 0; j < coords.length; j++) {\r\n                if (Math.abs(coords[j].usrCoords[1] - coords[i].usrCoords[1]) > Mat.eps) {\r\n                    tmpslopes[j] =\r\n                        (coords[j].usrCoords[2] - coords[i].usrCoords[2]) /\r\n                        (coords[j].usrCoords[1] - coords[i].usrCoords[1]);\r\n                }\r\n            }\r\n\r\n            slopes[i] = this.median(tmpslopes);\r\n            yintercepts.push(coords[i].usrCoords[2] - slopes[i] * coords[i].usrCoords[1]);\r\n        }\r\n\r\n        return [this.median(yintercepts), this.median(slopes), -1];\r\n    },\r\n\r\n    /**\r\n     * Generate values of a standard normal random variable with the Marsaglia polar method, see\r\n     * <a href=\"https://en.wikipedia.org/wiki/Marsaglia_polar_method\">https://en.wikipedia.org/wiki/Marsaglia_polar_method</a>.\r\n     * See also D. E. Knuth, The art of computer programming, vol 2, p. 117.\r\n     *\r\n     * @param {Number} mean mean value of the normal distribution\r\n     * @param {Number} stdDev standard deviation of the normal distribution\r\n     * @returns {Number} value of a standard normal random variable\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    generateGaussian: function (mean, stdDev) {\r\n        var u, v, s;\r\n\r\n        if (this.hasSpare) {\r\n            this.hasSpare = false;\r\n            return this.spare * stdDev + mean;\r\n        }\r\n\r\n        do {\r\n            u = Math.random() * 2 - 1;\r\n            v = Math.random() * 2 - 1;\r\n            s = u * u + v * v;\r\n        } while (s >= 1 || s === 0);\r\n\r\n        s = Math.sqrt((-2.0 * Math.log(s)) / s);\r\n\r\n        this.spare = v * s;\r\n        this.hasSpare = true;\r\n        return mean + stdDev * u * s;\r\n    },\r\n\r\n    /**\r\n     * Generate value of a standard normal random variable with given mean and standard deviation.\r\n     * Alias for {@link JXG.Math.Statistics#generateGaussian}\r\n     *\r\n     * @param {Number} mean\r\n     * @param {Number} stdDev\r\n     * @returns Number\r\n     * @memberof JXG.Math.Statistics\r\n     * @see JXG.Math.Statistics.generateGaussian\r\n     * @example\r\n     *  let board = JXG.JSXGraph.initBoard('JXGbox',\r\n     *       { boundingbox: [-5, 1.5, 5, -.03], axis: true});\r\n     *\r\n     *   let runs = [\r\n     *       [0, 0.2, 'blue'],\r\n     *       [0, 1.0, 'red'],\r\n     *       [0, 5.0, 'orange'],\r\n     *       [-2,0.5, 'green'],\r\n     *   ]\r\n     *\r\n     *   let labelY = 1.2\r\n     *   runs.forEach((run,i) => {\r\n     *       board.create('segment',[[1.0,labelY-(i/20)],[2.0,labelY-(i/20)]],{strokeColor:run[2]})\r\n     *       board.create('text',[2.5,labelY-(i/20),`&mu;=${run[0]}, &#963;<sup>2</sup>=${run[1]}`])\r\n     *\r\n     *       let x = Array(50000).fill(0).map(() => JXG.Math.Statistics.randomNormal(run[0],Math.sqrt(run[1])))  // sqrt so Std Dev, not Variance\r\n     *       let res = JXG.Math.Statistics.histogram(x, { bins: 40, density: true, cumulative: false, range: false });\r\n     *       board.create('curve', [res[1], res[0]], { strokeColor: run[2], strokeWidth:2});\r\n     *   })\r\n     *\r\n     * </pre><div id=\"JXGda56df4d-a5a5-4c87-9ffc-9bbc1b512302-4\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     * {\r\n     *  let board = JXG.JSXGraph.initBoard('JXGda56df4d-a5a5-4c87-9ffc-9bbc1b512302-4',\r\n     *       { boundingbox: [-5, 1.5, 5, -.03], axis: true});\r\n     *\r\n     *   let runs = [\r\n     *       [0, 0.2, 'blue'],\r\n     *       [0, 1.0, 'red'],\r\n     *       [0, 5.0, 'orange'],\r\n     *       [-2,0.5, 'green'],\r\n     *   ]\r\n     *\r\n     *   let labelY = 1.2\r\n     *   runs.forEach((run,i) => {\r\n     *       board.create('segment',[[1.0,labelY-(i/20)],[2.0,labelY-(i/20)]],{strokeColor:run[2]})\r\n     *       board.create('text',[2.5,labelY-(i/20),`&mu;=${run[0]}, &#963;<sup>2</sup>=${run[1]}`])\r\n     *\r\n     *       let x = Array(50000).fill(0).map(() => JXG.Math.Statistics.randomNormal(run[0],Math.sqrt(run[1])))  // sqrt so Std Dev, not Variance\r\n     *       let res = JXG.Math.Statistics.histogram(x, { bins: 40, density: true, cumulative: false, range: false });\r\n     *       board.create('curve', [res[1], res[0]], { strokeColor: run[2], strokeWidth:2});\r\n     *   })\r\n     * }\r\n     * </script><pre>\r\n\r\n     */\r\n    randomNormal: function (mean, stdDev) {\r\n        return this.generateGaussian(mean, stdDev);\r\n    },\r\n\r\n    /**\r\n     * Generate value of a uniform distributed random variable in the interval [a, b].\r\n     * @param {Number} a\r\n     * @param {Number} b\r\n     * @returns Number\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    randomUniform: function (a, b) {\r\n        return Math.random() * (b - a) + a;\r\n    },\r\n\r\n    /**\r\n     * Generate value of a random variable with exponential distribution, i.e.\r\n     * <i>f(x; lambda) = lambda * e^(-lambda x)</i> if <i>x >= 0</i> and <i>f(x; lambda) = 0</i> if <i>x < 0</i>.\r\n     * See <a href=\"https://en.wikipedia.org/wiki/Exponential_distribution\">https://en.wikipedia.org/wiki/Exponential_distribution</a>.\r\n     * Algorithm: D.E. Knuth, TAOCP 2, p. 128.\r\n     *\r\n     * @param {Number} lambda <i>&gt; 0</i>\r\n     * @returns Number\r\n     * @memberof JXG.Math.Statistics\r\n     * @example\r\n     *  let board = JXG.JSXGraph.initBoard('JXGbox',\r\n     *       { boundingbox: [-.5, 1.5, 5, -.1], axis: true});\r\n     *\r\n     *   let runs = [\r\n     *       [0.5, 'red'],\r\n     *       [1.0, 'green'],\r\n     *       [1.5, 'blue'],\r\n     *   ]\r\n     *\r\n     *   let labelY = 1\r\n     *   runs.forEach((run,i) => {\r\n     *       board.create('segment',[[1.8,labelY-(i/20)],[2.3,labelY-(i/20)]],{strokeColor:run[1]})\r\n     *       board.create('text',[2.5,labelY-(i/20),`&lambda;=${run[0]}`])\r\n     *\r\n     *       let x = Array(50000).fill(0).map(() => JXG.Math.Statistics.randomExponential(run[0]))\r\n     *       let res = JXG.Math.Statistics.histogram(x, { bins: 40, density: true, cumulative: false, range: false });\r\n     *       board.create('curve', [res[1], res[0]], { strokeColor: run[1], strokeWidth:2});\r\n     *   })\r\n     *\r\n     * </pre><div id=\"JXGda56df4d-a5a5-4c87-9ffc-9bbc1b512302-5\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     * {\r\n     *  let board = JXG.JSXGraph.initBoard('JXGda56df4d-a5a5-4c87-9ffc-9bbc1b512302-5',\r\n     *       { boundingbox: [-.5, 1.5, 5, -.1], axis: true});\r\n     *\r\n     *   let runs = [\r\n     *       [0.5, 'red'],\r\n     *       [1.0, 'green'],\r\n     *       [1.5, 'blue'],\r\n     *   ]\r\n     *\r\n     *   let labelY = 1\r\n     *   runs.forEach((run,i) => {\r\n     *       board.create('segment',[[1.8,labelY-(i/20)],[2.3,labelY-(i/20)]],{strokeColor:run[1]})\r\n     *       board.create('text',[2.5,labelY-(i/20),`&lambda;=${run[0]}`])\r\n     *\r\n     *       let x = Array(50000).fill(0).map(() => JXG.Math.Statistics.randomExponential(run[0]))\r\n     *       let res = JXG.Math.Statistics.histogram(x, { bins: 40, density: true, cumulative: false, range: false });\r\n     *       board.create('curve', [res[1], res[0]], { strokeColor: run[1], strokeWidth:2});\r\n     *   })\r\n     * }\r\n     * </script><pre>\r\n\r\n    */\r\n    randomExponential: function (lbda) {\r\n        var u;\r\n\r\n        // Knuth, TAOCP 2, p 128\r\n        // See https://en.wikipedia.org/wiki/Exponential_distribution\r\n        if (lbda <= 0) {\r\n            return NaN;\r\n        }\r\n\r\n        do {\r\n            u = Math.random();\r\n        } while (u === 0);\r\n\r\n        return -Math.log(u) / lbda;\r\n    },\r\n\r\n    /**\r\n     * Generate value of a random variable with gamma distribution of order alpha.\r\n     * See <a href=\"https://en.wikipedia.org/wiki/Gamma_distribution\">https://en.wikipedia.org/wiki/Gamma_distribution</a>.\r\n     * Algorithm: D.E. Knuth, TAOCP 2, p. 129.\r\n\r\n     * @param {Number} a shape, <i> &gt; 0</i>\r\n     * @param {Number} [b=1] scale, <i> &gt; 0</i>\r\n     * @param {Number} [t=0] threshold\r\n     * @returns Number\r\n     * @memberof JXG.Math.Statistics\r\n     * @example\r\n     *  let board = JXG.JSXGraph.initBoard('jxgbox',\r\n     *       { boundingbox: [-1.7, .5, 20, -.03], axis: true});\r\n     *\r\n     *   let runs = [\r\n     *       [0.5, 1.0, 'brown'],\r\n     *       [1.0, 2.0, 'red'],\r\n     *       [2.0, 2.0, 'orange'],\r\n     *       [3.0, 2.0, 'yellow'],\r\n     *       [5.0, 1.0, 'green'],\r\n     *       [9.0, 0.5, 'black'],\r\n     *       [7.5, 1.0, 'purple'],\r\n     *   ]\r\n     *\r\n     *   let labelY = .4\r\n     *   runs.forEach((run,i) => {\r\n     *       board.create('segment',[[7,labelY-(i/50)],[9,labelY-(i/50)]],{strokeColor:run[2]})\r\n     *       board.create('text',[10,labelY-(i/50),`k=${run[0]}, &theta;=${run[1]}`])\r\n     *\r\n     *       // density\r\n     *       let x = Array(50000).fill(0).map(() => JXG.Math.Statistics.randomGamma(run[0],run[1]))\r\n     *       let res = JXG.Math.Statistics.histogram(x, { bins: 50, density: true, cumulative: false, range: [0, 20] });\r\n     *       board.create('curve', [res[1], res[0]], { strokeColor: run[2]});\r\n     *\r\n     *   })\r\n     *\r\n     *\r\n     * </pre>\r\n     * <div id=\"JXGda56df4d-a5a5-4c87-9ffc-9bbc1b512302-6\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     * {\r\n     *  let board = JXG.JSXGraph.initBoard('JXGda56df4d-a5a5-4c87-9ffc-9bbc1b512302-6',\r\n     *       { boundingbox: [-1.7, .5, 20, -.03], axis: true});\r\n     *\r\n     *   let runs = [\r\n     *       [0.5, 1.0, 'brown'],\r\n     *       [1.0, 2.0, 'red'],\r\n     *       [2.0, 2.0, 'orange'],\r\n     *       [3.0, 2.0, 'yellow'],\r\n     *       [5.0, 1.0, 'green'],\r\n     *       [9.0, 0.5, 'black'],\r\n     *       [7.5, 1.0, 'purple'],\r\n     *   ]\r\n     *\r\n     *   let labelY = .4\r\n     *   runs.forEach((run,i) => {\r\n     *       board.create('segment',[[7,labelY-(i/50)],[9,labelY-(i/50)]],{strokeColor:run[2]})\r\n     *       board.create('text',[10,labelY-(i/50),`k=${run[0]}, &theta;=${run[1]}`])\r\n     *\r\n     *       let x = Array(50000).fill(0).map(() => JXG.Math.Statistics.randomGamma(run[0],run[1]))\r\n     *       let res = JXG.Math.Statistics.histogram(x, { bins: 50, density: true, cumulative: false, range: [0, 20] });\r\n     *       board.create('curve', [res[1], res[0]], { strokeColor: run[2]});\r\n     *   })\r\n     * }\r\n     * </script><pre>\r\n     *\r\n     */\r\n    randomGamma: function (a, b, t) {\r\n        var u, v, x, y,\r\n            p, q;\r\n\r\n        if (a <= 0) {\r\n            return NaN;\r\n        }\r\n\r\n        b = b || 1;\r\n        t = t || 0;\r\n\r\n        if (a === 1) {\r\n            return b * this.randomExponential(1) + t;\r\n        }\r\n\r\n        if (a < 1) {\r\n            // Method by Ahrens\r\n            // Knuth, TAOCP 2, Ex. 16, p 551\r\n            p = Math.E / (a + Math.E);\r\n\r\n            do {\r\n                u = Math.random();\r\n                do {\r\n                    v = Math.random();\r\n                } while (v === 0);\r\n                if (u < p) {\r\n                    x = Math.pow(v, 1 / a);\r\n                    q = Math.exp(-x);\r\n                } else {\r\n                    x = 1 - Math.log(v);\r\n                    q = Math.pow(x, a - 1);\r\n                }\r\n                u = Math.random();\r\n            } while (u >= q);\r\n            return b * x + t;\r\n        }\r\n\r\n        // a > 1\r\n        // Knuth, TAOCP 2, p 129\r\n        do {\r\n            y = Math.tan(Math.PI * Math.random());\r\n            x = Math.sqrt(2 * a - 1) * y + a - 1;\r\n            if (x > 0) {\r\n                v = Math.random();\r\n            } else {\r\n                continue;\r\n            }\r\n        } while (x <= 0.0 || v > (1 + y * y) * Math.exp((a - 1) * Math.log(x / (a - 1)) - Math.sqrt(2 * a - 1) * y));\r\n\r\n        return b * x + t;\r\n    },\r\n\r\n    /**\r\n     * Generate value of a random variable with beta distribution with shape parameters alpha and beta.\r\n     * See <a href=\"https://en.wikipedia.org/wiki/Beta_distribution\">https://en.wikipedia.org/wiki/Beta_distribution</a>.\r\n     *\r\n     * @param {Number} alpha <i>&gt; 0</i>\r\n     * @param {Number} beta <i>&gt; 0</i>\r\n     * @returns Number\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    randomBeta: function (a, b) {\r\n        // Knuth, TAOCP 2, p 129\r\n        var x1, x2, x;\r\n\r\n        if (a <= 0 || b <= 0) {\r\n            return NaN;\r\n        }\r\n\r\n        x1 = this.randomGamma(a);\r\n        x2 = this.randomGamma(b);\r\n        x = x1 / (x1 + x2);\r\n        return x;\r\n    },\r\n\r\n    /**\r\n     * Generate value of a random variable with chi-square distribution with k degrees of freedom.\r\n     * See <a href=\"https://en.wikipedia.org/wiki/Chi-squared_distribution\">https://en.wikipedia.org/wiki/Chi-squared_distribution</a>.\r\n     *\r\n     * @param {Number} k <i>&gt; 0</i>\r\n     * @returns Number\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    randomChisquare: function (nu) {\r\n        // Knuth, TAOCP 2, p 130\r\n\r\n        if (nu <= 0) {\r\n            return NaN;\r\n        }\r\n\r\n        return 2 * this.randomGamma(nu * 0.5);\r\n    },\r\n\r\n    /**\r\n     * Generate value of a random variable with F-distribution with d<sub>1</sub> and d<sub>2</sub> degrees of freedom.\r\n     * See <a href=\"https://en.wikipedia.org/wiki/F-distribution\">https://en.wikipedia.org/wiki/F-distribution</a>.\r\n     * @param {Number} d1 <i>&gt; 0</i>\r\n     * @param {Number} d2 <i>&gt; 0</i>\r\n     * @returns Number\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    randomF: function (nu1, nu2) {\r\n        // Knuth, TAOCP 2, p 130\r\n        var y1, y2;\r\n\r\n        if (nu1 <= 0 || nu2 <= 0) {\r\n            return NaN;\r\n        }\r\n\r\n        y1 = this.randomChisquare(nu1);\r\n        y2 = this.randomChisquare(nu2);\r\n\r\n        return (y1 * nu2) / (y2 * nu1);\r\n    },\r\n\r\n    /**\r\n     * Generate value of a random variable with Students-t-distribution with &nu; degrees of freedom.\r\n     * See <a href=\"https://en.wikipedia.org/wiki/Student%27s_t-distribution\">https://en.wikipedia.org/wiki/Student%27s_t-distribution</a>.\r\n     * @param {Number} nu <i>&gt; 0</i>\r\n     * @returns Number\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    randomT: function (nu) {\r\n        // Knuth, TAOCP 2, p 130\r\n        var y1, y2;\r\n\r\n        if (nu <= 0) {\r\n            return NaN;\r\n        }\r\n\r\n        y1 = this.randomNormal(0, 1);\r\n        y2 = this.randomChisquare(nu);\r\n\r\n        return y1 / Math.sqrt(y2 / nu);\r\n    },\r\n\r\n    /**\r\n     * Generate values for a random variable in binomial distribution with parameters <i>n</i> and <i>p</i>.\r\n     * See <a href=\"https://en.wikipedia.org/wiki/Binomial_distribution\">https://en.wikipedia.org/wiki/Binomial_distribution</a>.\r\n     * It uses algorithm BG from <a href=\"https://dl.acm.org/doi/pdf/10.1145/42372.42381\">https://dl.acm.org/doi/pdf/10.1145/42372.42381</a>.\r\n     *\r\n     * @param {Number} n Number of trials (n >= 0)\r\n     * @param {Number} p Probability (0 <= p <= 1)\r\n     * @returns Number Integer value of a random variable in binomial distribution\r\n     * @memberof JXG.Math.Statistics\r\n     *\r\n     * @example\r\n     * let board = JXG.JSXGraph.initBoard('jxgbox',\r\n     *     { boundingbox: [-1.7, .5, 30, -.03], axis: true });\r\n     *\r\n     * let runs = [\r\n     *     [0.5, 20, 'blue'],\r\n     *     [0.7, 20, 'green'],\r\n     *     [0.5, 40, 'red'],\r\n     * ];\r\n     *\r\n     * let labelY = .4;\r\n     * runs.forEach((run, i) => {\r\n     *     board.create('segment', [[7, labelY - (i / 50)], [9, labelY - (i / 50)]], { strokeColor: run[2] });\r\n     *     board.create('text', [10, labelY - (i / 50), `p=${run[0]}, n=${run[1]}`]);\r\n     *\r\n     *     let x = Array(50000).fill(0).map(() => JXG.Math.Statistics.randomBinomial(run[1], run[0]));\r\n     *     let res = JXG.Math.Statistics.histogram(x, {\r\n     *         bins: 40,\r\n     *         density: true,\r\n     *         cumulative: false,\r\n     *         range: [0, 40]\r\n     *     });\r\n     *     board.create('curve', [res[1], res[0]], { strokeColor: run[2] });\r\n     * });\r\n     *\r\n     *\r\n     * </pre><div id=\"JXGda56df4d-a5a5-4c87-9ffc-9bbc1b512302-3\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     * {\r\n     *  let board = JXG.JSXGraph.initBoard('JXGda56df4d-a5a5-4c87-9ffc-9bbc1b512302-3',\r\n     *       { boundingbox: [-1.7, .5, 30, -.03], axis: true});\r\n     *\r\n     *   let runs = [\r\n     *       [0.5, 20, 'blue'],\r\n     *       [0.7, 20, 'green'],\r\n     *       [0.5, 40, 'red'],\r\n     *   ]\r\n     *\r\n     *   let labelY = .4\r\n     *   runs.forEach((run,i) => {\r\n     *       board.create('segment',[[7,labelY-(i/50)],[9,labelY-(i/50)]],{strokeColor:run[2]})\r\n     *       board.create('text',[10,labelY-(i/50),`p=${run[0]}, n=${run[1]}`])\r\n     *\r\n     *       let x = Array(50000).fill(0).map(() => JXG.Math.Statistics.randomBinomial(run[1],run[0]))\r\n     *       let res = JXG.Math.Statistics.histogram(x, { bins: 40, density: true, cumulative: false, range: [0, 40] });\r\n     *       board.create('curve', [res[1], res[0]], { strokeColor: run[2]});\r\n     *   })\r\n     * }\r\n     * </script><pre>\r\n     *\r\n     */\r\n    randomBinomial: function (n, p) {\r\n        var x, y, c,\r\n            a, b, N1;\r\n\r\n        if (p < 0 || p > 1 || n < 0) {\r\n            return NaN;\r\n        }\r\n\r\n        // Edge cases\r\n        if (p === 0) {\r\n            return 0;\r\n        }\r\n        if (p === 1) {\r\n            return n;\r\n        }\r\n\r\n        // Now, we can assume 0 < p < 1.\r\n\r\n        // Fast path for common cases\r\n        if (n === 0) {\r\n            return 0;\r\n        }\r\n        if (n === 1) {\r\n            return ((Math.random() < p) ? 1 : 0);\r\n        }\r\n\r\n        // Exploit symmetry\r\n        if (p > 0.5) {\r\n            return n - this.randomBinomial(n, 1 - p);\r\n        }\r\n\r\n        // General case: n > 1, p <= 0.5\r\n        if (n < 100) {\r\n            // n small:\r\n            // Algorithm BG (Devroye) from:\r\n            // https://dl.acm.org/doi/pdf/10.1145/42372.42381\r\n            // Time O(np) so suitable for np small only.\r\n            x = -1;\r\n            y = 0;\r\n\r\n            c = Math.log(1 - p);\r\n            if (c === 0) {\r\n                return 0;\r\n            }\r\n\r\n            do {\r\n                x += 1;\r\n                y += Math.floor(Math.log(Math.random()) / c) + 1;\r\n            } while (y < n);\r\n        } else {\r\n            // n large:\r\n            // Knuth, TAOCP 2, p 131\r\n            a = 1 + Math.floor(n * 0.5);\r\n            b = n - a + 1;\r\n            x = this.randomBeta(a, b);\r\n            if (x >= p) {\r\n                N1 = this.randomBinomial(a - 1, p / x);\r\n                x = N1;\r\n            } else {\r\n                N1 = this.randomBinomial(b - 1, (p - x) / (1 - x));\r\n                x = a + N1;\r\n            }\r\n        }\r\n        return x;\r\n    },\r\n\r\n    /**\r\n     * Generate values for a random variable in geometric distribution with probability <i>p</i>.\r\n     * See <a href=\"https://en.wikipedia.org/wiki/Geometric_distribution\">https://en.wikipedia.org/wiki/Geometric_distribution</a>.\r\n     *\r\n     * @param {Number} p (0 <= p <= 1)\r\n     * @returns Number\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    randomGeometric: function (p) {\r\n        var u;\r\n\r\n        if (p < 0 || p > 1) {\r\n            return NaN;\r\n        }\r\n        // Knuth, TAOCP 2, p 131\r\n        u = Math.random();\r\n\r\n        return Math.ceil(Math.log(u) / Math.log(1 - p));\r\n    },\r\n\r\n    /**\r\n     * Generate values for a random variable in Poisson distribution with mean <i>mu</i>.\r\n     * See <a href=\"https://en.wikipedia.org/wiki/Poisson_distribution\">https://en.wikipedia.org/wiki/Poisson_distribution</a>.\r\n     *\r\n     * @param {Number} mu (0 < mu)\r\n     * @returns Number\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    randomPoisson: function (mu) {\r\n        var e = Math.exp(-mu),\r\n            N,\r\n            m = 0,\r\n            u = 1,\r\n            x,\r\n            alpha = 7 / 8;\r\n\r\n        if (mu <= 0) {\r\n            return NaN;\r\n        }\r\n\r\n        // Knuth, TAOCP 2, p 132\r\n        if (mu < 10) {\r\n            do {\r\n                u *= Math.random();\r\n                m += 1;\r\n            } while (u > e);\r\n            N = m - 1;\r\n        } else {\r\n            m = Math.floor(alpha * mu);\r\n            x = this.randomGamma(m);\r\n            if (x < mu) {\r\n                N = m + this.randomPoisson(mu - x);\r\n            } else {\r\n                N = this.randomBinomial(m - 1, mu / x);\r\n            }\r\n        }\r\n        return N;\r\n    },\r\n\r\n    /**\r\n     * Generate values for a random variable in Pareto distribution with\r\n     * shape <i>gamma</i> and scale <i>k</i>.\r\n     * See <a href=\"https://en.wikipedia.org/wiki/Pareto_distribution\">https://en.wikipedia.org/wiki/Pareto_distribution</a>.\r\n     * Method: use inverse transformation sampling.\r\n     *\r\n     * @param {Number} gamma shape (0 < gamma)\r\n     * @param {Number} k scale (0 < k < x)\r\n     * @returns Number\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    randomPareto: function (gamma, k) {\r\n        var u = Math.random();\r\n\r\n        if (gamma <= 0 || k <= 0) {\r\n            return NaN;\r\n        }\r\n        return k * Math.pow(1 - u, -1 / gamma);\r\n    },\r\n\r\n    /**\r\n     * Generate values for a random variable in hypergeometric distribution.\r\n     * Samples are drawn from a hypergeometric distribution with specified parameters, <i>good</i> (ways to make a good selection),\r\n     * <i>bad</i> (ways to make a bad selection), and <i>samples</i> (number of items sampled, which is less than or equal to <i>good + bad</i>).\r\n     * <p>\r\n     * Naive implementation with runtime <i>O(samples)</i>.\r\n     *\r\n     * @param {Number} good ways to make a good selection\r\n     * @param {Number} bad ways to make a bad selection\r\n     * @param {Number} samples number of items sampled\r\n     * @returns\r\n     * @memberof JXG.Math.Statistics\r\n     */\r\n    randomHypergeometric: function (good, bad, k) {\r\n        var i, u,\r\n            x = 0,\r\n            // kk,\r\n            // n = good + bad,\r\n            d1 = good + bad - k,\r\n            d2 = Math.min(good, bad),\r\n            y = d2;\r\n\r\n        if (good < 1 || bad < 1 || k > good + bad) {\r\n            return NaN;\r\n        }\r\n\r\n        // Naive method\r\n        // kk = Math.min(k, n - k);\r\n        // for (i = 0; i < k; i ++) {\r\n        //     u = Math.random();\r\n        //     if (n * u <= good) {\r\n        //         x += 1;\r\n        //         if (x === good) {\r\n        //             return x;\r\n        //         }\r\n        //         good -= 1;\r\n        //     }\r\n        //     n -= 1;\r\n        // }\r\n        // return x;\r\n\r\n        // Implementation from\r\n        // Monte Carlo by George S. Fishman\r\n        // https://link.springer.com/book/10.1007/978-1-4757-2553-7\r\n        // page 218\r\n        //\r\n        i = k;\r\n        while (y * i > 0) {\r\n            u = Math.random();\r\n            y -= Math.floor(u + y / (d1 + i));\r\n            i -= 1;\r\n        }\r\n        x = d2 - y;\r\n        if (good <= bad) {\r\n            return x;\r\n        } else {\r\n            return k - x;\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Compute the histogram of a dataset.\r\n     * Optional parameters can be supplied through a JavaScript object\r\n     * with the following default values:\r\n     * <pre>\r\n     * {\r\n     *   bins: 10,          // Number of bins\r\n     *   range: false,      // false or array. The lower and upper range of the bins.\r\n     *                      // If not provided, range is simply [min(x), max(x)].\r\n     *                      // Values outside the range are ignored.\r\n     *   density: false,    // If true, normalize the counts by dividing by sum(counts)\r\n     *   cumulative: false\r\n     * }\r\n     * </pre>\r\n     * The function returns an array containing two arrays. The first array is of length bins+1\r\n     * containing the start values of the bins. The last entry contains the end values of the last bin.\r\n     * <p>\r\n     * The second array contains the counts of each bin.\r\n     * @param {Array} x\r\n     * @param {Object} opt Optional parameters\r\n     * @returns Array [bin, counts] Array bins contains start values of bins, array counts contains\r\n     * the number of entries of x which are contained in each bin.\r\n     * @memberof JXG.Math.Statistics\r\n     *\r\n     * @example\r\n     *  let board = JXG.JSXGraph.initBoard('jxgbox',\r\n     *       { boundingbox: [-1.7, .5, 20, -.03], axis: true});\r\n     *  let board2 = JXG.JSXGraph.initBoard('jxgbox2',\r\n     *       { boundingbox: [-1.6, 1.1, 20, -.06], axis: true});\r\n     *\r\n     *   let runs = [\r\n     *       [0.5, 1.0, 'brown'],\r\n     *       [1.0, 2.0, 'red'],\r\n     *       [2.0, 2.0, 'orange'],\r\n     *       [3.0, 2.0, 'yellow'],\r\n     *       [5.0, 1.0, 'green'],\r\n     *       [9.0, 0.5, 'black'],\r\n     *       [7.5, 1.0, 'purple'],\r\n     *   ]\r\n     *\r\n     *   let labelY = .4\r\n     *   runs.forEach((run,i) => {\r\n     *       board.create('segment',[[7,labelY-(i/50)],[9,labelY-(i/50)]],{strokeColor:run[2]})\r\n     *       board.create('text',[10,labelY-(i/50),`k=${run[0]}, &theta;=${run[1]}`])\r\n     *\r\n     *       // density\r\n     *       let x = Array(50000).fill(0).map(() => JXG.Math.Statistics.randomGamma(run[0],run[1]))\r\n     *       let res = JXG.Math.Statistics.histogram(x, { bins: 50, density: true, cumulative: false, range: [0, 20] });\r\n     *       board.create('curve', [res[1], res[0]], { strokeColor: run[2], strokeWidth:2});\r\n     *\r\n     *       // cumulative density\r\n     *       res = JXG.Math.Statistics.histogram(x, { bins: 50, density: true, cumulative: true, range: [0, 20] });\r\n     *       res[0].unshift(0)  // add zero to front so cumulative starts at zero\r\n     *       res[1].unshift(0)\r\n     *       board2.create('curve', [res[1], res[0]], { strokeColor: run[2], strokeWidth:2 });\r\n     *   })\r\n     *\r\n     *\r\n     * </pre><div id=\"JXGda56df4d-a5a5-4c87-9ffc-9bbc1b512302\" class=\"jxgbox\" style=\"width: 300px; height: 300px; float:left;\"></div>\r\n     * <div style='float:left;'>&nbsp;&nbsp;</div>\r\n     * <div id=\"JXGda56df4d-a5a5-4c87-9ffc-9bbc1b512302-2\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     * {\r\n     *  let board = JXG.JSXGraph.initBoard('JXGda56df4d-a5a5-4c87-9ffc-9bbc1b512302',\r\n     *       { boundingbox: [-1.7, .5, 20, -.03], axis: true});\r\n     *  let board2 = JXG.JSXGraph.initBoard('JXGda56df4d-a5a5-4c87-9ffc-9bbc1b512302-2',\r\n     *       { boundingbox: [-1.6, 1.1, 20, -.06], axis: true});\r\n     *\r\n     *   let runs = [\r\n     *       [0.5, 1.0, 'brown'],\r\n     *       [1.0, 2.0, 'red'],\r\n     *       [2.0, 2.0, 'orange'],\r\n     *       [3.0, 2.0, 'yellow'],\r\n     *       [5.0, 1.0, 'green'],\r\n     *       [9.0, 0.5, 'black'],\r\n     *       [7.5, 1.0, 'purple'],\r\n     *   ]\r\n     *\r\n     *   let labelY = .4\r\n     *   runs.forEach((run,i) => {\r\n     *       board.create('segment',[[7,labelY-(i/50)],[9,labelY-(i/50)]],{strokeColor:run[2]})\r\n     *       board.create('text',[10,labelY-(i/50),`k=${run[0]}, &theta;=${run[1]}`])\r\n     *\r\n     *       let x = Array(50000).fill(0).map(() => JXG.Math.Statistics.randomGamma(run[0],run[1]))\r\n     *       let res = JXG.Math.Statistics.histogram(x, { bins: 50, density: true, cumulative: false, range: [0, 20] });\r\n     *       board.create('curve', [res[1], res[0]], { strokeColor: run[2], strokeWidth:2});\r\n     *\r\n     *       // cumulative density\r\n     *       res = JXG.Math.Statistics.histogram(x, { bins: 50, density: true, cumulative: true, range: [0, 20] });\r\n     *       res[0].unshift(0)  // add zero to front so cumulative starts at zero\r\n     *       res[1].unshift(0)\r\n     *       board2.create('curve', [res[1], res[0]], { strokeColor: run[2], strokeWidth:2 });\r\n     *   })\r\n     * }\r\n     * </script><pre>\r\n     *\r\n     */\r\n    histogram: function (x, opt) {\r\n        var i, le, k,\r\n            mi, ma, num_bins, delta,\r\n            range,\r\n            s,\r\n            counts = [],\r\n            bins = [],\r\n            no_bin = 0;        // Count of long tail elements not in histogram range\r\n\r\n        // Evaluate number of bins\r\n        num_bins = opt.bins || 10;\r\n\r\n        // Evaluate range\r\n        range = opt.range || false;\r\n        if (range === false) {\r\n            mi = Math.min.apply(null, x);\r\n            ma = Math.max.apply(null, x);\r\n        } else {\r\n            mi = range[0];\r\n            ma = range[1];\r\n        }\r\n\r\n        // Set uniform delta\r\n        if (num_bins > 0) {\r\n            delta = (ma - mi) / (num_bins - 1);\r\n        } else {\r\n            delta = 0;\r\n        }\r\n\r\n        // Set the bins and init the counts array\r\n        for (i = 0; i < num_bins; i++) {\r\n            counts.push(0);\r\n            bins.push(mi + i * delta);\r\n        }\r\n        // bins.push(ma);\r\n\r\n        // Determine the counts\r\n        le = x.length;\r\n        for (i = 0; i < le; i++) {\r\n            k = Math.floor((x[i] - mi) / delta);\r\n            if (k >= 0 && k < num_bins) {\r\n                counts[k] += 1;\r\n            } else {\r\n                no_bin += 1;\r\n            }\r\n        }\r\n\r\n        // Normalize if density===true\r\n        if (opt.density) {\r\n            s = JXG.Math.Statistics.sum(counts) + no_bin; // Normalize including long tail\r\n            for (i = 0; i < num_bins; i++) {\r\n                counts[i] /= (s * delta);\r\n                // counts[i] /= s;\r\n            }\r\n        }\r\n\r\n        // Cumulative counts\r\n        if (opt.cumulative) {\r\n            if (opt.density) {\r\n                for (i = 0; i < num_bins; i++) {\r\n                    counts[i] *= delta;  // Normalize\r\n                }\r\n            } for (i = 1; i < num_bins; i++) {\r\n                counts[i] += counts[i - 1];\r\n            }\r\n        }\r\n\r\n        return [counts, bins];\r\n    }\r\n};\r\n\r\nexport default Mat.Statistics;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, html_sanitize: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview expect.js provides utilities for parameter magic by normalizing multi-type parameters.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"./type.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Coords from \"../base/coords.js\";\r\n\r\n/**\r\n * The JXG.Expect namespace provides method to normalize access on coordinates,\r\n * i.e. provides utilities for parameter magic by normalizing multi-type parameters.\r\n * @namespace\r\n */\r\nJXG.Expect = {\r\n    /**\r\n     * Apply an expect method on every element of an array.\r\n     *\r\n     * @param {Array} a\r\n     * @param {function} format\r\n     * @param {Boolean} [copy=false]\r\n     *\r\n     * @returns {Array}\r\n     */\r\n    each: function (a, format, copy) {\r\n        var i,\r\n            len,\r\n            r = [];\r\n\r\n        if (Type.exists(a.length)) {\r\n            len = a.length;\r\n            for (i = 0; i < len; i++) {\r\n                r.push(format.call(this, a[i], copy));\r\n            }\r\n        }\r\n\r\n        return r;\r\n    },\r\n\r\n    /**\r\n     * Normalize points and coord objects into a coord object.\r\n     *\r\n     * @param {JXG.Point|JXG.Coords} c\r\n     * @param {Boolean} [copy=false] Return a copy, not a reference\r\n     *\r\n     * @returns {JXG.Coords}\r\n     */\r\n    coords: function (c, copy) {\r\n        var coord = c;\r\n\r\n        if (c && c.elementClass === Const.OBJECT_CLASS_POINT) {\r\n            coord = c.coords;\r\n        } else if (c.usrCoords && c.scrCoords && c.usr2screen) {\r\n            coord = c;\r\n        }\r\n\r\n        if (copy) {\r\n            coord = new Coords(Const.COORDS_BY_USER, coord.usrCoords, coord.board);\r\n        }\r\n\r\n        return coord;\r\n    },\r\n\r\n    /**\r\n     * Normalize points, coordinate arrays and coord objects into a coordinate array.\r\n     *\r\n     * @param {JXG.Point|JXG.Coords|Array} c\r\n     * @param {Boolean} [copy=false] Return a copy, not a reference\r\n     *\r\n     * @returns {Array} Homogeneous coordinates\r\n     */\r\n    coordsArray: function (c, copy) {\r\n        var coord;\r\n\r\n        if (!Type.isArray(c)) {\r\n            coord = this.coords(c).usrCoords;\r\n        } else {\r\n            coord = c;\r\n        }\r\n\r\n        if (coord.length < 3) {\r\n            coord.unshift(1);\r\n        }\r\n\r\n        if (copy) {\r\n            coord = [coord[0], coord[1], coord[2]];\r\n        }\r\n\r\n        return coord;\r\n    }\r\n};\r\n\r\nexport default JXG.Expect;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Mat from \"./math.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\nJXG.Math.DoubleBits = function () {\r\n    var DOUBLE_VIEW = new Float64Array(1),\r\n        UINT_VIEW = new Uint32Array(DOUBLE_VIEW.buffer),\r\n        doubleBitsLE,\r\n        toDoubleLE,\r\n        lowUintLE,\r\n        highUintLE,\r\n        // doubleBits,\r\n        // toDouble,\r\n        // lowUint,\r\n        // highUint,\r\n        // hasTypedArrays = false,\r\n        doubleBitsBE,\r\n        toDoubleBE,\r\n        lowUintBE,\r\n        highUintBE;\r\n\r\n    if (Float64Array !== undefined) {\r\n        DOUBLE_VIEW[0] = 1.0;\r\n        // hasTypedArrays = true;\r\n        if (UINT_VIEW[1] === 0x3ff00000) {\r\n            // Use little endian\r\n            doubleBitsLE = function (n) {\r\n                DOUBLE_VIEW[0] = n;\r\n                return [UINT_VIEW[0], UINT_VIEW[1]];\r\n            };\r\n            toDoubleLE = function (lo, hi) {\r\n                UINT_VIEW[0] = lo;\r\n                UINT_VIEW[1] = hi;\r\n                return DOUBLE_VIEW[0];\r\n            };\r\n\r\n            lowUintLE = function (n) {\r\n                DOUBLE_VIEW[0] = n;\r\n                return UINT_VIEW[0];\r\n            };\r\n\r\n            highUintLE = function (n) {\r\n                DOUBLE_VIEW[0] = n;\r\n                return UINT_VIEW[1];\r\n            };\r\n\r\n            this.doubleBits = doubleBitsLE;\r\n            this.pack = toDoubleLE;\r\n            this.lo = lowUintLE;\r\n            this.hi = highUintLE;\r\n        } else if (UINT_VIEW[0] === 0x3ff00000) {\r\n            // Use big endian\r\n            doubleBitsBE = function (n) {\r\n                DOUBLE_VIEW[0] = n;\r\n                return [UINT_VIEW[1], UINT_VIEW[0]];\r\n            };\r\n\r\n            toDoubleBE = function (lo, hi) {\r\n                UINT_VIEW[1] = lo;\r\n                UINT_VIEW[0] = hi;\r\n                return DOUBLE_VIEW[0];\r\n            };\r\n\r\n            lowUintBE = function (n) {\r\n                DOUBLE_VIEW[0] = n;\r\n                return UINT_VIEW[1];\r\n            };\r\n\r\n            highUintBE = function (n) {\r\n                DOUBLE_VIEW[0] = n;\r\n                return UINT_VIEW[0];\r\n            };\r\n\r\n            this.doubleBits = doubleBitsBE;\r\n            this.pack = toDoubleBE;\r\n            this.lo = lowUintBE;\r\n            this.hi = highUintBE;\r\n            // } else {\r\n            //     hasTypedArrays = false;\r\n        }\r\n    }\r\n\r\n    // if (!hasTypedArrays) {\r\n    //     var buffer = new Buffer(8)\r\n    //     doubleBits = function(n) {\r\n    //         buffer.writeDoubleLE(n, 0, true);\r\n    //         return [buffer.readUInt32LE(0, true), buffer.readUInt32LE(4, true)];\r\n    //     };\r\n\r\n    //     toDouble = function(lo, hi) {\r\n    //         buffer.writeUInt32LE(lo, 0, true);\r\n    //         buffer.writeUInt32LE(hi, 4, true);\r\n    //         return buffer.readDoubleLE(0, true);\r\n    //     };\r\n    //     lowUint = function(n) {\r\n    //         buffer.writeDoubleLE(n, 0, true);\r\n    //         return buffer.readUInt32LE(0, true);\r\n    //     };\r\n\r\n    //     highUint = function(n) {\r\n    //         buffer.writeDoubleLE(n, 0, true);\r\n    //         return buffer.readUInt32LE(4, true);\r\n    //     };\r\n\r\n    //     this.doubleBits = doubleBits;\r\n    //     this.pack = toDouble;\r\n    //     this.lo = lowUint;\r\n    //     this.hi = highUint;\r\n    // }\r\n};\r\n\r\nJXG.extend(\r\n    JXG.Math.DoubleBits.prototype,\r\n    /** @lends JXG.Math.DoubleBits.prototype */ {\r\n        sign: function (n) {\r\n            return this.hi(n) >>> 31;\r\n        },\r\n\r\n        exponent: function (n) {\r\n            var b = this.hi(n);\r\n            return ((b << 1) >>> 21) - 1023;\r\n        },\r\n\r\n        fraction: function (n) {\r\n            var lo = this.lo(n),\r\n                hi = this.hi(n),\r\n                b = hi & ((1 << 20) - 1);\r\n\r\n            if (hi & 0x7ff00000) {\r\n                b += 1 << 20;\r\n            }\r\n            return [lo, b];\r\n        },\r\n\r\n        denormalized: function (n) {\r\n            var hi = this.hi(n);\r\n            return !(hi & 0x7ff00000);\r\n        }\r\n    }\r\n);\r\n\r\nvar doubleBits = new JXG.Math.DoubleBits(),\r\n    /**\r\n     * Interval for interval arithmetics. Consists of the properties\r\n     * <ul>\r\n     *  <li>lo\r\n     *  <li>hi\r\n     * </ul>\r\n     * @name JXG.Math.Interval\r\n     * @type Object\r\n     */\r\n    MatInterval = function (lo, hi) {\r\n        if (lo !== undefined && hi !== undefined) {\r\n            // possible cases:\r\n            // - Interval(1, 2)\r\n            // - Interval(Interval(1, 1), Interval(2, 2))     // singletons are required\r\n            if (Mat.IntervalArithmetic.isInterval(lo)) {\r\n                if (!Mat.IntervalArithmetic.isSingleton(lo)) {\r\n                    throw new TypeError(\r\n                        \"JXG.Math.IntervalArithmetic: interval `lo` must be a singleton\"\r\n                    );\r\n                }\r\n                this.lo = lo.lo;\r\n            } else {\r\n                this.lo = lo;\r\n            }\r\n            if (Mat.IntervalArithmetic.isInterval(hi)) {\r\n                if (!Mat.IntervalArithmetic.isSingleton(hi)) {\r\n                    throw new TypeError(\r\n                        \"JXG.Math.IntervalArithmetic: interval `hi` must be a singleton\"\r\n                    );\r\n                }\r\n                this.hi = hi.hi;\r\n            } else {\r\n                this.hi = hi;\r\n            }\r\n        } else if (lo !== undefined) {\r\n            // possible cases:\r\n            // - Interval([1, 2])\r\n            // - Interval([Interval(1, 1), Interval(2, 2)])\r\n            if (Array.isArray(lo)) {\r\n                return new MatInterval(lo[0], lo[1]);\r\n            }\r\n            // - Interval(1)\r\n            return new MatInterval(lo, lo);\r\n        } else {\r\n            // This else is necessary even if jslint declares it as redundant\r\n            // possible cases:\r\n            // - Interval()\r\n            this.lo = this.hi = 0;\r\n        }\r\n    };\r\n\r\nJXG.extend(MatInterval.prototype, {\r\n    print: function () {\r\n        console.log(\"[\", this.lo, this.hi, \"]\");\r\n    },\r\n\r\n    set: function (lo, hi) {\r\n        this.lo = lo;\r\n        this.hi = hi;\r\n        return this;\r\n    },\r\n\r\n    bounded: function (lo, hi) {\r\n        return this.set(Mat.IntervalArithmetic.prev(lo), Mat.IntervalArithmetic.next(hi));\r\n    },\r\n\r\n    boundedSingleton: function (v) {\r\n        return this.bounded(v, v);\r\n    },\r\n\r\n    assign: function (lo, hi) {\r\n        if (typeof lo !== \"number\" || typeof hi !== 'number') {\r\n            throw new TypeError(\"JXG.Math.Interval#assign: arguments must be numbers\");\r\n        }\r\n        if (isNaN(lo) || isNaN(hi) || lo > hi) {\r\n            return this.setEmpty();\r\n        }\r\n        return this.set(lo, hi);\r\n    },\r\n\r\n    setEmpty: function () {\r\n        return this.set(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY);\r\n    },\r\n\r\n    setWhole: function () {\r\n        return this.set(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY);\r\n    },\r\n\r\n    open: function (lo, hi) {\r\n        return this.assign(Mat.IntervalArithmetic.next(lo), Mat.IntervalArithmetic.prev(hi));\r\n    },\r\n\r\n    halfOpenLeft: function (lo, hi) {\r\n        return this.assign(Mat.IntervalArithmetic.next(lo), hi);\r\n    },\r\n\r\n    halfOpenRight: function (lo, hi) {\r\n        return this.assign(lo, Mat.IntervalArithmetic.prev(hi));\r\n    },\r\n\r\n    toArray: function () {\r\n        return [this.lo, this.hi];\r\n    },\r\n\r\n    clone: function () {\r\n        return new MatInterval().set(this.lo, this.hi);\r\n    }\r\n});\r\n\r\n/**\r\n * Object for interval arithmetics.\r\n * @name JXG.Math.IntervalArithmetic\r\n * @namespace\r\n * @exports Mat.IntervalArithmetic as JXG.Math.IntervalArithmetic\r\n *\r\n * @description\r\n * Interval arithmetic is a technique used to mitigate rounding and measurement errors in mathematical computation\r\n * by computing function bounds. Instead of representing a value as a single number, interval arithmetic represents each value as a range.\r\n * <br><br>\r\n *\r\n * For example, we wish to calculate the area of a rectangle from direct measurements using a standard meter stick with an uncertainty\r\n * of 0.0005 m (half the “least count measurement” of 1 mm). We measure one side nominally as L=1,\r\n * so 0.9995 ≤ L ≤ 1.0005, the other nominally as W=2 so the interval is [1.9995, 2.0005].\r\n *\r\n * <pre>\r\n * let L = JXG.Math.IntervalArithmetic.Interval(0.9995, 1.0005)\r\n * let W = JXG.Math.IntervalArithmetic.Interval(1.9995, 2.0005)\r\n *\r\n * let A = JXG.Math.IntervalArithmetic.mul(L, W)\r\n *\r\n * console.log('area:', A) // {hi: 2.0015002500000003, lo: 1.99850025}\r\n * </pre>\r\n *\r\n */\r\nJXG.Math.IntervalArithmetic = {\r\n    Interval: function (lo, hi) {\r\n        return new MatInterval(lo, hi);\r\n    },\r\n\r\n    isInterval: function (i) {\r\n        return (\r\n            i !== null &&\r\n            typeof i === \"object\" &&\r\n            typeof i.lo === \"number\" &&\r\n            typeof i.hi === \"number\"\r\n        );\r\n    },\r\n\r\n    isSingleton: function (i) {\r\n        return i.lo === i.hi;\r\n    },\r\n\r\n    /*\r\n     * Arithmetics\r\n     */\r\n\r\n    /**\r\n     * Addition\r\n     *\r\n     * @param {JXG.Math.Interval|Number} x\r\n     * @param {JXG.Math.Interval|Number} y\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    add: function (x, y) {\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        if (Type.isNumber(y)) {\r\n            y = this.Interval(y);\r\n        }\r\n        return new MatInterval(this.addLo(x.lo, y.lo), this.addHi(x.hi, y.hi));\r\n    },\r\n\r\n    /**\r\n     * Subtraction\r\n     *\r\n     * @param {JXG.Math.Interval|Number} x\r\n     * @param {JXG.Math.Interval|Number} y\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    sub: function (x, y) {\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        if (Type.isNumber(y)) {\r\n            y = this.Interval(y);\r\n        }\r\n        return new MatInterval(this.subLo(x.lo, y.hi), this.subHi(x.hi, y.lo));\r\n    },\r\n\r\n    /**\r\n     * Multiplication\r\n     *\r\n     * @param {JXG.Math.Interval|Number} x\r\n     * @param {JXG.Math.Interval|Number} y\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    mul: function (x, y) {\r\n        var xl, xh, yl, yh, out;\r\n\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        if (Type.isNumber(y)) {\r\n            y = this.Interval(y);\r\n        }\r\n\r\n        if (this.isEmpty(x) || this.isEmpty(y)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        xl = x.lo;\r\n        xh = x.hi;\r\n        yl = y.lo;\r\n        yh = y.hi;\r\n        out = new MatInterval();\r\n\r\n        if (xl < 0) {\r\n            if (xh > 0) {\r\n                if (yl < 0) {\r\n                    if (yh > 0) {\r\n                        // mixed * mixed\r\n                        out.lo = Math.min(this.mulLo(xl, yh), this.mulLo(xh, yl));\r\n                        out.hi = Math.max(this.mulHi(xl, yl), this.mulHi(xh, yh));\r\n                    } else {\r\n                        // mixed * negative\r\n                        out.lo = this.mulLo(xh, yl);\r\n                        out.hi = this.mulHi(xl, yl);\r\n                    }\r\n                } else {\r\n                    if (yh > 0) {\r\n                        // mixed * positive\r\n                        out.lo = this.mulLo(xl, yh);\r\n                        out.hi = this.mulHi(xh, yh);\r\n                    } else {\r\n                        // mixed * zero\r\n                        out.lo = 0;\r\n                        out.hi = 0;\r\n                    }\r\n                }\r\n            } else {\r\n                if (yl < 0) {\r\n                    if (yh > 0) {\r\n                        // negative * mixed\r\n                        out.lo = this.mulLo(xl, yh);\r\n                        out.hi = this.mulHi(xl, yl);\r\n                    } else {\r\n                        // negative * negative\r\n                        out.lo = this.mulLo(xh, yh);\r\n                        out.hi = this.mulHi(xl, yl);\r\n                    }\r\n                } else {\r\n                    if (yh > 0) {\r\n                        // negative * positive\r\n                        out.lo = this.mulLo(xl, yh);\r\n                        out.hi = this.mulHi(xh, yl);\r\n                    } else {\r\n                        // negative * zero\r\n                        out.lo = 0;\r\n                        out.hi = 0;\r\n                    }\r\n                }\r\n            }\r\n        } else {\r\n            if (xh > 0) {\r\n                if (yl < 0) {\r\n                    if (yh > 0) {\r\n                        // positive * mixed\r\n                        out.lo = this.mulLo(xh, yl);\r\n                        out.hi = this.mulHi(xh, yh);\r\n                    } else {\r\n                        // positive * negative\r\n                        out.lo = this.mulLo(xh, yl);\r\n                        out.hi = this.mulHi(xl, yh);\r\n                    }\r\n                } else {\r\n                    if (yh > 0) {\r\n                        // positive * positive\r\n                        out.lo = this.mulLo(xl, yl);\r\n                        out.hi = this.mulHi(xh, yh);\r\n                    } else {\r\n                        // positive * zero\r\n                        out.lo = 0;\r\n                        out.hi = 0;\r\n                    }\r\n                }\r\n            } else {\r\n                // zero * any other value\r\n                out.lo = 0;\r\n                out.hi = 0;\r\n            }\r\n        }\r\n        return out;\r\n    },\r\n\r\n    /**\r\n     * Division\r\n     *\r\n     * @param {JXG.Math.Interval|Number} x\r\n     * @param {JXG.Math.Interval|Number} y\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    div: function (x, y) {\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        if (Type.isNumber(y)) {\r\n            y = this.Interval(y);\r\n        }\r\n\r\n        if (this.isEmpty(x) || this.isEmpty(y)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        if (this.zeroIn(y)) {\r\n            if (y.lo !== 0) {\r\n                if (y.hi !== 0) {\r\n                    return this.divZero(x);\r\n                }\r\n                return this.divNegative(x, y.lo);\r\n            }\r\n            if (y.hi !== 0) {\r\n                return this.divPositive(x, y.hi);\r\n            }\r\n            return this.EMPTY.clone();\r\n        }\r\n        return this.divNonZero(x, y);\r\n    },\r\n\r\n    /**\r\n     * Return +x (i.e. identity)\r\n     *\r\n     * @param {JXG.Math.Interval} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    positive: function (x) {\r\n        return new MatInterval(x.lo, x.hi);\r\n    },\r\n\r\n    /**\r\n     * Return -x\r\n     *\r\n     * @param {JXG.Math.Interval} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    negative: function (x) {\r\n        if (Type.isNumber(x)) {\r\n            return new MatInterval(-x);\r\n        }\r\n        return new MatInterval(-x.hi, -x.lo);\r\n    },\r\n\r\n    /*\r\n     * Utils\r\n     */\r\n\r\n    /**\r\n     * Test if interval is empty set.\r\n     * @param {JXG.Math.Interval} i\r\n     * @returns Boolean\r\n     */\r\n    isEmpty: function (i) {\r\n        return i.lo > i.hi;\r\n    },\r\n\r\n    /**\r\n     * Test if interval is (-Infinity, Infinity).\r\n     * @param {JXG.Math.Interval} i\r\n     * @returns Boolean\r\n     */\r\n    isWhole: function (i) {\r\n        return i.lo === -Infinity && i.hi === Infinity;\r\n    },\r\n\r\n    /**\r\n     * Test if interval contains 0.\r\n     * @param {JXG.Math.Interval} i\r\n     * @returns Boolean\r\n     */\r\n    zeroIn: function (i) {\r\n        return this.hasValue(i, 0);\r\n    },\r\n\r\n    /**\r\n     * Test if interval contains a specific value.\r\n     * @param {JXG.Math.Interval} i\r\n     * @param {Number} value\r\n     * @returns Boolean\r\n     */\r\n    hasValue: function (i, value) {\r\n        if (this.isEmpty(i)) {\r\n            return false;\r\n        }\r\n        return i.lo <= value && value <= i.hi;\r\n    },\r\n\r\n    /**\r\n     * Test if interval x contains interval y.\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns Boolean\r\n     */\r\n    hasInterval: function (x, y) {\r\n        if (this.isEmpty(x)) {\r\n            return true;\r\n        }\r\n        return !this.isEmpty(y) && y.lo <= x.lo && x.hi <= y.hi;\r\n    },\r\n\r\n    /**\r\n     * Test if intervals x and y have non-zero intersection.\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns Boolean\r\n     */\r\n    intervalsOverlap: function (x, y) {\r\n        if (this.isEmpty(x) || this.isEmpty(y)) {\r\n            return false;\r\n        }\r\n        return (x.lo <= y.lo && y.lo <= x.hi) || (y.lo <= x.lo && x.lo <= y.hi);\r\n    },\r\n\r\n    /*\r\n     * Division\r\n     */\r\n    /**\r\n     * @private\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    divNonZero: function (x, y) {\r\n        var xl = x.lo,\r\n            xh = x.hi,\r\n            yl = y.lo,\r\n            yh = y.hi,\r\n            out = new MatInterval();\r\n\r\n        if (xh < 0) {\r\n            if (yh < 0) {\r\n                out.lo = this.divLo(xh, yl);\r\n                out.hi = this.divHi(xl, yh);\r\n            } else {\r\n                out.lo = this.divLo(xl, yl);\r\n                out.hi = this.divHi(xh, yh);\r\n            }\r\n        } else if (xl < 0) {\r\n            if (yh < 0) {\r\n                out.lo = this.divLo(xh, yh);\r\n                out.hi = this.divHi(xl, yh);\r\n            } else {\r\n                out.lo = this.divLo(xl, yl);\r\n                out.hi = this.divHi(xh, yl);\r\n            }\r\n        } else {\r\n            if (yh < 0) {\r\n                out.lo = this.divLo(xh, yh);\r\n                out.hi = this.divHi(xl, yl);\r\n            } else {\r\n                out.lo = this.divLo(xl, yh);\r\n                out.hi = this.divHi(xh, yl);\r\n            }\r\n        }\r\n        return out;\r\n    },\r\n\r\n    /**\r\n     * @private\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    divPositive: function (x, v) {\r\n        if (x.lo === 0 && x.hi === 0) {\r\n            return x;\r\n        }\r\n\r\n        if (this.zeroIn(x)) {\r\n            // mixed considering zero in both ends\r\n            return this.WHOLE;\r\n        }\r\n\r\n        if (x.hi < 0) {\r\n            // negative / v\r\n            return new MatInterval(Number.NEGATIVE_INFINITY, this.divHi(x.hi, v));\r\n        }\r\n        // positive / v\r\n        return new MatInterval(this.divLo(x.lo, v), Number.POSITIVE_INFINITY);\r\n    },\r\n\r\n    /**\r\n     * @private\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    divNegative: function (x, v) {\r\n        if (x.lo === 0 && x.hi === 0) {\r\n            return x;\r\n        }\r\n\r\n        if (this.zeroIn(x)) {\r\n            // mixed considering zero in both ends\r\n            return this.WHOLE;\r\n        }\r\n\r\n        if (x.hi < 0) {\r\n            // negative / v\r\n            return new MatInterval(this.divLo(x.hi, v), Number.POSITIVE_INFINITY);\r\n        }\r\n        // positive / v\r\n        return new MatInterval(Number.NEGATIVE_INFINITY, this.divHi(x.lo, v));\r\n    },\r\n\r\n    /**\r\n     * @private\r\n     * @param {JXG.Math.Interval} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    divZero: function (x) {\r\n        if (x.lo === 0 && x.hi === 0) {\r\n            return x;\r\n        }\r\n        return this.WHOLE;\r\n    },\r\n\r\n    /*\r\n     * Algebra\r\n     */\r\n    /**\r\n     * x mod y:  x - n * y\r\n     * @param {JXG.Math.Interval|Number} x\r\n     * @param {JXG.Math.Interval|Number} y\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    fmod: function (x, y) {\r\n        var yb, n;\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        if (Type.isNumber(y)) {\r\n            y = this.Interval(y);\r\n        }\r\n        if (this.isEmpty(x) || this.isEmpty(y)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        yb = x.lo < 0 ? y.lo : y.hi;\r\n        n = x.lo / yb;\r\n        if (n < 0) {\r\n            n = Math.ceil(n);\r\n        } else {\r\n            n = Math.floor(n);\r\n        }\r\n        // x mod y = x - n * y\r\n        return this.sub(x, this.mul(y, new MatInterval(n)));\r\n    },\r\n\r\n    /**\r\n     * 1 / x\r\n     * @param {JXG.Math.Interval|Number} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    multiplicativeInverse: function (x) {\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        if (this.isEmpty(x)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        if (this.zeroIn(x)) {\r\n            if (x.lo !== 0) {\r\n                if (x.hi !== 0) {\r\n                    // [negative, positive]\r\n                    return this.WHOLE;\r\n                }\r\n                // [negative, zero]\r\n                return new MatInterval(Number.NEGATIVE_INFINITY, this.divHi(1, x.lo));\r\n            }\r\n            if (x.hi !== 0) {\r\n                // [zero, positive]\r\n                return new MatInterval(this.divLo(1, x.hi), Number.POSITIVE_INFINITY);\r\n            }\r\n            // [zero, zero]\r\n            return this.EMPTY.clone();\r\n        }\r\n        // [positive, positive]\r\n        return new MatInterval(this.divLo(1, x.hi), this.divHi(1, x.lo));\r\n    },\r\n\r\n    /**\r\n     * x<sup>power</sup>\r\n     * @param {JXG.Math.Interval|Number} x\r\n     * @param {JXG.Math.Interval|Number} power\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    pow: function (x, power) {\r\n        var yl, yh;\r\n\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        if (this.isEmpty(x)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        if (this.isInterval(power)) {\r\n            if (!this.isSingleton(power)) {\r\n                return this.EMPTY.clone();\r\n            }\r\n            power = power.lo;\r\n        }\r\n\r\n        if (power === 0) {\r\n            if (x.lo === 0 && x.hi === 0) {\r\n                // 0^0\r\n                return this.EMPTY.clone();\r\n            }\r\n            // x^0\r\n            return this.ONE.clone();\r\n        }\r\n        if (power < 0) {\r\n            // compute [1 / x]^-power if power is negative\r\n            return this.pow(this.multiplicativeInverse(x), -power);\r\n        }\r\n\r\n        // power > 0\r\n        if (power % 1 === 0) {\r\n            // isSafeInteger(power) as boolean) {\r\n            // power is integer\r\n            if (x.hi < 0) {\r\n                // [negative, negative]\r\n                // assume that power is even so the operation will yield a positive interval\r\n                // if not then just switch the sign and order of the interval bounds\r\n                yl = this.powLo(-x.hi, power);\r\n                yh = this.powHi(-x.lo, power);\r\n                if ((power & 1) === 1) {\r\n                    // odd power\r\n                    return new MatInterval(-yh, -yl);\r\n                }\r\n                // even power\r\n                return new MatInterval(yl, yh);\r\n            }\r\n            if (x.lo < 0) {\r\n                // [negative, positive]\r\n                if ((power & 1) === 1) {\r\n                    return new MatInterval(-this.powLo(-x.lo, power), this.powHi(x.hi, power));\r\n                }\r\n                // even power means that any negative number will be zero (min value = 0)\r\n                // and the max value will be the max of x.lo^power, x.hi^power\r\n                return new MatInterval(0, this.powHi(Math.max(-x.lo, x.hi), power));\r\n            }\r\n            // [positive, positive]\r\n            return new MatInterval(this.powLo(x.lo, power), this.powHi(x.hi, power));\r\n        }\r\n        console.warn(\r\n            \"power is not an integer, you should use nth-root instead, returning an empty interval\"\r\n        );\r\n        return this.EMPTY.clone();\r\n    },\r\n\r\n    /**\r\n     * sqrt(x)\r\n     * @param {JXG.Math.Interval|Number} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    sqrt: function (x) {\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        return this.nthRoot(x, 2);\r\n    },\r\n\r\n    /**\r\n     * x<sup>1/n</sup>\r\n     * @param {JXG.Math.Interval|Number} x\r\n     * @param {Number} n\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    nthRoot: function (x, n) {\r\n        var power, yl, yh, yp, yn;\r\n\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        if (this.isEmpty(x) || n < 0) {\r\n            // compute 1 / x^-power if power is negative\r\n            return this.EMPTY.clone();\r\n        }\r\n\r\n        // singleton interval check\r\n        if (this.isInterval(n)) {\r\n            if (!this.isSingleton(n)) {\r\n                return this.EMPTY.clone();\r\n            }\r\n            n = n.lo;\r\n        }\r\n\r\n        power = 1 / n;\r\n        if (x.hi < 0) {\r\n            // [negative, negative]\r\n            //if ((isSafeInteger(n) as boolean) && (n & 1) === 1) {\r\n            if (n % 1 === 0 && (n & 1) === 1) {\r\n                // when n is odd we can always take the nth root\r\n                yl = this.powHi(-x.lo, power);\r\n                yh = this.powLo(-x.hi, power);\r\n                return new MatInterval(-yl, -yh);\r\n            }\r\n\r\n            // n is not odd therefore there's no nth root\r\n            return this.EMPTY.clone();\r\n        }\r\n        if (x.lo < 0) {\r\n            // [negative, positive]\r\n            yp = this.powHi(x.hi, power);\r\n            // if ((isSafeInteger(n) as boolean) && (n & 1) === 1) {\r\n            if (n % 1 === 0 && (n & 1) === 1) {\r\n                // nth root of x.lo is possible (n is odd)\r\n                yn = -this.powHi(-x.lo, power);\r\n                return new MatInterval(yn, yp);\r\n            }\r\n            return new MatInterval(0, yp);\r\n        }\r\n        // [positive, positive]\r\n        return new MatInterval(this.powLo(x.lo, power), this.powHi(x.hi, power));\r\n    },\r\n\r\n    /*\r\n     * Misc\r\n     */\r\n    /**\r\n     *\r\n     * @param {JXG.Math.Interval|Number} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    exp: function (x) {\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        if (this.isEmpty(x)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        return new MatInterval(this.expLo(x.lo), this.expHi(x.hi));\r\n    },\r\n\r\n    /**\r\n     * Natural log\r\n     * @param {JXG.Math.Interval|Number} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    log: function (x) {\r\n        var l;\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        if (this.isEmpty(x)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        l = x.lo <= 0 ? Number.NEGATIVE_INFINITY : this.logLo(x.lo);\r\n        return new MatInterval(l, this.logHi(x.hi));\r\n    },\r\n\r\n    /**\r\n     * Natural log, alias for {@link JXG.Math.IntervalArithmetic#log}.\r\n     * @param {JXG.Math.Interval|Number} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    ln: function (x) {\r\n        return this.log(x);\r\n    },\r\n\r\n    // export const LOG_EXP_10 = this.log(new MatInterval(10, 10))\r\n    // export const LOG_EXP_2 = log(new MatInterval(2, 2))\r\n    /**\r\n     * Logarithm to base 10.\r\n     * @param {JXG.Math.Interval|Number} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    log10: function (x) {\r\n        if (this.isEmpty(x)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        return this.div(this.log(x), this.log(new MatInterval(10, 10)));\r\n    },\r\n\r\n    /**\r\n     * Logarithm to base 2.\r\n     * @param {JXG.Math.Interval|Number} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    log2: function (x) {\r\n        if (this.isEmpty(x)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        return this.div(this.log(x), this.log(new MatInterval(2, 2)));\r\n    },\r\n\r\n    /**\r\n     * Hull of intervals x and y\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    hull: function (x, y) {\r\n        var badX = this.isEmpty(x),\r\n            badY = this.isEmpty(y);\r\n        if (badX && badY) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        if (badX) {\r\n            return y.clone();\r\n        }\r\n        if (badY) {\r\n            return x.clone();\r\n        }\r\n        return new MatInterval(Math.min(x.lo, y.lo), Math.max(x.hi, y.hi));\r\n    },\r\n\r\n    /**\r\n     * Intersection of intervals x and y\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    intersection: function (x, y) {\r\n        var lo, hi;\r\n        if (this.isEmpty(x) || this.isEmpty(y)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        lo = Math.max(x.lo, y.lo);\r\n        hi = Math.min(x.hi, y.hi);\r\n        if (lo <= hi) {\r\n            return new MatInterval(lo, hi);\r\n        }\r\n        return this.EMPTY.clone();\r\n    },\r\n\r\n    /**\r\n     * Union of overlapping intervals x and y\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    union: function (x, y) {\r\n        if (!this.intervalsOverlap(x, y)) {\r\n            throw new Error(\"Interval#unions do not overlap\");\r\n        }\r\n        return new MatInterval(Math.min(x.lo, y.lo), Math.max(x.hi, y.hi));\r\n    },\r\n\r\n    /**\r\n     * Difference of overlapping intervals x and y\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    difference: function (x, y) {\r\n        if (this.isEmpty(x) || this.isWhole(y)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        if (this.intervalsOverlap(x, y)) {\r\n            if (x.lo < y.lo && y.hi < x.hi) {\r\n                // difference creates multiple subsets\r\n                throw new Error(\"Interval.difference: difference creates multiple intervals\");\r\n            }\r\n\r\n            // handle corner cases first\r\n            if ((y.lo <= x.lo && y.hi === Infinity) || (y.hi >= x.hi && y.lo === -Infinity)) {\r\n                return this.EMPTY.clone();\r\n            }\r\n\r\n            // NOTE: empty interval is handled automatically\r\n            // e.g.\r\n            //\r\n            //    n = difference([0,1], [0,1]) // n = Interval(next(1), 1) = EMPTY\r\n            //    isEmpty(n) === true\r\n            //\r\n            if (y.lo <= x.lo) {\r\n                return new MatInterval().halfOpenLeft(y.hi, x.hi);\r\n            }\r\n\r\n            // y.hi >= x.hi\r\n            return new MatInterval().halfOpenRight(x.lo, y.lo);\r\n        }\r\n        return x.clone();\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    width: function (x) {\r\n        if (this.isEmpty(x)) {\r\n            return 0;\r\n        }\r\n        return this.subHi(x.hi, x.lo);\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    abs: function (x) {\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        if (this.isEmpty(x)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        if (x.lo >= 0) {\r\n            return x.clone();\r\n        }\r\n        if (x.hi <= 0) {\r\n            return this.negative(x);\r\n        }\r\n        return new MatInterval(0, Math.max(-x.lo, x.hi));\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    max: function (x, y) {\r\n        var badX = this.isEmpty(x),\r\n            badY = this.isEmpty(y);\r\n        if (badX && badY) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        if (badX) {\r\n            return y.clone();\r\n        }\r\n        if (badY) {\r\n            return x.clone();\r\n        }\r\n        return new MatInterval(Math.max(x.lo, y.lo), Math.max(x.hi, y.hi));\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    min: function (x, y) {\r\n        var badX = this.isEmpty(x),\r\n            badY = this.isEmpty(y);\r\n        if (badX && badY) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        if (badX) {\r\n            return y.clone();\r\n        }\r\n        if (badY) {\r\n            return x.clone();\r\n        }\r\n        return new MatInterval(Math.min(x.lo, y.lo), Math.min(x.hi, y.hi));\r\n    },\r\n\r\n    /*\r\n     * Trigonometric\r\n     */\r\n    onlyInfinity: function (x) {\r\n        return !isFinite(x.lo) && x.lo === x.hi;\r\n    },\r\n\r\n    _handleNegative: function (interval) {\r\n        var n;\r\n        if (interval.lo < 0) {\r\n            if (interval.lo === -Infinity) {\r\n                interval.lo = 0;\r\n                interval.hi = Infinity;\r\n            } else {\r\n                n = Math.ceil(-interval.lo / this.piTwiceLow);\r\n                interval.lo += this.piTwiceLow * n;\r\n                interval.hi += this.piTwiceLow * n;\r\n            }\r\n        }\r\n        return interval;\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    cos: function (x) {\r\n        var cache, pi2, t, cosv, lo, hi, rlo, rhi;\r\n\r\n        if (this.isEmpty(x) || this.onlyInfinity(x)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n\r\n        // create a clone of `x` because the clone is going to be modified\r\n        cache = new MatInterval().set(x.lo, x.hi);\r\n        this._handleNegative(cache);\r\n\r\n        pi2 = this.PI_TWICE;\r\n        t = this.fmod(cache, pi2);\r\n        if (this.width(t) >= pi2.lo) {\r\n            return new MatInterval(-1, 1);\r\n        }\r\n\r\n        // when t.lo > pi it's the same as\r\n        // -cos(t - pi)\r\n        if (t.lo >= this.piHigh) {\r\n            cosv = this.cos(this.sub(t, this.PI));\r\n            return this.negative(cosv);\r\n        }\r\n\r\n        lo = t.lo;\r\n        hi = t.hi;\r\n        rlo = this.cosLo(hi);\r\n        rhi = this.cosHi(lo);\r\n        // it's ensured that t.lo < pi and that t.lo >= 0\r\n        if (hi <= this.piLow) {\r\n            // when t.hi < pi\r\n            // [cos(t.lo), cos(t.hi)]\r\n            return new MatInterval(rlo, rhi);\r\n        }\r\n        if (hi <= pi2.lo) {\r\n            // when t.hi < 2pi\r\n            // [-1, max(cos(t.lo), cos(t.hi))]\r\n            return new MatInterval(-1, Math.max(rlo, rhi));\r\n        }\r\n        // t.lo < pi and t.hi > 2pi\r\n        return new MatInterval(-1, 1);\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    sin: function (x) {\r\n        if (this.isEmpty(x) || this.onlyInfinity(x)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        return this.cos(this.sub(x, this.PI_HALF));\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    tan: function (x) {\r\n        var cache, t, pi;\r\n        if (this.isEmpty(x) || this.onlyInfinity(x)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n\r\n        // create a clone of `x` because the clone is going to be modified\r\n        cache = new MatInterval().set(x.lo, x.hi);\r\n        this._handleNegative(cache);\r\n\r\n        pi = this.PI;\r\n        t = this.fmod(cache, pi);\r\n        if (t.lo >= this.piHalfLow) {\r\n            t = this.sub(t, pi);\r\n        }\r\n        if (t.lo <= -this.piHalfLow || t.hi >= this.piHalfLow) {\r\n            return this.WHOLE.clone();\r\n        }\r\n        return new MatInterval(this.tanLo(t.lo), this.tanHi(t.hi));\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    asin: function (x) {\r\n        var lo, hi;\r\n        if (this.isEmpty(x) || x.hi < -1 || x.lo > 1) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        lo = x.lo <= -1 ? -this.piHalfHigh : this.asinLo(x.lo);\r\n        hi = x.hi >= 1 ? this.piHalfHigh : this.asinHi(x.hi);\r\n        return new MatInterval(lo, hi);\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    acos: function (x) {\r\n        var lo, hi;\r\n        if (this.isEmpty(x) || x.hi < -1 || x.lo > 1) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        lo = x.hi >= 1 ? 0 : this.acosLo(x.hi);\r\n        hi = x.lo <= -1 ? this.piHigh : this.acosHi(x.lo);\r\n        return new MatInterval(lo, hi);\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    acot: function (x) {\r\n        if (this.isEmpty(x)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        return new MatInterval(this.acotLo(x.lo), this.acotHi(x.hi));\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    atan: function (x) {\r\n        if (this.isEmpty(x)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        return new MatInterval(this.atanLo(x.lo), this.atanHi(x.hi));\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    sinh: function (x) {\r\n        if (this.isEmpty(x)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        return new MatInterval(this.sinhLo(x.lo), this.sinhHi(x.hi));\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    cosh: function (x) {\r\n        if (this.isEmpty(x)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        if (x.hi < 0) {\r\n            return new MatInterval(this.coshLo(x.hi), this.coshHi(x.lo));\r\n        }\r\n        if (x.lo >= 0) {\r\n            return new MatInterval(this.coshLo(x.lo), this.coshHi(x.hi));\r\n        }\r\n        return new MatInterval(1, this.coshHi(-x.lo > x.hi ? x.lo : x.hi));\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @returns JXG.Math.Interval\r\n     */\r\n    tanh: function (x) {\r\n        if (this.isEmpty(x)) {\r\n            return this.EMPTY.clone();\r\n        }\r\n        return new MatInterval(this.tanhLo(x.lo), this.tanhHi(x.hi));\r\n    },\r\n\r\n    /*\r\n     * Relational\r\n     */\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns Boolean\r\n     */\r\n    equal: function (x, y) {\r\n        if (this.isEmpty(x)) {\r\n            return this.isEmpty(y);\r\n        }\r\n        return !this.isEmpty(y) && x.lo === y.lo && x.hi === y.hi;\r\n    },\r\n\r\n    // almostEqual: function(x, y): void {\r\n    //     x = Array.isArray(x) ? x : x.toArray();\r\n    //     y = Array.isArray(y) ? y : y.toArray();\r\n    //     assertEps(x[0], y[0])\r\n    //     assertEps(x[1], y[1])\r\n    // },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns Boolean\r\n     */\r\n    notEqual: function (x, y) {\r\n        if (this.isEmpty(x)) {\r\n            return !this.isEmpty(y);\r\n        }\r\n        return this.isEmpty(y) || x.hi < y.lo || x.lo > y.hi;\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns Boolean\r\n     */\r\n    lt: function (x, y) {\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        if (Type.isNumber(y)) {\r\n            y = this.Interval(y);\r\n        }\r\n        if (this.isEmpty(x) || this.isEmpty(y)) {\r\n            return false;\r\n        }\r\n        return x.hi < y.lo;\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns Boolean\r\n     */\r\n    gt: function (x, y) {\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        if (Type.isNumber(y)) {\r\n            y = this.Interval(y);\r\n        }\r\n        if (this.isEmpty(x) || this.isEmpty(y)) {\r\n            return false;\r\n        }\r\n        return x.lo > y.hi;\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns Boolean\r\n     */\r\n    leq: function (x, y) {\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        if (Type.isNumber(y)) {\r\n            y = this.Interval(y);\r\n        }\r\n        if (this.isEmpty(x) || this.isEmpty(y)) {\r\n            return false;\r\n        }\r\n        return x.hi <= y.lo;\r\n    },\r\n\r\n    /**\r\n     * @param {JXG.Math.Interval} x\r\n     * @param {JXG.Math.Interval} y\r\n     * @returns Boolean\r\n     */\r\n    geq: function (x, y) {\r\n        if (Type.isNumber(x)) {\r\n            x = this.Interval(x);\r\n        }\r\n        if (Type.isNumber(y)) {\r\n            y = this.Interval(y);\r\n        }\r\n        if (this.isEmpty(x) || this.isEmpty(y)) {\r\n            return false;\r\n        }\r\n        return x.lo >= y.hi;\r\n    },\r\n\r\n    /*\r\n     * Constants\r\n     */\r\n    piLow: (3373259426.0 + 273688.0 / (1 << 21)) / (1 << 30),\r\n    piHigh: (3373259426.0 + 273689.0 / (1 << 21)) / (1 << 30),\r\n    piHalfLow: ((3373259426.0 + 273688.0 / (1 << 21)) / (1 << 30)) * 0.5,\r\n    piHalfHigh: ((3373259426.0 + 273689.0 / (1 << 21)) / (1 << 30)) * 0.5,\r\n    piTwiceLow: ((3373259426.0 + 273688.0 / (1 << 21)) / (1 << 30)) * 2,\r\n    piTwiceHigh: ((3373259426.0 + 273689.0 / (1 << 21)) / (1 << 30)) * 2,\r\n\r\n    /*\r\n     * Round\r\n     * Rounding functions for numbers\r\n     */\r\n    identity: function (v) {\r\n        return v;\r\n    },\r\n\r\n    _prev: function (v) {\r\n        if (v === Infinity) {\r\n            return v;\r\n        }\r\n        return this.nextafter(v, -Infinity);\r\n    },\r\n\r\n    _next: function (v) {\r\n        if (v === -Infinity) {\r\n            return v;\r\n        }\r\n        return this.nextafter(v, Infinity);\r\n    },\r\n\r\n    prev: function (v) {\r\n        return this._prev(v);\r\n    },\r\n\r\n    next: function (v) {\r\n        return this._next(v);\r\n    },\r\n\r\n    toInteger: function (x) {\r\n        return x < 0 ? Math.ceil(x) : Math.floor(x);\r\n    },\r\n\r\n    addLo: function (x, y) {\r\n        return this.prev(x + y);\r\n    },\r\n    addHi: function (x, y) {\r\n        return this.next(x + y);\r\n    },\r\n    subLo: function (x, y) {\r\n        return this.prev(x - y);\r\n    },\r\n    subHi: function (x, y) {\r\n        return this.next(x - y);\r\n    },\r\n    mulLo: function (x, y) {\r\n        return this.prev(x * y);\r\n    },\r\n    mulHi: function (x, y) {\r\n        return this.next(x * y);\r\n    },\r\n    divLo: function (x, y) {\r\n        return this.prev(x / y);\r\n    },\r\n    divHi: function (x, y) {\r\n        return this.next(x / y);\r\n    },\r\n    intLo: function (x) {\r\n        return this.toInteger(this.prev(x));\r\n    },\r\n    intHi: function (x) {\r\n        return this.toInteger(this.next(x));\r\n    },\r\n    logLo: function (x) {\r\n        return this.prev(Math.log(x));\r\n    },\r\n    logHi: function (x) {\r\n        return this.next(Math.log(x));\r\n    },\r\n    expLo: function (x) {\r\n        return this.prev(Math.exp(x));\r\n    },\r\n    expHi: function (x) {\r\n        return this.next(Math.exp(x));\r\n    },\r\n    sinLo: function (x) {\r\n        return this.prev(Math.sin(x));\r\n    },\r\n    sinHi: function (x) {\r\n        return this.next(Math.sin(x));\r\n    },\r\n    cosLo: function (x) {\r\n        return this.prev(Math.cos(x));\r\n    },\r\n    cosHi: function (x) {\r\n        return this.next(Math.cos(x));\r\n    },\r\n    tanLo: function (x) {\r\n        return this.prev(Math.tan(x));\r\n    },\r\n    tanHi: function (x) {\r\n        return this.next(Math.tan(x));\r\n    },\r\n    asinLo: function (x) {\r\n        return this.prev(Math.asin(x));\r\n    },\r\n    asinHi: function (x) {\r\n        return this.next(Math.asin(x));\r\n    },\r\n    acosLo: function (x) {\r\n        return this.prev(Math.acos(x));\r\n    },\r\n    acosHi: function (x) {\r\n        return this.next(Math.acos(x));\r\n    },\r\n    acotLo: function (x) {\r\n        return this.prev(Mat.acot(x));\r\n    },\r\n    acotHi: function (x) {\r\n        return this.next(Mat.acot(x));\r\n    },\r\n    atanLo: function (x) {\r\n        return this.prev(Math.atan(x));\r\n    },\r\n    atanHi: function (x) {\r\n        return this.next(Math.atan(x));\r\n    },\r\n    sinhLo: function (x) {\r\n        return this.prev(Mat.sinh(x));\r\n    },\r\n    sinhHi: function (x) {\r\n        return this.next(Mat.sinh(x));\r\n    },\r\n    coshLo: function (x) {\r\n        return this.prev(Mat.cosh(x));\r\n    },\r\n    coshHi: function (x) {\r\n        return this.next(Mat.cosh(x));\r\n    },\r\n    tanhLo: function (x) {\r\n        return this.prev(Mat.tanh(x));\r\n    },\r\n    tanhHi: function (x) {\r\n        return this.next(Mat.tanh(x));\r\n    },\r\n    sqrtLo: function (x) {\r\n        return this.prev(Math.sqrt(x));\r\n    },\r\n    sqrtHi: function (x) {\r\n        return this.next(Math.sqrt(x));\r\n    },\r\n\r\n    powLo: function (x, power) {\r\n        var y;\r\n        if (power % 1 !== 0) {\r\n            // power has decimals\r\n            return this.prev(Math.pow(x, power));\r\n        }\r\n\r\n        y = (power & 1) === 1 ? x : 1;\r\n        power >>= 1;\r\n        while (power > 0) {\r\n            x = this.mulLo(x, x);\r\n            if ((power & 1) === 1) {\r\n                y = this.mulLo(x, y);\r\n            }\r\n            power >>= 1;\r\n        }\r\n        return y;\r\n    },\r\n\r\n    powHi: function (x, power) {\r\n        var y;\r\n        if (power % 1 !== 0) {\r\n            // power has decimals\r\n            return this.next(Math.pow(x, power));\r\n        }\r\n\r\n        y = (power & 1) === 1 ? x : 1;\r\n        power >>= 1;\r\n        while (power > 0) {\r\n            x = this.mulHi(x, x);\r\n            if ((power & 1) === 1) {\r\n                y = this.mulHi(x, y);\r\n            }\r\n            power >>= 1;\r\n        }\r\n        return y;\r\n    },\r\n\r\n    /**\r\n     * @ignore\r\n     * @private\r\n     */\r\n    disable: function () {\r\n        this.next = this.prev = this.identity;\r\n    },\r\n\r\n    /**\r\n     * @ignore\r\n     * @private\r\n     */\r\n    enable: function () {\r\n        this.prev = function (v) {\r\n            return this._prev(v);\r\n        };\r\n\r\n        this.next = function (v) {\r\n            return this._next(v);\r\n        };\r\n    },\r\n\r\n    /*\r\n     * nextafter\r\n     */\r\n    SMALLEST_DENORM: Math.pow(2, -1074),\r\n    UINT_MAX: -1 >>> 0,\r\n\r\n    nextafter: function (x, y) {\r\n        var lo, hi;\r\n\r\n        if (isNaN(x) || isNaN(y)) {\r\n            return NaN;\r\n        }\r\n        if (x === y) {\r\n            return x;\r\n        }\r\n        if (x === 0) {\r\n            if (y < 0) {\r\n                return -this.SMALLEST_DENORM;\r\n            }\r\n            return this.SMALLEST_DENORM;\r\n        }\r\n        hi = doubleBits.hi(x);\r\n        lo = doubleBits.lo(x);\r\n        if (y > x === x > 0) {\r\n            if (lo === this.UINT_MAX) {\r\n                hi += 1;\r\n                lo = 0;\r\n            } else {\r\n                lo += 1;\r\n            }\r\n        } else {\r\n            if (lo === 0) {\r\n                lo = this.UINT_MAX;\r\n                hi -= 1;\r\n            } else {\r\n                lo -= 1;\r\n            }\r\n        }\r\n        return doubleBits.pack(lo, hi);\r\n    }\r\n};\r\n\r\nJXG.Math.IntervalArithmetic.PI = new MatInterval(\r\n    Mat.IntervalArithmetic.piLow,\r\n    Mat.IntervalArithmetic.piHigh\r\n);\r\nJXG.Math.IntervalArithmetic.PI_HALF = new MatInterval(\r\n    Mat.IntervalArithmetic.piHalfLow,\r\n    Mat.IntervalArithmetic.piHalfHigh\r\n);\r\nJXG.Math.IntervalArithmetic.PI_TWICE = new MatInterval(\r\n    Mat.IntervalArithmetic.piTwiceLow,\r\n    Mat.IntervalArithmetic.piTwiceHigh\r\n);\r\nJXG.Math.IntervalArithmetic.ZERO = new MatInterval(0);\r\nJXG.Math.IntervalArithmetic.ONE = new MatInterval(1);\r\nJXG.Math.IntervalArithmetic.WHOLE = new MatInterval().setWhole();\r\nJXG.Math.IntervalArithmetic.EMPTY = new MatInterval().setEmpty();\r\n\r\nexport default JXG.Math.IntervalArithmetic;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Andreas Walter,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * Functions for color conversions. This was originally based on a class to parse color values by\r\n * Stoyan Stefanov <sstoo@gmail.com> (see https://www.phpied.com/rgb-color-parser-in-javascript/)\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"./type.js\";\r\nimport Mat from \"../math/math.js\";\r\n\r\n// private constants and helper functions\r\n\r\n// simple colors contains string color constants that can be used in various browser\r\n// in javascript\r\nvar simpleColors = {\r\n        aliceblue: \"f0f8ff\",\r\n        antiquewhite: \"faebd7\",\r\n        aqua: \"00ffff\",\r\n        aquamarine: \"7fffd4\",\r\n        azure: \"f0ffff\",\r\n        beige: \"f5f5dc\",\r\n        bisque: \"ffe4c4\",\r\n        black: \"000000\",\r\n        blanchedalmond: \"ffebcd\",\r\n        blue: \"0000ff\",\r\n        blueviolet: \"8a2be2\",\r\n        brown: \"a52a2a\",\r\n        burlywood: \"deb887\",\r\n        cadetblue: \"5f9ea0\",\r\n        chartreuse: \"7fff00\",\r\n        chocolate: \"d2691e\",\r\n        coral: \"ff7f50\",\r\n        cornflowerblue: \"6495ed\",\r\n        cornsilk: \"fff8dc\",\r\n        crimson: \"dc143c\",\r\n        cyan: \"00ffff\",\r\n        darkblue: \"00008b\",\r\n        darkcyan: \"008b8b\",\r\n        darkgoldenrod: \"b8860b\",\r\n        darkgray: \"a9a9a9\",\r\n        darkgreen: \"006400\",\r\n        darkkhaki: \"bdb76b\",\r\n        darkmagenta: \"8b008b\",\r\n        darkolivegreen: \"556b2f\",\r\n        darkorange: \"ff8c00\",\r\n        darkorchid: \"9932cc\",\r\n        darkred: \"8b0000\",\r\n        darksalmon: \"e9967a\",\r\n        darkseagreen: \"8fbc8f\",\r\n        darkslateblue: \"483d8b\",\r\n        darkslategray: \"2f4f4f\",\r\n        darkturquoise: \"00ced1\",\r\n        darkviolet: \"9400d3\",\r\n        deeppink: \"ff1493\",\r\n        deepskyblue: \"00bfff\",\r\n        dimgray: \"696969\",\r\n        dodgerblue: \"1e90ff\",\r\n        feldspar: \"d19275\",\r\n        firebrick: \"b22222\",\r\n        floralwhite: \"fffaf0\",\r\n        forestgreen: \"228b22\",\r\n        fuchsia: \"ff00ff\",\r\n        gainsboro: \"dcdcdc\",\r\n        ghostwhite: \"f8f8ff\",\r\n        gold: \"ffd700\",\r\n        goldenrod: \"daa520\",\r\n        gray: \"808080\",\r\n        green: \"008000\",\r\n        greenyellow: \"adff2f\",\r\n        honeydew: \"f0fff0\",\r\n        hotpink: \"ff69b4\",\r\n        indianred: \"cd5c5c\",\r\n        indigo: \"4b0082\",\r\n        ivory: \"fffff0\",\r\n        khaki: \"f0e68c\",\r\n        lavender: \"e6e6fa\",\r\n        lavenderblush: \"fff0f5\",\r\n        lawngreen: \"7cfc00\",\r\n        lemonchiffon: \"fffacd\",\r\n        lightblue: \"add8e6\",\r\n        lightcoral: \"f08080\",\r\n        lightcyan: \"e0ffff\",\r\n        lightgoldenrodyellow: \"fafad2\",\r\n        lightgrey: \"d3d3d3\",\r\n        lightgreen: \"90ee90\",\r\n        lightpink: \"ffb6c1\",\r\n        lightsalmon: \"ffa07a\",\r\n        lightseagreen: \"20b2aa\",\r\n        lightskyblue: \"87cefa\",\r\n        lightslateblue: \"8470ff\",\r\n        lightslategray: \"778899\",\r\n        lightsteelblue: \"b0c4de\",\r\n        lightyellow: \"ffffe0\",\r\n        lime: \"00ff00\",\r\n        limegreen: \"32cd32\",\r\n        linen: \"faf0e6\",\r\n        magenta: \"ff00ff\",\r\n        maroon: \"800000\",\r\n        mediumaquamarine: \"66cdaa\",\r\n        mediumblue: \"0000cd\",\r\n        mediumorchid: \"ba55d3\",\r\n        mediumpurple: \"9370d8\",\r\n        mediumseagreen: \"3cb371\",\r\n        mediumslateblue: \"7b68ee\",\r\n        mediumspringgreen: \"00fa9a\",\r\n        mediumturquoise: \"48d1cc\",\r\n        mediumvioletred: \"c71585\",\r\n        midnightblue: \"191970\",\r\n        mintcream: \"f5fffa\",\r\n        mistyrose: \"ffe4e1\",\r\n        moccasin: \"ffe4b5\",\r\n        navajowhite: \"ffdead\",\r\n        navy: \"000080\",\r\n        oldlace: \"fdf5e6\",\r\n        olive: \"808000\",\r\n        olivedrab: \"6b8e23\",\r\n        orange: \"ffa500\",\r\n        orangered: \"ff4500\",\r\n        orchid: \"da70d6\",\r\n        palegoldenrod: \"eee8aa\",\r\n        palegreen: \"98fb98\",\r\n        paleturquoise: \"afeeee\",\r\n        palevioletred: \"d87093\",\r\n        papayawhip: \"ffefd5\",\r\n        peachpuff: \"ffdab9\",\r\n        peru: \"cd853f\",\r\n        pink: \"ffc0cb\",\r\n        plum: \"dda0dd\",\r\n        powderblue: \"b0e0e6\",\r\n        purple: \"800080\",\r\n        red: \"ff0000\",\r\n        rosybrown: \"bc8f8f\",\r\n        royalblue: \"4169e1\",\r\n        saddlebrown: \"8b4513\",\r\n        salmon: \"fa8072\",\r\n        sandybrown: \"f4a460\",\r\n        seagreen: \"2e8b57\",\r\n        seashell: \"fff5ee\",\r\n        sienna: \"a0522d\",\r\n        silver: \"c0c0c0\",\r\n        skyblue: \"87ceeb\",\r\n        slateblue: \"6a5acd\",\r\n        slategray: \"708090\",\r\n        snow: \"fffafa\",\r\n        springgreen: \"00ff7f\",\r\n        steelblue: \"4682b4\",\r\n        tan: \"d2b48c\",\r\n        teal: \"008080\",\r\n        thistle: \"d8bfd8\",\r\n        tomato: \"ff6347\",\r\n        turquoise: \"40e0d0\",\r\n        venetianred: \"ae181e\",\r\n        violet: \"ee82ee\",\r\n        violetred: \"d02090\",\r\n        wheat: \"f5deb3\",\r\n        white: \"ffffff\",\r\n        whitesmoke: \"f5f5f5\",\r\n        yellow: \"ffff00\",\r\n        yellowgreen: \"9acd32\"\r\n    },\r\n    // array of color definition objects\r\n    colorDefs = [\r\n        {\r\n            re: /^\\s*rgba\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*([\\d.]{1,3})\\s*\\)\\s*$/,\r\n            example: [\"rgba(123, 234, 45, 0.5)\", \"rgba(255,234,245,1.0)\"],\r\n            process: function (bits) {\r\n                return [parseInt(bits[1], 10), parseInt(bits[2], 10), parseInt(bits[3], 10)];\r\n            }\r\n        },\r\n        {\r\n            re: /^\\s*rgb\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*\\)\\s*$/,\r\n            example: [\"rgb(123, 234, 45)\", \"rgb(255,234,245)\"],\r\n            process: function (bits) {\r\n                return [parseInt(bits[1], 10), parseInt(bits[2], 10), parseInt(bits[3], 10)];\r\n            }\r\n        },\r\n        {\r\n            re: /^(\\w{2})(\\w{2})(\\w{2})$/,\r\n            example: [\"#00ff00\", \"336699\"],\r\n            process: function (bits) {\r\n                return [parseInt(bits[1], 16), parseInt(bits[2], 16), parseInt(bits[3], 16)];\r\n            }\r\n        },\r\n        {\r\n            re: /^(\\w{1})(\\w{1})(\\w{1})$/,\r\n            example: [\"#fb0\", \"f0f\"],\r\n            process: function (bits) {\r\n                return [\r\n                    parseInt(bits[1] + bits[1], 16),\r\n                    parseInt(bits[2] + bits[2], 16),\r\n                    parseInt(bits[3] + bits[3], 16)\r\n                ];\r\n            }\r\n        }\r\n    ];\r\n\r\n/**\r\n * Converts a valid HTML/CSS color string into a rgb value array. This is the base\r\n * function for the following wrapper functions which only adjust the output to\r\n * different flavors like an object, string or hex values.\r\n * @param {String|Array|Number} color A valid HTML or CSS styled color value, e.g. '#12ab21', '#abc', 'black'\r\n * or 'rgb(12, 132, 233)'. This can also be an array containing three color values either from 0.0 to 1.0 or\r\n * from 0 to 255. They will be interpreted as red, green, and blue values. In case this is a number this method\r\n * expects the parameters ag and ab.\r\n * @param {Number} ag\r\n * @param {Number} ab\r\n * @returns {Array} RGB color values as an array [r, g, b] with values ranging from 0 to 255.\r\n */\r\nJXG.rgbParser = function (color, ag, ab) {\r\n    var color_string,\r\n        channels,\r\n        re,\r\n        processor,\r\n        bits,\r\n        i,\r\n        r,\r\n        g,\r\n        b,\r\n        values = color,\r\n        testFloat;\r\n\r\n    if (!Type.exists(color)) {\r\n        return [];\r\n    }\r\n\r\n    if (Type.exists(ag) && Type.exists(ab)) {\r\n        values = [color, ag, ab];\r\n    }\r\n\r\n    color_string = values;\r\n\r\n    testFloat = false;\r\n    if (Type.isArray(color_string)) {\r\n        for (i = 0; i < 3; i++) {\r\n            testFloat = testFloat || /\\./.test(values[i].toString());\r\n        }\r\n\r\n        for (i = 0; i < 3; i++) {\r\n            testFloat = testFloat && values[i] >= 0.0 && values[i] <= 1.0;\r\n        }\r\n\r\n        if (testFloat) {\r\n            return [\r\n                Math.ceil(values[0] * 255),\r\n                Math.ceil(values[1] * 255),\r\n                Math.ceil(values[2] * 255)\r\n            ];\r\n        }\r\n\r\n        return values;\r\n    }\r\n\r\n    if (typeof values === 'string') {\r\n        color_string = values;\r\n    }\r\n\r\n    // strip any leading #\r\n    if (color_string.charAt(0) === \"#\") {\r\n        // remove # if any\r\n        color_string = color_string.slice(1, 7);\r\n    }\r\n\r\n    color_string = color_string.replace(/ /g, \"\").toLowerCase();\r\n\r\n    // before getting into regexps, try simple matches\r\n    // and overwrite the input\r\n    color_string = simpleColors[color_string] || color_string;\r\n\r\n    // search through the colorDefs definitions to find a match\r\n    for (i = 0; i < colorDefs.length; i++) {\r\n        re = colorDefs[i].re;\r\n        processor = colorDefs[i].process;\r\n        bits = re.exec(color_string);\r\n\r\n        if (bits) {\r\n            channels = processor(bits);\r\n            r = channels[0];\r\n            g = channels[1];\r\n            b = channels[2];\r\n        }\r\n    }\r\n\r\n    if (isNaN(r) || isNaN(g) || isNaN(b)) {\r\n        return [];\r\n    }\r\n\r\n    // validate/cleanup values\r\n    r = r < 0 || isNaN(r) ? 0 : r > 255 ? 255 : r;\r\n    g = g < 0 || isNaN(g) ? 0 : g > 255 ? 255 : g;\r\n    b = b < 0 || isNaN(b) ? 0 : b > 255 ? 255 : b;\r\n\r\n    return [r, g, b];\r\n};\r\n\r\nJXG.isColor = function (strColor) {\r\n    var s = new Option().style;\r\n    s.color = strColor;\r\n    return s.color !== '';\r\n};\r\n\r\n/**\r\n * Converts a valid HTML/CSS color string into a string of the 'rgb(r, g, b)' format.\r\n * @param {String|Array|Number} color A valid HTML or CSS styled color value, e.g. '#12ab21', '#abc', 'black'\r\n * or 'rgb(12, 132, 233)'. This can also be an array containing three color values either from 0.0 to 1.0 or\r\n * from 0 to 255. They will be interpreted as red, green, and blue values. In case this is a number this method\r\n * expects the parameters ag and ab.\r\n * @param {Number} ag\r\n * @param {Number} ab\r\n * @returns {String} A 'rgb(r, g, b)' formatted string\r\n */\r\nJXG.rgb2css = function (color, ag, ab) {\r\n    var r;\r\n\r\n    r = JXG.rgbParser(color, ag, ab);\r\n\r\n    return \"rgb(\" + r[0] + \", \" + r[1] + \", \" + r[2] + \")\";\r\n};\r\n\r\n/**\r\n * Converts a valid HTML/CSS color string into a HTML rgb string.\r\n * @param {String|Array|Number} color A valid HTML or CSS styled color value, e.g. '#12ab21', '#abc', 'black'\r\n * or 'rgb(12, 132, 233)'. This can also be an array containing three color values either from 0.0 to 1.0 or\r\n * from 0 to 255. They will be interpreted as red, green, and blue values. In case this is a number this method\r\n * expects the parameters ag and ab.\r\n * @param {Number} ag\r\n * @param {Number} ab\r\n * @returns {String} A '#rrggbb' formatted string\r\n */\r\nJXG.rgb2hex = function (color, ag, ab) {\r\n    var r, g, b;\r\n\r\n    r = JXG.rgbParser(color, ag, ab);\r\n    g = r[1];\r\n    b = r[2];\r\n    r = r[0];\r\n    r = r.toString(16);\r\n    g = g.toString(16);\r\n    b = b.toString(16);\r\n\r\n    if (r.length === 1) {\r\n        r = \"0\" + r;\r\n    }\r\n\r\n    if (g.length === 1) {\r\n        g = \"0\" + g;\r\n    }\r\n\r\n    if (b.length === 1) {\r\n        b = \"0\" + b;\r\n    }\r\n\r\n    return \"#\" + r + g + b;\r\n};\r\n\r\n/**\r\n * Converts a valid HTML/CSS color string from the '#rrggbb' format into the 'rgb(r, g, b)' format.\r\n * @param {String} hex A valid HTML or CSS styled color value, e.g. '#12ab21', '#abc', or 'black'\r\n * @deprecated Use {@link JXG#rgb2css} instead.\r\n * @returns {String} A 'rgb(r, g, b)' formatted string\r\n */\r\nJXG.hex2rgb = function (hex) {\r\n    JXG.deprecated(\"JXG.hex2rgb()\", \"JXG.rgb2css()\");\r\n    return JXG.rgb2css(hex);\r\n};\r\n\r\n/**\r\n * Converts HSV color to RGB color.\r\n * Based on C Code in \"Computer Graphics -- Principles and Practice,\"\r\n * Foley et al, 1996, p. 593.\r\n * See also https://www.had2know.org/technology/hsv-rgb-conversion-formula-calculator.html\r\n * @param {Number} H value between 0 and 360\r\n * @param {Number} S value between 0.0 (shade of gray) to 1.0 (pure color)\r\n * @param {Number} V value between 0.0 (black) to 1.0 (white)\r\n * @returns {String} RGB color string\r\n */\r\nJXG.hsv2rgb = function (H, S, V) {\r\n    var R, G, B, f, i, hTemp, p, q, t;\r\n\r\n    H = ((H % 360.0) + 360.0) % 360;\r\n\r\n    if (S === 0) {\r\n        if (isNaN(H) || H < Mat.eps) {\r\n            R = V;\r\n            G = V;\r\n            B = V;\r\n        } else {\r\n            return \"#ffffff\";\r\n        }\r\n    } else {\r\n        if (H >= 360) {\r\n            hTemp = 0.0;\r\n        } else {\r\n            hTemp = H;\r\n        }\r\n\r\n        // h is now IN [0,6)\r\n        hTemp = hTemp / 60;\r\n        // largest integer <= h\r\n        i = Math.floor(hTemp);\r\n        // fractional part of h\r\n        f = hTemp - i;\r\n        p = V * (1.0 - S);\r\n        q = V * (1.0 - S * f);\r\n        t = V * (1.0 - S * (1.0 - f));\r\n\r\n        switch (i) {\r\n            case 0:\r\n                R = V;\r\n                G = t;\r\n                B = p;\r\n                break;\r\n            case 1:\r\n                R = q;\r\n                G = V;\r\n                B = p;\r\n                break;\r\n            case 2:\r\n                R = p;\r\n                G = V;\r\n                B = t;\r\n                break;\r\n            case 3:\r\n                R = p;\r\n                G = q;\r\n                B = V;\r\n                break;\r\n            case 4:\r\n                R = t;\r\n                G = p;\r\n                B = V;\r\n                break;\r\n            case 5:\r\n                R = V;\r\n                G = p;\r\n                B = q;\r\n                break;\r\n        }\r\n    }\r\n\r\n    R = Math.round(R * 255).toString(16);\r\n    R = R.length === 2 ? R : R.length === 1 ? \"0\" + R : '00';\r\n    G = Math.round(G * 255).toString(16);\r\n    G = G.length === 2 ? G : G.length === 1 ? \"0\" + G : '00';\r\n    B = Math.round(B * 255).toString(16);\r\n    B = B.length === 2 ? B : B.length === 1 ? \"0\" + B : '00';\r\n\r\n    return [\"#\", R, G, B].join(\"\");\r\n};\r\n\r\n/**\r\n * Converts a color from the RGB color space into the HSV space. Input can be any valid HTML/CSS color definition.\r\n * @param {String|Array|Number} color A valid HTML or CSS styled color value, e.g. '#12ab21', '#abc', 'black'\r\n * or 'rgb(12, 132, 233)'. This can also be an array containing three color values either from 0.0 to 1.0 or\r\n * from 0 to 255. They will be interpreted as red, green, and blue values. In case this is a number this method\r\n * expects the parameters ag and ab. See <a href=\"https://www.had2know.org/technology/hsv-rgb-conversion-formula-calculator.html\">https://www.had2know.org/technology/hsv-rgb-conversion-formula-calculator.html</a>.\r\n * @param {Number} ag\r\n * @param {Number} ab\r\n * @returns {Array} Contains the h, s, and v value in this order.\r\n *\r\n */\r\nJXG.rgb2hsv = function (color, ag, ab) {\r\n    var r, g, b, fr, fg, fb, fmax, fmin, h, s, v, max, min;\r\n\r\n    r = JXG.rgbParser(color, ag, ab);\r\n\r\n    g = r[1];\r\n    b = r[2];\r\n    r = r[0];\r\n    fr = r / 255.0;\r\n    fg = g / 255.0;\r\n    fb = b / 255.0;\r\n    max = Math.max(r, g, b);\r\n    min = Math.min(r, g, b);\r\n    fmax = max / 255.0;\r\n    fmin = min / 255.0;\r\n\r\n    v = fmax;\r\n    s = 0.0;\r\n\r\n    if (v > 0) {\r\n        s = (v - fmin) / v;\r\n    }\r\n\r\n    h = 1.0 / (fmax - fmin);\r\n\r\n    if (s > 0) {\r\n        if (max === r) {\r\n            h = (fg - fb) * h;\r\n        } else if (max === g) {\r\n            h = 2 + (fb - fr) * h;\r\n        } else {\r\n            h = 4 + (fr - fg) * h;\r\n        }\r\n    }\r\n\r\n    h *= 60;\r\n\r\n    if (h < 0) {\r\n        h += 360;\r\n    }\r\n\r\n    if (max === min) {\r\n        h = 0.0;\r\n    }\r\n\r\n    return [h, s, v];\r\n};\r\n\r\n/**\r\n * Converts a color from the RGB color space into the LMS space. Input can be any valid HTML/CSS color definition.\r\n * @param {String|Array|Number} color A valid HTML or CSS styled color value, e.g. '#12ab21', '#abc', 'black'\r\n * or 'rgb(12, 132, 233)'. This can also be an array containing three color values either from 0.0 to 1.0 or\r\n * from 0 to 255. They will be interpreted as red, green, and blue values. In case this is a number this method\r\n * expects the parameters ag and ab.\r\n * @param {Number} ag\r\n * @param {Number} ab\r\n * @returns {Array} Contains the l, m, and s value in this order.\r\n */\r\nJXG.rgb2LMS = function (color, ag, ab) {\r\n    var r,\r\n        g,\r\n        b,\r\n        l,\r\n        m,\r\n        s,\r\n        ret,\r\n        // constants\r\n        matrix = [\r\n            [0.05059983, 0.08585369, 0.0095242],\r\n            [0.01893033, 0.08925308, 0.01370054],\r\n            [0.00292202, 0.00975732, 0.07145979]\r\n        ];\r\n\r\n    r = JXG.rgbParser(color, ag, ab);\r\n    g = r[1];\r\n    b = r[2];\r\n    r = r[0];\r\n\r\n    // de-gamma\r\n    // Maybe this can be made faster by using a cache\r\n    r = Math.pow(r, 0.476190476);\r\n    g = Math.pow(g, 0.476190476);\r\n    b = Math.pow(b, 0.476190476);\r\n\r\n    l = r * matrix[0][0] + g * matrix[0][1] + b * matrix[0][2];\r\n    m = r * matrix[1][0] + g * matrix[1][1] + b * matrix[1][2];\r\n    s = r * matrix[2][0] + g * matrix[2][1] + b * matrix[2][2];\r\n\r\n    ret = [l, m, s];\r\n    ret.l = l;\r\n    ret.m = m;\r\n    ret.s = s;\r\n\r\n    return ret;\r\n};\r\n\r\n/**\r\n * Convert color information from LMS to RGB color space.\r\n * @param {Number} l\r\n * @param {Number} m\r\n * @param {Number} s\r\n * @returns {Array} Contains the r, g, and b value in this order.\r\n */\r\nJXG.LMS2rgb = function (l, m, s) {\r\n    var r,\r\n        g,\r\n        b,\r\n        ret,\r\n        // constants\r\n        matrix = [\r\n            [30.830854, -29.832659, 1.610474],\r\n            [-6.481468, 17.715578, -2.532642],\r\n            [-0.37569, -1.199062, 14.273846]\r\n        ],\r\n        // re-gamma, inspired by GIMP modules/display-filter-color-blind.c:\r\n        // Copyright (C) 2002-2003 Michael Natterer <mitch@gimp.org>,\r\n        //                         Sven Neumann <sven@gimp.org>,\r\n        //                         Robert Dougherty <bob@vischeck.com> and\r\n        //                         Alex Wade <alex@vischeck.com>\r\n        // This code is an implementation of an algorithm described by Hans Brettel,\r\n        // Francoise Vienot and John Mollon in the Journal of the Optical Society of\r\n        // America V14(10), pg 2647. (See http://vischeck.com/ for more info.)\r\n        lut_lookup = function (value) {\r\n            var offset = 127,\r\n                step = 64;\r\n\r\n            while (step > 0) {\r\n                if (Math.pow(offset, 0.476190476) > value) {\r\n                    offset -= step;\r\n                } else {\r\n                    if (Math.pow(offset + 1, 0.476190476) > value) {\r\n                        return offset;\r\n                    }\r\n\r\n                    offset += step;\r\n                }\r\n\r\n                step /= 2;\r\n            }\r\n\r\n            /*  the algorithm above can't reach 255  */\r\n            if (offset === 254 && 13.994955247 < value) {\r\n                return 255;\r\n            }\r\n\r\n            return offset;\r\n        };\r\n\r\n    // transform back to rgb\r\n    r = l * matrix[0][0] + m * matrix[0][1] + s * matrix[0][2];\r\n    g = l * matrix[1][0] + m * matrix[1][1] + s * matrix[1][2];\r\n    b = l * matrix[2][0] + m * matrix[2][1] + s * matrix[2][2];\r\n\r\n    r = lut_lookup(r);\r\n    g = lut_lookup(g);\r\n    b = lut_lookup(b);\r\n\r\n    ret = [r, g, b];\r\n    ret.r = r;\r\n    ret.g = g;\r\n    ret.b = b;\r\n\r\n    return ret;\r\n};\r\n\r\n/**\r\n * Splits a RGBA color value like #112233AA into it's RGB and opacity parts.\r\n * @param {String} rgba A RGBA color value\r\n * @returns {Array} An array containing the rgb color value in the first and the opacity in the second field.\r\n */\r\nJXG.rgba2rgbo = function (rgba) {\r\n    var opacity;\r\n\r\n    if (rgba.length === 9 && rgba.charAt(0) === \"#\") {\r\n        opacity = parseInt(rgba.slice(7, 9).toUpperCase(), 16) / 255;\r\n        rgba = rgba.slice(0, 7);\r\n    } else {\r\n        opacity = 1;\r\n    }\r\n\r\n    return [rgba, opacity];\r\n};\r\n\r\n/**\r\n * Generates a RGBA color value like #112233AA from it's RGB and opacity parts.\r\n * @param {String|Array} rgb A valid HTML or CSS styled color value, e.g. '#12ab21', '#abc', 'black'\r\n * or 'rgb(12, 132, 233)'. This can also be an array containing three color values either from 0.0 to 1.0 or\r\n * from 0 to 255. They will be interpreted as red, green, and blue values.\r\n * @param {Number} o The desired opacity >=0, <=1.\r\n * @returns {String} The RGBA color value.\r\n */\r\nJXG.rgbo2rgba = function (rgb, o) {\r\n    var rgba;\r\n\r\n    if (rgb === \"none\" || rgb === 'transparent') {\r\n        return rgb;\r\n    }\r\n\r\n    rgba = Math.round(o * 255).toString(16);\r\n    if (rgba.length === 1) {\r\n        rgba = \"0\" + rgba;\r\n    }\r\n\r\n    return JXG.rgb2hex(rgb) + rgba;\r\n};\r\n\r\n/**\r\n * Decolorizes the given color.\r\n * @param {String} color HTML string containing the HTML color code.\r\n * @returns {String} Returns a HTML color string\r\n */\r\nJXG.rgb2bw = function (color) {\r\n    var x,\r\n        tmp,\r\n        arr,\r\n        HexChars = '0123456789ABCDEF';\r\n\r\n    if (color === 'none') {\r\n        return color;\r\n    }\r\n\r\n    arr = JXG.rgbParser(color);\r\n    x = Math.floor(0.3 * arr[0] + 0.59 * arr[1] + 0.11 * arr[2]);\r\n\r\n    // rgbParser and Math.floor ensure that x is 0 <= x <= 255.\r\n    // Bitwise operators can be used.\r\n    /*jslint bitwise: true*/\r\n    tmp = HexChars.charAt((x >> 4) & 0xf) + HexChars.charAt(x & 0xf);\r\n\r\n    color = \"#\" + tmp + tmp + tmp;\r\n\r\n    return color;\r\n};\r\n\r\n/**\r\n * Converts a color into how a colorblind human approximately would see it.\r\n * @param {String} color HTML string containing the HTML color code.\r\n * @param {String} deficiency The type of color blindness. Possible\r\n * options are <i>protanopia</i>, <i>deuteranopia</i>, and <i>tritanopia</i>.\r\n * @returns {String} Returns a HTML color string\r\n */\r\nJXG.rgb2cb = function (color, deficiency) {\r\n    var rgb,\r\n        l,\r\n        m,\r\n        s,\r\n        lms,\r\n        tmp,\r\n        a1,\r\n        b1,\r\n        c1,\r\n        a2,\r\n        b2,\r\n        c2,\r\n        inflection,\r\n        HexChars = '0123456789ABCDEF';\r\n\r\n    if (color === 'none') {\r\n        return color;\r\n    }\r\n\r\n    lms = JXG.rgb2LMS(color);\r\n    l = lms[0];\r\n    m = lms[1];\r\n    s = lms[2];\r\n\r\n    deficiency = deficiency.toLowerCase();\r\n\r\n    switch (deficiency) {\r\n        case \"protanopia\":\r\n            a1 = -0.06150039994295001;\r\n            b1 = 0.08277001656812001;\r\n            c1 = -0.013200141220000003;\r\n            a2 = 0.05858939668799999;\r\n            b2 = -0.07934519995360001;\r\n            c2 = 0.013289415272000003;\r\n            inflection = 0.6903216543277437;\r\n\r\n            tmp = s / m;\r\n\r\n            if (tmp < inflection) {\r\n                l = -(b1 * m + c1 * s) / a1;\r\n            } else {\r\n                l = -(b2 * m + c2 * s) / a2;\r\n            }\r\n            break;\r\n        case \"tritanopia\":\r\n            a1 = -0.00058973116217;\r\n            b1 = 0.007690316482;\r\n            c1 = -0.01011703519052;\r\n            a2 = 0.025495080838999994;\r\n            b2 = -0.0422740347;\r\n            c2 = 0.017005316784;\r\n            inflection = 0.8349489908460004;\r\n\r\n            tmp = m / l;\r\n\r\n            if (tmp < inflection) {\r\n                s = -(a1 * l + b1 * m) / c1;\r\n            } else {\r\n                s = -(a2 * l + b2 * m) / c2;\r\n            }\r\n            break;\r\n        default:\r\n            a1 = -0.06150039994295001;\r\n            b1 = 0.08277001656812001;\r\n            c1 = -0.013200141220000003;\r\n            a2 = 0.05858939668799999;\r\n            b2 = -0.07934519995360001;\r\n            c2 = 0.013289415272000003;\r\n            inflection = 0.5763833686400911;\r\n\r\n            tmp = s / l;\r\n\r\n            if (tmp < inflection) {\r\n                m = -(a1 * l + c1 * s) / b1;\r\n            } else {\r\n                m = -(a2 * l + c2 * s) / b2;\r\n            }\r\n            break;\r\n    }\r\n\r\n    rgb = JXG.LMS2rgb(l, m, s);\r\n\r\n    // LMS2rgb returns an array of values ranging from 0 to 255 (both included)\r\n    // bitwise operators are safe to use.\r\n    /*jslint bitwise: true*/\r\n    tmp = HexChars.charAt((rgb[0] >> 4) & 0xf) + HexChars.charAt(rgb[0] & 0xf);\r\n    color = \"#\" + tmp;\r\n    tmp = HexChars.charAt((rgb[1] >> 4) & 0xf) + HexChars.charAt(rgb[1] & 0xf);\r\n    color += tmp;\r\n    tmp = HexChars.charAt((rgb[2] >> 4) & 0xf) + HexChars.charAt(rgb[2] & 0xf);\r\n    color += tmp;\r\n\r\n    return color;\r\n};\r\n\r\n/**\r\n * Lightens (percent > 0) or darkens (percent < 0) the color by the specified factor.\r\n * @param {String} color\r\n * @param {Number} percent\r\n * @returns {String}\r\n */\r\nJXG.shadeColor = function (color, percent) {\r\n    var arr = JXG.rgbParser(color),\r\n        r = arr[0],\r\n        g = arr[1],\r\n        b = arr[2];\r\n\r\n    r = parseInt(r + 255 * percent);\r\n    g = parseInt(g + 255 * percent);\r\n    b = parseInt(b + 255 * percent);\r\n\r\n    r = (r > 0) ? r : 0;\r\n    g = (g > 0) ? g : 0;\r\n    b = (b > 0) ? b : 0;\r\n\r\n    r = (r < 255) ? r : 255;\r\n    g = (g < 255) ? g : 255;\r\n    b = (b < 255) ? b : 255;\r\n\r\n    r = Math.round(r);\r\n    g = Math.round(g);\r\n    b = Math.round(b);\r\n\r\n    return JXG.rgb2hex([r, g, b]);\r\n};\r\n\r\n/**\r\n * Lightens the color by the specified factor.\r\n * @param {String} color\r\n * @param {Number} percent\r\n * @returns {String}\r\n *\r\n * @see JXG.shadeColor\r\n */\r\nJXG.lightenColor = function (color, percent) {\r\n    return JXG.shadeColor(color, percent);\r\n};\r\n\r\n/**\r\n * Darkens the color by the specified factor.\r\n * @param {String} color\r\n * @param {Number} percent\r\n * @returns {String}\r\n *\r\n * @see JXG.shadeColor\r\n */\r\nJXG.darkenColor = function (color, percent) {\r\n    return JXG.shadeColor(color, -1 * percent);\r\n};\r\n\r\n/**\r\n * Determines highlight color to a given color. Done by reducing (or increasing) the opacity.\r\n * @param {String} color HTML RGBA string containing the HTML color code.\r\n * @returns {String} Returns a HTML RGBA color string\r\n */\r\nJXG.autoHighlight = function (colstr) {\r\n    var col = JXG.rgba2rgbo(colstr),\r\n        c = col[0],\r\n        opa = col[1];\r\n\r\n    if (colstr.charAt(0) === \"#\") {\r\n        if (opa < 0.3) {\r\n            opa *= 1.8;\r\n        } else {\r\n            opa *= 0.4;\r\n        }\r\n\r\n        return JXG.rgbo2rgba(c, opa);\r\n    }\r\n\r\n    return colstr;\r\n};\r\n\r\n/**\r\n * Calculate whether a light or a dark color is needed as a contrast.\r\n * Especially useful to determine whether white or black font goes\r\n * better with a given background color.\r\n * @param {String} hexColor HEX value of color.\r\n * @param {String} [darkColor=\"#000000\"] HEX string for a dark color.\r\n * @param {String} [lightColor=\"#ffffff\"] HEX string for a light color.\r\n * @param {Number} [threshold=8]\r\n * @returns {String} Returns darkColor or lightColor.\r\n */\r\nJXG.contrast = function (hexColor, darkColor, lightColor, threshold) {\r\n    var rgb,\r\n        black = \"#000000\",\r\n        rgbBlack,\r\n        l1,\r\n        l2,\r\n        contrastRatio;\r\n\r\n    darkColor = darkColor || \"#000000\";\r\n    lightColor = lightColor || \"#ffffff\";\r\n    threshold = threshold || 7;\r\n\r\n    // hexColor RGB\r\n    rgb = JXG.rgbParser(hexColor);\r\n\r\n    // Black RGB\r\n    rgbBlack = JXG.rgbParser(black);\r\n\r\n    // Calc contrast ratio\r\n    l1 =\r\n        0.2126 * Math.pow(rgb[0] / 255, 2.2) +\r\n        0.7152 * Math.pow(rgb[1] / 255, 2.2) +\r\n        0.0722 * Math.pow(rgb[2] / 255, 2.2);\r\n\r\n    l2 =\r\n        0.2126 * Math.pow(rgbBlack[0] / 255, 2.2) +\r\n        0.7152 * Math.pow(rgbBlack[1] / 255, 2.2) +\r\n        0.0722 * Math.pow(rgbBlack[2] / 255, 2.2);\r\n\r\n    if (l1 > l2) {\r\n        contrastRatio = Math.floor((l1 + 0.05) / (l2 + 0.05));\r\n    } else {\r\n        contrastRatio = Math.floor((l2 + 0.05) / (l1 + 0.05));\r\n    }\r\n    contrastRatio = contrastRatio - 1;\r\n\r\n    // If contrast is more than threshold, return darkColor\r\n    if (contrastRatio > threshold) {\r\n        return darkColor;\r\n    }\r\n    // if not, return lightColor.\r\n    return lightColor;\r\n};\r\n\r\n/**\r\n * Use the color scheme of JSXGraph up to version 1.3.2.\r\n * This method has to be called before JXG.JSXGraph.initBoard();\r\n *\r\n * @see JXG.palette\r\n * @see JXG.paletteWong\r\n *\r\n * @example\r\n *\r\n * JXG.setClassicColors();\r\n * var board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-5, 5, 5,-5]});\r\n *\r\n */\r\nJXG.setClassicColors = function () {\r\n    JXG.Options.elements.strokeColor = 'blue';\r\n    JXG.Options.elements.fillColor = 'red';\r\n    JXG.Options.hatch.strokeColor = 'blue';\r\n    JXG.Options.angle.fillColor = \"#ff7f00\";\r\n    JXG.Options.angle.highlightFillColor = \"#ff7f00\";\r\n    JXG.Options.angle.strokeColor = \"#ff7f00\";\r\n    JXG.Options.angle.label.strokeColor = 'blue';\r\n    JXG.Options.arc.strokeColor = 'blue';\r\n    JXG.Options.circle.center.fillColor = 'red';\r\n    JXG.Options.circle.center.strokeColor = 'blue';\r\n    JXG.Options.circumcircle.strokeColor = 'blue';\r\n    JXG.Options.circumcircle.center.fillColor = 'red';\r\n    JXG.Options.circumcircle.center.strokeColor = 'blue';\r\n    JXG.Options.circumcirclearc.strokeColor = 'blue';\r\n    JXG.Options.circumcirclesector.strokeColor = 'blue';\r\n    JXG.Options.circumcirclesector.fillColor = 'green';\r\n    JXG.Options.circumcirclesector.highlightFillColor = 'green';\r\n    JXG.Options.conic.strokeColor = 'blue';\r\n    JXG.Options.curve.strokeColor = 'blue';\r\n    JXG.Options.incircle.strokeColor = 'blue';\r\n    JXG.Options.incircle.center.fillColor = 'red';\r\n    JXG.Options.incircle.center.strokeColor = 'blue';\r\n    JXG.Options.inequality.fillColor = 'red';\r\n    JXG.Options.integral.fillColor = 'red';\r\n    JXG.Options.integral.curveLeft.color = 'red';\r\n    JXG.Options.integral.curveRight.color = 'red';\r\n    JXG.Options.line.strokeColor = 'blue';\r\n    JXG.Options.point.fillColor = 'red';\r\n    JXG.Options.point.strokeColor = 'red';\r\n    JXG.Options.polygon.fillColor = 'green';\r\n    JXG.Options.polygon.highlightFillColor = 'green';\r\n    JXG.Options.polygon.vertices.strokeColor = 'red';\r\n    JXG.Options.polygon.vertices.fillColor = 'red';\r\n    JXG.Options.regularpolygon.fillColor = 'green';\r\n    JXG.Options.regularpolygon.highlightFillColor = 'green';\r\n    JXG.Options.regularpolygon.vertices.strokeColor = 'red';\r\n    JXG.Options.regularpolygon.vertices.fillColor = 'red';\r\n    JXG.Options.riemannsum.fillColor = 'yellow';\r\n    JXG.Options.sector.fillColor = 'green';\r\n    JXG.Options.sector.highlightFillColor = 'green';\r\n    JXG.Options.semicircle.center.fillColor = 'red';\r\n    JXG.Options.semicircle.center.strokeColor = 'blue';\r\n    JXG.Options.slopetriangle.fillColor = 'red';\r\n    JXG.Options.slopetriangle.highlightFillColor = 'red';\r\n    JXG.Options.turtle.arrow.strokeColor = 'blue';\r\n};\r\n\r\nJXG.extend(\r\n    JXG,\r\n    /** @lends JXG */ {\r\n        /**\r\n         * Bang Wong color palette,\r\n         * optimized for various type\r\n         * of color blindness.\r\n         * It contains values for\r\n         * <ul>\r\n         * <li> 'black'\r\n         * <li> 'orange'\r\n         * <li> 'skyblue'\r\n         * <li> 'bluishgreen'\r\n         * <li> 'yellow'\r\n         * <li> 'darkblue'\r\n         * <li> 'vermillion'\r\n         * <li> 'reddishpurple'\r\n         * </ul>\r\n         *\r\n         * As substitutes for standard colors, it contains the following aliases:\r\n         *\r\n         * <ul>\r\n         * <li> black (= #000000)\r\n         * <li> blue (= darkblue)\r\n         * <li> green (= bluishgreen)\r\n         * <li> purple (= reddishpurple)\r\n         * <li> red (= vermillion)\r\n         * <li> white (= #ffffff)\r\n         * </ul>\r\n         *\r\n         * See <a href=\"https://www.nature.com/articles/nmeth.1618\">Bang Wong: \"Points of view: Color blindness\"</a>\r\n         * and\r\n         * <a href=\"https://davidmathlogic.com/colorblind/\">https://davidmathlogic.com/colorblind/</a>.\r\n         *\r\n         * @name JXG.paletteWong\r\n         * @type Object\r\n         * @see JXG.palette\r\n         * @example\r\n         * var p = board.create('line', [[-1, 1], [2, -3]], {strokeColor: JXG.paletteWong.yellow});\r\n         */\r\n        paletteWong: {\r\n            black: \"#000000\",\r\n            orange: \"#E69F00\",\r\n            skyblue: \"#56B4E9\",\r\n            bluishgreen: \"#009E73\",\r\n            yellow: \"#F0E442\",\r\n            darkblue: \"#0072B2\",\r\n            vermillion: \"#D55E00\",\r\n            reddishpurple: \"#CC79A7\",\r\n\r\n            blue: \"#0072B2\",\r\n            red: \"#D55E00\", // vermillion\r\n            green: \"#009E73\", // bluishgreen\r\n            purple: \"#CC79A7\", // reddishpurple\r\n            white: \"#ffffff\"\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * Default color palette.\r\n * Contains at least color values for\r\n * <ul>\r\n * <li> black\r\n * <li> blue\r\n * <li> green\r\n * <li> purple\r\n * <li> red\r\n * <li> white\r\n * <li> yellow\r\n * </ul>\r\n *\r\n * @name JXG.palette\r\n * @type Object\r\n * @default JXG.paletteWong\r\n * @see JXG.paletteWong\r\n *\r\n * @example\r\n *\r\n * var p = board.create('line', [[-1, 1], [2, -3]], {strokeColor: JXG.palette.yellow});\r\n *\r\n */\r\nJXG.palette = JXG.paletteWong;\r\n\r\nexport default JXG;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, AMprocessNode: true, MathJax: true, document: true */\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"./constants.js\";\r\nimport EventEmitter from \"../utils/event.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Mat from \"../math/math.js\";\r\n\r\n/**\r\n * @fileoverview In this file the Coords object is defined, a class to manage all\r\n * properties and methods coordinates usually have.\r\n */\r\n\r\n/**\r\n * Constructs a new Coordinates object.\r\n * @class This is the Coordinates class.\r\n * All members a coordinate has to provide\r\n * are defined here.\r\n * @param {Number} method The type of coordinates given by the user. Accepted values are <b>COORDS_BY_SCREEN</b> and <b>COORDS_BY_USER</b>.\r\n * @param {Array} coordinates An array of affine coordinates.\r\n * @param {JXG.Board} board A reference to a board.\r\n * @param {Boolean} [emitter=true]\r\n * @constructor\r\n */\r\nJXG.Coords = function (method, coordinates, board, emitter) {\r\n    /**\r\n     * Stores the board the object is used on.\r\n     * @type JXG.Board\r\n     */\r\n    this.board = board;\r\n\r\n    /**\r\n     * Stores coordinates for user view as homogeneous coordinates.\r\n     * @type Array\r\n     */\r\n    this.usrCoords = [];\r\n    //this.usrCoords = new Float64Array(3);\r\n\r\n    /**\r\n     * Stores coordinates for screen view as homogeneous coordinates.\r\n     * @type Array\r\n     */\r\n    this.scrCoords = [];\r\n    //this.scrCoords = new Float64Array(3);\r\n\r\n    /**\r\n     * If true, this coordinates object will emit update events every time\r\n     * the coordinates are set.\r\n     * @type boolean\r\n     * @default true\r\n     */\r\n    this.emitter = !Type.exists(emitter) || emitter;\r\n\r\n    if (this.emitter) {\r\n        EventEmitter.eventify(this);\r\n    }\r\n    this.setCoordinates(method, coordinates, false, true);\r\n};\r\n\r\nJXG.extend(\r\n    JXG.Coords.prototype,\r\n    /** @lends JXG.Coords.prototype */ {\r\n        /**\r\n         * Normalize homogeneous coordinates\r\n         * @private\r\n         */\r\n        normalizeUsrCoords: function () {\r\n            if (Math.abs(this.usrCoords[0]) > Mat.eps) {\r\n                this.usrCoords[1] /= this.usrCoords[0];\r\n                this.usrCoords[2] /= this.usrCoords[0];\r\n                this.usrCoords[0] = 1.0;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Compute screen coordinates out of given user coordinates.\r\n         * @private\r\n         */\r\n        usr2screen: function (doRound) {\r\n            var mround = Math.round, // Is faster on IE, maybe slower with JIT compilers\r\n                b = this.board,\r\n                uc = this.usrCoords,\r\n                oc = b.origin.scrCoords;\r\n\r\n            if (doRound === true) {\r\n                this.scrCoords[0] = mround(uc[0]);\r\n                this.scrCoords[1] = mround(uc[0] * oc[1] + uc[1] * b.unitX);\r\n                this.scrCoords[2] = mround(uc[0] * oc[2] - uc[2] * b.unitY);\r\n            } else {\r\n                this.scrCoords[0] = uc[0];\r\n                this.scrCoords[1] = uc[0] * oc[1] + uc[1] * b.unitX;\r\n                this.scrCoords[2] = uc[0] * oc[2] - uc[2] * b.unitY;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Compute user coordinates out of given screen coordinates.\r\n         * @private\r\n         */\r\n        screen2usr: function () {\r\n            var o = this.board.origin.scrCoords,\r\n                sc = this.scrCoords,\r\n                b = this.board;\r\n\r\n            this.usrCoords[0] = 1.0;\r\n            this.usrCoords[1] = (sc[1] - o[1]) / b.unitX;\r\n            this.usrCoords[2] = (o[2] - sc[2]) / b.unitY;\r\n        },\r\n\r\n        /**\r\n         * Calculate distance of one point to another.\r\n         * @param {Number} coord_type The type of coordinates used here. Possible values are <b>JXG.COORDS_BY_USER</b> and <b>JXG.COORDS_BY_SCREEN</b>.\r\n         * @param {JXG.Coords} coordinates The Coords object to which the distance is calculated.\r\n         * @returns {Number} The distance\r\n         */\r\n        distance: function (coord_type, coordinates) {\r\n            var sum = 0,\r\n                c,\r\n                ucr = this.usrCoords,\r\n                scr = this.scrCoords,\r\n                f;\r\n\r\n            if (coord_type === Const.COORDS_BY_USER) {\r\n                c = coordinates.usrCoords;\r\n                f = ucr[0] - c[0];\r\n                sum = f * f;\r\n\r\n                if (sum > Mat.eps * Mat.eps) {\r\n                    return Number.POSITIVE_INFINITY;\r\n                }\r\n                return Mat.hypot(ucr[1] - c[1], ucr[2] - c[2]);\r\n            } else {\r\n                c = coordinates.scrCoords;\r\n                return Mat.hypot(scr[1] - c[1], scr[2] - c[2]);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Set coordinates by either user coordinates or screen coordinates and recalculate the other one.\r\n         * @param {Number} coord_type The type of coordinates used here. Possible values are <b>COORDS_BY_USER</b> and <b>COORDS_BY_SCREEN</b>.\r\n         * @param {Array} coordinates An array of affine coordinates the Coords object is set to.\r\n         * @param {Boolean} [doRound=true] flag If true or null round the coordinates in usr2screen. This is used in smooth curve plotting.\r\n         * The IE needs rounded coordinates. Id doRound==false we have to round in updatePathString.\r\n         * @param {Boolean} [noevent=false]\r\n         * @returns {JXG.Coords} Reference to the coords object.\r\n         */\r\n        setCoordinates: function (coord_type, coordinates, doRound, noevent) {\r\n            var uc = this.usrCoords,\r\n                sc = this.scrCoords,\r\n                // Original values\r\n                ou = [uc[0], uc[1], uc[2]],\r\n                os = [sc[0], sc[1], sc[2]];\r\n\r\n            if (coord_type === Const.COORDS_BY_USER) {\r\n                if (coordinates.length === 2) {\r\n                    // Euclidean coordinates\r\n                    uc[0] = 1.0;\r\n                    uc[1] = coordinates[0];\r\n                    uc[2] = coordinates[1];\r\n                } else {\r\n                    // Homogeneous coordinates (normalized)\r\n                    uc[0] = coordinates[0];\r\n                    uc[1] = coordinates[1];\r\n                    uc[2] = coordinates[2];\r\n                    this.normalizeUsrCoords();\r\n                }\r\n                this.usr2screen(doRound);\r\n            } else {\r\n                if (coordinates.length === 2) {\r\n                    // Euclidean coordinates\r\n                    sc[1] = coordinates[0];\r\n                    sc[2] = coordinates[1];\r\n                } else {\r\n                    // Homogeneous coordinates (normalized)\r\n                    sc[1] = coordinates[1];\r\n                    sc[2] = coordinates[2];\r\n                }\r\n                this.screen2usr();\r\n            }\r\n\r\n            if (this.emitter && !noevent && (os[1] !== sc[1] || os[2] !== sc[2])) {\r\n                this.triggerEventHandlers([\"update\"], [ou, os]);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Copy array, either scrCoords or usrCoords\r\n         * Uses slice() in case of standard arrays and set() in case of\r\n         * typed arrays.\r\n         * @private\r\n         * @param {String} obj Either 'scrCoords' or 'usrCoords'\r\n         * @param {Number} offset Offset, defaults to 0 if not given\r\n         * @returns {Array} Returns copy of the coords array either as standard array or as\r\n         *   typed array.\r\n         */\r\n        copy: function (obj, offset) {\r\n            if (offset === undefined) {\r\n                offset = 0;\r\n            }\r\n\r\n            return this[obj].slice(offset);\r\n        },\r\n\r\n        /**\r\n         * Test if one of the usrCoords is NaN or the coordinates are infinite.\r\n         * @returns {Boolean} true if the coordinates are finite, false otherwise.\r\n         */\r\n        isReal: function () {\r\n            return (\r\n                !isNaN(this.usrCoords[1] + this.usrCoords[2]) &&\r\n                Math.abs(this.usrCoords[0]) > Mat.eps\r\n            );\r\n        },\r\n\r\n        /**\r\n         * Triggered whenever the coordinates change.\r\n         * @name JXG.Coords#update\r\n         * @param {Array} ou Old user coordinates\r\n         * @param {Array} os Old screen coordinates\r\n         * @event\r\n         */\r\n        __evt__update: function (ou, os) {},\r\n\r\n        /**\r\n         * @ignore\r\n         */\r\n        __evt: function () {}\r\n    }\r\n);\r\n\r\nexport default JXG.Coords;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*\r\n    Some functionalities in this file were developed as part of a software project\r\n    with students. We would like to thank all contributors for their help:\r\n\r\n    Winter semester 2024/2025:\r\n        Philipp Ditz,\r\n        Florian Hein,\r\n        Pirmin Hinderling,\r\n        Tim Sauer\r\n */\r\n\r\n/*global JXG: true, define: true, window: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview In this file the Text element is defined.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"./constants.js\";\r\nimport GeometryElement from \"./element.js\";\r\nimport GeonextParser from \"../parser/geonext.js\";\r\nimport Env from \"../utils/env.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport CoordsElement from \"./coordselement.js\";\r\n\r\nvar priv = {\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    HTMLSliderInputEventHandler: function () {\r\n        this._val = parseFloat(this.rendNodeRange.value);\r\n        this.rendNodeOut.value = this.rendNodeRange.value;\r\n        this.board.update();\r\n    }\r\n};\r\n\r\n/**\r\n * Construct and handle texts.\r\n *\r\n * The coordinates can be relative to the coordinates of an element\r\n * given in {@link JXG.Options#text.anchor}.\r\n *\r\n * MathJax, HTML and GEONExT syntax can be handled.\r\n * @class Creates a new text object. Do not use this constructor to create a text. Use {@link JXG.Board#create} with\r\n * type {@link Text} instead.\r\n * @augments JXG.GeometryElement\r\n * @augments JXG.CoordsElement\r\n * @param {string|JXG.Board} board The board the new text is drawn on.\r\n * @param {Array} coordinates An array with the user coordinates of the text.\r\n * @param {Object} attributes An object containing visual properties and optional a name and a id.\r\n * @param {string|function} content A string or a function returning a string.\r\n *\r\n */\r\nJXG.Text = function (board, coords, attributes, content) {\r\n    var tmp;\r\n\r\n    this.constructor(board, attributes, Const.OBJECT_TYPE_TEXT, Const.OBJECT_CLASS_TEXT);\r\n\r\n    this.element = this.board.select(attributes.anchor);\r\n    this.coordsConstructor(coords, this.evalVisProp('islabel'));\r\n\r\n    this.content = \"\";\r\n    this.plaintext = \"\";\r\n    this.plaintextOld = null;\r\n    this.orgText = \"\";\r\n\r\n    this.needsSizeUpdate = false;\r\n    // Only used by infobox anymore\r\n    this.hiddenByParent = false;\r\n\r\n    /**\r\n     * Width and height of the text element in pixel.\r\n     *\r\n     * @private\r\n     * @type Array\r\n     */\r\n    this.size = [1.0, 1.0];\r\n    this.id = this.board.setId(this, 'T');\r\n\r\n    this.board.renderer.drawText(this);\r\n    this.board.finalizeAdding(this);\r\n\r\n    // Set text before drawing\r\n    // this._createFctUpdateText(content);\r\n    // this.updateText();\r\n\r\n    // Set attribute visible to true. This is necessary to\r\n    // create all sub-elements for button, input and checkbox\r\n    tmp = this.visProp.visible;\r\n    this.visProp.visible = true;\r\n    this.setText(content);\r\n    // Restore the correct attribute visible.\r\n    this.visProp.visible = tmp;\r\n\r\n    if (Type.isString(this.content)) {\r\n        this.notifyParents(this.content);\r\n    }\r\n    this.elType = 'text';\r\n\r\n    this.methodMap = Type.deepCopy(this.methodMap, {\r\n        setText: \"setTextJessieCode\",\r\n        // free: 'free',\r\n        move: \"setCoords\",\r\n        Size: \"getSize\",\r\n        setAutoPosition: \"setAutoPosition\"\r\n    });\r\n};\r\n\r\nJXG.Text.prototype = new GeometryElement();\r\nType.copyPrototypeMethods(JXG.Text, CoordsElement, 'coordsConstructor');\r\n\r\nJXG.extend(\r\n    JXG.Text.prototype,\r\n    /** @lends JXG.Text.prototype */ {\r\n        /**\r\n         * @private\r\n         * @param {Number} x\r\n         * @param {Number} y\r\n         * @returns {Boolean}\r\n        */\r\n        // Test if the screen coordinates (x,y) are in a small stripe\r\n        // at the left side or at the right side of the text.\r\n        // Sensitivity is set in this.board.options.precision.hasPoint.\r\n        // If dragarea is set to 'all' (default), tests if the screen\r\n        // coordinates (x,y) are in within the text boundary.\r\n        hasPoint: function (x, y) {\r\n            var lft, rt, top, bot, ax, ay, type, r;\r\n\r\n            if (Type.isObject(this.evalVisProp('precision'))) {\r\n                type = this.board._inputDevice;\r\n                r = this.evalVisProp('precision.' + type);\r\n            } else {\r\n                // 'inherit'\r\n                r = this.board.options.precision.hasPoint;\r\n            }\r\n            if (this.transformations.length > 0) {\r\n                //Transform the mouse/touch coordinates\r\n                // back to the original position of the text.\r\n                lft = Mat.matVecMult(\r\n                    Mat.inverse(this.board.renderer.joinTransforms(this, this.transformations)),\r\n                    [1, x, y]\r\n                );\r\n                x = lft[1];\r\n                y = lft[2];\r\n            }\r\n\r\n            ax = this.getAnchorX();\r\n            if (ax === 'right') {\r\n                lft = this.coords.scrCoords[1] - this.size[0];\r\n            } else if (ax === 'middle') {\r\n                lft = this.coords.scrCoords[1] - 0.5 * this.size[0];\r\n            } else {\r\n                lft = this.coords.scrCoords[1];\r\n            }\r\n            rt = lft + this.size[0];\r\n\r\n            ay = this.getAnchorY();\r\n            if (ay === 'top') {\r\n                bot = this.coords.scrCoords[2] + this.size[1];\r\n            } else if (ay === 'middle') {\r\n                bot = this.coords.scrCoords[2] + 0.5 * this.size[1];\r\n            } else {\r\n                bot = this.coords.scrCoords[2];\r\n            }\r\n            top = bot - this.size[1];\r\n\r\n            if (this.evalVisProp('dragarea') === 'all') {\r\n                return x >= lft - r && x < rt + r && y >= top - r && y <= bot + r;\r\n            }\r\n            // e.g. 'small'\r\n            return (\r\n                y >= top - r &&\r\n                y <= bot + r &&\r\n                ((x >= lft - r && x <= lft + 2 * r) || (x >= rt - 2 * r && x <= rt + r))\r\n            );\r\n        },\r\n\r\n        /**\r\n         * This sets the updateText function of this element depending on the type of text content passed.\r\n         * Used by {@link JXG.Text#_setText}.\r\n         * @param {String|Function|Number} text\r\n         * @private\r\n         * @see JXG.Text#_setText\r\n         */\r\n        _createFctUpdateText: function (text) {\r\n            var updateText, e, digits,\r\n                resolvedText,\r\n                i, that,\r\n                ev_p = this.evalVisProp('parse'),\r\n                ev_um = this.evalVisProp('usemathjax'),\r\n                ev_uk = this.evalVisProp('usekatex'),\r\n                convertJessieCode = false;\r\n\r\n            this.orgText = text;\r\n\r\n            if (Type.isFunction(text)) {\r\n                /**\r\n                 * Dynamically created function to update the content\r\n                 * of a text. Can not be overwritten.\r\n                 * <p>\r\n                 * &lt;value&gt; tags will not be evaluated if text is provided by a function\r\n                 * <p>\r\n                 * Sets the property <tt>plaintext</tt> of the text element.\r\n                 *\r\n                 * @private\r\n                 */\r\n                this.updateText = function () {\r\n                    resolvedText = text().toString(); // Evaluate function\r\n                    if (ev_p && !ev_um && !ev_uk) {\r\n                        this.plaintext = this.replaceSub(\r\n                            this.replaceSup(\r\n                                this.convertGeonextAndSketchometry2CSS(resolvedText, false)\r\n                            )\r\n                        );\r\n                    } else {\r\n                        this.plaintext = resolvedText;\r\n                    }\r\n                };\r\n            } else {\r\n                if (Type.isNumber(text) && this.evalVisProp('formatnumber')) {\r\n                    if (this.evalVisProp('tofraction')) {\r\n                        if (ev_um) {\r\n                            this.content = '\\\\(' + Type.toFraction(text, true) + '\\\\)';\r\n                        } else {\r\n                            this.content = Type.toFraction(text, ev_uk);\r\n                        }\r\n                    } else {\r\n                        digits = this.evalVisProp('digits');\r\n                        if (this.useLocale()) {\r\n                            this.content = this.formatNumberLocale(text, digits);\r\n                        } else {\r\n                            this.content = Type.toFixed(text, digits);\r\n                        }\r\n                    }\r\n                } else if (Type.isString(text) && ev_p) {\r\n                    if (this.evalVisProp('useasciimathml')) {\r\n                        // ASCIIMathML\r\n                        // value-tags are not supported\r\n                        this.content = \"'`\" + text + \"`'\";\r\n                    } else if (ev_um || ev_uk) {\r\n                        // MathJax or KaTeX\r\n                        // Replace value-tags by functions\r\n                        // sketchofont is ignored\r\n                        this.content = this.valueTagToJessieCode(text);\r\n                        if (!Type.isArray(this.content)) {\r\n                            // For some reason we don't have to mask backslashes in an array of strings\r\n                            // anymore.\r\n                            //\r\n                            // for (i = 0; i < this.content.length; i++) {\r\n                            //     this.content[i] = this.content[i].replace(/\\\\/g, \"\\\\\\\\\"); // Replace single backslash by double\r\n                            // }\r\n                            // } else {\r\n                            this.content = this.content.replace(/\\\\/g, \"\\\\\\\\\"); // Replace single backslash by double\r\n                        }\r\n                    } else {\r\n                        // No TeX involved.\r\n                        // Converts GEONExT syntax into JavaScript string\r\n                        // Short math is allowed\r\n                        // Replace value-tags by functions\r\n                        // Avoid geonext2JS calls\r\n                        this.content = this.poorMansTeX(this.valueTagToJessieCode(text));\r\n                    }\r\n                    convertJessieCode = true;\r\n                } else {\r\n                    this.content = text;\r\n                }\r\n\r\n                // Generate function which returns the text to be displayed\r\n                if (convertJessieCode) {\r\n                    // Convert JessieCode to JS function\r\n                    if (Type.isArray(this.content)) {\r\n                        // This is the case if the text contained value-tags.\r\n                        // These value-tags consist of JessieCode snippets\r\n                        // which are now replaced by JavaScript functions\r\n                        that = this;\r\n                        for (i = 0; i < this.content.length; i++) {\r\n                            if (this.content[i][0] !== '\"') {\r\n                                this.content[i] = this.board.jc.snippet(this.content[i], true, \"\", false);\r\n                                for (e in this.content[i].deps) {\r\n                                    this.addParents(this.content[i].deps[e]);\r\n                                    this.content[i].deps[e].addChild(this);\r\n                                }\r\n                            }\r\n                        }\r\n\r\n                        updateText = function() {\r\n                            var i, t,\r\n                                digits = that.evalVisProp('digits'),\r\n                                txt = '';\r\n\r\n                            for (i = 0; i < that.content.length; i++) {\r\n                                if (Type.isFunction(that.content[i])) {\r\n                                    t = that.content[i]();\r\n                                    if (that.useLocale()) {\r\n                                        t = that.formatNumberLocale(t, digits);\r\n                                    } else {\r\n                                        t = Type.toFixed(t, digits);\r\n                                    }\r\n                                } else {\r\n                                    t = that.content[i];\r\n                                    // Instead of 't.at(t.length - 1)' also 't.(-1)' should work.\r\n                                    // However in Moodle 4.2 't.(-1)' returns an empty string.\r\n                                    // In plain HTML pages it works.\r\n                                    if (t[0] === '\"' && t[t.length - 1] === '\"') {\r\n                                        t = t.slice(1, -1);\r\n                                    }\r\n                                }\r\n\r\n                                txt += t;\r\n                            }\r\n                            return txt;\r\n                        };\r\n                    } else {\r\n                        updateText = this.board.jc.snippet(this.content, true, \"\", false);\r\n                        for (e in updateText.deps) {\r\n                            this.addParents(updateText.deps[e]);\r\n                            updateText.deps[e].addChild(this);\r\n                        }\r\n                    }\r\n\r\n                    // Ticks have been escaped in valueTagToJessieCode\r\n                    this.updateText = function () {\r\n                        this.plaintext = this.unescapeTicks(updateText());\r\n                    };\r\n                } else {\r\n                    this.updateText = function () {\r\n                        this.plaintext = this.content; // text;\r\n                    };\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Defines new content. This is used by {@link JXG.Text#setTextJessieCode} and {@link JXG.Text#setText}. This is required because\r\n         * JessieCode needs to filter all Texts inserted into the DOM and thus has to replace setText by setTextJessieCode.\r\n         * @param {String|Function|Number} text\r\n         * @returns {JXG.Text}\r\n         * @private\r\n         */\r\n        _setText: function (text) {\r\n            this._createFctUpdateText(text);\r\n\r\n            // First evaluation of the string.\r\n            // We need this for display='internal' and Canvas\r\n            this.updateText();\r\n            this.fullUpdate();\r\n\r\n            // We do not call updateSize for the infobox to speed up rendering\r\n            if (!this.board.infobox || this.id !== this.board.infobox.id) {\r\n                this.updateSize(); // updateSize() is called at least once.\r\n            }\r\n\r\n            // This may slow down canvas renderer\r\n            // if (this.board.renderer.type === 'canvas') {\r\n            //     this.board.fullUpdate();\r\n            // }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Defines new content but converts &lt; and &gt; to HTML entities before updating the DOM.\r\n         * @param {String|function} text\r\n         */\r\n        setTextJessieCode: function (text) {\r\n            var s;\r\n\r\n            this.visProp.castext = text;\r\n            if (Type.isFunction(text)) {\r\n                s = function () {\r\n                    return Type.sanitizeHTML(text());\r\n                };\r\n            } else {\r\n                if (Type.isNumber(text)) {\r\n                    s = text;\r\n                } else {\r\n                    s = Type.sanitizeHTML(text);\r\n                }\r\n            }\r\n\r\n            return this._setText(s);\r\n        },\r\n\r\n        /**\r\n         * Defines new content.\r\n         * @param {String|function} text\r\n         * @returns {JXG.Text} Reference to the text object.\r\n         */\r\n        setText: function (text) {\r\n            return this._setText(text);\r\n        },\r\n\r\n        /**\r\n         * Recompute the width and the height of the text box.\r\n         * Updates the array {@link JXG.Text#size} with pixel values.\r\n         * The result may differ from browser to browser\r\n         * by some pixels.\r\n         * In canvas an old IEs we use a very crude estimation of the dimensions of\r\n         * the textbox.\r\n         * JSXGraph needs {@link JXG.Text#size} for applying rotations in IE and\r\n         * for aligning text.\r\n         *\r\n         * @return {this} [description]\r\n         */\r\n        updateSize: function () {\r\n            var tmp,\r\n                that,\r\n                node,\r\n                ev_d = this.evalVisProp('display');\r\n\r\n            if (!Env.isBrowser || this.board.renderer.type === 'no') {\r\n                return this;\r\n            }\r\n            node = this.rendNode;\r\n\r\n            /**\r\n             * offsetWidth and offsetHeight seem to be supported for internal vml elements by IE10+ in IE8 mode.\r\n             */\r\n            if (ev_d === \"html\" || this.board.renderer.type === 'vml') {\r\n                if (Type.exists(node.offsetWidth)) {\r\n                    that = this;\r\n                    window.setTimeout(function () {\r\n                        that.size = [node.offsetWidth, node.offsetHeight];\r\n                        that.needsUpdate = true;\r\n                        that.updateRenderer();\r\n                    }, 0);\r\n                    // In case, there is non-zero padding or borders\r\n                    // the following approach does not longer work.\r\n                    // s = [node.offsetWidth, node.offsetHeight];\r\n                    // if (s[0] === 0 && s[1] === 0) { // Some browsers need some time to set offsetWidth and offsetHeight\r\n                    //     that = this;\r\n                    //     window.setTimeout(function () {\r\n                    //         that.size = [node.offsetWidth, node.offsetHeight];\r\n                    //         that.needsUpdate = true;\r\n                    //         that.updateRenderer();\r\n                    //     }, 0);\r\n                    // } else {\r\n                    //     this.size = s;\r\n                    // }\r\n                } else {\r\n                    this.size = this.crudeSizeEstimate();\r\n                }\r\n            } else if (ev_d === 'internal') {\r\n                if (this.board.renderer.type === 'svg') {\r\n                    that = this;\r\n                    window.setTimeout(function () {\r\n                        try {\r\n                            tmp = node.getBBox();\r\n                            that.size = [tmp.width, tmp.height];\r\n                            that.needsUpdate = true;\r\n                            that.updateRenderer();\r\n                        } catch (e) {}\r\n                    }, 0);\r\n                } else if (this.board.renderer.type === 'canvas') {\r\n                    this.size = this.crudeSizeEstimate();\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * A very crude estimation of the dimensions of the textbox in case nothing else is available.\r\n         * @returns {Array}\r\n         */\r\n        crudeSizeEstimate: function () {\r\n            var ev_fs = parseFloat(this.evalVisProp('fontsize'));\r\n            return [ev_fs * this.plaintext.length * 0.45, ev_fs * 0.9];\r\n        },\r\n\r\n        /**\r\n         * Decode unicode entities into characters.\r\n         * @param {String} string\r\n         * @returns {String}\r\n         */\r\n        utf8_decode: function (string) {\r\n            return string.replace(/&#x(\\w+);/g, function (m, p1) {\r\n                return String.fromCharCode(parseInt(p1, 16));\r\n            });\r\n        },\r\n\r\n        /**\r\n         * Replace _{} by &lt;sub&gt;\r\n         * @param {String} te String containing _{}.\r\n         * @returns {String} Given string with _{} replaced by &lt;sub&gt;.\r\n         */\r\n        replaceSub: function (te) {\r\n            if (!te.indexOf) {\r\n                return te;\r\n            }\r\n\r\n            var j,\r\n                i = te.indexOf(\"_{\");\r\n\r\n            // The regexp in here are not used for filtering but to provide some kind of sugar for label creation,\r\n            // i.e. replacing _{...} with <sub>...</sub>. What is passed would get out anyway.\r\n            /*jslint regexp: true*/\r\n            while (i >= 0) {\r\n                te = te.slice(0, i) + te.slice(i).replace(/_\\{/, \"<sub>\");\r\n                j = te.indexOf(\"}\", i + 4);\r\n                if (j >= 0) {\r\n                    te = te.slice(0, j) + te.slice(j).replace(/\\}/, \"</sub>\");\r\n                }\r\n                i = te.indexOf(\"_{\");\r\n            }\r\n\r\n            i = te.indexOf(\"_\");\r\n            while (i >= 0) {\r\n                te = te.slice(0, i) + te.slice(i).replace(/_(.?)/, \"<sub>$1</sub>\");\r\n                i = te.indexOf(\"_\");\r\n            }\r\n\r\n            return te;\r\n        },\r\n\r\n        /**\r\n         * Replace ^{} by &lt;sup&gt;\r\n         * @param {String} te String containing ^{}.\r\n         * @returns {String} Given string with ^{} replaced by &lt;sup&gt;.\r\n         */\r\n        replaceSup: function (te) {\r\n            if (!te.indexOf) {\r\n                return te;\r\n            }\r\n\r\n            var j,\r\n                i = te.indexOf(\"^{\");\r\n\r\n            // The regexp in here are not used for filtering but to provide some kind of sugar for label creation,\r\n            // i.e. replacing ^{...} with <sup>...</sup>. What is passed would get out anyway.\r\n            /*jslint regexp: true*/\r\n            while (i >= 0) {\r\n                te = te.slice(0, i) + te.slice(i).replace(/\\^\\{/, \"<sup>\");\r\n                j = te.indexOf(\"}\", i + 4);\r\n                if (j >= 0) {\r\n                    te = te.slice(0, j) + te.slice(j).replace(/\\}/, \"</sup>\");\r\n                }\r\n                i = te.indexOf(\"^{\");\r\n            }\r\n\r\n            i = te.indexOf(\"^\");\r\n            while (i >= 0) {\r\n                te = te.slice(0, i) + te.slice(i).replace(/\\^(.?)/, \"<sup>$1</sup>\");\r\n                i = te.indexOf(\"^\");\r\n            }\r\n\r\n            return te;\r\n        },\r\n\r\n        /**\r\n         * Return the width of the text element.\r\n         * @returns {Array} [width, height] in pixel\r\n         */\r\n        getSize: function () {\r\n            return this.size;\r\n        },\r\n\r\n        /**\r\n         * Move the text to new coordinates.\r\n         * @param {number} x\r\n         * @param {number} y\r\n         * @returns {object} reference to the text object.\r\n         */\r\n        setCoords: function (x, y) {\r\n            var coordsAnchor, dx, dy;\r\n            if (Type.isArray(x) && x.length > 1) {\r\n                y = x[1];\r\n                x = x[0];\r\n            }\r\n\r\n            if (this.evalVisProp('islabel') && Type.exists(this.element)) {\r\n                coordsAnchor = this.element.getLabelAnchor();\r\n                dx = (x - coordsAnchor.usrCoords[1]) * this.board.unitX;\r\n                dy = -(y - coordsAnchor.usrCoords[2]) * this.board.unitY;\r\n\r\n                this.relativeCoords.setCoordinates(Const.COORDS_BY_SCREEN, [dx, dy]);\r\n            } else {\r\n                this.coords.setCoordinates(Const.COORDS_BY_USER, [x, y]);\r\n            }\r\n\r\n            // this should be a local update, otherwise there might be problems\r\n            // with the tick update routine resulting in orphaned tick labels\r\n            this.fullUpdate();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Evaluates the text.\r\n         * Then, the update function of the renderer\r\n         * is called.\r\n         */\r\n        update: function (fromParent) {\r\n            if (!this.needsUpdate) {\r\n                return this;\r\n            }\r\n\r\n            this.updateCoords(fromParent);\r\n            this.updateText();\r\n\r\n            if (this.evalVisProp('display') === 'internal') {\r\n                if (Type.isString(this.plaintext)) {\r\n                    this.plaintext = this.utf8_decode(this.plaintext);\r\n                }\r\n            }\r\n\r\n            this.checkForSizeUpdate();\r\n            if (this.needsSizeUpdate) {\r\n                this.updateSize();\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Used to save updateSize() calls.\r\n         * Called in JXG.Text.update\r\n         * That means this.update() has been called.\r\n         * More tests are in JXG.Renderer.updateTextStyle. The latter tests\r\n         * are one update off. But this should pose not too many problems, since\r\n         * it affects fontSize and cssClass changes.\r\n         *\r\n         * @private\r\n         */\r\n        checkForSizeUpdate: function () {\r\n            if (this.board.infobox && this.id === this.board.infobox.id) {\r\n                this.needsSizeUpdate = false;\r\n            } else {\r\n                // For some magic reason it is more efficient on the iPad to\r\n                // call updateSize() for EVERY text element EVERY time.\r\n                this.needsSizeUpdate = this.plaintextOld !== this.plaintext;\r\n\r\n                if (this.needsSizeUpdate) {\r\n                    this.plaintextOld = this.plaintext;\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * The update function of the renderer\r\n         * is called.\r\n         * @private\r\n         */\r\n        updateRenderer: function () {\r\n            if (\r\n                //this.board.updateQuality === this.board.BOARD_QUALITY_HIGH &&\r\n                this.evalVisProp('autoposition')\r\n            ) {\r\n                this.setAutoPosition().updateConstraint();\r\n            }\r\n            return this.updateRendererGeneric('updateText');\r\n        },\r\n\r\n        /**\r\n         * Converts shortened math syntax into correct syntax:  3x instead of 3*x or\r\n         * (a+b)(3+1) instead of (a+b)*(3+1).\r\n         *\r\n         * @private\r\n         * @param{String} expr Math term\r\n         * @returns {string} expanded String\r\n         */\r\n        expandShortMath: function (expr) {\r\n            var re = /([)0-9.])\\s*([(a-zA-Z_])/g;\r\n            return expr.replace(re, \"$1*$2\");\r\n        },\r\n\r\n        /**\r\n         * Converts the GEONExT syntax of the <value> terms into JavaScript.\r\n         * Also, all Objects whose name appears in the term are searched and\r\n         * the text is added as child to these objects.\r\n         * This method is called if the attribute parse==true is set.\r\n         *\r\n         * Obsolete, replaced by JXG.Text.valueTagToJessieCode\r\n         *\r\n         * @param{String} contentStr String to be parsed\r\n         * @param{Boolean} [expand] Optional flag if shortened math syntax is allowed (e.g. 3x instead of 3*x).\r\n         * @param{Boolean} [avoidGeonext2JS] Optional flag if geonext2JS should be called. For backwards compatibility\r\n         * this has to be set explicitly to true.\r\n         * @param{Boolean} [outputTeX] Optional flag which has to be true if the resulting term will be sent to MathJax or KaTeX.\r\n         * If true, \"_\" and \"^\" are NOT replaced by HTML tags sub and sup. Default: false, i.e. the replacement is done.\r\n         * This flag allows the combination of &lt;value&gt; tag containing calculations with TeX output.\r\n         *\r\n         * @deprecated\r\n         * @private\r\n         * @see JXG.GeonextParser#geonext2JS\r\n         * @see JXG.Text#valueTagToJessieCode\r\n         *\r\n         */\r\n        generateTerm: function (contentStr, expand, avoidGeonext2JS) {\r\n            var res,\r\n                term,\r\n                i,\r\n                j,\r\n                plaintext = '\"\"';\r\n\r\n            // Revert possible jc replacement\r\n            contentStr = contentStr || \"\";\r\n            contentStr = contentStr.replace(/\\r/g, \"\");\r\n            contentStr = contentStr.replace(/\\n/g, \"\");\r\n            contentStr = contentStr.replace(/\"/g, \"'\");\r\n            contentStr = contentStr.replace(/'/g, \"\\\\'\");\r\n\r\n            // Old GEONExT syntax, not (yet) supported as TeX output.\r\n            // Otherwise, the else clause should be used.\r\n            // That means, i.e. the <arc> tag and <sqrt> tag are not\r\n            // converted into TeX syntax.\r\n            contentStr = contentStr.replace(/&amp;arc;/g, \"&ang;\");\r\n            contentStr = contentStr.replace(/<arc\\s*\\/>/g, \"&ang;\");\r\n            contentStr = contentStr.replace(/&lt;arc\\s*\\/&gt;/g, \"&ang;\");\r\n            contentStr = contentStr.replace(/&lt;sqrt\\s*\\/&gt;/g, \"&radic;\");\r\n\r\n            contentStr = contentStr.replace(/&lt;value&gt;/g, \"<value>\");\r\n            contentStr = contentStr.replace(/&lt;\\/value&gt;/g, \"</value>\");\r\n\r\n            // Convert GEONExT syntax into  JavaScript syntax\r\n            i = contentStr.indexOf(\"<value>\");\r\n            j = contentStr.indexOf(\"</value>\");\r\n            if (i >= 0) {\r\n                while (i >= 0) {\r\n                    plaintext +=\r\n                        ' + \"' + this.replaceSub(this.replaceSup(contentStr.slice(0, i))) + '\"';\r\n                    // plaintext += ' + \"' + this.replaceSub(contentStr.slice(0, i)) + '\"';\r\n\r\n                    term = contentStr.slice(i + 7, j);\r\n                    term = term.replace(/\\s+/g, \"\"); // Remove all whitespace\r\n                    if (expand === true) {\r\n                        term = this.expandShortMath(term);\r\n                    }\r\n                    if (avoidGeonext2JS) {\r\n                        res = term;\r\n                    } else {\r\n                        res = GeonextParser.geonext2JS(term, this.board);\r\n                    }\r\n                    res = res.replace(/\\\\\"/g, \"'\");\r\n                    res = res.replace(/\\\\'/g, \"'\");\r\n\r\n                    // GEONExT-Hack: apply rounding once only.\r\n                    if (res.indexOf('toFixed') < 0) {\r\n                        // output of a value tag\r\n                        if (\r\n                            Type.isNumber(\r\n                                Type.bind(this.board.jc.snippet(res, true, '', false), this)()\r\n                            )\r\n                        ) {\r\n                            // may also be a string\r\n                            plaintext += '+(' + res + ').toFixed(' + this.evalVisProp('digits') + ')';\r\n                        } else {\r\n                            plaintext += '+(' + res + ')';\r\n                        }\r\n                    } else {\r\n                        plaintext += '+(' + res + ')';\r\n                    }\r\n\r\n                    contentStr = contentStr.slice(j + 8);\r\n                    i = contentStr.indexOf(\"<value>\");\r\n                    j = contentStr.indexOf(\"</value>\");\r\n                }\r\n            }\r\n\r\n            plaintext += ' + \"' + this.replaceSub(this.replaceSup(contentStr)) + '\"';\r\n            plaintext = this.convertGeonextAndSketchometry2CSS(plaintext);\r\n\r\n            // This should replace e.g. &amp;pi; by &pi;\r\n            plaintext = plaintext.replace(/&amp;/g, \"&\");\r\n            plaintext = plaintext.replace(/\"/g, \"'\");\r\n\r\n            return plaintext;\r\n        },\r\n\r\n        /**\r\n         * Replace value-tags in string by JessieCode functions.\r\n         * @param {String} contentStr\r\n         * @returns String\r\n         * @private\r\n         * @example\r\n         * \"The x-coordinate of A is &lt;value&gt;X(A)&lt;/value&gt;\"\r\n         *\r\n         */\r\n        valueTagToJessieCode: function (contentStr) {\r\n            var res, term,\r\n                i, j,\r\n                expandShortMath = true,\r\n                textComps = [],\r\n                tick = '\"';\r\n\r\n            contentStr = contentStr || \"\";\r\n            contentStr = contentStr.replace(/\\r/g, \"\");\r\n            contentStr = contentStr.replace(/\\n/g, \"\");\r\n\r\n            contentStr = contentStr.replace(/&lt;value&gt;/g, \"<value>\");\r\n            contentStr = contentStr.replace(/&lt;\\/value&gt;/g, \"</value>\");\r\n\r\n            // Convert content of value tag (GEONExT/JessieCode) syntax into JavaScript syntax\r\n            i = contentStr.indexOf(\"<value>\");\r\n            j = contentStr.indexOf(\"</value>\");\r\n            if (i >= 0) {\r\n                while (i >= 0) {\r\n                    // Add string fragment before <value> tag\r\n                    textComps.push(tick + this.escapeTicks(contentStr.slice(0, i)) + tick);\r\n\r\n                    term = contentStr.slice(i + 7, j);\r\n                    term = term.replace(/\\s+/g, \"\"); // Remove all whitespace\r\n                    if (expandShortMath === true) {\r\n                        term = this.expandShortMath(term);\r\n                    }\r\n                    res = term;\r\n                    res = res.replace(/\\\\\"/g, \"'\").replace(/\\\\'/g, \"'\");\r\n\r\n                    // // Hack: apply rounding once only.\r\n                    // if (res.indexOf('toFixed') < 0) {\r\n                    //     // Output of a value tag\r\n                    //     // Run the JessieCode parser\r\n                    //     if (\r\n                    //         Type.isNumber(\r\n                    //             Type.bind(this.board.jc.snippet(res, true, \"\", false), this)()\r\n                    //         )\r\n                    //     ) {\r\n                    //         // Output is number\r\n                    //         // textComps.push(\r\n                    //         //     '(' + res + ').toFixed(' + this.evalVisProp('digits') + ')'\r\n                    //         // );\r\n                    //         textComps.push('(' + res + ')');\r\n                    //     } else {\r\n                    //         // Output is a string\r\n                    //         textComps.push(\"(\" + res + \")\");\r\n                    //     }\r\n                    // } else {\r\n                        textComps.push(\"(\" + res + \")\");\r\n                    // }\r\n                    contentStr = contentStr.slice(j + 8);\r\n                    i = contentStr.indexOf(\"<value>\");\r\n                    j = contentStr.indexOf(\"</value>\");\r\n                }\r\n            }\r\n            // Add trailing string fragment\r\n            textComps.push(tick + this.escapeTicks(contentStr) + tick);\r\n\r\n            // return textComps.join(\" + \").replace(/&amp;/g, \"&\");\r\n            for (i = 0; i < textComps.length; i++) {\r\n                textComps[i] = textComps[i].replace(/&amp;/g, \"&\");\r\n            }\r\n            return textComps;\r\n        },\r\n\r\n        /**\r\n         * Simple math rendering using HTML / CSS only. In case of array,\r\n         * handle each entry separately and return array with the\r\n         * rendering strings.\r\n         *\r\n         * @param {String|Array} s\r\n         * @returns {String|Array}\r\n         * @see JXG.Text#convertGeonextAndSketchometry2CSS\r\n         * @private\r\n         * @see JXG.Text#replaceSub\r\n         * @see JXG.Text#replaceSup\r\n         * @see JXG.Text#convertGeonextAndSketchometry2CSS\r\n         */\r\n        poorMansTeX: function (s) {\r\n            var i, a;\r\n            if (Type.isArray(s)) {\r\n                a = [];\r\n                for (i = 0; i < s.length; i++) {\r\n                    a.push(this.poorMansTeX(s[i]));\r\n                }\r\n                return a;\r\n            }\r\n\r\n            s = s\r\n                .replace(/<arc\\s*\\/*>/g, \"&ang;\")\r\n                .replace(/&lt;arc\\s*\\/*&gt;/g, \"&ang;\")\r\n                .replace(/<sqrt\\s*\\/*>/g, \"&radic;\")\r\n                .replace(/&lt;sqrt\\s*\\/*&gt;/g, \"&radic;\");\r\n            return this.convertGeonextAndSketchometry2CSS(this.replaceSub(this.replaceSup(s)), true);\r\n        },\r\n\r\n        /**\r\n         * Replace ticks by URI escape sequences\r\n         *\r\n         * @param {String} s\r\n         * @returns String\r\n         * @private\r\n         *\r\n         */\r\n        escapeTicks: function (s) {\r\n            return s.replace(/\"/g, \"%22\").replace(/'/g, \"%27\");\r\n        },\r\n\r\n        /**\r\n         * Replace escape sequences for ticks by ticks\r\n         *\r\n         * @param {String} s\r\n         * @returns String\r\n         * @private\r\n         */\r\n        unescapeTicks: function (s) {\r\n            return s.replace(/%22/g, '\"').replace(/%27/g, \"'\");\r\n        },\r\n\r\n        /**\r\n         * Converts the GEONExT tags <overline> and <arrow> to\r\n         * HTML span tags with proper CSS formatting.\r\n         * @private\r\n         * @see JXG.Text.poorMansTeX\r\n         * @see JXG.Text._setText\r\n         */\r\n        convertGeonext2CSS: function (s) {\r\n            if (Type.isString(s)) {\r\n                s = s.replace(\r\n                    /(<|&lt;)overline(>|&gt;)/g,\r\n                    \"<span style=text-decoration:overline;>\"\r\n                );\r\n                s = s.replace(/(<|&lt;)\\/overline(>|&gt;)/g, \"</span>\");\r\n                s = s.replace(\r\n                    /(<|&lt;)arrow(>|&gt;)/g,\r\n                    \"<span style=text-decoration:overline;>\"\r\n                );\r\n                s = s.replace(/(<|&lt;)\\/arrow(>|&gt;)/g, \"</span>\");\r\n            }\r\n\r\n            return s;\r\n        },\r\n\r\n        /**\r\n         * Converts the sketchometry tag <sketchofont> to\r\n         * HTML span tags with proper CSS formatting.\r\n         *\r\n         * @param {String|Function|Number} s Text\r\n         * @param {Boolean} escape Flag if ticks should be escaped. Escaping is necessary\r\n         * if s is a text. It has to be avoided if s is a function returning text.\r\n         * @private\r\n         * @see JXG.Text._setText\r\n         * @see JXG.Text.convertGeonextAndSketchometry2CSS\r\n         *\r\n         */\r\n        convertSketchometry2CSS: function (s, escape) {\r\n            var t1 = \"<span class=\\\"sketcho sketcho-inherit sketcho-\",\r\n                t2 = \"\\\"></span>\";\r\n\r\n            if (Type.isString(s)) {\r\n                if (escape) {\r\n                    t1 = this.escapeTicks(t1);\r\n                    t2 = this.escapeTicks(t2);\r\n                }\r\n                s = s.replace(/(<|&lt;)sketchofont(>|&gt;)/g, t1);\r\n                s = s.replace(/(<|&lt;)\\/sketchofont(>|&gt;)/g, t2);\r\n            }\r\n\r\n            return s;\r\n        },\r\n\r\n        /**\r\n         * Alias for convertGeonext2CSS and convertSketchometry2CSS\r\n         *\r\n         * @param {String|Function|Number} s Text\r\n         * @param {Boolean} escape Flag if ticks should be escaped\r\n         * @private\r\n         * @see JXG.Text.convertGeonext2CSS\r\n         * @see JXG.Text.convertSketchometry2CSS\r\n         */\r\n        convertGeonextAndSketchometry2CSS: function (s, escape) {\r\n            s = this.convertGeonext2CSS(s);\r\n            s = this.convertSketchometry2CSS(s, escape);\r\n            return s;\r\n        },\r\n\r\n        /**\r\n         * Finds dependencies in a given term and notifies the parents by adding the\r\n         * dependent object to the found objects child elements.\r\n         * @param {String} content String containing dependencies for the given object.\r\n         * @private\r\n         */\r\n        notifyParents: function (content) {\r\n            var search,\r\n                res = null;\r\n\r\n            // revert possible jc replacement\r\n            content = content.replace(/&lt;value&gt;/g, \"<value>\");\r\n            content = content.replace(/&lt;\\/value&gt;/g, \"</value>\");\r\n\r\n            do {\r\n                search = /<value>([\\w\\s*/^\\-+()[\\],<>=!]+)<\\/value>/;\r\n                res = search.exec(content);\r\n\r\n                if (res !== null) {\r\n                    GeonextParser.findDependencies(this, res[1], this.board);\r\n                    content = content.slice(res.index);\r\n                    content = content.replace(search, \"\");\r\n                }\r\n            } while (res !== null);\r\n\r\n            return this;\r\n        },\r\n\r\n        // documented in element.js\r\n        getParents: function () {\r\n            var p;\r\n            if (this.relativeCoords !== undefined) {\r\n                // Texts with anchor elements, excluding labels\r\n                p = [\r\n                    this.relativeCoords.usrCoords[1],\r\n                    this.relativeCoords.usrCoords[2],\r\n                    this.orgText\r\n                ];\r\n            } else {\r\n                // Other texts\r\n                p = [this.Z(), this.X(), this.Y(), this.orgText];\r\n            }\r\n\r\n            if (this.parents.length !== 0) {\r\n                p = this.parents;\r\n            }\r\n\r\n            return p;\r\n        },\r\n\r\n        /**\r\n         * Returns the bounding box of the text element in user coordinates as an\r\n         * array of length 4: [upper left x, upper left y, lower right x, lower right y].\r\n         * The method assumes that the lower left corner is at position [el.X(), el.Y()]\r\n         * of the text element el, i.e. the attributes anchorX, anchorY are ignored.\r\n         *\r\n         * <p>\r\n         * <strong>Attention:</strong> for labels, [0, 0, 0, 0] is returned.\r\n         *\r\n         * @returns Array\r\n         */\r\n        bounds: function () {\r\n            var c = this.coords.usrCoords;\r\n\r\n            if (\r\n                this.evalVisProp('islabel') ||\r\n                this.board.unitY === 0 ||\r\n                this.board.unitX === 0\r\n            ) {\r\n                return [0, 0, 0, 0];\r\n            }\r\n            return [\r\n                c[1],\r\n                c[2] + this.size[1] / this.board.unitY,\r\n                c[1] + this.size[0] / this.board.unitX,\r\n                c[2]\r\n            ];\r\n        },\r\n\r\n        /**\r\n         * Returns the value of the attribute \"anchorX\". If this equals \"auto\",\r\n         * returns \"left\", \"middle\", or \"right\", depending on the\r\n         * value of the attribute \"position\".\r\n         * @returns String\r\n         */\r\n        getAnchorX: function () {\r\n            var a = this.evalVisProp('anchorx');\r\n            if (a === 'auto') {\r\n                switch (this.visProp.position) {\r\n                    case \"top\":\r\n                    case \"bot\":\r\n                        return 'middle';\r\n                    case \"rt\":\r\n                    case \"lrt\":\r\n                    case \"urt\":\r\n                        return 'left';\r\n                    case \"lft\":\r\n                    case \"llft\":\r\n                    case \"ulft\":\r\n                    default:\r\n                        return 'right';\r\n                }\r\n            }\r\n            return a;\r\n        },\r\n\r\n        /**\r\n         * Returns the value of the attribute \"anchorY\". If this equals \"auto\",\r\n         * returns \"bottom\", \"middle\", or \"top\", depending on the\r\n         * value of the attribute \"position\".\r\n         * @returns String\r\n         */\r\n        getAnchorY: function () {\r\n            var a = this.evalVisProp('anchory');\r\n            if (a === 'auto') {\r\n                switch (this.visProp.position) {\r\n                    case \"top\":\r\n                    case \"ulft\":\r\n                    case \"urt\":\r\n                        return 'bottom';\r\n                    case \"bot\":\r\n                    case \"lrt\":\r\n                    case \"llft\":\r\n                        return 'top';\r\n                    case \"rt\":\r\n                    case \"lft\":\r\n                    default:\r\n                        return 'middle';\r\n                }\r\n            }\r\n            return a;\r\n        },\r\n\r\n        /**\r\n         * Computes the number of overlaps of a box of w pixels width, h pixels height\r\n         * and center (x, y)\r\n         *\r\n         * An overlap occurs when either:\r\n         * <ol>\r\n         *   <li> For labels/points: Their bounding boxes intersect\r\n         *   <li> For other objects: The object contains the center point of the box\r\n         * </ol>\r\n         *\r\n         * @private\r\n         * @param  {Number} x x-coordinate of the center (screen coordinates)\r\n         * @param  {Number} y y-coordinate of the center (screen coordinates)\r\n         * @param  {Number} w width of the box in pixel\r\n         * @param  {Number} h width of the box in pixel\r\n         * @param  {Array} [whiteList] array of ids which should be ignored\r\n         * @return {Number}   Number of overlapping elements\r\n         */\r\n        getNumberOfConflicts: function(x, y, w, h, whiteList) {\r\n            whiteList = whiteList || [];\r\n            var count = 0,\r\n                i, obj,\r\n                coords,\r\n                saveHasInnerPoints,\r\n                savePointPrecision = this.board.options.precision.hasPoint,\r\n                objCenterX, objCenterY,\r\n                objWidth, objHeight;\r\n\r\n            // set a new precision for hasPoint\r\n            // this.board.options.precision.hasPoint = Math.max(w, h) * 0.5;\r\n            this.board.options.precision.hasPoint = (w + h) * 0.3;\r\n\r\n            // loop over all objects\r\n            for (i = 0; i < this.board.objectsList.length; i++) {\r\n                obj = this.board.objectsList[i];\r\n\r\n                //Skip the object if it is not meant to influence label position\r\n                if (\r\n                    obj.visPropCalc.visible &&\r\n                    obj !== this &&\r\n                    whiteList.indexOf(obj.id) === -1 &&\r\n                    obj.evalVisProp('ignoreforlabelautoposition') !== true\r\n                ) {\r\n                    // Save hasinnerpoints and temporarily disable to handle polygon areas\r\n                    saveHasInnerPoints = obj.visProp.hasinnerpoints;\r\n                    obj.visProp.hasinnerpoints = false;\r\n\r\n                    // If is label or point use other conflict detection\r\n                    if (\r\n                        obj.visProp.islabel ||\r\n                        obj.elementClass === Const.OBJECT_CLASS_POINT\r\n                    ) {\r\n                        // get coords and size of the object\r\n                        coords = obj.coords.scrCoords;\r\n                        objCenterX = coords[1];\r\n                        objCenterY = coords[2];\r\n                        objWidth = obj.size[0];\r\n                        objHeight = obj.size[1];\r\n\r\n                        // move coords to the center of the label\r\n                        if (obj.visProp.islabel) {\r\n                            // Vertical adjustment\r\n                            if (obj.visProp.anchory === 'top') {\r\n                                objCenterY = objCenterY + objHeight / 2;\r\n                            } else {\r\n                                objCenterY = objCenterY - objHeight / 2;\r\n                            }\r\n\r\n                            // Horizontal adjustment\r\n                            if (obj.visProp.anchorx === 'left') {\r\n                                objCenterX = objCenterX + objWidth / 2;\r\n                            } else {\r\n                                objCenterX = objCenterX - objWidth / 2;\r\n                            }\r\n                        } else {\r\n                            // Points are treated dimensionless\r\n                            objWidth = 0;\r\n                            objHeight = 0;\r\n                        }\r\n\r\n                        // Check for overlap\r\n                        if (\r\n                            Math.abs(objCenterX - x) < (w + objWidth) / 2 &&\r\n                            Math.abs(objCenterY - y) < (h + objHeight) / 2\r\n                        ) {\r\n                            count++;\r\n                        }\r\n\r\n                        //if not label or point check conflict with hasPoint\r\n                    } else if (obj.hasPoint(x, y)) {\r\n                        count++;\r\n                    }\r\n\r\n                    // Restore original hasinnerpoints\r\n                    obj.visProp.hasinnerpoints = saveHasInnerPoints;\r\n                }\r\n            }\r\n\r\n            // Restore original precision\r\n            this.board.options.precision.hasPoint = savePointPrecision;\r\n\r\n            return count;\r\n        },\r\n        /**\r\n         * Calculates the score of a label position with a given radius and angle. The score is calculated by the following rules:\r\n         * <ul>\r\n         * <li> the maximum score is 0\r\n         * <li> if the label is outside of the bounding box, the score is reduced by 1\r\n         * <li> for each conflict, the score is reduced by 1\r\n         * <li> the score is reduced by the displacement (angle difference between old and new position) of the label\r\n         * <li> the score is reduced by the angle between the original label position and the new label position\r\n         * </ul>\r\n         *\r\n         * @param {number} radius radius in pixels\r\n         * @param {number} angle angle in radians\r\n         * @returns {number} Position score, higher values indicate better positions\r\n         */\r\n        calculateScore: function(radius, angle) {\r\n            var x, y, co, si, angleCurrentOffset, angleDifference,\r\n                score = 0,\r\n                cornerPoint = [0,0],\r\n                w = this.getSize()[0],\r\n                h = this.getSize()[1],\r\n                anchorCoords,\r\n                currentOffset = this.evalVisProp('offset'),\r\n                boundingBox = this.board.getBoundingBox();\r\n\r\n            if (this.evalVisProp('islabel') && Type.exists(this.element)) {\r\n                anchorCoords = this.element.getLabelAnchor().scrCoords;\r\n            } else {\r\n                return 0;\r\n            }\r\n            co = Math.cos(angle);\r\n            si = Math.sin(angle);\r\n\r\n            // calculate new position with srccoords, radius and angle\r\n            x = anchorCoords[1] + radius * co;\r\n            y = anchorCoords[2] - radius * si;\r\n\r\n            // if the label was placed on the left side of the element, the anchorx is set to \"right\"\r\n            if (co < 0) {\r\n                cornerPoint[0] = x - w;\r\n                x -= w / 2;\r\n            } else {\r\n                cornerPoint[0] = x + w;\r\n                x += w / 2;\r\n            }\r\n\r\n            // If the label was placed on the bottom side of the element, so the anchory is set to \"top\"\r\n            if (si < 0) {\r\n                cornerPoint[1] = y + h;\r\n                y += h / 2;\r\n            } else {\r\n                cornerPoint[1] = y - h;\r\n                y -= h / 2;\r\n            }\r\n\r\n            // If label was not in bounding box, score is reduced by 1\r\n            if(\r\n                cornerPoint[0] < 0 ||\r\n                cornerPoint[0] > (boundingBox[2] - boundingBox[0]) * this.board.unitX ||\r\n                cornerPoint[1] < 0 ||\r\n                cornerPoint[1] > (boundingBox[1] - boundingBox[3]) * this.board.unitY\r\n            ) {\r\n                score -= 1;\r\n            }\r\n\r\n            // Per conflict, score is reduced by 1\r\n            score -= this.getNumberOfConflicts(x, y, w, h, Type.evaluate(this.visProp.autopositionwhitelist));\r\n\r\n            // Calculate displacement, minimum score is 0 if radius is minRadius, maximum score is < 1 when radius is maxRadius\r\n            score -= radius / this.evalVisProp('autopositionmindistance') / 10 - 0.1;\r\n\r\n            // Calculate angle between current offset and new offset\r\n            angleCurrentOffset = Math.atan2(currentOffset[1], currentOffset[0]);\r\n\r\n            // If angle is negative, add 2*PI to get positive angle\r\n            if (angleCurrentOffset < 0) {\r\n                angleCurrentOffset += 2 * Math.PI;\r\n            }\r\n\r\n            // Calculate displacement by angle between original label position and new label position,\r\n            // use cos to check if angle is on the right side.\r\n            // If both angles are on the right side and more than 180° apart, add 2*PI. e.g. 0.1 and 6.1 are near each other\r\n            if (co > 0 && Math.cos(angleCurrentOffset) > 0 && Math.abs(angle - angleCurrentOffset) > Math.PI) {\r\n                angleDifference = Math.abs(angle - angleCurrentOffset - 2 * Math.PI);\r\n            } else {\r\n                angleDifference = Math.abs(angle - angleCurrentOffset);\r\n            }\r\n\r\n            // Minimum score is 0 if angle difference is 0, maximum score is pi / 10\r\n            score -= angleDifference / 10;\r\n\r\n            return score;\r\n        },\r\n\r\n        /**\r\n         * Automatically positions the label by finding the optimal position.\r\n         * Aims to minimize conflicts while maintaining readability.\r\n         * <p>\r\n         * The method tests 60 different angles (0 to 2π) at 3 different distances (radii).\r\n         * It evaluates each position using calculateScore(radius, angle) and chooses the position with the highest score.\r\n         * Then the label's anchor points and offset are adjusted accordingly.\r\n         *\r\n         * @returns {JXG.Text} Reference to the text object.\r\n         */\r\n        setAutoPosition: function() {\r\n            var radius, angle, radiusStep,\r\n                i,\r\n                bestScore = -Infinity, bestRadius, bestAngle,\r\n                minRadius = this.evalVisProp('autopositionmindistance'),\r\n                maxRadius = this.evalVisProp('autopositionmaxdistance'),\r\n                score,\r\n                co, si,\r\n                currentOffset = this.evalVisProp('offset'),\r\n                currentRadius,\r\n                currentAngle,\r\n                numAngles = 60,\r\n                numRadius = 4;\r\n\r\n            if (\r\n                this === this.board.infobox ||\r\n                !this.element ||\r\n                !this.visPropCalc.visible ||\r\n                !this.evalVisProp('islabel')\r\n            ) {\r\n                return this;\r\n            }\r\n\r\n            // Calculate current position\r\n            currentRadius = Math.sqrt(currentOffset[0] * currentOffset[0] + currentOffset[1] * currentOffset[1]);\r\n            currentAngle = Math.atan2(currentOffset[1], currentOffset[0]);\r\n\r\n            if (this.calculateScore(currentRadius, currentAngle) === 0) {\r\n                return this;\r\n            }\r\n\r\n            // Initialize search at min radius\r\n            radius = minRadius;\r\n            // Calculate step size\r\n            radiusStep = (maxRadius - minRadius) / (numRadius - 1);\r\n\r\n            // Test the different radii\r\n            while (maxRadius - radius > -0.01) {\r\n\r\n                // Radius gets bigger so just check if its smaller than maxnumber of angles.\r\n                for (i = 0; i < numAngles; i++) {\r\n\r\n                    // calculate angle\r\n                    angle = i / numAngles * 2 * Math.PI;\r\n\r\n                    // calculate score\r\n                    score = this.calculateScore(radius, angle);\r\n\r\n                    // if score is better than bestScore, set bestAngle, bestRadius and bestScore\r\n                    if (score > bestScore) {\r\n                        bestAngle = angle;\r\n                        bestRadius = radius;\r\n                        bestScore = score;\r\n                    }\r\n\r\n                    // if bestScore is 0, break, because it can't get better\r\n                    if (bestScore === 0) {\r\n                        radius = maxRadius;\r\n                        break;\r\n                    }\r\n                }\r\n\r\n                radius += radiusStep;\r\n            }\r\n\r\n            co = Math.cos(bestAngle);\r\n            si = Math.sin(bestAngle);\r\n\r\n            // If label is on the left side of the element, the anchorx is set to \"right\"\r\n            if (co < 0) {\r\n                this.visProp.anchorx = 'right';\r\n            } else {\r\n                this.visProp.anchorx = 'left';\r\n            }\r\n\r\n            // If label is on the bottom side of the element, so the anchory is set to \"top\"\r\n            if (si < 0) {\r\n                this.visProp.anchory = 'top';\r\n            } else {\r\n                this.visProp.anchory = 'bottom';\r\n            }\r\n\r\n            // Set offset\r\n            this.visProp.offset = [bestRadius * co, bestRadius * si];\r\n\r\n            return this;\r\n        }\r\n\r\n        // /**\r\n        //  * Computes the number of overlaps of a box of w pixels width, h pixels height\r\n        //  * and center (x, y)\r\n        //  *\r\n        //  * @private\r\n        //  * @param  {Number} x x-coordinate of the center (screen coordinates)\r\n        //  * @param  {Number} y y-coordinate of the center (screen coordinates)\r\n        //  * @param  {Number} w width of the box in pixel\r\n        //  * @param  {Number} h width of the box in pixel\r\n        //  * @param  {Array} [whiteList] array of ids which should be ignored\r\n        //  * @return {Number}   Number of overlapping elements\r\n        //  */\r\n        // getNumberOfConflicts: function (x, y, w, h, whiteList) {\r\n        //     whiteList = whiteList || [];\r\n        //     var count = 0,\r\n        //         i, obj, le,\r\n        //         savePointPrecision,\r\n        //         saveHasInnerPoints;\r\n\r\n        //     // Set the precision of hasPoint to half the max if label isn't too long\r\n        //     savePointPrecision = this.board.options.precision.hasPoint;\r\n        //     // this.board.options.precision.hasPoint = Math.max(w, h) * 0.5;\r\n        //     this.board.options.precision.hasPoint = (w + h) * 0.25;\r\n        //     // TODO:\r\n        //     // Make it compatible with the objects' visProp.precision attribute\r\n        //     for (i = 0, le = this.board.objectsList.length; i < le; i++) {\r\n        //         obj = this.board.objectsList[i];\r\n        //         saveHasInnerPoints = obj.visProp.hasinnerpoints;\r\n        //         obj.visProp.hasinnerpoints = false;\r\n        //         if (\r\n        //             obj.visPropCalc.visible &&\r\n        //             obj.elType !== \"axis\" &&\r\n        //             obj.elType !== \"ticks\" &&\r\n        //             obj !== this.board.infobox &&\r\n        //             obj !== this &&\r\n        //             obj.hasPoint(x, y) &&\r\n        //             whiteList.indexOf(obj.id) === -1\r\n        //         ) {\r\n        //             count++;\r\n        //         }\r\n        //         obj.visProp.hasinnerpoints = saveHasInnerPoints;\r\n        //     }\r\n        //     this.board.options.precision.hasPoint = savePointPrecision;\r\n\r\n        //     return count;\r\n        // },\r\n\r\n        // /**\r\n        //  * Sets the offset of a label element to the position with the least number\r\n        //  * of overlaps with other elements, while retaining the distance to its\r\n        //  * anchor element. Twelve different angles are possible.\r\n        //  *\r\n        //  * @returns {JXG.Text} Reference to the text object.\r\n        //  */\r\n        // setAutoPosition: function () {\r\n        //     var x, y, cx, cy,\r\n        //         anchorCoords,\r\n        //         // anchorX, anchorY,\r\n        //         w = this.size[0],\r\n        //         h = this.size[1],\r\n        //         start_angle, angle,\r\n        //         optimum = {\r\n        //             conflicts: Infinity,\r\n        //             angle: 0,\r\n        //             r: 0\r\n        //         },\r\n        //         max_r, delta_r,\r\n        //         conflicts, offset, r,\r\n        //         num_positions = 12,\r\n        //         step = (2 * Math.PI) / num_positions,\r\n        //         j, dx, dy, co, si;\r\n\r\n        //     if (\r\n        //         this === this.board.infobox ||\r\n        //         !this.visPropCalc.visible ||\r\n        //         !this.evalVisProp('islabel') ||\r\n        //         !this.element\r\n        //     ) {\r\n        //         return this;\r\n        //     }\r\n\r\n        //     // anchorX = this.evalVisProp('anchorx');\r\n        //     // anchorY = this.evalVisProp('anchory');\r\n        //     offset = this.evalVisProp('offset');\r\n        //     anchorCoords = this.element.getLabelAnchor();\r\n        //     cx = anchorCoords.scrCoords[1];\r\n        //     cy = anchorCoords.scrCoords[2];\r\n\r\n        //     // Set dx, dy as the relative position of the center of the label\r\n        //     // to its anchor element ignoring anchorx and anchory.\r\n        //     dx = offset[0];\r\n        //     dy = offset[1];\r\n\r\n        //     conflicts = this.getNumberOfConflicts(cx + dx, cy - dy, w, h, this.evalVisProp('autopositionwhitelist'));\r\n        //     if (conflicts === 0) {\r\n        //         return this;\r\n        //     }\r\n        //     // console.log(this.id, conflicts, w, h);\r\n        //     // r = Geometry.distance([0, 0], offset, 2);\r\n\r\n        //     r = this.evalVisProp('autopositionmindistance');\r\n        //     max_r = this.evalVisProp('autopositionmaxdistance');\r\n        //     delta_r = 0.2 * r;\r\n\r\n        //     start_angle = Math.atan2(dy, dx);\r\n\r\n        //     optimum.conflicts = conflicts;\r\n        //     optimum.angle = start_angle;\r\n        //     optimum.r = r;\r\n\r\n        //     while (optimum.conflicts > 0 && r <= max_r) {\r\n        //         for (\r\n        //             j = 1, angle = start_angle + step;\r\n        //             j < num_positions && optimum.conflicts > 0;\r\n        //             j++\r\n        //         ) {\r\n        //             co = Math.cos(angle);\r\n        //             si = Math.sin(angle);\r\n\r\n        //             x = cx + r * co;\r\n        //             y = cy - r * si;\r\n\r\n        //             conflicts = this.getNumberOfConflicts(x, y, w, h, this.evalVisProp('autopositionwhitelist'));\r\n        //             if (conflicts < optimum.conflicts) {\r\n        //                 optimum.conflicts = conflicts;\r\n        //                 optimum.angle = angle;\r\n        //                 optimum.r = r;\r\n        //             }\r\n        //             if (optimum.conflicts === 0) {\r\n        //                 break;\r\n        //             }\r\n        //             angle += step;\r\n        //         }\r\n        //         r += delta_r;\r\n        //     }\r\n        //     // console.log(this.id, \"after\", optimum)\r\n        //     r = optimum.r;\r\n        //     co = Math.cos(optimum.angle);\r\n        //     si = Math.sin(optimum.angle);\r\n        //     this.visProp.offset = [r * co, r * si];\r\n\r\n        //     if (co < -0.2) {\r\n        //         this.visProp.anchorx = 'right'\r\n        //     } else if (co > 0.2) {\r\n        //         this.visProp.anchorx = 'left'\r\n        //     } else {\r\n        //         this.visProp.anchorx = 'middle'\r\n        //     }\r\n\r\n        //     return this;\r\n        // }\r\n    }\r\n);\r\n\r\n/**\r\n * @class Constructs a text element.\r\n *\r\n * The coordinates can either be absolute (i.e. respective to the coordinate system of the board) or be relative to the coordinates of an element\r\n * given in {@link Text#anchor}.\r\n * <p>\r\n * HTML, MathJaX, KaTeX and GEONExT syntax can be handled.\r\n * <p>\r\n * There are two ways to display texts:\r\n * <ul>\r\n * <li> using the text element of the renderer (canvas or svg). In most cases this is the suitable approach if speed matters.\r\n * However, advanced rendering like MathJax, KaTeX or HTML/CSS are not possible.\r\n * <li> using HTML &lt;div&gt;. This is the most flexible approach. The drawback is that HTML can only be display \"above\" the geometry elements.\r\n * If HTML should be displayed in an inbetween layer, conder to use an element of type {@link ForeignObject} (available in svg renderer, only).\r\n * </ul>\r\n * @pseudo\r\n * @name Text\r\n * @augments JXG.Text\r\n * @constructor\r\n * @type JXG.Text\r\n *\r\n * @param {number,function_number,function_number,function_String,function} z_,x,y,str Parent elements for text elements.\r\n *                     <p>\r\n *   Parent elements can be two or three elements of type number, a string containing a GEONE<sub>x</sub>T\r\n *   constraint, or a function which takes no parameter and returns a number. Every parent element beside the last determines one coordinate.\r\n *   If a coordinate is\r\n *   given by a number, the number determines the initial position of a free text. If given by a string or a function that coordinate will be constrained\r\n *   that means the user won't be able to change the texts's position directly by mouse because it will be calculated automatically depending on the string\r\n *   or the function's return value. If two parent elements are given the coordinates will be interpreted as 2D affine Euclidean coordinates, if three such\r\n *   parent elements are given they will be interpreted as homogeneous coordinates.\r\n *                     <p>\r\n *                     The text to display may be given as string or as function returning a string.\r\n *\r\n * There is the attribute 'display' which takes the values 'html' or 'internal'. In case of 'html' an HTML division tag is created to display\r\n * the text. In this case it is also possible to use MathJax, KaTeX, or ASCIIMathML. If neither of these is used, basic Math rendering is\r\n * applied.\r\n * <p>\r\n * In case of 'internal', an SVG text element is used to display the text.\r\n * @see JXG.Text\r\n * @example\r\n * // Create a fixed text at position [0,1].\r\n *   var t1 = board.create('text',[0,1,\"Hello World\"]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG896013aa-f24e-4e83-ad50-7bc7df23f6b7\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var t1_board = JXG.JSXGraph.initBoard('JXG896013aa-f24e-4e83-ad50-7bc7df23f6b7', {boundingbox: [-3, 6, 5, -3], axis: true, showcopyright: false, shownavigation: false});\r\n *   var t1 = t1_board.create('text',[0,1,\"Hello World\"]);\r\n * </script><pre>\r\n * @example\r\n * // Create a variable text at a variable position.\r\n *   var s = board.create('slider',[[0,4],[3,4],[-2,0,2]]);\r\n *   var graph = board.create('text',\r\n *                        [function(x){ return s.Value();}, 1,\r\n *                         function(){return \"The value of s is\"+JXG.toFixed(s.Value(), 2);}\r\n *                        ]\r\n *                     );\r\n * </pre><div class=\"jxgbox\" id=\"JXG5441da79-a48d-48e8-9e53-75594c384a1c\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var t2_board = JXG.JSXGraph.initBoard('JXG5441da79-a48d-48e8-9e53-75594c384a1c', {boundingbox: [-3, 6, 5, -3], axis: true, showcopyright: false, shownavigation: false});\r\n *   var s = t2_board.create('slider',[[0,4],[3,4],[-2,0,2]]);\r\n *   var t2 = t2_board.create('text',[function(x){ return s.Value();}, 1, function(){return \"The value of s is \"+JXG.toFixed(s.Value(), 2);}]);\r\n * </script><pre>\r\n * @example\r\n * // Create a text bound to the point A\r\n * var p = board.create('point',[0, 1]),\r\n *     t = board.create('text',[0, -1,\"Hello World\"], {anchor: p});\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXGff5a64b2-2b9a-11e5-8dd9-901b0e1b8723\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGff5a64b2-2b9a-11e5-8dd9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p = board.create('point',[0, 1]),\r\n *         t = board.create('text',[0, -1,\"Hello World\"], {anchor: p});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createText = function (board, parents, attributes) {\r\n    var t,\r\n        attr = Type.copyAttributes(attributes, board.options, 'text'),\r\n        coords = parents.slice(0, -1),\r\n        content = parents[parents.length - 1];\r\n\r\n    // Backwards compatibility\r\n    attr.anchor = attr.parent || attr.anchor;\r\n    t = CoordsElement.create(JXG.Text, board, coords, attr, content);\r\n\r\n    if (!t) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create text with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [x,y], [z,x,y], [element,transformation]\"\r\n        );\r\n    }\r\n\r\n    if (attr.rotate !== 0) {\r\n        // This is the default value, i.e. no rotation\r\n        t.addRotation(attr.rotate);\r\n    }\r\n\r\n    return t;\r\n};\r\n\r\nJXG.registerElement(\"text\", JXG.createText);\r\n\r\n/**\r\n * @class Labels are text objects tied to other elements like points, lines and curves.\r\n * Labels are handled internally by JSXGraph, only. There is NO constructor \"board.create('label', ...)\".\r\n *\r\n * @description\r\n * Labels for points are positioned with the attributes {@link Text#anchorX}, {@link Text#anchorX} and {@link Label#offset}.\r\n * <p>\r\n * Labels for lines, segments, curves and circles can be controlled additionally by the attributes {@link Label#position} and\r\n * {@link Label#distance}, i.e. for a segment [A, B] one could use the follwoing attributes:\r\n * <ul>\r\n * <li> \"position\": determines, where in the direction of the segment from A to B the label is placed\r\n * <li> \"distance\": determines the (orthogonal) distance of the label from the line segment. It is a factor which is multiplied by the font-size.\r\n * <li> \"offset: [h, v]\": a final correction in pixel (horizontally: h, vertically: v)\r\n * <li> \"anchorX\" ('left', 'middle', 'right') and \"anchorY\" ('bottom', 'middle', 'top'): determines which part of the\r\n * label string is the anchor position that is positioned to the coordinates determined by \"position\", \"distance\" and \"offset\".\r\n * </ul>\r\n *\r\n * @pseudo\r\n * @name Label\r\n * @augments JXG.Text\r\n * @constructor\r\n * @type JXG.Text\r\n */\r\n//  See element.js#createLabel\r\n\r\n/**\r\n * [[x,y], [w px, h px], [range]\r\n */\r\nJXG.createHTMLSlider = function (board, parents, attributes) {\r\n    var t,\r\n        par,\r\n        attr = Type.copyAttributes(attributes, board.options, 'htmlslider');\r\n\r\n    if (parents.length !== 2 || parents[0].length !== 2 || parents[1].length !== 3) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create htmlslider with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parents are: [[x,y], [min, start, max]]\"\r\n        );\r\n    }\r\n\r\n    // Backwards compatibility\r\n    attr.anchor = attr.parent || attr.anchor;\r\n    attr.fixed = attr.fixed || true;\r\n\r\n    par = [\r\n        parents[0][0],\r\n        parents[0][1],\r\n        '<form style=\"display:inline\">' +\r\n            '<input type=\"range\" /><span></span><input type=\"text\" />' +\r\n            \"</form>\"\r\n    ];\r\n\r\n    t = JXG.createText(board, par, attr);\r\n    t.type = Type.OBJECT_TYPE_HTMLSLIDER;\r\n\r\n    t.rendNodeForm = t.rendNode.childNodes[0];\r\n\r\n    t.rendNodeRange = t.rendNodeForm.childNodes[0];\r\n    t.rendNodeRange.min = parents[1][0];\r\n    t.rendNodeRange.max = parents[1][2];\r\n    t.rendNodeRange.step = attr.step;\r\n    t.rendNodeRange.value = parents[1][1];\r\n\r\n    t.rendNodeLabel = t.rendNodeForm.childNodes[1];\r\n    t.rendNodeLabel.id = t.rendNode.id + \"_label\";\r\n\r\n    if (attr.withlabel) {\r\n        t.rendNodeLabel.innerText = t.name + \"=\";\r\n    }\r\n\r\n    t.rendNodeOut = t.rendNodeForm.childNodes[2];\r\n    t.rendNodeOut.value = parents[1][1];\r\n\r\n    try {\r\n        t.rendNodeForm.id = t.rendNode.id + \"_form\";\r\n        t.rendNodeRange.id = t.rendNode.id + \"_range\";\r\n        t.rendNodeOut.id = t.rendNode.id + \"_out\";\r\n    } catch (e) {\r\n        JXG.debug(e);\r\n    }\r\n\r\n    t.rendNodeRange.style.width = attr.widthrange + 'px';\r\n    t.rendNodeRange.style.verticalAlign = 'middle';\r\n    t.rendNodeOut.style.width = attr.widthout + 'px';\r\n\r\n    t._val = parents[1][1];\r\n\r\n    if (JXG.supportsVML()) {\r\n        /*\r\n         * OnChange event is used for IE browsers\r\n         * The range element is supported since IE10\r\n         */\r\n        Env.addEvent(t.rendNodeForm, \"change\", priv.HTMLSliderInputEventHandler, t);\r\n    } else {\r\n        /*\r\n         * OnInput event is used for non-IE browsers\r\n         */\r\n        Env.addEvent(t.rendNodeForm, \"input\", priv.HTMLSliderInputEventHandler, t);\r\n    }\r\n\r\n    t.Value = function () {\r\n        return this._val;\r\n    };\r\n\r\n    return t;\r\n};\r\n\r\nJXG.registerElement(\"htmlslider\", JXG.createHTMLSlider);\r\n\r\nexport default JXG.Text;\r\n// export default {\r\n//     Text: JXG.Text,\r\n//     createText: JXG.createText,\r\n//     createHTMLSlider: JXG.createHTMLSlider\r\n// };\r\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","/*\r\n Copyright 2008-2025\r\n Matthias Ehmann,\r\n Michael Gerhaeuser,\r\n Carsten Miller,\r\n Bianca Valentin,\r\n Alfred Wassermann,\r\n Peter Wilfahrt\r\n\r\n This file is part of JSXGraph.\r\n\r\n JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n You can redistribute it and/or modify it under the terms of the\r\n\r\n * GNU Lesser General Public License as published by\r\n the Free Software Foundation, either version 3 of the License, or\r\n (at your option) any later version\r\n OR\r\n * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n JSXGraph is distributed in the hope that it will be useful,\r\n but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n GNU Lesser General Public License for more details.\r\n\r\n You should have received a copy of the GNU Lesser General Public License and\r\n the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, DOMParser: true, ActiveXObject: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"./type.js\";\r\n\r\n/**\r\n * Holds browser independent xml parsing routines. Won't work in environments other than browsers.\r\n * @namespace\r\n */\r\nJXG.XML = {\r\n    /**\r\n     * Cleans out unneccessary whitespaces in a chunk of xml.\r\n     * @param {Object} el\r\n     */\r\n    cleanWhitespace: function (el) {\r\n        var cur = el.firstChild;\r\n\r\n        while (Type.exists(cur)) {\r\n            if (cur.nodeType === 3 && !/\\S/.test(cur.nodeValue)) {\r\n                el.removeChild(cur);\r\n            } else if (cur.nodeType === 1) {\r\n                this.cleanWhitespace(cur);\r\n            }\r\n            cur = cur.nextSibling;\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Converts a given string into a XML tree.\r\n     * @param {String} str\r\n     * @returns {Object} The xml tree represented by the root node.\r\n     */\r\n    parse: function (str) {\r\n        var parser, tree, DP;\r\n\r\n        // DOMParser is a function in all browsers, except older IE and Safari.\r\n        // In IE it does not exists (workaround in else branch), in Safari it's an object.\r\n        if (typeof DOMParser === \"function\" || typeof DOMParser === 'object') {\r\n            DP = DOMParser;\r\n        } else {\r\n            // IE workaround, since there is no DOMParser\r\n            DP = function () {\r\n                this.parseFromString = function (str) {\r\n                    var d;\r\n\r\n                    if (typeof ActiveXObject === 'function') {\r\n                        d = new ActiveXObject('MSXML.DomDocument');\r\n                        d.loadXML(str);\r\n                    }\r\n\r\n                    return d;\r\n                };\r\n            };\r\n        }\r\n\r\n        parser = new DP();\r\n        tree = parser.parseFromString(str, \"text/xml\");\r\n        this.cleanWhitespace(tree);\r\n\r\n        return tree;\r\n    }\r\n};\r\n\r\nexport default JXG.XML;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n/*eslint no-loss-of-precision: off */\r\n\r\nimport Mat from \"./math.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Probability functions, e.g. error function,\r\n * see: https://en.wikipedia.org/wiki/Error_function\r\n * Ported from\r\n * by https://github.com/jeremybarnes/cephes/blob/master/cprob/ndtr.c,\r\n *\r\n * Cephes Math Library Release 2.9:  November, 2000\r\n * Copyright 1984, 1987, 1988, 1992, 2000 by Stephen L. Moshier\r\n *\r\n * @name JXG.Math.ProbFuncs\r\n * @exports Mat.ProbFuncs as JXG.Math.ProbFuncs\r\n * @namespace\r\n */\r\nMat.ProbFuncs = {\r\n    MAXNUM: 1.701411834604692317316873e38, // 2**127\r\n    SQRTH: 7.07106781186547524401e-1, // sqrt(2)/2\r\n    SQRT2: 1.4142135623730950488, // sqrt(2)\r\n    MAXLOG: 7.08396418532264106224e2, // log 2**1022\r\n\r\n    P: [\r\n        2.46196981473530512524e-10, 5.64189564831068821977e-1, 7.46321056442269912687,\r\n        4.86371970985681366614e1, 1.96520832956077098242e2, 5.26445194995477358631e2,\r\n        9.3452852717195760754e2, 1.02755188689515710272e3, 5.57535335369399327526e2\r\n    ],\r\n\r\n    Q: [\r\n        1.32281951154744992508e1, 8.67072140885989742329e1, 3.54937778887819891062e2,\r\n        9.75708501743205489753e2, 1.82390916687909736289e3, 2.24633760818710981792e3,\r\n        1.65666309194161350182e3, 5.57535340817727675546e2\r\n    ],\r\n\r\n    R: [\r\n        5.64189583547755073984e-1, 1.27536670759978104416, 5.01905042251180477414,\r\n        6.16021097993053585195, 7.4097426995044893916, 2.9788666537210024067\r\n    ],\r\n\r\n    S: [\r\n        2.2605286322011727659, 9.39603524938001434673, 1.20489539808096656605e1,\r\n        1.70814450747565897222e1, 9.60896809063285878198, 3.3690764510008151605\r\n    ],\r\n\r\n    T: [\r\n        9.60497373987051638749, 9.00260197203842689217e1, 2.23200534594684319226e3,\r\n        7.00332514112805075473e3, 5.55923013010394962768e4\r\n    ],\r\n\r\n    U: [\r\n        3.35617141647503099647e1, 5.21357949780152679795e2, 4.59432382970980127987e3,\r\n        2.26290000613890934246e4, 4.92673942608635921086e4\r\n    ],\r\n\r\n    // UTHRESH: 37.519379347,\r\n    M: 128.0,\r\n    MINV: 0.0078125,\r\n\r\n    /**\r\n     *\r\n     *\tExponential of squared argument\r\n     *\r\n     * SYNOPSIS:\r\n     *\r\n     * double x, y, expx2();\r\n     * int sign;\r\n     *\r\n     * y = expx2( x, sign );\r\n     *\r\n     *\r\n     *\r\n     * DESCRIPTION:\r\n     *\r\n     * Computes y = exp(x*x) while suppressing error amplification\r\n     * that would ordinarily arise from the inexactness of the\r\n     * exponential argument x*x.\r\n     *\r\n     * If sign < 0, the result is inverted; i.e., y = exp(-x*x) .\r\n     *\r\n     *\r\n     * ACCURACY:\r\n     *\r\n     *                      Relative error:\r\n     * arithmetic    domain     # trials      peak         rms\r\n     *   IEEE      -26.6, 26.6    10^7       3.9e-16     8.9e-17\r\n     *\r\n     * @private\r\n     * @param  {Number} x\r\n     * @param  {Number} sign (int)\r\n     * @returns {Number}\r\n     */\r\n    expx2: function (x, sign) {\r\n        // double x;\r\n        // int sign;\r\n        var u, u1, m, f;\r\n\r\n        x = Math.abs(x);\r\n        if (sign < 0) {\r\n            x = -x;\r\n        }\r\n\r\n        // Represent x as an exact multiple of M plus a residual.\r\n        //    M is a power of 2 chosen so that exp(m * m) does not overflow\r\n        //    or underflow and so that |x - m| is small.\r\n        m = this.MINV * Math.floor(this.M * x + 0.5);\r\n        f = x - m;\r\n\r\n        // x^2 = m^2 + 2mf + f^2\r\n        u = m * m;\r\n        u1 = 2 * m * f + f * f;\r\n\r\n        if (sign < 0) {\r\n            u = -u;\r\n            u1 = -u1;\r\n        }\r\n\r\n        if (u + u1 > this.MAXLOG) {\r\n            return Infinity;\r\n        }\r\n\r\n        // u is exact, u1 is small.\r\n        u = Math.exp(u) * Math.exp(u1);\r\n        return u;\r\n    },\r\n\r\n    /**\r\n     *\r\n     *\tEvaluate polynomial\r\n     *\r\n     * SYNOPSIS:\r\n     *\r\n     * int N;\r\n     * double x, y, coef[N+1], polevl[];\r\n     *\r\n     * y = polevl( x, coef, N );\r\n     *\r\n     * DESCRIPTION:\r\n     *\r\n     * Evaluates polynomial of degree N:\r\n     *\r\n     *                     2          N\r\n     * y  =  C  + C x + C x  +...+ C x\r\n     *        0    1     2          N\r\n     *\r\n     * Coefficients are stored in reverse order:\r\n     *\r\n     * coef[0] = C  , ..., coef[N] = C  .\r\n     *            N                   0\r\n     *\r\n     *  The function p1evl() assumes that coef[N] = 1.0 and is\r\n     * omitted from the array.  Its calling arguments are\r\n     * otherwise the same as polevl().\r\n     *\r\n     *\r\n     * SPEED:\r\n     *\r\n     * In the interest of speed, there are no checks for out\r\n     * of bounds arithmetic.  This routine is used by most of\r\n     * the functions in the library.  Depending on available\r\n     * equipment features, the user may wish to rewrite the\r\n     * program in microcode or assembly language.\r\n     *\r\n     * @private\r\n     * @param  {Number} x\r\n     * @param  {Number} coef\r\n     * @param  {Number} N\r\n     * @returns {Number}\r\n     */\r\n    polevl: function (x, coef, N) {\r\n        var ans, i;\r\n\r\n        if (Type.exists(coef.reduce)) {\r\n            return coef.reduce(function (acc, c) {\r\n                return acc * x + c;\r\n            }, 0);\r\n        }\r\n        // Polyfill\r\n        for (i = 0, ans = 0; i <= N; i++) {\r\n            ans = ans * x + coef[i];\r\n        }\r\n        return ans;\r\n    },\r\n\r\n    /**\r\n     * Evaluate polynomial when coefficient of x is 1.0.\r\n     * Otherwise same as polevl.\r\n     *\r\n     * @private\r\n     * @param  {Number} x\r\n     * @param  {Number} coef\r\n     * @param  {Number} N\r\n     * @returns {Number}\r\n     */\r\n    p1evl: function (x, coef, N) {\r\n        var ans, i;\r\n\r\n        if (Type.exists(coef.reduce)) {\r\n            return coef.reduce(function (acc, c) {\r\n                return acc * x + c;\r\n            }, 1);\r\n        }\r\n        // Polyfill\r\n        for (i = 0, ans = 1; i < N; i++) {\r\n            ans = ans * x + coef[i];\r\n        }\r\n        return ans;\r\n    },\r\n\r\n    /**\r\n     *\r\n     *\tNormal distribution function\r\n     *\r\n     * SYNOPSIS:\r\n     *\r\n     * y = ndtr( x );\r\n     *\r\n     * DESCRIPTION:\r\n     *\r\n     * Returns the area under the Gaussian probability density\r\n     * function, integrated from minus infinity to x:\r\n     *\r\n     *                            x\r\n     *                             -\r\n     *                   1        | |          2\r\n     *    ndtr(x)  = ---------    |    exp( - t /2 ) dt\r\n     *               sqrt(2pi)  | |\r\n     *                           -\r\n     *                          -inf.\r\n     *\r\n     *             =  ( 1 + erf(z) ) / 2\r\n     *             =  erfc(z) / 2\r\n     *\r\n     * where z = x/sqrt(2). Computation is via the functions\r\n     * erf and erfc with care to avoid error amplification in computing exp(-x^2).\r\n     *\r\n     *\r\n     * ACCURACY:\r\n     *\r\n     *                      Relative error:\r\n     * arithmetic   domain     # trials      peak         rms\r\n     *    IEEE     -13,0        30000       1.3e-15     2.2e-16\r\n     *\r\n     *\r\n     * ERROR MESSAGES:\r\n     *\r\n     *   message         condition         value returned\r\n     * erfc underflow    x > 37.519379347       0.0\r\n     *\r\n     * @param  {Number} a\r\n     * @returns {Number}\r\n     */\r\n    ndtr: function (a) {\r\n        // a: double, return double\r\n        var x, y, z;\r\n\r\n        x = a * this.SQRTH;\r\n        z = Math.abs(x);\r\n\r\n        if (z < 1.0) {\r\n            y = 0.5 + 0.5 * this.erf(x);\r\n        } else {\r\n            y = 0.5 * this.erfce(z);\r\n            /* Multiply by exp(-x^2 / 2)  */\r\n            z = this.expx2(a, -1);\r\n            y = y * Math.sqrt(z);\r\n            if (x > 0) {\r\n                y = 1.0 - y;\r\n            }\r\n        }\r\n        return y;\r\n    },\r\n\r\n    /**\r\n     * @private\r\n     * @param  {Number} a\r\n     * @returns {Number}\r\n     */\r\n    _underflow: function (a) {\r\n        console.log(\"erfc\", 'UNDERFLOW');\r\n        if (a < 0) {\r\n            return 2.0;\r\n        }\r\n        return 0.0;\r\n    },\r\n\r\n    /**\r\n     *\r\n     *\tComplementary error function\r\n     *\r\n     * SYNOPSIS:\r\n     *\r\n     * double x, y, erfc();\r\n     *\r\n     * y = erfc( x );\r\n     *\r\n     *\r\n     *\r\n     * DESCRIPTION:\r\n     *\r\n     *\r\n     *  1 - erf(x) =\r\n     *\r\n     *                           inf.\r\n     *                             -\r\n     *                  2         | |          2\r\n     *   erfc(x)  =  --------     |    exp( - t  ) dt\r\n     *               sqrt(pi)   | |\r\n     *                           -\r\n     *                            x\r\n     *\r\n     *\r\n     * For small x, erfc(x) = 1 - erf(x); otherwise rational\r\n     * approximations are computed.\r\n     *\r\n     * A special function expx2.c is used to suppress error amplification\r\n     * in computing exp(-x^2).\r\n     *\r\n     *\r\n     * ACCURACY:\r\n     *\r\n     *                      Relative error:\r\n     * arithmetic   domain     # trials      peak         rms\r\n     *    IEEE      0,26.6417   30000       1.3e-15     2.2e-16\r\n     *\r\n     *\r\n     * ERROR MESSAGES:\r\n     *\r\n     *   message         condition              value returned\r\n     * erfc underflow    x > 9.231948545 (DEC)       0.0\r\n     *\r\n     * @param  {Number} a\r\n     * @returns {Number}\r\n     */\r\n    erfc: function (a) {\r\n        var p, q, x, y, z;\r\n\r\n        if (a < 0.0) {\r\n            x = -a;\r\n        } else {\r\n            x = a;\r\n        }\r\n        if (x < 1.0) {\r\n            return 1.0 - this.erf(a);\r\n        }\r\n\r\n        z = -a * a;\r\n        if (z < -this.MAXLOG) {\r\n            return this._underflow(a);\r\n        }\r\n\r\n        z = this.expx2(a, -1); // Compute z = exp(z).\r\n\r\n        if (x < 8.0) {\r\n            p = this.polevl(x, this.P, 8);\r\n            q = this.p1evl(x, this.Q, 8);\r\n        } else {\r\n            p = this.polevl(x, this.R, 5);\r\n            q = this.p1evl(x, this.S, 6);\r\n        }\r\n\r\n        y = (z * p) / q;\r\n\r\n        if (a < 0) {\r\n            y = 2.0 - y;\r\n        }\r\n\r\n        if (y === 0.0) {\r\n            return this._underflow(a);\r\n        }\r\n\r\n        return y;\r\n    },\r\n\r\n    /**\r\n     * Exponentially scaled erfc function\r\n     *   exp(x^2) erfc(x)\r\n     *   valid for x > 1.\r\n     *   Use with ndtr and expx2.\r\n     *\r\n     * @private\r\n     * @param {Number} x\r\n     * @returns {Number}\r\n     */\r\n    erfce: function (x) {\r\n        var p, q;\r\n\r\n        if (x < 8.0) {\r\n            p = this.polevl(x, this.P, 8);\r\n            q = this.p1evl(x, this.Q, 8);\r\n        } else {\r\n            p = this.polevl(x, this.R, 5);\r\n            q = this.p1evl(x, this.S, 6);\r\n        }\r\n        return p / q;\r\n    },\r\n\r\n    /**\r\n     *\tError function\r\n     *\r\n     * SYNOPSIS:\r\n     *\r\n     * double x, y, erf();\r\n     *\r\n     * y = erf( x );\r\n     *\r\n     *\r\n     *\r\n     * DESCRIPTION:\r\n     *\r\n     * The integral is\r\n     *\r\n     *                           x\r\n     *                            -\r\n     *                 2         | |          2\r\n     *   erf(x)  =  --------     |    exp( - t  ) dt.\r\n     *              sqrt(pi)   | |\r\n     *                          -\r\n     *                           0\r\n     *\r\n     * For 0 <= |x| < 1, erf(x) = x * P4(x**2)/Q5(x**2); otherwise\r\n     * erf(x) = 1 - erfc(x).\r\n     *\r\n     *\r\n     * ACCURACY:\r\n     *\r\n     *                      Relative error:\r\n     * arithmetic   domain     # trials      peak         rms\r\n     *    DEC       0,1         14000       4.7e-17     1.5e-17\r\n     *    IEEE      0,1         30000       3.7e-16     1.0e-16\r\n     *\r\n     * @param  {Number} x\r\n     * @returns {Number}\r\n     */\r\n    erf: function (x) {\r\n        var y, z;\r\n\r\n        if (Math.abs(x) > 1.0) {\r\n            return 1.0 - this.erfc(x);\r\n        }\r\n        z = x * x;\r\n        y = (x * this.polevl(z, this.T, 4)) / this.p1evl(z, this.U, 5);\r\n        return y;\r\n    },\r\n\r\n    s2pi: 2.50662827463100050242, // sqrt(2pi)\r\n\r\n    // approximation for 0 <= |y - 0.5| <= 3/8 */\r\n    P0: [\r\n        -5.99633501014107895267e1, 9.80010754185999661536e1, -5.66762857469070293439e1,\r\n        1.39312609387279679503e1, -1.23916583867381258016\r\n    ],\r\n\r\n    Q0: [\r\n        1.95448858338141759834, 4.67627912898881538453, 8.63602421390890590575e1,\r\n        -2.25462687854119370527e2, 2.00260212380060660359e2, -8.20372256168333339912e1,\r\n        1.59056225126211695515e1, -1.18331621121330003142\r\n    ],\r\n\r\n    //  Approximation for interval z = sqrt(-2 log y ) between 2 and 8\r\n    //  i.e., y between exp(-2) = .135 and exp(-32) = 1.27e-14.\r\n    P1: [\r\n        4.05544892305962419923, 3.15251094599893866154e1, 5.71628192246421288162e1,\r\n        4.408050738932008347e1, 1.46849561928858024014e1, 2.18663306850790267539,\r\n        -1.40256079171354495875e-1, -3.50424626827848203418e-2, -8.57456785154685413611e-4\r\n    ],\r\n\r\n    Q1: [\r\n        1.57799883256466749731e1, 4.53907635128879210584e1, 4.1317203825467203044e1,\r\n        1.50425385692907503408e1, 2.50464946208309415979, -1.42182922854787788574e-1,\r\n        -3.80806407691578277194e-2, -9.33259480895457427372e-4\r\n    ],\r\n\r\n    // Approximation for interval z = sqrt(-2 log y ) between 8 and 64\r\n    // i.e., y between exp(-32) = 1.27e-14 and exp(-2048) = 3.67e-890.\r\n    P2: [\r\n        3.2377489177694603597, 6.91522889068984211695, 3.93881025292474443415,\r\n        1.33303460815807542389, 2.01485389549179081538e-1, 1.23716634817820021358e-2,\r\n        3.01581553508235416007e-4, 2.65806974686737550832e-6, 6.2397453918498329373e-9\r\n    ],\r\n\r\n    Q2: [\r\n        6.02427039364742014255, 3.67983563856160859403, 1.37702099489081330271,\r\n        2.1623699359449663589e-1, 1.34204006088543189037e-2, 3.28014464682127739104e-4,\r\n        2.89247864745380683936e-6, 6.79019408009981274425e-9\r\n    ],\r\n\r\n    /**\r\n     *\r\n     *\tInverse of Normal distribution function\r\n     *\r\n     * SYNOPSIS:\r\n     *\r\n     * double x, y, ndtri();\r\n     *\r\n     * x = ndtri( y );\r\n     *\r\n     * DESCRIPTION:\r\n     *\r\n     * Returns the argument, x, for which the area under the\r\n     * Gaussian probability density function (integrated from\r\n     * minus infinity to x) is equal to y.\r\n     *\r\n     *\r\n     * For small arguments 0 < y < exp(-2), the program computes\r\n     * z = sqrt( -2.0 * log(y) );  then the approximation is\r\n     * x = z - log(z)/z  - (1/z) P(1/z) / Q(1/z).\r\n     * There are two rational functions P/Q, one for 0 < y < exp(-32)\r\n     * and the other for y up to exp(-2).  For larger arguments,\r\n     * w = y - 0.5, and  x/sqrt(2pi) = w + w**3 R(w**2)/S(w**2)).\r\n     *\r\n     *\r\n     * ACCURACY:\r\n     *\r\n     *                      Relative error:\r\n     * arithmetic   domain        # trials      peak         rms\r\n     *    DEC      0.125, 1         5500       9.5e-17     2.1e-17\r\n     *    DEC      6e-39, 0.135     3500       5.7e-17     1.3e-17\r\n     *    IEEE     0.125, 1        20000       7.2e-16     1.3e-16\r\n     *    IEEE     3e-308, 0.135   50000       4.6e-16     9.8e-17\r\n     *\r\n     *\r\n     * ERROR MESSAGES:\r\n     *\r\n     *   message         condition    value returned\r\n     * ndtri domain       x <= 0        -MAXNUM\r\n     * ndtri domain       x >= 1         MAXNUM\r\n     *\r\n     * @param  {Number} y0\r\n     * @returns {Number}\r\n     */\r\n    ndtri: function (y0) {\r\n        var x, y, z, y2, x0, x1, code;\r\n\r\n        if (y0 <= 0.0) {\r\n            //console.log(\"ndtri\", \"DOMAIN \");\r\n            return -Infinity; // -this.MAXNUM;\r\n        }\r\n        if (y0 >= 1.0) {\r\n            // console.log(\"ndtri\", 'DOMAIN');\r\n            return Infinity; // this.MAXNUM;\r\n        }\r\n\r\n        code = 1;\r\n        y = y0;\r\n        if (y > 1.0 - 0.13533528323661269189) {\r\n            // 0.135... = exp(-2)\r\n            y = 1.0 - y;\r\n            code = 0;\r\n        }\r\n\r\n        if (y > 0.13533528323661269189) {\r\n            y = y - 0.5;\r\n            y2 = y * y;\r\n            x = y + y * ((y2 * this.polevl(y2, this.P0, 4)) / this.p1evl(y2, this.Q0, 8));\r\n            x = x * this.s2pi;\r\n            return x;\r\n        }\r\n\r\n        x = Math.sqrt(-2.0 * Math.log(y));\r\n        x0 = x - Math.log(x) / x;\r\n\r\n        z = 1.0 / x;\r\n        if (x < 8.0) {\r\n            // y > exp(-32) = 1.2664165549e-14\r\n            x1 = (z * this.polevl(z, this.P1, 8)) / this.p1evl(z, this.Q1, 8);\r\n        } else {\r\n            x1 = (z * this.polevl(z, this.P2, 8)) / this.p1evl(z, this.Q2, 8);\r\n        }\r\n        x = x0 - x1;\r\n        if (code !== 0) {\r\n            x = -x;\r\n        }\r\n        return x;\r\n    },\r\n\r\n    /**\r\n     * Inverse of error function erf.\r\n     *\r\n     * @param  {Number} x\r\n     * @returns {Number}\r\n     */\r\n    erfi: function (x) {\r\n        return this.ndtri((x + 1) * 0.5) * this.SQRTH;\r\n    }\r\n};\r\n\r\nexport default Mat.ProbFuncs;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport Mat from \"./math.js\";\r\n\r\n/**\r\n * Functions for extrapolation of sequences. Used for finding limits of sequences which is used for curve plotting.\r\n * @name JXG.Math.Extrapolate\r\n * @exports Mat.Extrapolate as JXG.Math.Extrapolate\r\n * @namespace\r\n */\r\nMat.Extrapolate = {\r\n    upper: 15,\r\n    infty: 1e4,\r\n\r\n    /**\r\n     * Wynn's epsilon algorithm. Ported from the FORTRAN version in\r\n     * Ernst Joachim Weniger, \"Nonlinear sequence transformations for the acceleration of convergence\r\n     * and the summation of divergent series\", Computer Physics Reports Vol. 10, 189-371 (1989).\r\n     *\r\n     * @param {Number} s_n next value of sequence, i.e. n-th element of sequence\r\n     * @param {Number} n index of s_n in the sequence\r\n     * @param {Array} e One-dimensional array containing the extrapolation data. Has to be supplied by the calling routine.\r\n     * @returns {Number} New estimate of the limit of the sequence.\r\n     *\r\n     * @memberof JXG.Math.Extrapolate\r\n     */\r\n    wynnEps: function (s_n, n, e) {\r\n        var HUGE = 1e20,\r\n            TINY = 1e-15,\r\n            f0 = 1, // f0 may be changed to other values, see vanden Broeck, Schwartz (1979)\r\n            f,\r\n            j,\r\n            aux1,\r\n            aux2,\r\n            diff,\r\n            estlim;\r\n\r\n        e[n] = s_n;\r\n        if (n === 0) {\r\n            estlim = s_n;\r\n        } else {\r\n            aux2 = 0.0;\r\n            for (j = n; j > 0; j--) {\r\n                aux1 = aux2;\r\n                aux2 = e[j - 1];\r\n                diff = e[j] - aux2;\r\n                if (Math.abs(diff) <= TINY) {\r\n                    e[j - 1] = HUGE;\r\n                } else {\r\n                    f = (n - j + 1) % 2 === 1 ? f0 : 1;\r\n                    e[j - 1] = aux1 * f + 1 / diff;\r\n                }\r\n            }\r\n            estlim = e[n % 2];\r\n        }\r\n\r\n        return estlim;\r\n    },\r\n\r\n    // wynnRho: function(s_n, n, e) {\r\n    //     var HUGE = 1.e+20,\r\n    //         TINY = 1.e-15,\r\n    //         j, f,\r\n    //         aux1, aux2, diff, estlim;\r\n\r\n    //     e[n] = s_n;\r\n    //     if (n === 0) {\r\n    //         estlim = s_n;\r\n    //     } else {\r\n    //         aux2 = 0.0;\r\n    //         for (j = n; j >= 1; j--) {\r\n    //             aux1 = aux2;\r\n    //             aux2 = e[j - 1];\r\n    //             diff = e[j] - aux2;\r\n    //             if (Math.abs(diff) <= TINY) {\r\n    //                 e[j - 1] = HUGE;\r\n    //             } else {\r\n    //                 f = ((n - j + 1) % 2 === 1) ? n - j + 1  : 1;\r\n    //                 e[j - 1] = aux1 + f / diff;\r\n    //             }\r\n    //         }\r\n    //         estlim = e[n % 2];\r\n    //     }\r\n\r\n    //     return estlim;\r\n    // },\r\n\r\n    /**\r\n     * Aitken transformation. Ported from the FORTRAN version in\r\n     * Ernst Joachim Weniger, \"Nonlinear sequence transformations for the acceleration of convergence\r\n     * and the summation of divergent series\", Computer Physics Reports Vol. 10, 189-371 (1989).\r\n     *\r\n     * @param {Number} s_n next value of sequence, i.e. n-th element of sequence\r\n     * @param {Number} n index of s_n in the sequence\r\n     * @param {Array} a One-dimensional array containing the extrapolation data. Has to be supplied by the calling routine.\r\n     * @returns {Number} New estimate of the limit of the sequence.\r\n     *\r\n     * @memberof JXG.Math.Extrapolate\r\n     */\r\n    aitken: function (s_n, n, a) {\r\n        var estlim,\r\n            HUGE = 1e20,\r\n            TINY = 1e-15,\r\n            denom,\r\n            v,\r\n            lowmax,\r\n            j,\r\n            m;\r\n\r\n        a[n] = s_n;\r\n        if (n < 2) {\r\n            estlim = s_n;\r\n        } else {\r\n            lowmax = n / 2;\r\n            for (j = 1; j <= lowmax; j++) {\r\n                m = n - 2 * j;\r\n                denom = a[m + 2] - 2 * a[m + 1] + a[m];\r\n                if (Math.abs(denom) < TINY) {\r\n                    a[m] = HUGE;\r\n                } else {\r\n                    v = a[m] - a[m + 1];\r\n                    a[m] -= (v * v) / denom;\r\n                }\r\n            }\r\n            estlim = a[n % 2];\r\n        }\r\n        return estlim;\r\n    },\r\n\r\n    /**\r\n     * Iterated Brezinski transformation. Ported from the FORTRAN version in\r\n     * Ernst Joachim Weniger, \"Nonlinear sequence transformations for the acceleration of convergence\r\n     * and the summation of divergent series\", Computer Physics Reports Vol. 10, 189-371 (1989).\r\n     *\r\n     * @param {Number} s_n next value of sequence, i.e. n-th element of sequence\r\n     * @param {Number} n index of s_n in the sequence\r\n     * @param {Array} a One-dimensional array containing the extrapolation data. Has to be supplied by the calling routine.\r\n     * @returns {Number} New estimate of the limit of the sequence.\r\n     *\r\n     * @memberof JXG.Math.Extrapolate\r\n     */\r\n    brezinski: function (s_n, n, a) {\r\n        var estlim,\r\n            HUGE = 1e20,\r\n            TINY = 1e-15,\r\n            denom,\r\n            d0,\r\n            d1,\r\n            d2,\r\n            lowmax,\r\n            j,\r\n            m;\r\n\r\n        a[n] = s_n;\r\n        if (n < 3) {\r\n            estlim = s_n;\r\n        } else {\r\n            lowmax = n / 3;\r\n            m = n;\r\n            for (j = 1; j <= lowmax; j++) {\r\n                m -= 3;\r\n                d0 = a[m + 1] - a[m];\r\n                d1 = a[m + 2] - a[m + 1];\r\n                d2 = a[m + 3] - a[m + 2];\r\n                denom = d2 * (d1 - d0) - d0 * (d2 - d1);\r\n                if (Math.abs(denom) < TINY) {\r\n                    a[m] = HUGE;\r\n                } else {\r\n                    a[m] = a[m + 1] - (d0 * d1 * (d2 - d1)) / denom;\r\n                }\r\n            }\r\n            estlim = a[n % 3];\r\n        }\r\n        return estlim;\r\n    },\r\n\r\n    /**\r\n     * Extrapolated iteration to approximate the value f(x_0).\r\n     *\r\n     * @param {Number} x0 Value for which the limit of f is to be determined. f(x0) may or may not exist.\r\n     * @param {Number} h0 Initial (signed) distance from x0.\r\n     * @param {Function} f Function for which the limit at x0 is to be determined\r\n     * @param {String} method String to choose the method. Available values: \"wynnEps\", \"aitken\", \"brezinski\"\r\n     * @param {Number} step_type Approximation method. step_type = 0 uses the sequence x0 + h0/n; step_type = 1 uses the sequence x0 + h0 * 2^(-n)\r\n     *\r\n     * @returns {Array} Array of length 3. Position 0: estimated value for f(x0), position 1: 'finite', 'infinite', or 'NaN'.\r\n     * Position 2: value between 0 and 1 judging the reliability of the result (1: high, 0: not successful).\r\n     *\r\n     * @memberof JXG.Math.Extrapolate\r\n     * @see JXG.Math.Extrapolate.limit\r\n     * @see JXG.Math.Extrapolate.wynnEps\r\n     * @see JXG.Math.Extrapolate.aitken\r\n     * @see JXG.Math.Extrapolate.brezinski\r\n     */\r\n    iteration: function (x0, h0, f, method, step_type) {\r\n        var n,\r\n            v,\r\n            w,\r\n            estlim = NaN,\r\n            diff,\r\n            r = 0.5,\r\n            E = [],\r\n            result = \"finite\",\r\n            h = h0;\r\n\r\n        step_type = step_type || 0;\r\n\r\n        for (n = 1; n <= this.upper; n++) {\r\n            h = step_type === 0 ? h0 / (n + 1) : h * r;\r\n            v = f(x0 + h, true);\r\n\r\n            w = this[method](v, n - 1, E);\r\n            //console.log(n, x0 + h, v, w);\r\n            if (isNaN(w)) {\r\n                result = 'NaN';\r\n                break;\r\n            }\r\n            if (v !== 0 && w / v > this.infty) {\r\n                estlim = w;\r\n                result = 'infinite';\r\n                break;\r\n            }\r\n            diff = w - estlim;\r\n            if (Math.abs(diff) < 1e-7) {\r\n                break;\r\n            }\r\n            estlim = w;\r\n        }\r\n        return [estlim, result, 1 - (n - 1) / this.upper];\r\n    },\r\n\r\n    /**\r\n     * Levin transformation. See Numerical Recipes, ed. 3.\r\n     * Not yet ready for use.\r\n     *\r\n     * @param {Number} s_n next value of sequence, i.e. n-th element of sequence\r\n     * @param {Number} n index of s_n in the sequence\r\n     * @param {Array} numer One-dimensional array containing the extrapolation data for the numerator. Has to be supplied by the calling routine.\r\n     * @param {Array} denom One-dimensional array containing the extrapolation data for the denominator. Has to be supplied by the calling routine.\r\n     *\r\n     * @memberof JXG.Math.Extrapolate\r\n     */\r\n    levin: function (s_n, n, omega, beta, numer, denom) {\r\n        var HUGE = 1e20,\r\n            TINY = 1e-15,\r\n            j,\r\n            fact,\r\n            ratio,\r\n            term,\r\n            estlim;\r\n\r\n        term = 1.0 / (beta + n);\r\n        numer[n] = s_n / omega;\r\n        denom[n] = 1 / omega;\r\n        if (n > 0) {\r\n            numer[n - 1] = numer[n] - numer[n - 1];\r\n            denom[n - 1] = denom[n] - denom[n - 1];\r\n            if (n > 1) {\r\n                ratio = (beta + n - 1) * term;\r\n                for (j = 2; j <= n; j++) {\r\n                    fact = (beta + n - j) * Math.pow(ratio, j - 2) * term;\r\n                    numer[n - j] = numer[n - j + 1] - fact * numer[n - j];\r\n                    denom[n - j] = denom[n - j + 1] - fact * denom[n - j];\r\n                    term *= ratio;\r\n                }\r\n            }\r\n        }\r\n        if (Math.abs(denom[0]) < TINY) {\r\n            estlim = HUGE;\r\n        } else {\r\n            estlim = numer[0] / denom[0];\r\n        }\r\n        return estlim;\r\n    },\r\n\r\n    iteration_levin: function (x0, h0, f, step_type) {\r\n        var n,\r\n            v,\r\n            w,\r\n            estlim = NaN,\r\n            v_prev,\r\n            delta,\r\n            diff,\r\n            omega,\r\n            beta = 1,\r\n            r = 0.5,\r\n            numer = [],\r\n            denom = [],\r\n            result = \"finite\",\r\n            h = h0,\r\n            transform = 'u';\r\n\r\n        step_type = step_type || 0;\r\n\r\n        v_prev = f(x0 + h0, true);\r\n        for (n = 1; n <= this.upper; n++) {\r\n            h = step_type === 0 ? h0 / (n + 1) : h * r;\r\n            v = f(x0 + h, true);\r\n            delta = v - v_prev;\r\n            if (Math.abs(delta) < 1) {\r\n                transform = 'u';\r\n            } else {\r\n                transform = 't';\r\n            }\r\n            if (transform === 'u') {\r\n                omega = (beta + n) * delta; // u transformation\r\n            } else {\r\n                omega = delta; // t transformation\r\n            }\r\n\r\n            v_prev = v;\r\n            w = this.levin(v, n - 1, omega, beta, numer, denom);\r\n            diff = w - estlim;\r\n            // console.log(n, delta, transform, x0 + h, v, w, diff);\r\n\r\n            if (isNaN(w)) {\r\n                result = 'NaN';\r\n                break;\r\n            }\r\n            if (v !== 0 && w / v > this.infty) {\r\n                estlim = w;\r\n                result = 'infinite';\r\n                break;\r\n            }\r\n            if (Math.abs(diff) < 1e-7) {\r\n                break;\r\n            }\r\n            estlim = w;\r\n        }\r\n        return [estlim, result, 1 - (n - 1) / this.upper];\r\n    },\r\n\r\n    /**\r\n     *\r\n     * @param {Number} x0 Value for which the limit of f is to be determined. f(x0) may or may not exist.\r\n     * @param {Number} h0 Initial (signed) distance from x0.\r\n     * @param {Function} f Function for which the limit at x0 is to be determined\r\n     *\r\n     * @returns {Array} Array of length 3. Position 0: estimated value for f(x0), position 1: 'finite', 'infinite', or 'NaN'.\r\n     * Position 2: value between 0 and 1 judging the reliability of the result (1: high, 0: not successful).\r\n     * In case that the extrapolation fails, position 1 and 2 contain 'direct' and 0.\r\n     *\r\n     * @example\r\n     * var f1 = (x) => Math.log(x),\r\n     *     f2 = (x) => Math.tan(x - Math.PI * 0.5),\r\n     *     f3 = (x) => 4 / x;\r\n     *\r\n     * var x0 = 0.0000001;\r\n     * var h = 0.1;\r\n     * for (let f of [f1, f2, f3]) {\r\n     *     console.log(\"x0=\", x0, f.toString());\r\n     *     console.log(JXG.Math.Extrapolate.limit(x0, h, f));\r\n     *  }\r\n     *\r\n     * </pre><div id=\"JXG5e8c6a7e-eeae-43fb-a669-26b5c9e40cab\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXG5e8c6a7e-eeae-43fb-a669-26b5c9e40cab',\r\n     *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n     *     var f1 = (x) => Math.log(x),\r\n     *         f2 = (x) => Math.tan(x - Math.PI * 0.5),\r\n     *         f3 = (x) => 4 / x;\r\n     *\r\n     *     var x0 = 0.0000001;\r\n     *     var h = 0.1;\r\n     *     for (let f of [f1, f2, f3]) {\r\n     *         console.log(\"x0=\", x0, f.toString());\r\n     *         console.log(JXG.Math.Extrapolate.limit(x0, h, f));\r\n     *      }\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     *\r\n     * @see JXG.Math.Extrapolate.iteration\r\n     * @memberof JXG.Math.Extrapolate\r\n     */\r\n    limit: function (x0, h0, f) {\r\n        return this.iteration_levin(x0, h0, f, 0);\r\n        //return this.iteration(x0, h0, f, 'wynnEps', 1);\r\n\r\n        // var algs = ['wynnEps', 'levin'], //, 'wynnEps', 'levin', 'aitken', 'brezinski'],\r\n        //     le = algs.length,\r\n        //     i, t, res;\r\n        // for (i = 0; i < le; i++) {\r\n        //     for (t = 0; t < 1; t++) {\r\n        //         if (algs[i] === 'levin') {\r\n        //             res = this.iteration_levin(x0, h0, f, t);\r\n        //         } else {\r\n        //             res = this.iteration(x0, h0, f, algs[i], t);\r\n        //         }\r\n        //         if (res[2] > 0.6) {\r\n        //             return res;\r\n        //         }\r\n        //         console.log(algs[i], t, res)\r\n        //     }\r\n        // }\r\n        // return [f(x0 + Math.sign(h0) * Math.sqrt(Mat.eps)), 'direct', 0];\r\n    }\r\n};\r\n\r\nexport default Mat.Extrapolate;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG:true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport Mat from \"./math.js\";\r\nimport Geometry from \"./geometry.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Instantiate a new quadtree.\r\n *\r\n * @name JXG.Math.Quadtree\r\n * @exports Mat.Quadtree as JXG.Math.Quadtree\r\n * @param {Array} bbox Bounding box of the new quad (sub)tree.\r\n * @param {Object} config Configuration object. Default value: to {capacity: 10}\r\n * @param {Object} [parent] Parent object or null if root.\r\n *\r\n * @constructor\r\n */\r\nMat.Quadtree = function (bbox, config, parent) {\r\n    config = config || {\r\n        capacity: 10,\r\n        pointType: 'coords'\r\n    };\r\n\r\n    /**\r\n     * Configuration object for quadtree.\r\n     *\r\n     * @name JXG.Math.Quadtree.config\r\n     * @type Object\r\n     */\r\n    this.config = {};\r\n    /**\r\n     * The maximum number of points stored in a quadtree node\r\n     * before it is subdivided.\r\n     * @name JXG.Math.Quadtree.config#capacity\r\n     * @type Number\r\n     * @default 10\r\n     */\r\n    this.config.capacity = config.capacity || 10;\r\n\r\n    /**\r\n     * Type of a point object. Possible values are:\r\n     * 'coords', 'object'.\r\n     * @name JXG.Math.Quadtree.config#pointType\r\n     * @type String\r\n     * @default 'coords'\r\n     */\r\n    this.config.pointType = config.pointType || 'coords';\r\n\r\n    /**\r\n     * Point storage.\r\n     * @name JXG.Math.Quadtree#points\r\n     * @type Array\r\n     */\r\n    this.points = [];\r\n\r\n    this.xlb = bbox[0];\r\n    this.xub = bbox[2];\r\n    this.ylb = bbox[3];\r\n    this.yub = bbox[1];\r\n\r\n    /**\r\n     * Parent quadtree or null if there is not parent.\r\n     *\r\n     * @name JXG.Math.Quadtree#parent\r\n     * @type JXG.Math.Quadtree\r\n     *\r\n     */\r\n    this.parent = parent || null;\r\n\r\n    /**\r\n     * In a subdivided quadtree this represents the top left subtree.\r\n     * @name JXG.Math.Quadtree#northWest\r\n     * @type JXG.Math.Quadtree\r\n     */\r\n    this.northWest = null;\r\n\r\n    /**\r\n     * In a subdivided quadtree this represents the top right subtree.\r\n     * @name JXG.Math.Quadtree#northEast\r\n     * @type JXG.Math.Quadtree\r\n     */\r\n    this.northEast = null;\r\n\r\n    /**\r\n     * In a subdivided quadtree this represents the bottom right subtree.\r\n     * @name JXG.Math.Quadtree#southEast\r\n     * @type JXG.Math.Quadtree\r\n     */\r\n    this.southEast = null;\r\n\r\n    /**\r\n     * In a subdivided quadtree this represents the bottom left subtree.\r\n     * @name JXG.Math.Quadtree#southWest\r\n     * @type JXG.Math.Quadtree\r\n     */\r\n    this.southWest = null;\r\n\r\n};\r\n\r\nType.extend(\r\n    Mat.Quadtree.prototype,\r\n    /** @lends JXG.Math.Quadtree.prototype */ {\r\n        /**\r\n         * Checks if the given coordinates are inside of the boundaries of the quadtree.\r\n         * The quadtree is open to the left and botton and closed to\r\n         * right and top.\r\n         *\r\n         * @param {Number} x\r\n         * @param {Number} y\r\n         * @returns {Boolean}\r\n         */\r\n        contains: function (x, y) {\r\n            return this.xlb < x && x <= this.xub && this.ylb < y && y <= this.yub;\r\n        },\r\n\r\n        /**\r\n         * Insert a new point into this quadtree if it is inside of\r\n         * the quadtree's boundaries.\r\n         *\r\n         * @param {JXG.Coords} p\r\n         * @returns {Boolean} true if insert succeeded, false otherwise.\r\n         */\r\n        insert: function (p) {\r\n            switch (this.config.pointType) {\r\n                case 'coords':\r\n                    if (!this.contains(p.usrCoords[1], p.usrCoords[2])) {\r\n                        return false;\r\n                    }\r\n                    break;\r\n                case 'object':\r\n                    if (!this.contains(p.x, p.y)) {\r\n                        return false;\r\n                    }\r\n                    break;\r\n            }\r\n\r\n            if (this.points.length < this.config.capacity && this.northWest === null) {\r\n                this.points.push(p);\r\n                return true;\r\n            }\r\n\r\n            // At this point the point has to be inserted into a subtree.\r\n            if (this.northWest === null) {\r\n                this.subdivide();\r\n            }\r\n\r\n            if (this.northWest.insert(p)) {\r\n                return true;\r\n            }\r\n\r\n            if (this.northEast.insert(p)) {\r\n                return true;\r\n            }\r\n\r\n            if (this.southEast.insert(p)) {\r\n                return true;\r\n            }\r\n\r\n            return !!this.southWest.insert(p);\r\n        },\r\n\r\n        /**\r\n         * Subdivide the quadtree.\r\n         */\r\n        subdivide: function () {\r\n            var // i, le,\r\n                cx = this.xlb + (this.xub - this.xlb) * 0.5,\r\n                cy = this.ylb + (this.yub - this.ylb) * 0.5;\r\n\r\n            this.northWest = new Mat.Quadtree([this.xlb, this.yub, cx, cy], this.config, this);\r\n            this.northEast = new Mat.Quadtree([cx, this.yub, this.xub, cy], this.config, this);\r\n            this.southEast = new Mat.Quadtree([this.xlb, cy, cx, this.ylb], this.config, this);\r\n            this.southWest = new Mat.Quadtree([cx, cy, this.xub, this.ylb], this.config, this);\r\n\r\n            // for (i = 0; i < le; i++) {\r\n            //     if (this.northWest.insert(this.points[i])) { continue; }\r\n            //     if (this.northEast.insert(this.points[i])) { continue; }\r\n            //     if (this.southEast.insert(this.points[i])) { continue; }\r\n            //     this.southWest.insert(this.points[i]);\r\n            // }\r\n        },\r\n\r\n        /**\r\n         * Internal _query method that lacks adjustment of the parameter.\r\n         * @name JXG.Math.Quadtree#_query\r\n         * @param {Number} x\r\n         * @param {Number} y\r\n         * @returns {Boolean|JXG.Quadtree} The quadtree if the point is found, false\r\n         * if none of the quadtrees contains the point (i.e. the point is not inside\r\n         * the root tree's AABB,i.e. axis-aligned bounding box).\r\n         * @private\r\n         */\r\n        _query: function (x, y) {\r\n            var r;\r\n\r\n            if (this.contains(x, y)) {\r\n                if (this.northWest === null) {\r\n                    return this;\r\n                }\r\n\r\n                r = this.northWest._query(x, y);\r\n                if (r) {\r\n                    return r;\r\n                }\r\n\r\n                r = this.northEast._query(x, y);\r\n                if (r) {\r\n                    return r;\r\n                }\r\n\r\n                r = this.southEast._query(x, y);\r\n                if (r) {\r\n                    return r;\r\n                }\r\n\r\n                r = this.southWest._query(x, y);\r\n                if (r) {\r\n                    return r;\r\n                }\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Retrieve the smallest quad tree that contains the given coordinate pair.\r\n         * @name JXG.Math.Quadtree#query\r\n         * @param {JXG.Coords|Number} xp\r\n         * @param {Number} y\r\n         * @returns {Boolean|JXG.Quadtree} The quadtree if the point is found, false\r\n         * if none of the quadtrees contains the point (i.e. the point is not inside\r\n         * the root tree's AABB (Axis-Aligned Bounding Box)).\r\n         */\r\n        query: function (xp, y) {\r\n            var _x, _y;\r\n\r\n            if (Type.exists(y)) {\r\n                _x = xp;\r\n                _y = y;\r\n            } else {\r\n                _x = xp.usrCoords[1];\r\n                _y = xp.usrCoords[2];\r\n            }\r\n\r\n            return this._query(_x, _y);\r\n        },\r\n\r\n        /**\r\n         * Check if the quadtree has a point which is inside of a sphere of\r\n         * radius tol around [x, y].\r\n         * @param {Number} x\r\n         * @param {Number} y\r\n         * @param {Number} tol\r\n         * @returns {Boolean}\r\n         */\r\n        hasPoint: function (x, y, tol) {\r\n            var r, i, le;\r\n\r\n            if (this.contains(x, y)) {\r\n                le = this.points.length;\r\n\r\n                switch (this.config.pointType) {\r\n                    case 'coords':\r\n                        for (i = 0; i < le; i++) {\r\n                            if (Geometry.distance([x, y], this.points[i].usrCoords.slice(1), 2) < tol) {\r\n                                return true;\r\n                            }\r\n                        }\r\n                        break;\r\n                    case 'object':\r\n                        for (i = 0; i < le; i++) {\r\n                            if (Geometry.distance([x, y], [this.points[i].x, this.points[i].y], 2) < tol) {\r\n                                return true;\r\n                            }\r\n                        }\r\n                        break;\r\n               }\r\n\r\n\r\n                if (this.northWest === null) {\r\n                    return false;\r\n                }\r\n\r\n                r = this.northWest.hasPoint(x, y, tol);\r\n                if (r) {\r\n                    return r;\r\n                }\r\n\r\n                r = this.northEast.hasPoint(x, y, tol);\r\n                if (r) {\r\n                    return r;\r\n                }\r\n\r\n                r = this.southEast.hasPoint(x, y, tol);\r\n                if (r) {\r\n                    return r;\r\n                }\r\n\r\n                r = this.southWest.hasPoint(x, y, tol);\r\n                if (r) {\r\n                    return r;\r\n                }\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         *\r\n         * @returns {Array}\r\n         */\r\n        getAllPoints: function() {\r\n            var pointsList = [];\r\n            this.getAllPointsRecursive(pointsList);\r\n            return pointsList;\r\n        },\r\n\r\n        /**\r\n         *\r\n         * @param {Array} pointsList\r\n         * @private\r\n         */\r\n        getAllPointsRecursive(pointsList) {\r\n            Array.prototype.push.apply(pointsList, this.points.slice());\r\n\r\n            if (this.northWest === null) {\r\n                return;\r\n            }\r\n\r\n            this.northWest.getAllPointsRecursive(pointsList);\r\n            this.northEast.getAllPointsRecursive(pointsList);\r\n            this.southEast.getAllPointsRecursive(pointsList);\r\n            this.southWest.getAllPointsRecursive(pointsList);\r\n        }\r\n\r\n    }\r\n);\r\n\r\nexport default Mat.Quadtree;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG:true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport Mat from \"./math.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Instantiate a new box quadtree.\r\n * A box quadtree stores AABBs, i.e. axis-aligned bounding boxes.\r\n * The box quadtree has four sub-quadtress which maybe null if not needed.\r\n *\r\n * @name JXG.Math.BoxQuadtree\r\n * @exports Mat.BoxQuadtree as JXG.Math.BoxQuadtree\r\n *\r\n * @param {Number} depth Maximum recursion depth.\r\n * @param {Number} capacity Maximum number of items stored in this node.\r\n * @param {Array} [bbox] Optional bounding box of the box quadtree. If not given, the bounding box is\r\n * determined by the items in the insert method. This will only work correctly if the first\r\n * call of insert contains the maximum bounding box.\r\n *\r\n * @constructor\r\n */\r\nMat.BoxQuadtree = function (depth, capacity, bbox) {\r\n    var l, t, r, b;\r\n\r\n    // console.log(\"---------------------------------------\")\r\n    depth--;\r\n\r\n    /**\r\n     * Maximum depth of the box quadtree node\r\n     * @name JXG.Math.BoxQuadtree#depth\r\n     * @type Number\r\n     * @private\r\n     */\r\n    this.depth = depth;\r\n\r\n    /**\r\n     * Capacity of the box quadtree node\r\n     * @name JXG.Math.BoxQuadtree#capacity\r\n     * @type Number\r\n     * @private\r\n     */\r\n    this.capacity = capacity;\r\n\r\n    /**\r\n     * Item storage.\r\n     *\r\n     * @name JXG.Math.BoxQuadtree#items\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.items = [];\r\n\r\n    /**\r\n     * In a subdivided quadtree this represents the top left subtree.\r\n     * @name JXG.Math.BoxQuadtree#northWest\r\n     * @type JXG.Math.BoxQuadtree\r\n     * @private\r\n     */\r\n    this.northWest = null;\r\n\r\n    /**\r\n     * In a subdivided quadtree this represents the top right subtree.\r\n     * @name JXG.Math.BoxQuadtree#northEast\r\n     * @type JXG.Math.BoxQuadtree\r\n     * @private\r\n     */\r\n    this.northEast = null;\r\n\r\n    /**\r\n     * In a subdivided quadtree this represents the bottom right subtree.\r\n     * @name JXG.Math.BoxQuadtree#southEast\r\n     * @type JXG.Math.BoxQuadtree\r\n     * @private\r\n     */\r\n    this.southEast = null;\r\n\r\n    /**\r\n     * In a subdivided quadtree this represents the bottom left subtree.\r\n     * @name JXG.Math.BoxQuadtree#southWest\r\n     * @type JXG.Math.BoxQuadtree\r\n     * @private\r\n     */\r\n    this.southWest = null;\r\n\r\n    /**\r\n     * Bounding box [left, top, right, bottom].\r\n     *\r\n     * @name JXG.Math.BoxQuadtree#bbox\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.bbox = null;\r\n\r\n    /**\r\n     * x-coordinate of bounding box center.\r\n     *\r\n     * @name JXG.Math.BoxQuadtree#cx\r\n     * @type Number\r\n     * @private\r\n     */\r\n    this.cx = null;\r\n\r\n    /**\r\n     * y-coordinate of bounding box center.\r\n     *\r\n     * @name JXG.Math.BoxQuadtree#cy\r\n     * @type Number\r\n     * @private\r\n     */\r\n    this.cy = null;\r\n\r\n    if (bbox) {\r\n        // Take supplied bounding box\r\n        l = bbox[0];\r\n        t = bbox[1];\r\n        r = bbox[2];\r\n        b = bbox[3];\r\n        this.cx = (l + r) * 0.5;\r\n        this.cy = (t + b) * 0.5;\r\n        this.bbox = [l, t, r, b];\r\n    }\r\n};\r\n\r\nType.extend(\r\n    Mat.BoxQuadtree.prototype,\r\n    /** @lends JXG.Math.BoxQuadtree.prototype */ {\r\n\r\n        /**\r\n         * Insert an array of items into the box quadtree. An item is an object\r\n         * containing at least the properties\r\n         * <ul>\r\n         *  <li> xlb: lower bound on x\r\n         *  <li> xub: upper bound on x\r\n         *  <li> ylb: lower bound on y\r\n         *  <li> yub: upper bound on y\r\n         * </ul>\r\n         * which define the axis-aligned bounding box (AABB) of that item. Additionally,\r\n         * more properties can be given.\r\n         *\r\n         * @param {Array} items to be inserted\r\n         * @returns {Object} reference to the box quadtree\r\n         */\r\n        insert: function(items) {\r\n            var i, le,\r\n                l, t, r, b,\r\n                it,\r\n                nw_it = [],\r\n                ne_it = [],\r\n                sw_it = [],\r\n                se_it = [],\r\n                in_nw, in_ne, in_sw, in_se;\r\n\r\n\r\n            if (this.bbox === null) {\r\n                // Use bounding box of the supplied items\r\n                le  = items.length;\r\n                l = b = Infinity;\r\n                r = t = -Infinity;\r\n                for (i = 0; i < items.length; i++) {\r\n                    it = items[i];\r\n                    l = (it.xlb < l) ? it.xlb : l;\r\n                    t = (it.yub > t) ? it.yub : t;\r\n                    r = (it.xub > r) ? it.xub : r;\r\n                    b = (it.ylb < b) ? it.ylb : b;\r\n                }\r\n                this.cx = (l + r) * 0.5;\r\n                this.cy = (t + b) * 0.5;\r\n                this.bbox = [l, t, r, b];\r\n            } else {\r\n                l = this.bbox[0];\r\n                t = this.bbox[1];\r\n                r = this.bbox[2];\r\n                b = this.bbox[3];\r\n            }\r\n\r\n            if (this.depth === 0 || this.items.length + items.length < this.capacity) {\r\n                // if (items.length + items.length < this.capacity) {\r\n                //     console.log(\"Capacity sufficient, D=\", this.depth, this.items.length, items.length);\r\n                // }\r\n                // if (depth === 0) {console.log(\"Max depth reached\", items.length, this.capacity); }\r\n\r\n                this.items = this.items.concat(items);\r\n                return this;\r\n            }\r\n\r\n            le  = items.length;\r\n            for (i = 0; i < le; i++) {\r\n                it = items[i];\r\n                in_nw = it.xlb <= this.cx && it.yub > this.cy;\r\n                in_sw = it.xlb <= this.cx && it.ylb <= this.cy;\r\n                in_ne = it.xub > this.cx && it.yub > this.cy;\r\n                in_se = it.xub > this.cx && it.ylb <= this.cy;\r\n\r\n                // If it overlaps all 4 quadrants then insert it at the current\r\n                // depth, otherwise append it to a list to be inserted under every\r\n                // quadrant that it overlaps.\r\n                if (in_nw && in_ne && in_se && in_sw) {\r\n                    this.items.push(it);\r\n                } else {\r\n                    if (in_nw) { nw_it.push(it); }\r\n                    if (in_sw) { sw_it.push(it); }\r\n                    if (in_ne) { ne_it.push(it); }\r\n                    if (in_se) { se_it.push(it); }\r\n                }\r\n            }\r\n\r\n            // Create the sub-quadrants, recursively.\r\n            this.subdivide(nw_it, sw_it, ne_it, se_it, l, t, r, b);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Insert an item into the box quadtree, where an item is an object\r\n         * containing at least the properties\r\n         *\r\n         * <ul>\r\n         *  <li> xlb: lower bound on x\r\n         *  <li> xub: upper bound on x\r\n         *  <li> ylb: lower bound on y\r\n         *  <li> yub: upper bound on y\r\n         * </ul>\r\n         * which define the axis-aligned bounding box (AABB) of that item. Additionally,\r\n         * more properties can be given.\r\n         *\r\n         * @param {Object} it Item to be inserted\r\n         * @returns {Object} reference to the box quadtree\r\n         */\r\n        insertItem: function(it) {\r\n            var l, t, r, b,\r\n                nw_it = [],\r\n                ne_it = [],\r\n                sw_it = [],\r\n                se_it = [],\r\n                in_nw, in_ne, in_sw, in_se;\r\n\r\n\r\n            if (this.bbox === null) {\r\n                // Use bounding box of the supplied items\r\n                l = b = Infinity;\r\n                r = t = -Infinity;\r\n\r\n                l = (it.xlb < l) ? it.xlb : l;\r\n                t = (it.yub > t) ? it.yub : t;\r\n                r = (it.xub > r) ? it.xub : r;\r\n                b = (it.ylb < b) ? it.ylb : b;\r\n\r\n                this.cx = (l + r) * 0.5;\r\n                this.cy = (t + b) * 0.5;\r\n                this.bbox = [l, t, r, b];\r\n            } else {\r\n                l = this.bbox[0];\r\n                t = this.bbox[1];\r\n                r = this.bbox[2];\r\n                b = this.bbox[3];\r\n            }\r\n\r\n            if (this.depth === 0 || this.items.length + 1 < this.capacity) {\r\n                this.items.push(it);\r\n                return this;\r\n            }\r\n\r\n            in_nw = it.xlb <= this.cx && it.yub > this.cy;\r\n            in_sw = it.xlb <= this.cx && it.ylb <= this.cy;\r\n            in_ne = it.xub > this.cx && it.yub > this.cy;\r\n            in_se = it.xub > this.cx && it.ylb <= this.cy;\r\n\r\n            // If it overlaps all 4 quadrants then insert it at the current\r\n            // depth, otherwise append it to a list to be inserted under every\r\n            // quadrant that it overlaps.\r\n            if (in_nw && in_ne && in_se && in_sw) {\r\n                this.items.push(it);\r\n            } else {\r\n                if (in_nw) { nw_it.push(it); }\r\n                if (in_sw) { sw_it.push(it); }\r\n                if (in_ne) { ne_it.push(it); }\r\n                if (in_se) { se_it.push(it); }\r\n            }\r\n\r\n            // Create the sub-quadrants, recursively.\r\n            this.subdivide(nw_it, sw_it, ne_it, se_it, l, t, r, b);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Create the sub-quadrants if necessary, recursively\r\n         * @param {Array} nw_it list of items for northWest subtree\r\n         * @param {Array} sw_it list of items for southWest subtree\r\n         * @param {Array} ne_it list of items for northEast subtree\r\n         * @param {Array} se_it list of items for southEast subtree\r\n         * @param {Number} l bounding box left\r\n         * @param {Number} t bounding box top\r\n         * @param {Number} r bounding box right\r\n         * @param {Number} b bounding box bottom\r\n         * @returns {Object} reference to the box quadtree\r\n         * @private\r\n         */\r\n        subdivide: function(nw_it, sw_it, ne_it, se_it, l, t, r, b) {\r\n            if (nw_it.length > 0) {\r\n                if (this.northWest === null) {\r\n                    this.northWest = new JXG.Math.BoxQuadtree(this.depth, this.capacity, [l, t, this.cx, this.cy]);\r\n                }\r\n                this.northWest.insert(nw_it);\r\n            }\r\n            if (sw_it.length > 0) {\r\n                if (this.southWest === null) {\r\n                    this.southWest = new JXG.Math.BoxQuadtree(this.depth, this.capacity, [l, this.cy, this.cx, b]);\r\n                }\r\n                this.southWest.insert(sw_it);\r\n            }\r\n            if (ne_it.length > 0) {\r\n                if (this.northEast === null) {\r\n                    this.northEast = new JXG.Math.BoxQuadtree(this.depth, this.capacity, [this.cx, t, r, this.cy]);\r\n                }\r\n                this.northEast.insert(ne_it);\r\n            }\r\n            if (se_it.length > 0) {\r\n                if (this.southEast === null) {\r\n                    this.southEast = new JXG.Math.BoxQuadtree(this.depth, this.capacity, [this.cx, this.cy, r, b]);\r\n                }\r\n                this.southEast.insert(se_it);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Find all entries of the box quadtree which have an overlap\r\n         * with the given rectangle (AABB). Items may appear multiple times.\r\n         *\r\n         * @param {Array} box AABB of the form [l, t, r, b]\r\n         * @returns {Array} list of items overlapping with box\r\n         */\r\n        find: function(box) {\r\n            var overlaps = function(item) {\r\n                    return box[2] >= item.xlb && box[0] <= item.xub &&\r\n                        box[3] <= item.yub && box[1] >= item.ylb;\r\n                },\r\n                hits = [],\r\n                i, le;\r\n\r\n            le = this.items.length;\r\n            for (i = 0; i < le; i++) {\r\n                if (overlaps(this.items[i])) {\r\n                    hits.push(this.items[i]);\r\n                }\r\n            }\r\n\r\n            if (this.northWest !== null && box[0] <= this.cx & box[1] >= this.cy) {\r\n                Type.concat(hits, this.northWest.find(box));\r\n            }\r\n            if (this.southWest !== null && box[0] <= this.cx & box[3] <= this.cy) {\r\n                Type.concat(hits, this.southWest.find(box));\r\n            }\r\n            if (this.northEast !== null && box[2] >= this.cx & box[1] >= this.cy) {\r\n                Type.concat(hits, this.northEast.find(box));\r\n            }\r\n            if (this.southEast !== null && box[2] >= this.cx & box[3] <= this.cy) {\r\n                Type.concat(hits, this.southEast.find(box));\r\n            }\r\n\r\n            return hits;\r\n        },\r\n\r\n        /**\r\n         * Analyze the box quadtree.\r\n         *\r\n         * @returns {Object} data about the box quadtree\r\n         */\r\n        analyzeTree: function() {\r\n            var stats = {\r\n                    number_items: this.items.length,\r\n                    depth: 1\r\n                }, tmp;\r\n\r\n            if (this.northWest !== null) {\r\n                tmp = this.northWest.analyzeTree();\r\n                stats.number_items += tmp.number_items;\r\n                stats.depth = Math.max(stats.depth, 1 + tmp.depth);\r\n            }\r\n            if (this.southWest !== null) {\r\n                tmp = this.southWest.analyzeTree();\r\n                stats.number_items += tmp.number_items;\r\n                stats.depth = Math.max(stats.depth, 1 + tmp.depth);\r\n            }\r\n            if (this.northEast !== null) {\r\n                tmp = this.northEast.analyzeTree();\r\n                stats.number_items += tmp.number_items;\r\n                stats.depth = Math.max(stats.depth, 1 + tmp.depth);\r\n            }\r\n            if (this.southEast !== null) {\r\n                tmp = this.southEast.analyzeTree();\r\n                stats.number_items += tmp.number_items;\r\n                stats.depth = Math.max(stats.depth, 1 + tmp.depth);\r\n            }\r\n\r\n            return stats;\r\n        },\r\n\r\n        /**\r\n         * Generate data to plot the box quadtree as curve using updateDataArray.\r\n         *\r\n         * @returns {Array} containing arrays dataX and dataY\r\n         *\r\n         * @example\r\n         *\r\n         * // qdt contains a BoxQuadtree\r\n         *\r\n         * var qdtcurve = board.create('curve', [[], []], { strokeWidth: 1, strokeColor: '#0000ff', strokeOpacity: 0.3 });\r\n         * qdtcurve.updateDataArray = function () {\r\n         *    var ret = qdt.plot();\r\n         *\r\n         *    this.dataX = ret[0];\r\n         *    this.dataY = ret[1];\r\n         *    console.log(qdt.analyzeTree());\r\n         * };\r\n         * board.update();\r\n         */\r\n        plot: function () {\r\n            var dataX = [],\r\n                dataY = [],\r\n                ret;\r\n\r\n            dataX.push(this.bbox[0]); dataY.push(this.bbox[3]);\r\n            dataX.push(this.bbox[2]); dataY.push(this.bbox[3]);\r\n            dataX.push(this.bbox[2]); dataY.push(this.bbox[1]);\r\n            dataX.push(this.bbox[0]); dataY.push(this.bbox[1]);\r\n            dataX.push(this.bbox[0]); dataY.push(this.bbox[3]);\r\n            dataX.push(NaN); dataY.push(NaN);\r\n\r\n            if (this.northWest !== null) {\r\n                ret = this.northWest.plot();\r\n                Type.concat(dataX, ret[0]);\r\n                Type.concat(dataY, ret[1]);\r\n            }\r\n\r\n            if (this.northEast !== null) {\r\n                ret = this.northEast.plot();\r\n                Type.concat(dataX, ret[0]);\r\n                Type.concat(dataY, ret[1]);\r\n            }\r\n\r\n            if (this.southEast !== null) {\r\n                ret = this.southEast.plot();\r\n                Type.concat(dataX, ret[0]);\r\n                Type.concat(dataY, ret[1]);\r\n            }\r\n\r\n            if (this.southWest !== null) {\r\n                ret = this.southWest.plot();\r\n                Type.concat(dataX, ret[0]);\r\n                Type.concat(dataY, ret[1]);\r\n            }\r\n\r\n            return [dataX, dataY];\r\n        }\r\n    }\r\n);\r\n\r\nexport default Mat.BoxQuadtree;\r\n","/*\r\n Copyright 2008-2025\r\n Matthias Ehmann,\r\n Carsten Miller,\r\n Reinhard Oldenburg,\r\n Andreas Walter,\r\n Alfred Wassermann\r\n\r\n This file is part of JSXGraph.\r\n\r\n JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n You can redistribute it and/or modify it under the terms of the\r\n\r\n * GNU Lesser General Public License as published by\r\n the Free Software Foundation, either version 3 of the License, or\r\n (at your option) any later version\r\n OR\r\n * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n JSXGraph is distributed in the hope that it will be useful,\r\n but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n GNU Lesser General Public License for more details.\r\n\r\n You should have received a copy of the GNU Lesser General Public License and\r\n the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n and <https://opensource.org/licenses/MIT/>.\r\n\r\n This is a port of jcobyla\r\n\r\n - to JavaScript by Reihard Oldenburg and\r\n - to JSXGraph by Alfred Wassermann\r\n - optimized by Andreas Walter\r\n */\r\n/*\r\n * jcobyla\r\n *\r\n * The MIT License\r\n *\r\n * Copyright (c) 2012 Anders Gustafsson, Cureos AB.\r\n *\r\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files\r\n * (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,\r\n * publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,\r\n * subject to the following conditions:\r\n *\r\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\r\n *\r\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r\n * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE\r\n * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r\n * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r\n *\r\n * Remarks:\r\n *\r\n * The original Fortran 77 version of this code was by Michael Powell (M.J.D.Powell @ damtp.cam.ac.uk)\r\n * The Fortran 90 version was by Alan Miller (Alan.Miller @ vic.cmis.csiro.au). Latest revision - 30 October 1998\r\n */\r\n\r\n/**\r\n * Constrained Optimization BY Linear Approximation in Java.\r\n *\r\n * COBYLA2 is an implementation of Powell's nonlinear derivative free constrained optimization that uses\r\n * a linear approximation approach. The algorithm is a sequential trust region algorithm that employs linear\r\n * approximations to the objective and constraint functions, where the approximations are formed by linear\r\n * interpolation at n + 1 points in the space of the variables and tries to maintain a regular shaped simplex\r\n * over iterations.\r\n *\r\n * It solves nonsmooth NLP with a moderate number of variables (about 100). Inequality constraints only.\r\n *\r\n * The initial point X is taken as one vertex of the initial simplex with zero being another, so, X should\r\n * not be entered as the zero vector.\r\n *\r\n * @author Anders Gustafsson, Cureos AB. Translation to Javascript by Reinhard Oldenburg, Goethe-University\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true, continue: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Mat from \"./math.js\";\r\n// import Type from \"../utils/type.js\";\r\n\r\n/**\r\n * The JXG.Math.Nlp namespace holds numerical algorithms for non-linear optimization.\r\n * @name JXG.Math.Nlp\r\n * @namespace\r\n *\r\n */\r\nJXG.Math.Nlp = {\r\n    arr: function (n) {\r\n        // Is 0 initialized\r\n        return new Float64Array(n);\r\n    },\r\n\r\n    arr2: function (n, m) {\r\n        var i = 0,\r\n            a = new Array(n);\r\n\r\n        while (i < n) {\r\n            a[i] = this.arr(m);\r\n            i++;\r\n        }\r\n        return a;\r\n    },\r\n\r\n    arraycopy: function (x, a, iox, b, n) {\r\n        var i = 0;\r\n        while (i < n) {\r\n            iox[i + b] = x[i + a];\r\n            i++;\r\n        }\r\n    },\r\n\r\n    lastNumberOfEvaluations: 0,\r\n    GetLastNumberOfEvaluations: function () {\r\n        return this.lastNumberOfEvaluations;\r\n    },\r\n    // status Variables\r\n    Normal: 0,\r\n    MaxIterationsReached: 1,\r\n    DivergingRoundingErrors: 2,\r\n\r\n    /**\r\n     * Minimizes the objective function F with respect to a set of inequality constraints CON,\r\n     * and returns the optimal variable array. F and CON may be non-linear, and should preferably be smooth.\r\n     * Calls {@link JXG.Math.Nlp#cobylb}.\r\n     *\r\n     * @param calcfc Interface implementation for calculating objective function and constraints.\r\n     * @param n Number of variables.\r\n     * @param m Number of constraints.\r\n     * @param x On input initial values of the variables (zero-based array). On output\r\n     * optimal values of the variables obtained in the COBYLA minimization.\r\n     * @param rhobeg Initial size of the simplex.\r\n     * @param rhoend Final value of the simplex.\r\n     * @param iprint Print level, 0 <= iprint <= 3, where 0 provides no output and\r\n     * 3 provides full output to the console.\r\n     * @param maxfun Maximum number of function evaluations before terminating.\r\n     * @param [testForRoundingErrors=false]\r\n     * @returns {Number} Exit status of the COBYLA2 optimization.\r\n     */\r\n    FindMinimum: function (calcfc, n, m, x, rhobeg, rhoend, iprint, maxfun, testForRoundingErrors) {\r\n        // CobylaExitStatus FindMinimum(final Calcfc calcfc, int n, int m, double[] x, double rhobeg, double rhoend, int iprint, int maxfun)\r\n        //     This subroutine minimizes an objective function F(X) subject to M\r\n        //     inequality constraints on X, where X is a vector of variables that has\r\n        //     N components.  The algorithm employs linear approximations to the\r\n        //     objective and constraint functions, the approximations being formed by\r\n        //     linear interpolation at N+1 points in the space of the variables.\r\n        //     We regard these interpolation points as vertices of a simplex.  The\r\n        //     parameter RHO controls the size of the simplex and it is reduced\r\n        //     automatically from RHOBEG to RHOEND.  For each RHO the subroutine tries\r\n        //     to achieve a good vector of variables for the current size, and then\r\n        //     RHO is reduced until the value RHOEND is reached.  Therefore RHOBEG and\r\n        //     RHOEND should be set to reasonable initial changes to and the required\r\n        //     accuracy in the variables respectively, but this accuracy should be\r\n        //     viewed as a subject for experimentation because it is not guaranteed.\r\n        //     The subroutine has an advantage over many of its competitors, however,\r\n        //     which is that it treats each constraint individually when calculating\r\n        //     a change to the variables, instead of lumping the constraints together\r\n        //     into a single penalty function.  The name of the subroutine is derived\r\n        //     from the phrase Constrained Optimization BY Linear Approximations.\r\n\r\n        //     The user must set the values of N, M, RHOBEG and RHOEND, and must\r\n        //     provide an initial vector of variables in X.  Further, the value of\r\n        //     IPRINT should be set to 0, 1, 2 or 3, which controls the amount of\r\n        //     printing during the calculation. Specifically, there is no output if\r\n        //     IPRINT=0 and there is output only at the end of the calculation if\r\n        //     IPRINT=1.  Otherwise each new value of RHO and SIGMA is printed.\r\n        //     Further, the vector of variables and some function information are\r\n        //     given either when RHO is reduced or when each new value of F(X) is\r\n        //     computed in the cases IPRINT=2 or IPRINT=3 respectively. Here SIGMA\r\n        //     is a penalty parameter, it being assumed that a change to X is an\r\n        //     improvement if it reduces the merit function\r\n        //                F(X)+SIGMA*MAX(0.0, - C1(X), - C2(X),..., - CM(X)),\r\n        //     where C1,C2,...,CM denote the constraint functions that should become\r\n        //     nonnegative eventually, at least to the precision of RHOEND. In the\r\n        //     printed output the displayed term that is multiplied by SIGMA is\r\n        //     called MAXCV, which stands for 'MAXimum Constraint Violation'.  The\r\n        //     argument ITERS is an integer variable that must be set by the user to a\r\n        //     limit on the number of calls of CALCFC, the purpose of this routine being\r\n        //     given below.  The value of ITERS will be altered to the number of calls\r\n        //     of CALCFC that are made.\r\n        //     In order to define the objective and constraint functions, we require\r\n        //     a subroutine that has the name and arguments\r\n        //                SUBROUTINE CALCFC (N,M,X,F,CON)\r\n        //                DIMENSION X(:),CON(:)  .\r\n        //     The values of N and M are fixed and have been defined already, while\r\n        //     X is now the current vector of variables. The subroutine should return\r\n        //     the objective and constraint functions at X in F and CON(1),CON(2),\r\n        //     ...,CON(M).  Note that we are trying to adjust X so that F(X) is as\r\n        //     small as possible subject to the constraint functions being nonnegative.\r\n\r\n        // Local variables\r\n        var mpp = m + 2,\r\n            status,\r\n            // Internal base-1 X array\r\n            iox = this.arr(n + 1),\r\n            that = this,\r\n            fcalcfc;\r\n\r\n        this.lastNumberOfEvaluations = 0;\r\n\r\n        if (testForRoundingErrors) {\r\n            console.log(\"Experimental feature 'testForRoundingErrors' is activated.\");\r\n        }\r\n\r\n        iox[0] = 0.0;\r\n        this.arraycopy(x, 0, iox, 1, n);\r\n\r\n        // Internal representation of the objective and constraints calculation method,\r\n        // accounting for that X and CON arrays in the cobylb method are base-1 arrays.\r\n        fcalcfc = function (n, m, thisx, con) {\r\n            // int n, int m, double[] x, double[] con\r\n            var ix = that.arr(n),\r\n                ocon, f;\r\n\r\n            that.lastNumberOfEvaluations = that.lastNumberOfEvaluations + 1;\r\n            that.arraycopy(thisx, 1, ix, 0, n);\r\n            ocon = that.arr(m);\r\n            f = calcfc(n, m, ix, ocon);\r\n            that.arraycopy(ocon, 0, con, 1, m);\r\n            return f;\r\n        };\r\n\r\n        status = this.cobylb(fcalcfc, n, m, mpp, iox, rhobeg, rhoend, iprint, maxfun, testForRoundingErrors);\r\n        this.arraycopy(iox, 1, x, 0, n);\r\n\r\n        return status;\r\n    },\r\n\r\n    //    private static CobylaExitStatus cobylb(Calcfc calcfc, int n, int m, int mpp, double[] x,\r\n    //      double rhobeg, double rhoend, int iprint, int maxfun)\r\n    /**\r\n     * JavaScript implementation of the non-linear optimization method COBYLA.\r\n     * @param {Function} calcfc\r\n     * @param {Number} n\r\n     * @param {Number} m\r\n     * @param {Number} mpp\r\n     * @param {Number} x\r\n     * @param {Number} rhobeg\r\n     * @param {Number} rhoend\r\n     * @param {Number} iprint\r\n     * @param {Number} maxfun\r\n     * @param {Boolean} [testForRoundingErrors=false]\r\n     * @returns {Number} Exit status of the COBYLA2 optimization\r\n     */\r\n    cobylb: function (calcfc, n, m, mpp, x, rhobeg, rhoend, iprint, maxfun, testForRoundingErrors) {\r\n        // calcf ist funktion die aufgerufen wird wie calcfc(n, m, ix, ocon)\r\n        // N.B. Arguments CON, SIM, SIMI, DATMAT, A, VSIG, VETA, SIGBAR, DX, W & IACT\r\n        //      have been removed.\r\n\r\n        //     Set the initial values of some parameters. The last column of SIM holds\r\n        //     the optimal vertex of the current simplex, and the preceding N columns\r\n        //     hold the displacements from the optimal vertex to the other vertices.\r\n        //     Further, SIMI holds the inverse of the matrix that is contained in the\r\n        //     first N columns of SIM.\r\n\r\n        // Local variables\r\n        var status = -1,\r\n            alpha = 0.25,\r\n            beta = 2.1,\r\n            gamma = 0.5,\r\n            delta = 1.1,\r\n            f = 0.0,\r\n            resmax = 0.0,\r\n            total,\r\n            np = n + 1,\r\n            mp = m + 1,\r\n            rho = rhobeg,\r\n            parmu = 0.0,\r\n            iflag = false,\r\n            ifull = false,\r\n            parsig = 0.0,\r\n            prerec = 0.0,\r\n            prerem = 0.0,\r\n            con = this.arr(1 + mpp),\r\n            sim = this.arr2(1 + n, 1 + np),\r\n            simi = this.arr2(1 + n, 1 + n),\r\n            datmat = this.arr2(1 + mpp, 1 + np),\r\n            a = this.arr2(1 + n, 1 + mp),\r\n            vsig = this.arr(1 + n),\r\n            veta = this.arr(1 + n),\r\n            sigbar = this.arr(1 + n),\r\n            dx = this.arr(1 + n),\r\n            w = this.arr(1 + n),\r\n            i, j, k, l,\r\n            temp, tempa,\r\n            nfvals, jdrop, ibrnch, skipVertexIdent,\r\n            phimin, nbest, error, pareta, wsig, weta,\r\n            cvmaxp, cvmaxm, dxsign, resnew, barmu,\r\n            phi, vmold, vmnew, trured, ratio, edgmax,\r\n            cmin, cmax, denom,\r\n            endless = true;\r\n\r\n        if (iprint >= 2) {\r\n            console.log(\"The initial value of RHO is \" + rho + \" and PARMU is set to zero.\");\r\n        }\r\n\r\n        nfvals = 0;\r\n        temp = 1.0 / rho;\r\n\r\n        for (i = 1; i <= n; ++i) {\r\n            sim[i][np] = x[i];\r\n            sim[i][i] = rho;\r\n            simi[i][i] = temp;\r\n        }\r\n\r\n        jdrop = np;\r\n        ibrnch = false;\r\n\r\n        //     Make the next call of the user-supplied subroutine CALCFC. These\r\n        //     instructions are also used for calling CALCFC during the iterations of\r\n        //     the algorithm.\r\n        //alert(\"Iteration \"+nfvals+\" x=\"+x);\r\n        L_40: do {\r\n            if (nfvals >= maxfun && nfvals > 0) {\r\n                status = this.MaxIterationsReached;\r\n                break L_40;\r\n            }\r\n\r\n            ++nfvals;\r\n            f = calcfc(n, m, x, con);\r\n            resmax = 0.0;\r\n            for (k = 1; k <= m; ++k) {\r\n                resmax = Math.max(resmax, -con[k]);\r\n            }\r\n            //alert(    \"   f=\"+f+\"  resmax=\"+resmax);\r\n\r\n            if (nfvals === iprint - 1 || iprint === 3) {\r\n                this.PrintIterationResult(nfvals, f, resmax, x, n, iprint);\r\n            }\r\n\r\n            con[mp] = f;\r\n            con[mpp] = resmax;\r\n\r\n            //     Set the recently calculated function values in a column of DATMAT. This\r\n            //     array has a column for each vertex of the current simplex, the entries of\r\n            //     each column being the values of the constraint functions (if any)\r\n            //     followed by the objective function and the greatest constraint violation\r\n            //     at the vertex.\r\n            skipVertexIdent = true;\r\n            if (!ibrnch) {\r\n                skipVertexIdent = false;\r\n\r\n                for (i = 1; i <= mpp; ++i) {\r\n                    datmat[i][jdrop] = con[i];\r\n                }\r\n\r\n                if (nfvals <= np) {\r\n                    //     Exchange the new vertex of the initial simplex with the optimal vertex if\r\n                    //     necessary. Then, if the initial simplex is not complete, pick its next\r\n                    //     vertex and calculate the function values there.\r\n\r\n                    if (jdrop <= n) {\r\n                        if (datmat[mp][np] <= f) {\r\n                            x[jdrop] = sim[jdrop][np];\r\n                        } else {\r\n                            sim[jdrop][np] = x[jdrop];\r\n                            for (k = 1; k <= mpp; ++k) {\r\n                                datmat[k][jdrop] = datmat[k][np];\r\n                                datmat[k][np] = con[k];\r\n                            }\r\n                            for (k = 1; k <= jdrop; ++k) {\r\n                                sim[jdrop][k] = -rho;\r\n                                temp = 0.0;\r\n                                for (i = k; i <= jdrop; ++i) {\r\n                                    temp -= simi[i][k];\r\n                                }\r\n                                simi[jdrop][k] = temp;\r\n                            }\r\n                        }\r\n                    }\r\n                    if (nfvals <= n) {\r\n                        jdrop = nfvals;\r\n                        x[jdrop] += rho;\r\n                        continue L_40;\r\n                    }\r\n                }\r\n                ibrnch = true;\r\n            }\r\n\r\n            L_140: do {\r\n                L_550: do {\r\n                    if (!skipVertexIdent) {\r\n                        //     Identify the optimal vertex of the current simplex.\r\n                        phimin = datmat[mp][np] + parmu * datmat[mpp][np];\r\n                        nbest = np;\r\n\r\n                        for (j = 1; j <= n; ++j) {\r\n                            temp = datmat[mp][j] + parmu * datmat[mpp][j];\r\n                            if (temp < phimin) {\r\n                                nbest = j;\r\n                                phimin = temp;\r\n                            } else if (\r\n                                temp === phimin &&\r\n                                parmu === 0.0 &&\r\n                                datmat[mpp][j] < datmat[mpp][nbest]\r\n                            ) {\r\n                                nbest = j;\r\n                            }\r\n                        }\r\n\r\n                        //     Switch the best vertex into pole position if it is not there already,\r\n                        //     and also update SIM, SIMI and DATMAT.\r\n                        if (nbest <= n) {\r\n                            for (i = 1; i <= mpp; ++i) {\r\n                                temp = datmat[i][np];\r\n                                datmat[i][np] = datmat[i][nbest];\r\n                                datmat[i][nbest] = temp;\r\n                            }\r\n                            for (i = 1; i <= n; ++i) {\r\n                                temp = sim[i][nbest];\r\n                                sim[i][nbest] = 0.0;\r\n                                sim[i][np] += temp;\r\n\r\n                                tempa = 0.0;\r\n                                for (k = 1; k <= n; ++k) {\r\n                                    sim[i][k] -= temp;\r\n                                    tempa -= simi[k][i];\r\n                                }\r\n                                simi[nbest][i] = tempa;\r\n                            }\r\n                        }\r\n\r\n                        //     Make an error return if SIGI is a poor approximation to the inverse of\r\n                        //     the leading N by N submatrix of SIG.\r\n                        error = 0.0;\r\n                        if (testForRoundingErrors) {\r\n                            for (i = 1; i <= n; ++i) {\r\n                                for (j = 1; j <= n; ++j) {\r\n                                    temp =\r\n                                        this.DOT_PRODUCT_ROW_COL(simi, i, sim, j, 1, n) -\r\n                                        (i === j ? 1.0 : 0.0);\r\n                                    // temp = this.DOT_PRODUCT(\r\n                                    //     this.PART(this.ROW(simi, i), 1, n),\r\n                                    //     this.PART(this.COL(sim, j), 1, n)\r\n                                    // ) - (i === j ? 1.0 : 0.0);\r\n\r\n                                    error = Math.max(error, Math.abs(temp));\r\n                                }\r\n                            }\r\n                        }\r\n                        if (error > 0.1) {\r\n                            status = this.DivergingRoundingErrors;\r\n                            break L_40;\r\n                        }\r\n\r\n                        //     Calculate the coefficients of the linear approximations to the objective\r\n                        //     and constraint functions, placing minus the objective function gradient\r\n                        //     after the constraint gradients in the array A. The vector W is used for\r\n                        //     working space.\r\n                        for (k = 1; k <= mp; ++k) {\r\n                            con[k] = -datmat[k][np];\r\n                            for (j = 1; j <= n; ++j) {\r\n                                w[j] = datmat[k][j] + con[k];\r\n                            }\r\n\r\n                            for (i = 1; i <= n; ++i) {\r\n                                a[i][k] =\r\n                                    (k === mp ? -1.0 : 1.0) *\r\n                                    this.DOT_PRODUCT_ROW_COL(w, -1, simi, i, 1, n);\r\n                                // this.DOT_PRODUCT(this.PART(w, 1, n), this.PART(this.COL(simi, i), 1, n));\r\n                            }\r\n                        }\r\n\r\n                        //     Calculate the values of sigma and eta, and set IFLAG = 0 if the current\r\n                        //     simplex is not acceptable.\r\n                        iflag = true;\r\n                        parsig = alpha * rho;\r\n                        pareta = beta * rho;\r\n\r\n                        for (j = 1; j <= n; ++j) {\r\n                            wsig = 0.0;\r\n                            weta = 0.0;\r\n                            for (k = 1; k <= n; ++k) {\r\n                                wsig += simi[j][k] * simi[j][k];\r\n                                weta += sim[k][j] * sim[k][j];\r\n                            }\r\n                            vsig[j] = 1.0 / Math.sqrt(wsig);\r\n                            veta[j] = Math.sqrt(weta);\r\n                            if (vsig[j] < parsig || veta[j] > pareta) {\r\n                                iflag = false;\r\n                            }\r\n                        }\r\n\r\n                        //     If a new vertex is needed to improve acceptability, then decide which\r\n                        //     vertex to drop from the simplex.\r\n                        if (!ibrnch && !iflag) {\r\n                            jdrop = 0;\r\n                            temp = pareta;\r\n                            for (j = 1; j <= n; ++j) {\r\n                                if (veta[j] > temp) {\r\n                                    jdrop = j;\r\n                                    temp = veta[j];\r\n                                }\r\n                            }\r\n                            if (jdrop === 0) {\r\n                                for (j = 1; j <= n; ++j) {\r\n                                    if (vsig[j] < temp) {\r\n                                        jdrop = j;\r\n                                        temp = vsig[j];\r\n                                    }\r\n                                }\r\n                            }\r\n\r\n                            //     Calculate the step to the new vertex and its sign.\r\n                            temp = gamma * rho * vsig[jdrop];\r\n                            for (k = 1; k <= n; ++k) {\r\n                                dx[k] = temp * simi[jdrop][k];\r\n                            }\r\n                            cvmaxp = 0.0;\r\n                            cvmaxm = 0.0;\r\n                            total = 0.0;\r\n                            for (k = 1; k <= mp; ++k) {\r\n                                // total = this.DOT_PRODUCT(this.PART(this.COL(a, k), 1, n), this.PART(dx, 1, n));\r\n                                total = this.DOT_PRODUCT_ROW_COL(dx, -1, a, k, 1, n);\r\n                                if (k < mp) {\r\n                                    temp = datmat[k][np];\r\n                                    cvmaxp = Math.max(cvmaxp, -total - temp);\r\n                                    cvmaxm = Math.max(cvmaxm, total - temp);\r\n                                }\r\n                            }\r\n                            dxsign = parmu * (cvmaxp - cvmaxm) > 2.0 * total ? -1.0 : 1.0;\r\n\r\n                            //     Update the elements of SIM and SIMI, and set the next X.\r\n                            temp = 0.0;\r\n                            for (i = 1; i <= n; ++i) {\r\n                                dx[i] = dxsign * dx[i];\r\n                                sim[i][jdrop] = dx[i];\r\n                                temp += simi[jdrop][i] * dx[i];\r\n                            }\r\n                            for (k = 1; k <= n; ++k) {\r\n                                simi[jdrop][k] /= temp;\r\n                            }\r\n\r\n                            for (j = 1; j <= n; ++j) {\r\n                                if (j !== jdrop) {\r\n                                    // temp = this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n));\r\n                                    temp = this.DOT_PRODUCT_ROW_COL(simi, j, dx, -1, 1, n);\r\n                                    for (k = 1; k <= n; ++k) {\r\n                                        simi[j][k] -= temp * simi[jdrop][k];\r\n                                    }\r\n                                }\r\n                                x[j] = sim[j][np] + dx[j];\r\n                            }\r\n                            continue L_40;\r\n                        }\r\n\r\n                        //     Calculate DX = x(*)-x(0).\r\n                        //     Branch if the length of DX is less than 0.5*RHO.\r\n                        ifull = this.trstlp(n, m, a, con, rho, dx);\r\n                        if (!ifull) {\r\n                            temp = 0.0;\r\n                            for (k = 1; k <= n; ++k) {\r\n                                temp += dx[k] * dx[k];\r\n                            }\r\n                            if (temp < 0.25 * rho * rho) {\r\n                                ibrnch = true;\r\n                                break L_550;\r\n                            }\r\n                        }\r\n\r\n                        //     Predict the change to F and the new maximum constraint violation if the\r\n                        //     variables are altered from x(0) to x(0) + DX.\r\n                        total = 0.0;\r\n                        resnew = 0.0;\r\n                        con[mp] = 0.0;\r\n                        for (k = 1; k <= mp; ++k) {\r\n                            //total = con[k] - this.DOT_PRODUCT(this.PART(this.COL(a, k), 1, n), this.PART(dx, 1, n));\r\n                            total = con[k] - this.DOT_PRODUCT_ROW_COL(dx, -1, a, k, 1, n);\r\n                            if (k < mp) {\r\n                                resnew = Math.max(resnew, total);\r\n                            }\r\n                        }\r\n\r\n                        //     Increase PARMU if necessary and branch back if this change alters the\r\n                        //     optimal vertex. Otherwise PREREM and PREREC will be set to the predicted\r\n                        //     reductions in the merit function and the maximum constraint violation\r\n                        //     respectively.\r\n                        prerec = datmat[mpp][np] - resnew;\r\n                        barmu = prerec > 0.0 ? total / prerec : 0.0;\r\n                        if (parmu < 1.5 * barmu) {\r\n                            parmu = 2.0 * barmu;\r\n                            if (iprint >= 2) {\r\n                                console.log(\"Increase in PARMU to \" + parmu);\r\n                            }\r\n                            phi = datmat[mp][np] + parmu * datmat[mpp][np];\r\n                            for (j = 1; j <= n; ++j) {\r\n                                temp = datmat[mp][j] + parmu * datmat[mpp][j];\r\n                                if (\r\n                                    temp < phi ||\r\n                                    (temp === phi &&\r\n                                        parmu === 0.0 &&\r\n                                        datmat[mpp][j] < datmat[mpp][np])\r\n                                ) {\r\n                                    continue L_140;\r\n                                }\r\n                            }\r\n                        }\r\n                        prerem = parmu * prerec - total;\r\n\r\n                        //     Calculate the constraint and objective functions at x(*).\r\n                        //     Then find the actual reduction in the merit function.\r\n                        for (k = 1; k <= n; ++k) {\r\n                            x[k] = sim[k][np] + dx[k];\r\n                        }\r\n                        ibrnch = true;\r\n                        continue L_40;\r\n                    }\r\n\r\n                    skipVertexIdent = false;\r\n                    vmold = datmat[mp][np] + parmu * datmat[mpp][np];\r\n                    vmnew = f + parmu * resmax;\r\n                    trured = vmold - vmnew;\r\n                    if (parmu === 0.0 && f === datmat[mp][np]) {\r\n                        prerem = prerec;\r\n                        trured = datmat[mpp][np] - resmax;\r\n                    }\r\n\r\n                    //     Begin the operations that decide whether x(*) should replace one of the\r\n                    //     vertices of the current simplex, the change being mandatory if TRURED is\r\n                    //     positive. Firstly, JDROP is set to the index of the vertex that is to be\r\n                    //     replaced.\r\n                    ratio = trured <= 0.0 ? 1.0 : 0.0;\r\n                    jdrop = 0;\r\n                    for (j = 1; j <= n; ++j) {\r\n                        // temp = Math.abs(this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n)));\r\n                        temp = Math.abs(this.DOT_PRODUCT_ROW_COL(simi, j, dx, -1, 1, n));\r\n                        if (temp > ratio) {\r\n                            jdrop = j;\r\n                            ratio = temp;\r\n                        }\r\n                        sigbar[j] = temp * vsig[j];\r\n                    }\r\n\r\n                    //     Calculate the value of ell.\r\n                    edgmax = delta * rho;\r\n                    l = 0;\r\n                    for (j = 1; j <= n; ++j) {\r\n                        if (sigbar[j] >= parsig || sigbar[j] >= vsig[j]) {\r\n                            temp = veta[j];\r\n                            if (trured > 0.0) {\r\n                                temp = 0.0;\r\n                                for (k = 1; k <= n; ++k) {\r\n                                    temp += Math.pow(dx[k] - sim[k][j], 2.0);\r\n                                }\r\n                                temp = Math.sqrt(temp);\r\n                            }\r\n                            if (temp > edgmax) {\r\n                                l = j;\r\n                                edgmax = temp;\r\n                            }\r\n                        }\r\n                    }\r\n                    if (l > 0) {\r\n                        jdrop = l;\r\n                    }\r\n\r\n                    if (jdrop !== 0) {\r\n                        //     Revise the simplex by updating the elements of SIM, SIMI and DATMAT.\r\n                        temp = 0.0;\r\n                        for (i = 1; i <= n; ++i) {\r\n                            sim[i][jdrop] = dx[i];\r\n                            temp += simi[jdrop][i] * dx[i];\r\n                        }\r\n                        for (k = 1; k <= n; ++k) {\r\n                            simi[jdrop][k] /= temp;\r\n                        }\r\n                        for (j = 1; j <= n; ++j) {\r\n                            if (j !== jdrop) {\r\n                                // temp = this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n));\r\n                                temp = this.DOT_PRODUCT_ROW_COL(simi, j, dx, -1, 1, n);\r\n                                for (k = 1; k <= n; ++k) {\r\n                                    simi[j][k] -= temp * simi[jdrop][k];\r\n                                }\r\n                            }\r\n                        }\r\n                        for (k = 1; k <= mpp; ++k) {\r\n                            datmat[k][jdrop] = con[k];\r\n                        }\r\n\r\n                        //     Branch back for further iterations with the current RHO.\r\n                        if (trured > 0.0 && trured >= 0.1 * prerem) {\r\n                            continue L_140;\r\n                        }\r\n                    }\r\n                    // If we end up here, we drop out.\r\n                } while (!endless);\r\n\r\n                if (!iflag) {\r\n                    ibrnch = false;\r\n                    continue L_140;\r\n                }\r\n\r\n                if (rho <= rhoend) {\r\n                    status = this.Normal;\r\n                    break L_40;\r\n                }\r\n\r\n                //     Otherwise reduce RHO if it is not at its least value and reset PARMU.\r\n                cmin = 0.0;\r\n                cmax = 0.0;\r\n                rho *= 0.5;\r\n                if (rho <= 1.5 * rhoend) {\r\n                    rho = rhoend;\r\n                }\r\n                if (parmu > 0.0) {\r\n                    denom = 0.0;\r\n                    for (k = 1; k <= mp; ++k) {\r\n                        cmin = datmat[k][np];\r\n                        cmax = cmin;\r\n                        for (i = 1; i <= n; ++i) {\r\n                            cmin = Math.min(cmin, datmat[k][i]);\r\n                            cmax = Math.max(cmax, datmat[k][i]);\r\n                        }\r\n                        if (k <= m && cmin < 0.5 * cmax) {\r\n                            temp = Math.max(cmax, 0.0) - cmin;\r\n                            denom = denom <= 0.0 ? temp : Math.min(denom, temp);\r\n                        }\r\n                    }\r\n                    if (denom === 0.0) {\r\n                        parmu = 0.0;\r\n                    } else if (cmax - cmin < parmu * denom) {\r\n                        parmu = (cmax - cmin) / denom;\r\n                    }\r\n                }\r\n                if (iprint >= 2) {\r\n                    console.log(\"Reduction in RHO to \" + rho + \"  and PARMU = \" + parmu);\r\n                }\r\n                if (iprint === 2) {\r\n                    this.PrintIterationResult(\r\n                        nfvals,\r\n                        datmat[mp][np],\r\n                        datmat[mpp][np],\r\n                        this.COL(sim, np),\r\n                        n,\r\n                        iprint\r\n                    );\r\n                }\r\n            } while (endless);\r\n        } while (endless);\r\n\r\n        switch (status) {\r\n            case this.Normal:\r\n                if (iprint >= 1) {\r\n                    console.log(\"%nNormal return from subroutine COBYLA%n\");\r\n                }\r\n                if (ifull) {\r\n                    if (iprint >= 1) {\r\n                        this.PrintIterationResult(nfvals, f, resmax, x, n, iprint);\r\n                    }\r\n                    return status;\r\n                }\r\n                break;\r\n            case this.MaxIterationsReached:\r\n                if (iprint >= 1) {\r\n                    console.log(\r\n                        \"%nReturn from subroutine COBYLA because the MAXFUN limit has been reached.%n\"\r\n                    );\r\n                }\r\n                break;\r\n            case this.DivergingRoundingErrors:\r\n                if (iprint >= 1) {\r\n                    console.log(\r\n                        \"%nReturn from subroutine COBYLA because rounding errors are becoming damaging.%n\"\r\n                    );\r\n                }\r\n                break;\r\n        }\r\n\r\n        for (k = 1; k <= n; ++k) {\r\n            x[k] = sim[k][np];\r\n        }\r\n        f = datmat[mp][np];\r\n        resmax = datmat[mpp][np];\r\n        if (iprint >= 1) {\r\n            this.PrintIterationResult(nfvals, f, resmax, x, n, iprint);\r\n        }\r\n\r\n        return status;\r\n    },\r\n\r\n    trstlp: function (n, m, a, b, rho, dx) {\r\n        //(int n, int m, double[][] a, double[] b, double rho, double[] dx)\r\n        // N.B. Arguments Z, ZDOTA, VMULTC, SDIRN, DXNEW, VMULTD & IACT have been removed.\r\n\r\n        //     This subroutine calculates an N-component vector DX by applying the\r\n        //     following two stages. In the first stage, DX is set to the shortest\r\n        //     vector that minimizes the greatest violation of the constraints\r\n        //       A(1,K)*DX(1)+A(2,K)*DX(2)+...+A(N,K)*DX(N) .GE. B(K), K = 2,3,...,M,\r\n        //     subject to the Euclidean length of DX being at most RHO. If its length is\r\n        //     strictly less than RHO, then we use the resultant freedom in DX to\r\n        //     minimize the objective function\r\n        //              -A(1,M+1)*DX(1) - A(2,M+1)*DX(2) - ... - A(N,M+1)*DX(N)\r\n        //     subject to no increase in any greatest constraint violation. This\r\n        //     notation allows the gradient of the objective function to be regarded as\r\n        //     the gradient of a constraint. Therefore the two stages are distinguished\r\n        //     by MCON .EQ. M and MCON .GT. M respectively. It is possible that a\r\n        //     degeneracy may prevent DX from attaining the target length RHO. Then the\r\n        //     value IFULL = 0 would be set, but usually IFULL = 1 on return.\r\n        //\r\n        //     In general NACT is the number of constraints in the active set and\r\n        //     IACT(1),...,IACT(NACT) are their indices, while the remainder of IACT\r\n        //     contains a permutation of the remaining constraint indices.  Further, Z\r\n        //     is an orthogonal matrix whose first NACT columns can be regarded as the\r\n        //     result of Gram-Schmidt applied to the active constraint gradients.  For\r\n        //     J = 1,2,...,NACT, the number ZDOTA(J) is the scalar product of the J-th\r\n        //     column of Z with the gradient of the J-th active constraint.  DX is the\r\n        //     current vector of variables and here the residuals of the active\r\n        //     constraints should be zero. Further, the active constraints have\r\n        //     nonnegative Lagrange multipliers that are held at the beginning of\r\n        //     VMULTC. The remainder of this vector holds the residuals of the inactive\r\n        //     constraints at DX, the ordering of the components of VMULTC being in\r\n        //     agreement with the permutation of the indices of the constraints that is\r\n        //     in IACT. All these residuals are nonnegative, which is achieved by the\r\n        //     shift RESMAX that makes the least residual zero.\r\n\r\n        //     Initialize Z and some other variables. The value of RESMAX will be\r\n        //     appropriate to DX = 0, while ICON will be the index of a most violated\r\n        //     constraint if RESMAX is positive. Usually during the first stage the\r\n        //     vector SDIRN gives a search direction that reduces all the active\r\n        //     constraint violations by one simultaneously.\r\n\r\n        // Local variables\r\n\r\n        var temp = 0,\r\n            nactx = 0,\r\n            resold = 0.0,\r\n            z = this.arr2(1 + n, 1 + n),\r\n            zdota = this.arr(2 + m),\r\n            vmultc = this.arr(2 + m),\r\n            sdirn = this.arr(1 + n),\r\n            dxnew = this.arr(1 + n),\r\n            vmultd = this.arr(2 + m),\r\n            iact = this.arr(2 + m),\r\n            mcon = m,\r\n            nact = 0,\r\n            icon, resmax,\r\n            i, k, first, optold, icount,\r\n            step, stpful, optnew, ratio,\r\n            isave, vsave, total,\r\n            kp, kk, sp, alpha, beta, tot, spabs,\r\n            acca, accb, zdotv, zdvabs, kw,\r\n            dd, ss, sd,\r\n            zdotw, zdwabs, kl, sumabs, tempa,\r\n            endless = true;\r\n\r\n        for (i = 1; i <= n; ++i) {\r\n            z[i][i] = 1.0;\r\n            dx[i] = 0.0;\r\n        }\r\n\r\n        icon = 0;\r\n        resmax = 0.0;\r\n        if (m >= 1) {\r\n            for (k = 1; k <= m; ++k) {\r\n                if (b[k] > resmax) {\r\n                    resmax = b[k];\r\n                    icon = k;\r\n                }\r\n            }\r\n            for (k = 1; k <= m; ++k) {\r\n                iact[k] = k;\r\n                vmultc[k] = resmax - b[k];\r\n            }\r\n        }\r\n\r\n        //     End the current stage of the calculation if 3 consecutive iterations\r\n        //     have either failed to reduce the best calculated value of the objective\r\n        //     function or to increase the number of active constraints since the best\r\n        //     value was calculated. This strategy prevents cycling, but there is a\r\n        //     remote possibility that it will cause premature termination.\r\n\r\n        first = true;\r\n        do {\r\n            L_60: do {\r\n                if (!first || (first && resmax === 0.0)) {\r\n                    mcon = m + 1;\r\n                    icon = mcon;\r\n                    iact[mcon] = mcon;\r\n                    vmultc[mcon] = 0.0;\r\n                }\r\n                first = false;\r\n\r\n                optold = 0.0;\r\n                icount = 0;\r\n                step = 0;\r\n                stpful = 0;\r\n\r\n                L_70: do {\r\n                    // optnew = (mcon === m) ? resmax : -this.DOT_PRODUCT(this.PART(dx, 1, n), this.PART(this.COL(a, mcon), 1, n));\r\n                    optnew =\r\n                        mcon === m ? resmax : -this.DOT_PRODUCT_ROW_COL(dx, -1, a, mcon, 1, n);\r\n\r\n                    if (icount === 0 || optnew < optold) {\r\n                        optold = optnew;\r\n                        nactx = nact;\r\n                        icount = 3;\r\n                    } else if (nact > nactx) {\r\n                        nactx = nact;\r\n                        icount = 3;\r\n                    } else {\r\n                        --icount;\r\n                    }\r\n                    if (icount === 0) {\r\n                        break L_60;\r\n                    }\r\n\r\n                    //     If ICON exceeds NACT, then we add the constraint with index IACT(ICON) to\r\n                    //     the active set. Apply Givens rotations so that the last N-NACT-1 columns\r\n                    //     of Z are orthogonal to the gradient of the new constraint, a scalar\r\n                    //     product being set to zero if its nonzero value could be due to computer\r\n                    //     rounding errors. The array DXNEW is used for working space.\r\n                    ratio = 0;\r\n                    if (icon <= nact) {\r\n                        if (icon < nact) {\r\n                            //     Delete the constraint that has the index IACT(ICON) from the active set.\r\n\r\n                            isave = iact[icon];\r\n                            vsave = vmultc[icon];\r\n                            k = icon;\r\n                            do {\r\n                                kp = k + 1;\r\n                                kk = iact[kp];\r\n                                sp = this.DOT_PRODUCT(\r\n                                    this.PART(this.COL(z, k), 1, n),\r\n                                    this.PART(this.COL(a, kk), 1, n)\r\n                                );\r\n                                temp = Mat.hypot(sp, zdota[kp]);\r\n                                alpha = zdota[kp] / temp;\r\n                                beta = sp / temp;\r\n                                zdota[kp] = alpha * zdota[k];\r\n                                zdota[k] = temp;\r\n                                for (i = 1; i <= n; ++i) {\r\n                                    temp = alpha * z[i][kp] + beta * z[i][k];\r\n                                    z[i][kp] = alpha * z[i][k] - beta * z[i][kp];\r\n                                    z[i][k] = temp;\r\n                                }\r\n                                iact[k] = kk;\r\n                                vmultc[k] = vmultc[kp];\r\n                                k = kp;\r\n                            } while (k < nact);\r\n\r\n                            iact[k] = isave;\r\n                            vmultc[k] = vsave;\r\n                        }\r\n                        --nact;\r\n\r\n                        //     If stage one is in progress, then set SDIRN to the direction of the next\r\n                        //     change to the current vector of variables.\r\n                        if (mcon > m) {\r\n                            //     Pick the next search direction of stage two.\r\n                            temp = 1.0 / zdota[nact];\r\n                            for (k = 1; k <= n; ++k) {\r\n                                sdirn[k] = temp * z[k][nact];\r\n                            }\r\n                        } else {\r\n                            // temp = this.DOT_PRODUCT(this.PART(sdirn, 1, n), this.PART(this.COL(z, nact + 1), 1, n));\r\n                            temp = this.DOT_PRODUCT_ROW_COL(sdirn, -1, z, nact + 1, 1, n);\r\n                            for (k = 1; k <= n; ++k) {\r\n                                sdirn[k] -= temp * z[k][nact + 1];\r\n                            }\r\n                        }\r\n                    } else {\r\n                        kk = iact[icon];\r\n                        for (k = 1; k <= n; ++k) {\r\n                            dxnew[k] = a[k][kk];\r\n                        }\r\n                        tot = 0.0;\r\n\r\n                        // {\r\n                        k = n;\r\n                        while (k > nact) {\r\n                            sp = 0.0;\r\n                            spabs = 0.0;\r\n                            for (i = 1; i <= n; ++i) {\r\n                                temp = z[i][k] * dxnew[i];\r\n                                sp += temp;\r\n                                spabs += Math.abs(temp);\r\n                            }\r\n                            acca = spabs + 0.1 * Math.abs(sp);\r\n                            accb = spabs + 0.2 * Math.abs(sp);\r\n                            if (spabs >= acca || acca >= accb) {\r\n                                sp = 0.0;\r\n                            }\r\n                            if (tot === 0.0) {\r\n                                tot = sp;\r\n                            } else {\r\n                                kp = k + 1;\r\n                                temp = Mat.hypot(sp, tot);\r\n                                alpha = sp / temp;\r\n                                beta = tot / temp;\r\n                                tot = temp;\r\n                                for (i = 1; i <= n; ++i) {\r\n                                    temp = alpha * z[i][k] + beta * z[i][kp];\r\n                                    z[i][kp] = alpha * z[i][kp] - beta * z[i][k];\r\n                                    z[i][k] = temp;\r\n                                }\r\n                            }\r\n                            --k;\r\n                        }\r\n                        // }\r\n\r\n                        if (tot === 0.0) {\r\n                            //     The next instruction is reached if a deletion has to be made from the\r\n                            //     active set in order to make room for the new active constraint, because\r\n                            //     the new constraint gradient is a linear combination of the gradients of\r\n                            //     the old active constraints.  Set the elements of VMULTD to the multipliers\r\n                            //     of the linear combination.  Further, set IOUT to the index of the\r\n                            //     constraint to be deleted, but branch if no suitable index can be found.\r\n\r\n                            ratio = -1.0;\r\n                            //{\r\n                            k = nact;\r\n                            do {\r\n                                zdotv = 0.0;\r\n                                zdvabs = 0.0;\r\n\r\n                                for (i = 1; i <= n; ++i) {\r\n                                    temp = z[i][k] * dxnew[i];\r\n                                    zdotv += temp;\r\n                                    zdvabs += Math.abs(temp);\r\n                                }\r\n                                acca = zdvabs + 0.1 * Math.abs(zdotv);\r\n                                accb = zdvabs + 0.2 * Math.abs(zdotv);\r\n                                if (zdvabs < acca && acca < accb) {\r\n                                    temp = zdotv / zdota[k];\r\n                                    if (temp > 0.0 && iact[k] <= m) {\r\n                                        tempa = vmultc[k] / temp;\r\n                                        if (ratio < 0.0 || tempa < ratio) {\r\n                                            ratio = tempa;\r\n                                        }\r\n                                    }\r\n\r\n                                    if (k >= 2) {\r\n                                        kw = iact[k];\r\n                                        for (i = 1; i <= n; ++i) {\r\n                                            dxnew[i] -= temp * a[i][kw];\r\n                                        }\r\n                                    }\r\n                                    vmultd[k] = temp;\r\n                                } else {\r\n                                    vmultd[k] = 0.0;\r\n                                }\r\n                            } while (--k > 0);\r\n                            //}\r\n                            if (ratio < 0.0) {\r\n                                break L_60;\r\n                            }\r\n\r\n                            //     Revise the Lagrange multipliers and reorder the active constraints so\r\n                            //     that the one to be replaced is at the end of the list. Also calculate the\r\n                            //     new value of ZDOTA(NACT) and branch if it is not acceptable.\r\n\r\n                            for (k = 1; k <= nact; ++k) {\r\n                                vmultc[k] = Math.max(0.0, vmultc[k] - ratio * vmultd[k]);\r\n                            }\r\n                            if (icon < nact) {\r\n                                isave = iact[icon];\r\n                                vsave = vmultc[icon];\r\n                                k = icon;\r\n                                do {\r\n                                    kp = k + 1;\r\n                                    kw = iact[kp];\r\n                                    sp = this.DOT_PRODUCT(\r\n                                        this.PART(this.COL(z, k), 1, n),\r\n                                        this.PART(this.COL(a, kw), 1, n)\r\n                                    );\r\n                                    temp = Mat.hypot(sp, zdota[kp]);\r\n                                    alpha = zdota[kp] / temp;\r\n                                    beta = sp / temp;\r\n                                    zdota[kp] = alpha * zdota[k];\r\n                                    zdota[k] = temp;\r\n                                    for (i = 1; i <= n; ++i) {\r\n                                        temp = alpha * z[i][kp] + beta * z[i][k];\r\n                                        z[i][kp] = alpha * z[i][k] - beta * z[i][kp];\r\n                                        z[i][k] = temp;\r\n                                    }\r\n                                    iact[k] = kw;\r\n                                    vmultc[k] = vmultc[kp];\r\n                                    k = kp;\r\n                                } while (k < nact);\r\n                                iact[k] = isave;\r\n                                vmultc[k] = vsave;\r\n                            }\r\n                            temp = this.DOT_PRODUCT(\r\n                                this.PART(this.COL(z, nact), 1, n),\r\n                                this.PART(this.COL(a, kk), 1, n)\r\n                            );\r\n                            if (temp === 0.0) {\r\n                                break L_60;\r\n                            }\r\n                            zdota[nact] = temp;\r\n                            vmultc[icon] = 0.0;\r\n                            vmultc[nact] = ratio;\r\n                        } else {\r\n                            //     Add the new constraint if this can be done without a deletion from the\r\n                            //     active set.\r\n\r\n                            ++nact;\r\n                            zdota[nact] = tot;\r\n                            vmultc[icon] = vmultc[nact];\r\n                            vmultc[nact] = 0.0;\r\n                        }\r\n\r\n                        //     Update IACT and ensure that the objective function continues to be\r\n                        //     treated as the last active constraint when MCON>M.\r\n\r\n                        iact[icon] = iact[nact];\r\n                        iact[nact] = kk;\r\n                        if (mcon > m && kk !== mcon) {\r\n                            k = nact - 1;\r\n                            sp = this.DOT_PRODUCT(\r\n                                this.PART(this.COL(z, k), 1, n),\r\n                                this.PART(this.COL(a, kk), 1, n)\r\n                            );\r\n                            temp = Mat.hypot(sp, zdota[nact]);\r\n                            alpha = zdota[nact] / temp;\r\n                            beta = sp / temp;\r\n                            zdota[nact] = alpha * zdota[k];\r\n                            zdota[k] = temp;\r\n                            for (i = 1; i <= n; ++i) {\r\n                                temp = alpha * z[i][nact] + beta * z[i][k];\r\n                                z[i][nact] = alpha * z[i][k] - beta * z[i][nact];\r\n                                z[i][k] = temp;\r\n                            }\r\n                            iact[nact] = iact[k];\r\n                            iact[k] = kk;\r\n                            temp = vmultc[k];\r\n                            vmultc[k] = vmultc[nact];\r\n                            vmultc[nact] = temp;\r\n                        }\r\n\r\n                        //     If stage one is in progress, then set SDIRN to the direction of the next\r\n                        //     change to the current vector of variables.\r\n                        if (mcon > m) {\r\n                            //     Pick the next search direction of stage two.\r\n                            temp = 1.0 / zdota[nact];\r\n                            for (k = 1; k <= n; ++k) {\r\n                                sdirn[k] = temp * z[k][nact];\r\n                            }\r\n                        } else {\r\n                            kk = iact[nact];\r\n                            // temp = (this.DOT_PRODUCT(this.PART(sdirn, 1, n),this.PART(this.COL(a, kk), 1, n)) - 1.0) / zdota[nact];\r\n                            temp =\r\n                                (this.DOT_PRODUCT_ROW_COL(sdirn, -1, a, kk, 1, n) - 1.0) /\r\n                                zdota[nact];\r\n                            for (k = 1; k <= n; ++k) {\r\n                                sdirn[k] -= temp * z[k][nact];\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    //     Calculate the step to the boundary of the trust region or take the step\r\n                    //     that reduces RESMAX to zero. The two statements below that include the\r\n                    //     factor 1.0E-6 prevent some harmless underflows that occurred in a test\r\n                    //     calculation. Further, we skip the step if it could be zero within a\r\n                    //     reasonable tolerance for computer rounding errors.\r\n                    dd = rho * rho;\r\n                    sd = 0.0;\r\n                    ss = 0.0;\r\n                    for (i = 1; i <= n; ++i) {\r\n                        if (Math.abs(dx[i]) >= 1.0e-6 * rho) {\r\n                            dd -= dx[i] * dx[i];\r\n                        }\r\n                        sd += dx[i] * sdirn[i];\r\n                        ss += sdirn[i] * sdirn[i];\r\n                    }\r\n                    if (dd <= 0.0) {\r\n                        break L_60;\r\n                    }\r\n                    temp = Math.sqrt(ss * dd);\r\n                    if (Math.abs(sd) >= 1.0e-6 * temp) {\r\n                        temp = Math.sqrt(ss * dd + sd * sd);\r\n                    }\r\n                    stpful = dd / (temp + sd);\r\n                    step = stpful;\r\n                    if (mcon === m) {\r\n                        acca = step + 0.1 * resmax;\r\n                        accb = step + 0.2 * resmax;\r\n                        if (step >= acca || acca >= accb) {\r\n                            break L_70;\r\n                        }\r\n                        step = Math.min(step, resmax);\r\n                    }\r\n\r\n                    //     Set DXNEW to the new variables if STEP is the steplength, and reduce\r\n                    //     RESMAX to the corresponding maximum residual if stage one is being done.\r\n                    //     Because DXNEW will be changed during the calculation of some Lagrange\r\n                    //     multipliers, it will be restored to the following value later.\r\n                    for (k = 1; k <= n; ++k) {\r\n                        dxnew[k] = dx[k] + step * sdirn[k];\r\n                    }\r\n                    if (mcon === m) {\r\n                        resold = resmax;\r\n                        resmax = 0.0;\r\n                        for (k = 1; k <= nact; ++k) {\r\n                            kk = iact[k];\r\n                            // temp = b[kk] - this.DOT_PRODUCT(this.PART(this.COL(a, kk), 1, n), this.PART(dxnew, 1, n));\r\n                            temp = b[kk] - this.DOT_PRODUCT_ROW_COL(dxnew, -1, a, kk, 1, n);\r\n                            resmax = Math.max(resmax, temp);\r\n                        }\r\n                    }\r\n\r\n                    //     Set VMULTD to the VMULTC vector that would occur if DX became DXNEW. A\r\n                    //     device is included to force VMULTD(K) = 0.0 if deviations from this value\r\n                    //     can be attributed to computer rounding errors. First calculate the new\r\n                    //     Lagrange multipliers.\r\n                    //{\r\n                    k = nact;\r\n                    do {\r\n                        zdotw = 0.0;\r\n                        zdwabs = 0.0;\r\n                        for (i = 1; i <= n; ++i) {\r\n                            temp = z[i][k] * dxnew[i];\r\n                            zdotw += temp;\r\n                            zdwabs += Math.abs(temp);\r\n                        }\r\n                        acca = zdwabs + 0.1 * Math.abs(zdotw);\r\n                        accb = zdwabs + 0.2 * Math.abs(zdotw);\r\n                        if (zdwabs >= acca || acca >= accb) {\r\n                            zdotw = 0.0;\r\n                        }\r\n                        vmultd[k] = zdotw / zdota[k];\r\n                        if (k >= 2) {\r\n                            kk = iact[k];\r\n                            for (i = 1; i <= n; ++i) {\r\n                                dxnew[i] -= vmultd[k] * a[i][kk];\r\n                            }\r\n                        }\r\n                    } while (k-- >= 2);\r\n                    if (mcon > m) {\r\n                        vmultd[nact] = Math.max(0.0, vmultd[nact]);\r\n                    }\r\n                    //}\r\n\r\n                    //     Complete VMULTC by finding the new constraint residuals.\r\n\r\n                    for (k = 1; k <= n; ++k) {\r\n                        dxnew[k] = dx[k] + step * sdirn[k];\r\n                    }\r\n                    if (mcon > nact) {\r\n                        kl = nact + 1;\r\n                        for (k = kl; k <= mcon; ++k) {\r\n                            kk = iact[k];\r\n                            total = resmax - b[kk];\r\n                            sumabs = resmax + Math.abs(b[kk]);\r\n                            for (i = 1; i <= n; ++i) {\r\n                                temp = a[i][kk] * dxnew[i];\r\n                                total += temp;\r\n                                sumabs += Math.abs(temp);\r\n                            }\r\n                            acca = sumabs + 0.1 * Math.abs(total);\r\n                            accb = sumabs + 0.2 * Math.abs(total);\r\n                            if (sumabs >= acca || acca >= accb) {\r\n                                total = 0.0;\r\n                            }\r\n                            vmultd[k] = total;\r\n                        }\r\n                    }\r\n\r\n                    //     Calculate the fraction of the step from DX to DXNEW that will be taken.\r\n\r\n                    ratio = 1.0;\r\n                    icon = 0;\r\n                    for (k = 1; k <= mcon; ++k) {\r\n                        if (vmultd[k] < 0.0) {\r\n                            temp = vmultc[k] / (vmultc[k] - vmultd[k]);\r\n                            if (temp < ratio) {\r\n                                ratio = temp;\r\n                                icon = k;\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    //     Update DX, VMULTC and RESMAX.\r\n\r\n                    temp = 1.0 - ratio;\r\n                    for (k = 1; k <= n; ++k) {\r\n                        dx[k] = temp * dx[k] + ratio * dxnew[k];\r\n                    }\r\n                    for (k = 1; k <= mcon; ++k) {\r\n                        vmultc[k] = Math.max(0.0, temp * vmultc[k] + ratio * vmultd[k]);\r\n                    }\r\n                    if (mcon === m) {\r\n                        resmax = resold + ratio * (resmax - resold);\r\n                    }\r\n\r\n                    //     If the full step is not acceptable then begin another iteration.\r\n                    //     Otherwise switch to stage two or end the calculation.\r\n                } while (icon > 0);\r\n\r\n                if (step === stpful) {\r\n                    return true;\r\n                }\r\n            } while (endless);\r\n\r\n            //     We employ any freedom that may be available to reduce the objective\r\n            //     function before returning a DX whose length is less than RHO.\r\n        } while (mcon === m);\r\n\r\n        return false;\r\n    },\r\n\r\n    PrintIterationResult: function (nfvals, f, resmax, x, n, iprint) {\r\n        if (iprint > 1) {\r\n            console.log(\"NFVALS = \" + nfvals + \"  F = \" + f + \"  MAXCV = \" + resmax);\r\n        }\r\n        if (iprint > 1) {\r\n            console.log(\"X = \" + this.PART(x, 1, n));\r\n        }\r\n    },\r\n\r\n    ROW: function (src, rowidx) {\r\n        return src[rowidx].slice();\r\n        // var col,\r\n        //     cols = src[0].length,\r\n        //     dest = this.arr(cols);\r\n\r\n        // for (col = 0; col < cols; ++col) {\r\n        //     dest[col] = src[rowidx][col];\r\n        // }\r\n        // return dest;\r\n    },\r\n\r\n    COL: function (src, colidx) {\r\n        var row,\r\n            rows = src.length,\r\n            dest = []; // this.arr(rows);\r\n\r\n        for (row = 0; row < rows; ++row) {\r\n            dest[row] = src[row][colidx];\r\n        }\r\n        return dest;\r\n    },\r\n\r\n    PART: function (src, from, to) {\r\n        return src.slice(from, to + 1);\r\n        // var srcidx,\r\n        //     dest = this.arr(to - from + 1),\r\n        //     destidx = 0;\r\n        // for (srcidx = from; srcidx <= to; ++srcidx, ++destidx) {\r\n        //     dest[destidx] = src[srcidx];\r\n        // }\r\n        // return dest;\r\n    },\r\n\r\n    FORMAT: function (x) {\r\n        return x.join(\",\");\r\n        // var i, fmt = \"\";\r\n        // for (i = 0; i < x.length; ++i) {\r\n        //     fmt += \", \" + x[i];\r\n        // }\r\n        // return fmt;\r\n    },\r\n\r\n    DOT_PRODUCT: function (lhs, rhs) {\r\n        var i,\r\n            sum = 0.0,\r\n            len = lhs.length;\r\n        for (i = 0; i < len; ++i) {\r\n            sum += lhs[i] * rhs[i];\r\n        }\r\n        return sum;\r\n    },\r\n\r\n    DOT_PRODUCT_ROW_COL: function (lhs, row, rhs, col, start, end) {\r\n        var i,\r\n            sum = 0.0;\r\n\r\n        if (row === -1) {\r\n            // lhs is vector\r\n            for (i = start; i <= end; ++i) {\r\n                sum += lhs[i] * rhs[i][col];\r\n            }\r\n        } else {\r\n            // lhs is row of matrix\r\n            if (col === -1) {\r\n                // rhs is vector\r\n                for (i = start; i <= end; ++i) {\r\n                    sum += lhs[row][i] * rhs[i];\r\n                }\r\n            } else {\r\n                // rhs is column of matrix\r\n                for (i = start; i <= end; ++i) {\r\n                    sum += lhs[row][i] * rhs[i][col];\r\n                }\r\n            }\r\n        }\r\n\r\n        return sum;\r\n    }\r\n};\r\n\r\nexport default JXG.Math.Nlp;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Coords from \"../base/coords.js\";\r\nimport Mat from \"./math.js\";\r\nimport Extrapolate from \"./extrapolate.js\";\r\nimport Numerics from \"./numerics.js\";\r\nimport Statistics from \"./statistics.js\";\r\nimport Geometry from \"./geometry.js\";\r\nimport IntervalArithmetic from \"./ia.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Functions for plotting of curves.\r\n * @name JXG.Math.Plot\r\n * @exports Mat.Plot as JXG.Math.Plot\r\n * @namespace\r\n */\r\nMat.Plot = {\r\n    /**\r\n     * Check if at least one point on the curve is finite and real.\r\n     **/\r\n    checkReal: function (points) {\r\n        var b = false,\r\n            i,\r\n            p,\r\n            len = points.length;\r\n\r\n        for (i = 0; i < len; i++) {\r\n            p = points[i].usrCoords;\r\n            if (!isNaN(p[1]) && !isNaN(p[2]) && Math.abs(p[0]) > Mat.eps) {\r\n                b = true;\r\n                break;\r\n            }\r\n        }\r\n        return b;\r\n    },\r\n\r\n    //----------------------------------------------------------------------\r\n    // Plot algorithm v0\r\n    //----------------------------------------------------------------------\r\n    /**\r\n     * Updates the data points of a parametric curve. This version is used if {@link JXG.Curve#doadvancedplot} is <tt>false</tt>.\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {Number} mi Left bound of curve\r\n     * @param {Number} ma Right bound of curve\r\n     * @param {Number} len Number of data points\r\n     * @returns {JXG.Curve} Reference to the curve object.\r\n     */\r\n    updateParametricCurveNaive: function (curve, mi, ma, len) {\r\n        var i,\r\n            t,\r\n            suspendUpdate = false,\r\n            stepSize = (ma - mi) / len;\r\n\r\n        for (i = 0; i < len; i++) {\r\n            t = mi + i * stepSize;\r\n            // The last parameter prevents rounding in usr2screen().\r\n            curve.points[i].setCoordinates(\r\n                Const.COORDS_BY_USER,\r\n                [curve.X(t, suspendUpdate), curve.Y(t, suspendUpdate)],\r\n                false\r\n            );\r\n            curve.points[i]._t = t;\r\n            suspendUpdate = true;\r\n        }\r\n        return curve;\r\n    },\r\n\r\n    //----------------------------------------------------------------------\r\n    // Plot algorithm v1\r\n    //----------------------------------------------------------------------\r\n    /**\r\n     * Crude and cheap test if the segment defined by the two points <tt>(x0, y0)</tt> and <tt>(x1, y1)</tt> is\r\n     * outside the viewport of the board. All parameters have to be given in screen coordinates.\r\n     *\r\n     * @private\r\n     * @deprecated\r\n     * @param {Number} x0\r\n     * @param {Number} y0\r\n     * @param {Number} x1\r\n     * @param {Number} y1\r\n     * @param {JXG.Board} board\r\n     * @returns {Boolean} <tt>true</tt> if the given segment is outside the visible area.\r\n     */\r\n    isSegmentOutside: function (x0, y0, x1, y1, board) {\r\n        return (\r\n            (y0 < 0 && y1 < 0) ||\r\n            (y0 > board.canvasHeight && y1 > board.canvasHeight) ||\r\n            (x0 < 0 && x1 < 0) ||\r\n            (x0 > board.canvasWidth && x1 > board.canvasWidth)\r\n        );\r\n    },\r\n\r\n    /**\r\n     * Compares the absolute value of <tt>dx</tt> with <tt>MAXX</tt> and the absolute value of <tt>dy</tt>\r\n     * with <tt>MAXY</tt>.\r\n     *\r\n     * @private\r\n     * @deprecated\r\n     * @param {Number} dx\r\n     * @param {Number} dy\r\n     * @param {Number} MAXX\r\n     * @param {Number} MAXY\r\n     * @returns {Boolean} <tt>true</tt>, if <tt>|dx| &lt; MAXX</tt> and <tt>|dy| &lt; MAXY</tt>.\r\n     */\r\n    isDistOK: function (dx, dy, MAXX, MAXY) {\r\n        return Math.abs(dx) < MAXX && Math.abs(dy) < MAXY && !isNaN(dx + dy);\r\n    },\r\n\r\n    /**\r\n     * @private\r\n     * @deprecated\r\n     */\r\n    isSegmentDefined: function (x0, y0, x1, y1) {\r\n        return !(isNaN(x0 + y0) && isNaN(x1 + y1));\r\n    },\r\n\r\n    /**\r\n     * Updates the data points of a parametric curve. This version is used if {@link JXG.Curve#doadvancedplot} is <tt>true</tt>.\r\n     * Since 0.99 this algorithm is deprecated. It still can be used if {@link JXG.Curve#doadvancedplotold} is <tt>true</tt>.\r\n     *\r\n     * @deprecated\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {Number} mi Left bound of curve\r\n     * @param {Number} ma Right bound of curve\r\n     * @returns {JXG.Curve} Reference to the curve object.\r\n     */\r\n    updateParametricCurveOld: function (curve, mi, ma) {\r\n        var i, t, d, x, y,\r\n            x0, y0,// t0,\r\n            top,\r\n            depth,\r\n            MAX_DEPTH,\r\n            MAX_XDIST,\r\n            MAX_YDIST,\r\n            suspendUpdate = false,\r\n            po = new Coords(Const.COORDS_BY_USER, [0, 0], curve.board, false),\r\n            dyadicStack = [],\r\n            depthStack = [],\r\n            pointStack = [],\r\n            divisors = [],\r\n            distOK = false,\r\n            j = 0,\r\n            distFromLine = function (p1, p2, p0) {\r\n                var lbda,\r\n                    x0 = p0[1] - p1[1],\r\n                    y0 = p0[2] - p1[2],\r\n                    x1 = p2[0] - p1[1],\r\n                    y1 = p2[1] - p1[2],\r\n                    den = x1 * x1 + y1 * y1;\r\n\r\n                if (den >= Mat.eps) {\r\n                    lbda = (x0 * x1 + y0 * y1) / den;\r\n                    if (lbda > 0) {\r\n                        if (lbda <= 1) {\r\n                            x0 -= lbda * x1;\r\n                            y0 -= lbda * y1;\r\n                            // lbda = 1.0;\r\n                        } else {\r\n                            x0 -= x1;\r\n                            y0 -= y1;\r\n                        }\r\n                    }\r\n                }\r\n                return Mat.hypot(x0, y0);\r\n            };\r\n\r\n        JXG.deprecated(\"Curve.updateParametricCurveOld()\");\r\n\r\n        if (curve.board.updateQuality === curve.board.BOARD_QUALITY_LOW) {\r\n            MAX_DEPTH = 15;\r\n            MAX_XDIST = 10; // 10\r\n            MAX_YDIST = 10; // 10\r\n        } else {\r\n            MAX_DEPTH = 21;\r\n            MAX_XDIST = 0.7; // 0.7\r\n            MAX_YDIST = 0.7; // 0.7\r\n        }\r\n\r\n        divisors[0] = ma - mi;\r\n        for (i = 1; i < MAX_DEPTH; i++) {\r\n            divisors[i] = divisors[i - 1] * 0.5;\r\n        }\r\n\r\n        i = 1;\r\n        dyadicStack[0] = 1;\r\n        depthStack[0] = 0;\r\n\r\n        t = mi;\r\n        po.setCoordinates(\r\n            Const.COORDS_BY_USER,\r\n            [curve.X(t, suspendUpdate), curve.Y(t, suspendUpdate)],\r\n            false\r\n        );\r\n\r\n        // Now, there was a first call to the functions defining the curve.\r\n        // Defining elements like sliders have been evaluated.\r\n        // Therefore, we can set suspendUpdate to false, so that these defining elements\r\n        // need not be evaluated anymore for the rest of the plotting.\r\n        suspendUpdate = true;\r\n        x0 = po.scrCoords[1];\r\n        y0 = po.scrCoords[2];\r\n        // t0 = t;\r\n\r\n        t = ma;\r\n        po.setCoordinates(\r\n            Const.COORDS_BY_USER,\r\n            [curve.X(t, suspendUpdate), curve.Y(t, suspendUpdate)],\r\n            false\r\n        );\r\n        x = po.scrCoords[1];\r\n        y = po.scrCoords[2];\r\n\r\n        pointStack[0] = [x, y];\r\n\r\n        top = 1;\r\n        depth = 0;\r\n\r\n        curve.points = [];\r\n        curve.points[j++] = new Coords(Const.COORDS_BY_SCREEN, [x0, y0], curve.board, false);\r\n\r\n        do {\r\n            distOK =\r\n                this.isDistOK(x - x0, y - y0, MAX_XDIST, MAX_YDIST) ||\r\n                this.isSegmentOutside(x0, y0, x, y, curve.board);\r\n            while (\r\n                depth < MAX_DEPTH &&\r\n                (!distOK || depth < 6) &&\r\n                (depth <= 7 || this.isSegmentDefined(x0, y0, x, y))\r\n            ) {\r\n                // We jump out of the loop if\r\n                // * depth>=MAX_DEPTH or\r\n                // * (depth>=6 and distOK) or\r\n                // * (depth>7 and segment is not defined)\r\n\r\n                dyadicStack[top] = i;\r\n                depthStack[top] = depth;\r\n                pointStack[top] = [x, y];\r\n                top += 1;\r\n\r\n                i = 2 * i - 1;\r\n                // Here, depth is increased and may reach MAX_DEPTH\r\n                depth++;\r\n                // In that case, t is undefined and we will see a jump in the curve.\r\n                t = mi + i * divisors[depth];\r\n\r\n                po.setCoordinates(\r\n                    Const.COORDS_BY_USER,\r\n                    [curve.X(t, suspendUpdate), curve.Y(t, suspendUpdate)],\r\n                    false,\r\n                    true\r\n                );\r\n                x = po.scrCoords[1];\r\n                y = po.scrCoords[2];\r\n                distOK =\r\n                    this.isDistOK(x - x0, y - y0, MAX_XDIST, MAX_YDIST) ||\r\n                    this.isSegmentOutside(x0, y0, x, y, curve.board);\r\n            }\r\n\r\n            if (j > 1) {\r\n                d = distFromLine(\r\n                    curve.points[j - 2].scrCoords,\r\n                    [x, y],\r\n                    curve.points[j - 1].scrCoords\r\n                );\r\n                if (d < 0.015) {\r\n                    j -= 1;\r\n                }\r\n            }\r\n\r\n            curve.points[j] = new Coords(Const.COORDS_BY_SCREEN, [x, y], curve.board, false);\r\n            curve.points[j]._t = t;\r\n            j += 1;\r\n\r\n            x0 = x;\r\n            y0 = y;\r\n            // t0 = t;\r\n\r\n            top -= 1;\r\n            x = pointStack[top][0];\r\n            y = pointStack[top][1];\r\n            depth = depthStack[top] + 1;\r\n            i = dyadicStack[top] * 2;\r\n        } while (top > 0 && j < 500000);\r\n\r\n        curve.numberPoints = curve.points.length;\r\n\r\n        return curve;\r\n    },\r\n\r\n    //----------------------------------------------------------------------\r\n    // Plot algorithm v2\r\n    //----------------------------------------------------------------------\r\n\r\n    /**\r\n     * Add a point to the curve plot. If the new point is too close to the previously inserted point,\r\n     * it is skipped.\r\n     * Used in {@link JXG.Curve._plotRecursive}.\r\n     *\r\n     * @private\r\n     * @param {JXG.Coords} pnt Coords to add to the list of points\r\n     */\r\n    _insertPoint_v2: function (curve, pnt, t) {\r\n        var lastReal = !isNaN(this._lastCrds[1] + this._lastCrds[2]), // The last point was real\r\n            newReal = !isNaN(pnt.scrCoords[1] + pnt.scrCoords[2]), // New point is real point\r\n            cw = curve.board.canvasWidth,\r\n            ch = curve.board.canvasHeight,\r\n            off = 500;\r\n\r\n        newReal =\r\n            newReal &&\r\n            pnt.scrCoords[1] > -off &&\r\n            pnt.scrCoords[2] > -off &&\r\n            pnt.scrCoords[1] < cw + off &&\r\n            pnt.scrCoords[2] < ch + off;\r\n\r\n        /*\r\n         * Prevents two consecutive NaNs or points wich are too close\r\n         */\r\n        if (\r\n            (!newReal && lastReal) ||\r\n            (newReal &&\r\n                (!lastReal ||\r\n                    Math.abs(pnt.scrCoords[1] - this._lastCrds[1]) > 0.7 ||\r\n                    Math.abs(pnt.scrCoords[2] - this._lastCrds[2]) > 0.7))\r\n        ) {\r\n            pnt._t = t;\r\n            curve.points.push(pnt);\r\n            this._lastCrds = pnt.copy('scrCoords');\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Check if there is a single NaN function value at t0.\r\n     * @param {*} curve\r\n     * @param {*} t0\r\n     * @returns {Boolean} true if there is a second NaN point close by, false otherwise\r\n     */\r\n    neighborhood_isNaN_v2: function (curve, t0) {\r\n        var is_undef,\r\n            pnt = new Coords(Const.COORDS_BY_USER, [0, 0], curve.board, false),\r\n            t,\r\n            p;\r\n\r\n        t = t0 + Mat.eps;\r\n        pnt.setCoordinates(Const.COORDS_BY_USER, [curve.X(t, true), curve.Y(t, true)], false);\r\n        p = pnt.usrCoords;\r\n        is_undef = isNaN(p[1] + p[2]);\r\n        if (!is_undef) {\r\n            t = t0 - Mat.eps;\r\n            pnt.setCoordinates(\r\n                Const.COORDS_BY_USER,\r\n                [curve.X(t, true), curve.Y(t, true)],\r\n                false\r\n            );\r\n            p = pnt.usrCoords;\r\n            is_undef = isNaN(p[1] + p[2]);\r\n            if (!is_undef) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    },\r\n\r\n    /**\r\n     * Investigate a function term at the bounds of intervals where\r\n     * the function is not defined, e.g. log(x) at x = 0.\r\n     *\r\n     * c is between a and b\r\n     * @private\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {Array} a Screen coordinates of the left interval bound\r\n     * @param {Array} b Screen coordinates of the right interval bound\r\n     * @param {Array} c Screen coordinates of the bisection point at (ta + tb) / 2\r\n     * @param {Number} ta Parameter which evaluates to a, i.e. [1, X(ta), Y(ta)] = a in screen coordinates\r\n     * @param {Number} tb Parameter which evaluates to b, i.e. [1, X(tb), Y(tb)] = b in screen coordinates\r\n     * @param {Number} tc (ta + tb) / 2 = tc. Parameter which evaluates to b, i.e. [1, X(tc), Y(tc)] = c in screen coordinates\r\n     * @param {Number} depth Actual recursion depth. The recursion stops if depth is equal to 0.\r\n     * @returns {JXG.Boolean} true if the point is inserted and the recursion should stop, false otherwise.\r\n     */\r\n    _borderCase: function (curve, a, b, c, ta, tb, tc, depth) {\r\n        var t, pnt, p,\r\n            p_good = null,\r\n            j,\r\n            max_it = 30,\r\n            is_undef = false,\r\n            t_nan, t_real;// t_real2;\r\n            // dx, dy,\r\n            // vx, vy, vx2, vy2;\r\n        // asymptote;\r\n\r\n        if (depth <= 1) {\r\n            pnt = new Coords(Const.COORDS_BY_USER, [0, 0], curve.board, false);\r\n            // Test if there is a single undefined point.\r\n            // If yes, we ignore it.\r\n            if (\r\n                isNaN(a[1] + a[2]) &&\r\n                !isNaN(c[1] + c[2]) &&\r\n                !this.neighborhood_isNaN_v2(curve, ta)\r\n            ) {\r\n                return false;\r\n            }\r\n            if (\r\n                isNaN(b[1] + b[2]) &&\r\n                !isNaN(c[1] + c[2]) &&\r\n                !this.neighborhood_isNaN_v2(curve, tb)\r\n            ) {\r\n                return false;\r\n            }\r\n            if (\r\n                isNaN(c[1] + c[2]) &&\r\n                (!isNaN(a[1] + a[2]) || !isNaN(b[1] + b[2])) &&\r\n                !this.neighborhood_isNaN_v2(curve, tc)\r\n            ) {\r\n                return false;\r\n            }\r\n\r\n            j = 0;\r\n            // Bisect a, b and c until the point t_real is inside of the definition interval\r\n            // and as close as possible at the boundary.\r\n            // t_real2 is the second closest point.\r\n            do {\r\n                // There are four cases:\r\n                //  a  |  c  |  b\r\n                // ---------------\r\n                // inf | R   | R\r\n                // R   | R   | inf\r\n                // inf | inf | R\r\n                // R   | inf | inf\r\n                //\r\n                if (isNaN(a[1] + a[2]) && !isNaN(c[1] + c[2])) {\r\n                    t_nan = ta;\r\n                    t_real = tc;\r\n                    // t_real2 = tb;\r\n                } else if (isNaN(b[1] + b[2]) && !isNaN(c[1] + c[2])) {\r\n                    t_nan = tb;\r\n                    t_real = tc;\r\n                    // t_real2 = ta;\r\n                } else if (isNaN(c[1] + c[2]) && !isNaN(b[1] + b[2])) {\r\n                    t_nan = tc;\r\n                    t_real = tb;\r\n                    // t_real2 = tb + (tb - tc);\r\n                } else if (isNaN(c[1] + c[2]) && !isNaN(a[1] + a[2])) {\r\n                    t_nan = tc;\r\n                    t_real = ta;\r\n                    // t_real2 = ta - (tc - ta);\r\n                } else {\r\n                    return false;\r\n                }\r\n                t = 0.5 * (t_nan + t_real);\r\n                pnt.setCoordinates(\r\n                    Const.COORDS_BY_USER,\r\n                    [curve.X(t, true), curve.Y(t, true)],\r\n                    false\r\n                );\r\n                p = pnt.usrCoords;\r\n\r\n                is_undef = isNaN(p[1] + p[2]);\r\n                if (is_undef) {\r\n                    t_nan = t;\r\n                } else {\r\n                    // t_real2 = t_real;\r\n                    t_real = t;\r\n                }\r\n                ++j;\r\n            } while (is_undef && j < max_it);\r\n\r\n            // If bisection was successful, take this point.\r\n            // Useful only for general curves, for function graph\r\n            // the code below overwrite p_good from here.\r\n            if (j < max_it) {\r\n                p_good = p.slice();\r\n                c = p.slice();\r\n                t_real = t;\r\n            }\r\n\r\n            // OK, bisection has been done now.\r\n            // t_real contains the closest inner point to the border of the interval we could find.\r\n            // t_real2 is the second nearest point to this boundary.\r\n            // Now we approximate the derivative by computing the slope of the line through these two points\r\n            // and test if it is \"infinite\", i.e larger than 400 in absolute values.\r\n            //\r\n            // vx = curve.X(t_real, true);\r\n            // vx2 = curve.X(t_real2, true);\r\n            // vy = curve.Y(t_real, true);\r\n            // vy2 = curve.Y(t_real2, true);\r\n            // dx = (vx - vx2) / (t_real - t_real2);\r\n            // dy = (vy - vy2) / (t_real - t_real2);\r\n\r\n            if (p_good !== null) {\r\n                this._insertPoint_v2(\r\n                    curve,\r\n                    new Coords(Const.COORDS_BY_USER, p_good, curve.board, false)\r\n                );\r\n                return true;\r\n            }\r\n        }\r\n        return false;\r\n    },\r\n\r\n    /**\r\n     * Recursive interval bisection algorithm for curve plotting.\r\n     * Used in {@link JXG.Curve.updateParametricCurve}.\r\n     * @private\r\n     * @deprecated\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {Array} a Screen coordinates of the left interval bound\r\n     * @param {Number} ta Parameter which evaluates to a, i.e. [1, X(ta), Y(ta)] = a in screen coordinates\r\n     * @param {Array} b Screen coordinates of the right interval bound\r\n     * @param {Number} tb Parameter which evaluates to b, i.e. [1, X(tb), Y(tb)] = b in screen coordinates\r\n     * @param {Number} depth Actual recursion depth. The recursion stops if depth is equal to 0.\r\n     * @param {Number} delta If the distance of the bisection point at (ta + tb) / 2 from the point (a + b) / 2 is less then delta,\r\n     *                 the segment [a,b] is regarded as straight line.\r\n     * @returns {JXG.Curve} Reference to the curve object.\r\n     */\r\n    _plotRecursive_v2: function (curve, a, ta, b, tb, depth, delta) {\r\n        var tc,\r\n            c,\r\n            ds,\r\n            mindepth = 0,\r\n            isSmooth,\r\n            isJump,\r\n            isCusp,\r\n            cusp_threshold = 0.5,\r\n            jump_threshold = 0.99,\r\n            pnt = new Coords(Const.COORDS_BY_USER, [0, 0], curve.board, false);\r\n\r\n        if (curve.numberPoints > 65536) {\r\n            return;\r\n        }\r\n\r\n        // Test if the function is undefined in an interval\r\n        if (depth < this.nanLevel && this._isUndefined(curve, a, ta, b, tb)) {\r\n            return this;\r\n        }\r\n\r\n        if (depth < this.nanLevel && this._isOutside(a, ta, b, tb, curve.board)) {\r\n            return this;\r\n        }\r\n\r\n        tc = (ta + tb) * 0.5;\r\n        pnt.setCoordinates(Const.COORDS_BY_USER, [curve.X(tc, true), curve.Y(tc, true)], false);\r\n        c = pnt.scrCoords;\r\n\r\n        if (this._borderCase(curve, a, b, c, ta, tb, tc, depth)) {\r\n            return this;\r\n        }\r\n\r\n        ds = this._triangleDists(a, b, c); // returns [d_ab, d_ac, d_cb, d_cd]\r\n\r\n        isSmooth = depth < this.smoothLevel && ds[3] < delta;\r\n\r\n        isJump =\r\n            (\r\n                depth <= this.jumpLevel && (isNaN(ds[0]) || isNaN(ds[1]) || isNaN(ds[2]))\r\n            ) || (\r\n                depth < this.jumpLevel &&\r\n                (\r\n                    ds[2] > jump_threshold * ds[0] ||\r\n                    ds[1] > jump_threshold * ds[0] ||\r\n                    ds[0] === Infinity ||\r\n                    ds[1] === Infinity ||\r\n                    ds[2] === Infinity\r\n                )\r\n            );\r\n\r\n        isCusp = depth < this.smoothLevel + 2 && ds[0] < cusp_threshold * (ds[1] + ds[2]);\r\n\r\n        if (isCusp) {\r\n            mindepth = 0;\r\n            isSmooth = false;\r\n        }\r\n\r\n        --depth;\r\n\r\n        if (isJump) {\r\n            this._insertPoint_v2(\r\n                curve,\r\n                new Coords(Const.COORDS_BY_SCREEN, [NaN, NaN], curve.board, false),\r\n                tc\r\n            );\r\n        } else if (depth <= mindepth || isSmooth) {\r\n            this._insertPoint_v2(curve, pnt, tc);\r\n            //if (this._borderCase(a, b, c, ta, tb, tc, depth)) {}\r\n        } else {\r\n            this._plotRecursive_v2(curve, a, ta, c, tc, depth, delta);\r\n\r\n            if (!isNaN(pnt.scrCoords[1] + pnt.scrCoords[2])) {\r\n                this._insertPoint_v2(curve, pnt, tc);\r\n            }\r\n\r\n            this._plotRecursive_v2(curve, c, tc, b, tb, depth, delta);\r\n        }\r\n\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * Updates the data points of a parametric curve. This version is used if {@link JXG.Curve#plotVersion} is <tt>3</tt>.\r\n     *\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {Number} mi Left bound of curve\r\n     * @param {Number} ma Right bound of curve\r\n     * @returns {JXG.Curve} Reference to the curve object.\r\n     */\r\n    updateParametricCurve_v2: function (curve, mi, ma) {\r\n        var ta, tb,\r\n            a, b,\r\n            suspendUpdate = false,\r\n            pa = new Coords(Const.COORDS_BY_USER, [0, 0], curve.board, false),\r\n            pb = new Coords(Const.COORDS_BY_USER, [0, 0], curve.board, false),\r\n            depth,\r\n            delta,\r\n            w2,\r\n            // h2,\r\n            bbox, ret_arr;\r\n\r\n        //console.time('plot');\r\n        if (curve.board.updateQuality === curve.board.BOARD_QUALITY_LOW) {\r\n            depth = curve.evalVisProp('recursiondepthlow') || 13;\r\n            delta = 2;\r\n            // this.smoothLevel = 5; //depth - 7;\r\n            this.smoothLevel = depth - 6;\r\n            this.jumpLevel = 3;\r\n        } else {\r\n            depth = curve.evalVisProp('recursiondepthhigh') || 17;\r\n            delta = 2;\r\n            // smoothLevel has to be small for graphs in a huge interval.\r\n            // this.smoothLevel = 3; //depth - 7; // 9\r\n            this.smoothLevel = depth - 9; // 9\r\n            this.jumpLevel = 2;\r\n        }\r\n        this.nanLevel = depth - 4;\r\n\r\n        curve.points = [];\r\n\r\n        if (this.xterm === 'x') {\r\n            // For function graphs we can restrict the plot interval\r\n            // to the visible area + plus margin\r\n            bbox = curve.board.getBoundingBox();\r\n            w2 = (bbox[2] - bbox[0]) * 0.3;\r\n            // h2 = (bbox[1] - bbox[3]) * 0.3;\r\n            ta = Math.max(mi, bbox[0] - w2);\r\n            tb = Math.min(ma, bbox[2] + w2);\r\n        } else {\r\n            ta = mi;\r\n            tb = ma;\r\n        }\r\n        pa.setCoordinates(\r\n            Const.COORDS_BY_USER,\r\n            [curve.X(ta, suspendUpdate), curve.Y(ta, suspendUpdate)],\r\n            false\r\n        );\r\n\r\n        // The first function calls of X() and Y() are done. We can now\r\n        // switch `suspendUpdate` on. If supported by the functions, this\r\n        // avoids for the rest of the plotting algorithm, evaluation of any\r\n        // parent elements.\r\n        suspendUpdate = true;\r\n\r\n        pb.setCoordinates(\r\n            Const.COORDS_BY_USER,\r\n            [curve.X(tb, suspendUpdate), curve.Y(tb, suspendUpdate)],\r\n            false\r\n        );\r\n\r\n        // Find start and end points of the visible area (plus a certain margin)\r\n        ret_arr = this._findStartPoint(curve, pa.scrCoords, ta, pb.scrCoords, tb);\r\n        pa.setCoordinates(Const.COORDS_BY_SCREEN, ret_arr[0], false);\r\n        ta = ret_arr[1];\r\n        ret_arr = this._findStartPoint(curve, pb.scrCoords, tb, pa.scrCoords, ta);\r\n        pb.setCoordinates(Const.COORDS_BY_SCREEN, ret_arr[0], false);\r\n        tb = ret_arr[1];\r\n\r\n        // Save the visible area.\r\n        // This can be used in Curve.hasPoint().\r\n        this._visibleArea = [ta, tb];\r\n\r\n        // Start recursive plotting algorithm\r\n        a = pa.copy('scrCoords');\r\n        b = pb.copy('scrCoords');\r\n        pa._t = ta;\r\n        curve.points.push(pa);\r\n        this._lastCrds = pa.copy('scrCoords'); // Used in _insertPoint\r\n        this._plotRecursive_v2(curve, a, ta, b, tb, depth, delta);\r\n        pb._t = tb;\r\n        curve.points.push(pb);\r\n\r\n        curve.numberPoints = curve.points.length;\r\n        //console.timeEnd('plot');\r\n\r\n        return curve;\r\n    },\r\n\r\n    //----------------------------------------------------------------------\r\n    // Plot algorithm v3\r\n    //----------------------------------------------------------------------\r\n    /**\r\n     *\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {*} pnt\r\n     * @param {*} t\r\n     * @param {*} depth\r\n     * @param {*} limes\r\n     * @private\r\n     */\r\n    _insertLimesPoint: function (curve, pnt, t, depth, limes) {\r\n        var p0, p1, p2;\r\n\r\n        // Ignore jump point if it follows limes\r\n        if (\r\n            (Math.abs(this._lastUsrCrds[1]) === Infinity &&\r\n                Math.abs(limes.left_x) === Infinity) ||\r\n            (Math.abs(this._lastUsrCrds[2]) === Infinity && Math.abs(limes.left_y) === Infinity)\r\n        ) {\r\n            // console.log(\"SKIP:\", pnt.usrCoords, this._lastUsrCrds, limes);\r\n            return;\r\n        }\r\n\r\n        // // Ignore jump left from limes\r\n        // if (Math.abs(limes.left_x) > 100 * Math.abs(this._lastUsrCrds[1])) {\r\n        //     x = Math.sign(limes.left_x) * Infinity;\r\n        // } else {\r\n        //     x = limes.left_x;\r\n        // }\r\n        // if (Math.abs(limes.left_y) > 100 * Math.abs(this._lastUsrCrds[2])) {\r\n        //     y = Math.sign(limes.left_y) * Infinity;\r\n        // } else {\r\n        //     y = limes.left_y;\r\n        // }\r\n        // //pnt.setCoordinates(Const.COORDS_BY_USER, [x, y], false);\r\n\r\n        // Add points at a jump. pnt contains [NaN, NaN]\r\n        //console.log(\"Add\", t, pnt.usrCoords, limes, depth)\r\n        p0 = new Coords(Const.COORDS_BY_USER, [limes.left_x, limes.left_y], curve.board);\r\n        p0._t = t;\r\n        curve.points.push(p0);\r\n\r\n        if (\r\n            !isNaN(limes.left_x) &&\r\n            !isNaN(limes.left_y) &&\r\n            !isNaN(limes.right_x) &&\r\n            !isNaN(limes.right_y) &&\r\n            (Math.abs(limes.left_x - limes.right_x) > Mat.eps ||\r\n                Math.abs(limes.left_y - limes.right_y) > Mat.eps)\r\n        ) {\r\n            p1 = new Coords(Const.COORDS_BY_SCREEN, pnt, curve.board);\r\n            p1._t = t;\r\n            curve.points.push(p1);\r\n        }\r\n\r\n        p2 = new Coords(Const.COORDS_BY_USER, [limes.right_x, limes.right_y], curve.board);\r\n        p2._t = t;\r\n        curve.points.push(p2);\r\n        this._lastScrCrds = p2.copy('scrCoords');\r\n        this._lastUsrCrds = p2.copy('usrCoords');\r\n    },\r\n\r\n    /**\r\n     * Add a point to the curve plot. If the new point is too close to the previously inserted point,\r\n     * it is skipped.\r\n     * Used in {@link JXG.Curve._plotRecursive}.\r\n     *\r\n     * @private\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {JXG.Coords} pnt Coords to add to the list of points\r\n     */\r\n    _insertPoint: function (curve, pnt, t, depth, limes) {\r\n        var last_is_real = !isNaN(this._lastScrCrds[1] + this._lastScrCrds[2]), // The last point was real\r\n            point_is_real = !isNaN(pnt[1] + pnt[2]), // New point is real point\r\n            cw = curve.board.canvasWidth,\r\n            ch = curve.board.canvasHeight,\r\n            p,\r\n            near = 0.8,\r\n            off = 500;\r\n\r\n        if (Type.exists(limes)) {\r\n            this._insertLimesPoint(curve, pnt, t, depth, limes);\r\n            return;\r\n        }\r\n\r\n        // Check if point has real coordinates and\r\n        // coordinates are not too far away from canvas.\r\n        point_is_real =\r\n            point_is_real &&\r\n            pnt[1] > -off &&\r\n            pnt[2] > -off &&\r\n            pnt[1] < cw + off &&\r\n            pnt[2] < ch + off;\r\n\r\n        // Prevent two consecutive NaNs\r\n        if (!last_is_real && !point_is_real) {\r\n            return;\r\n        }\r\n\r\n        // Prevent two consecutive points which are too close\r\n        if (\r\n            point_is_real &&\r\n            last_is_real &&\r\n            Math.abs(pnt[1] - this._lastScrCrds[1]) < near &&\r\n            Math.abs(pnt[2] - this._lastScrCrds[2]) < near\r\n        ) {\r\n            return;\r\n        }\r\n\r\n        // Prevent two consecutive points at infinity (either direction)\r\n        if (\r\n            (Math.abs(pnt[1]) === Infinity && Math.abs(this._lastUsrCrds[1]) === Infinity) ||\r\n            (Math.abs(pnt[2]) === Infinity && Math.abs(this._lastUsrCrds[2]) === Infinity)\r\n        ) {\r\n            return;\r\n        }\r\n\r\n        //console.log(\"add\", t, pnt.usrCoords, depth)\r\n        // Add regular point\r\n        p = new Coords(Const.COORDS_BY_SCREEN, pnt, curve.board);\r\n        p._t = t;\r\n        curve.points.push(p);\r\n        this._lastScrCrds = p.copy('scrCoords');\r\n        this._lastUsrCrds = p.copy('usrCoords');\r\n    },\r\n\r\n    /**\r\n     * Compute distances in screen coordinates between the points ab,\r\n     * ac, cb, and cd, where d = (a + b)/2.\r\n     * cd is used for the smoothness test, ab, ac, cb are used to detect jumps, cusps and poles.\r\n     *\r\n     * @private\r\n     * @param {Array} a Screen coordinates of the left interval bound\r\n     * @param {Array} b Screen coordinates of the right interval bound\r\n     * @param {Array} c Screen coordinates of the bisection point at (ta + tb) / 2\r\n     * @returns {Array} array of distances in screen coordinates between: ab, ac, cb, and cd.\r\n     */\r\n    _triangleDists: function (a, b, c) {\r\n        var d, d_ab, d_ac, d_cb, d_cd;\r\n\r\n        d = [a[0] * b[0], (a[1] + b[1]) * 0.5, (a[2] + b[2]) * 0.5];\r\n\r\n        d_ab = Geometry.distance(a, b, 3);\r\n        d_ac = Geometry.distance(a, c, 3);\r\n        d_cb = Geometry.distance(c, b, 3);\r\n        d_cd = Geometry.distance(c, d, 3);\r\n\r\n        return [d_ab, d_ac, d_cb, d_cd];\r\n    },\r\n\r\n    /**\r\n     * Test if the function is undefined on an interval:\r\n     * If the interval borders a and b are undefined, 20 random values\r\n     * are tested if they are undefined, too.\r\n     * Only if all values are undefined, we declare the function to be undefined in this interval.\r\n     *\r\n     * @private\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {Array} a Screen coordinates of the left interval bound\r\n     * @param {Number} ta Parameter which evaluates to a, i.e. [1, X(ta), Y(ta)] = a in screen coordinates\r\n     * @param {Array} b Screen coordinates of the right interval bound\r\n     * @param {Number} tb Parameter which evaluates to b, i.e. [1, X(tb), Y(tb)] = b in screen coordinates\r\n     */\r\n    _isUndefined: function (curve, a, ta, b, tb) {\r\n        var t, i, pnt;\r\n\r\n        if (!isNaN(a[1] + a[2]) || !isNaN(b[1] + b[2])) {\r\n            return false;\r\n        }\r\n\r\n        pnt = new Coords(Const.COORDS_BY_USER, [0, 0], curve.board, false);\r\n\r\n        for (i = 0; i < 20; ++i) {\r\n            t = ta + Math.random() * (tb - ta);\r\n            pnt.setCoordinates(\r\n                Const.COORDS_BY_USER,\r\n                [curve.X(t, true), curve.Y(t, true)],\r\n                false\r\n            );\r\n            if (!isNaN(pnt.scrCoords[0] + pnt.scrCoords[1] + pnt.scrCoords[2])) {\r\n                return false;\r\n            }\r\n        }\r\n\r\n        return true;\r\n    },\r\n\r\n    /**\r\n     * Decide if a path segment is too far from the canvas that we do not need to draw it.\r\n     * @private\r\n     * @param  {Array}  a  Screen coordinates of the start point of the segment\r\n     * @param  {Array}  ta Curve parameter of a  (unused).\r\n     * @param  {Array}  b  Screen coordinates of the end point of the segment\r\n     * @param  {Array}  tb Curve parameter of b (unused).\r\n     * @param  {JXG.Board} board\r\n     * @returns {Boolean}   True if the segment is too far away from the canvas, false otherwise.\r\n     */\r\n    _isOutside: function (a, ta, b, tb, board) {\r\n        var off = 500,\r\n            cw = board.canvasWidth,\r\n            ch = board.canvasHeight;\r\n\r\n        return !!(\r\n            (a[1] < -off && b[1] < -off) ||\r\n            (a[2] < -off && b[2] < -off) ||\r\n            (a[1] > cw + off && b[1] > cw + off) ||\r\n            (a[2] > ch + off && b[2] > ch + off)\r\n        );\r\n    },\r\n\r\n    /**\r\n     * Decide if a point of a curve is too far from the canvas that we do not need to draw it.\r\n     * @private\r\n     * @param {Array}  a  Screen coordinates of the point\r\n     * @param {JXG.Board} board\r\n     * @returns {Boolean}  True if the point is too far away from the canvas, false otherwise.\r\n     */\r\n    _isOutsidePoint: function (a, board) {\r\n        var off = 500,\r\n            cw = board.canvasWidth,\r\n            ch = board.canvasHeight;\r\n\r\n        return !!(a[1] < -off || a[2] < -off || a[1] > cw + off || a[2] > ch + off);\r\n    },\r\n\r\n    /**\r\n     * For a curve c(t) defined on the interval [ta, tb] find the first point\r\n     * which is in the visible area of the board (plus some outside margin).\r\n     * <p>\r\n     * This method is necessary to restrict the recursive plotting algorithm\r\n     * {@link JXG.Curve._plotRecursive} to the visible area and not waste\r\n     * recursion to areas far outside of the visible area.\r\n     * <p>\r\n     * This method can also be used to find the last visible point\r\n     * by reversing the input parameters.\r\n     *\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param  {Array}  ta Curve parameter of a.\r\n     * @param  {Array}  b  Screen coordinates of the end point of the segment (unused)\r\n     * @param  {Array}  tb Curve parameter of b\r\n     * @return {Array}  Array of length two containing the screen ccordinates of\r\n     * the starting point and the curve parameter at this point.\r\n     * @private\r\n     */\r\n    _findStartPoint: function (curve, a, ta, b, tb) {\r\n        // The code below is too unstable.\r\n        // E.g. [function(t) { return Math.pow(t, 2) * (t + 5) * Math.pow(t - 5, 2); }, -8, 8]\r\n        // Therefore, we return here.\r\n        return [a, ta];\r\n\r\n        // var i,\r\n        //     delta,\r\n        //     tc,\r\n        //     td,\r\n        //     z,\r\n        //     isFound,\r\n        //     w2,\r\n        //     h2,\r\n        //     pnt = new Coords(Const.COORDS_BY_USER, [0, 0], curve.board, false),\r\n        //     steps = 40,\r\n        //     eps = 0.01,\r\n        //     fnX1,\r\n        //     fnX2,\r\n        //     fnY1,\r\n        //     fnY2,\r\n        //     bbox = curve.board.getBoundingBox();\r\n\r\n        // if (true || !this._isOutsidePoint(a, curve.board)) {\r\n        //     return [a, ta];\r\n        // }\r\n        // w2 = (bbox[2] - bbox[0]) * 0.3;\r\n        // h2 = (bbox[1] - bbox[3]) * 0.3;\r\n        // bbox[0] -= w2;\r\n        // bbox[1] += h2;\r\n        // bbox[2] += w2;\r\n        // bbox[3] -= h2;\r\n\r\n        // delta = (tb - ta) / steps;\r\n        // tc = ta + delta;\r\n        // isFound = false;\r\n\r\n        // fnX1 = function (t) {\r\n        //     return curve.X(t, true) - bbox[0];\r\n        // };\r\n        // fnY1 = function (t) {\r\n        //     return curve.Y(t, true) - bbox[1];\r\n        // };\r\n        // fnX2 = function (t) {\r\n        //     return curve.X(t, true) - bbox[2];\r\n        // };\r\n        // fnY2 = function (t) {\r\n        //     return curve.Y(t, true) - bbox[3];\r\n        // };\r\n        // for (i = 0; i < steps; ++i) {\r\n        //     // Left border\r\n        //     z = bbox[0];\r\n        //     td = Numerics.root(fnX1, [tc - delta, tc], curve);\r\n        //     // td = Numerics.fzero(fnX1, [tc - delta, tc], this);\r\n        //     // console.log(\"A\", tc - delta, tc, td, Math.abs(this.X(td, true) - z));\r\n        //     if (Math.abs(curve.X(td, true) - z) < eps) {\r\n        //         //} * Math.abs(z)) {\r\n        //         isFound = true;\r\n        //         break;\r\n        //     }\r\n        //     // Top border\r\n        //     z = bbox[1];\r\n        //     td = Numerics.root(fnY1, [tc - delta, tc], curve);\r\n        //     // td = Numerics.fzero(fnY1, [tc - delta, tc], this);\r\n        //     // console.log(\"B\", tc - delta, tc, td, Math.abs(this.Y(td, true) - z));\r\n        //     if (Math.abs(curve.Y(td, true) - z) < eps) {\r\n        //         // * Math.abs(z)) {\r\n        //         isFound = true;\r\n        //         break;\r\n        //     }\r\n        //     // Right border\r\n        //     z = bbox[2];\r\n        //     td = Numerics.root(fnX2, [tc - delta, tc], curve);\r\n        //     // td = Numerics.fzero(fnX2, [tc - delta, tc], this);\r\n        //     // console.log(\"C\", tc - delta, tc, td, Math.abs(this.X(td, true) - z));\r\n        //     if (Math.abs(curve.X(td, true) - z) < eps) {\r\n        //         // * Math.abs(z)) {\r\n        //         isFound = true;\r\n        //         break;\r\n        //     }\r\n        //     // Bottom border\r\n        //     z = bbox[3];\r\n        //     td = Numerics.root(fnY2, [tc - delta, tc], curve);\r\n        //     // td = Numerics.fzero(fnY2, [tc - delta, tc], this);\r\n        //     // console.log(\"D\", tc - delta, tc, td, Math.abs(this.Y(td, true) - z));\r\n        //     if (Math.abs(curve.Y(td, true) - z) < eps) {\r\n        //         // * Math.abs(z)) {\r\n        //         isFound = true;\r\n        //         break;\r\n        //     }\r\n        //     tc += delta;\r\n        // }\r\n        // if (isFound) {\r\n        //     pnt.setCoordinates(\r\n        //         Const.COORDS_BY_USER,\r\n        //         [curve.X(td, true), curve.Y(td, true)],\r\n        //         false\r\n        //     );\r\n        //     return [pnt.scrCoords, td];\r\n        // }\r\n        // console.log(\"TODO _findStartPoint\", curve.Y.toString(), tc);\r\n        // pnt.setCoordinates(Const.COORDS_BY_USER, [curve.X(ta, true), curve.Y(ta, true)], false);\r\n        // return [pnt.scrCoords, ta];\r\n    },\r\n\r\n    /**\r\n     * Investigate a function term at the bounds of intervals where\r\n     * the function is not defined, e.g. log(x) at x = 0.\r\n     *\r\n     * c is inbetween a and b\r\n     *\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {Array} a Screen coordinates of the left interval bound\r\n     * @param {Array} b Screen coordinates of the right interval bound\r\n     * @param {Array} c Screen coordinates of the bisection point at (ta + tb) / 2\r\n     * @param {Number} ta Parameter which evaluates to a, i.e. [1, X(ta), Y(ta)] = a in screen coordinates\r\n     * @param {Number} tb Parameter which evaluates to b, i.e. [1, X(tb), Y(tb)] = b in screen coordinates\r\n     * @param {Number} tc (ta + tb) / 2 = tc. Parameter which evaluates to b, i.e. [1, X(tc), Y(tc)] = c in screen coordinates\r\n     * @param {Number} depth Actual recursion depth. The recursion stops if depth is equal to 0.\r\n     * @returns {JXG.Boolean} true if the point is inserted and the recursion should stop, false otherwise.\r\n     *\r\n     * @private\r\n     */\r\n    _getBorderPos: function (curve, ta, a, tc, c, tb, b) {\r\n        var t, pnt, p, j,\r\n            max_it = 30,\r\n            is_undef = false,\r\n            t_good, t_bad;\r\n\r\n        pnt = new Coords(Const.COORDS_BY_USER, [0, 0], curve.board, false);\r\n        j = 0;\r\n        // Bisect a, b and c until the point t_real is inside of the definition interval\r\n        // and as close as possible at the boundary.\r\n        // (t_real2 is/was the second closest point).\r\n        // There are four cases:\r\n        //  a  |  c  |  b\r\n        // ---------------\r\n        // inf | R   | R\r\n        // R   | R   | inf\r\n        // inf | inf | R\r\n        // R   | inf | inf\r\n        //\r\n        if (isNaN(a[1] + a[2]) && !isNaN(c[1] + c[2])) {\r\n            t_bad = ta;\r\n            t_good = tc;\r\n        } else if (isNaN(b[1] + b[2]) && !isNaN(c[1] + c[2])) {\r\n            t_bad = tb;\r\n            t_good = tc;\r\n        } else if (isNaN(c[1] + c[2]) && !isNaN(b[1] + b[2])) {\r\n            t_bad = tc;\r\n            t_good = tb;\r\n        } else if (isNaN(c[1] + c[2]) && !isNaN(a[1] + a[2])) {\r\n            t_bad = tc;\r\n            t_good = ta;\r\n        } else {\r\n            return false;\r\n        }\r\n        do {\r\n            t = 0.5 * (t_good + t_bad);\r\n            pnt.setCoordinates(\r\n                Const.COORDS_BY_USER,\r\n                [curve.X(t, true), curve.Y(t, true)],\r\n                false\r\n            );\r\n            p = pnt.usrCoords;\r\n            is_undef = isNaN(p[1] + p[2]);\r\n            if (is_undef) {\r\n                t_bad = t;\r\n            } else {\r\n                t_good = t;\r\n            }\r\n            ++j;\r\n        } while (j < max_it && Math.abs(t_good - t_bad) > Mat.eps);\r\n        return t;\r\n    },\r\n\r\n    /**\r\n     *\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {Number} ta\r\n     * @param {Number} tb\r\n     */\r\n    _getCuspPos: function (curve, ta, tb) {\r\n        var a = [curve.X(ta, true), curve.Y(ta, true)],\r\n            b = [curve.X(tb, true), curve.Y(tb, true)],\r\n            max_func = function (t) {\r\n                var c = [curve.X(t, true), curve.Y(t, true)];\r\n                return -(\r\n                    Mat.hypot(a[0] - c[0], a[1] - c[1]) +\r\n                    Mat.hypot(b[0] - c[0], b[1] - c[1])\r\n                );\r\n            };\r\n\r\n        return Numerics.fminbr(max_func, [ta, tb], curve);\r\n    },\r\n\r\n    /**\r\n     *\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {Number} ta\r\n     * @param {Number} tb\r\n     */\r\n    _getJumpPos: function (curve, ta, tb) {\r\n        var max_func = function (t) {\r\n            var e = Mat.eps * Mat.eps,\r\n                c1 = [curve.X(t, true), curve.Y(t, true)],\r\n                c2 = [curve.X(t + e, true), curve.Y(t + e, true)];\r\n            return -Math.abs((c2[1] - c1[1]) / (c2[0] - c1[0]));\r\n        };\r\n\r\n        return Numerics.fminbr(max_func, [ta, tb], curve);\r\n    },\r\n\r\n    /**\r\n     *\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {Number} t\r\n     * @private\r\n     */\r\n    _getLimits: function (curve, t) {\r\n        var res,\r\n            step = 2 / (curve.maxX() - curve.minX()),\r\n            x_l,\r\n            x_r,\r\n            y_l,\r\n            y_r;\r\n\r\n        // From left\r\n        res = Extrapolate.limit(t, -step, curve.X);\r\n        x_l = res[0];\r\n        if (res[1] === 'infinite') {\r\n            x_l = Math.sign(x_l) * Infinity;\r\n        }\r\n\r\n        res = Extrapolate.limit(t, -step, curve.Y);\r\n        y_l = res[0];\r\n        if (res[1] === 'infinite') {\r\n            y_l = Math.sign(y_l) * Infinity;\r\n        }\r\n\r\n        // From right\r\n        res = Extrapolate.limit(t, step, curve.X);\r\n        x_r = res[0];\r\n        if (res[1] === 'infinite') {\r\n            x_r = Math.sign(x_r) * Infinity;\r\n        }\r\n\r\n        res = Extrapolate.limit(t, step, curve.Y);\r\n        y_r = res[0];\r\n        if (res[1] === 'infinite') {\r\n            y_r = Math.sign(y_r) * Infinity;\r\n        }\r\n\r\n        return {\r\n            left_x: x_l,\r\n            left_y: y_l,\r\n            right_x: x_r,\r\n            right_y: y_r,\r\n            t: t\r\n        };\r\n    },\r\n\r\n    /**\r\n     *\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {Array} a\r\n     * @param {Number} tc\r\n     * @param {Array} c\r\n     * @param {Number} tb\r\n     * @param {Array} b\r\n     * @param {String} may_be_special\r\n     * @param {Number} depth\r\n     * @private\r\n     */\r\n    _getLimes: function (curve, ta, a, tc, c, tb, b, may_be_special, depth) {\r\n        var t;\r\n\r\n        if (may_be_special === 'border') {\r\n            t = this._getBorderPos(curve, ta, a, tc, c, tb, b);\r\n        } else if (may_be_special === 'cusp') {\r\n            t = this._getCuspPos(curve, ta, tb);\r\n        } else if (may_be_special === 'jump') {\r\n            t = this._getJumpPos(curve, ta, tb);\r\n        }\r\n        return this._getLimits(curve, t);\r\n    },\r\n\r\n    /**\r\n     * Recursive interval bisection algorithm for curve plotting.\r\n     * Used in {@link JXG.Curve.updateParametricCurve}.\r\n     * @private\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {Array} a Screen coordinates of the left interval bound\r\n     * @param {Number} ta Parameter which evaluates to a, i.e. [1, X(ta), Y(ta)] = a in screen coordinates\r\n     * @param {Array} b Screen coordinates of the right interval bound\r\n     * @param {Number} tb Parameter which evaluates to b, i.e. [1, X(tb), Y(tb)] = b in screen coordinates\r\n     * @param {Number} depth Actual recursion depth. The recursion stops if depth is equal to 0.\r\n     * @param {Number} delta If the distance of the bisection point at (ta + tb) / 2 from the point (a + b) / 2 is less then delta,\r\n     *                 the segment [a,b] is regarded as straight line.\r\n     * @returns {JXG.Curve} Reference to the curve object.\r\n     */\r\n    _plotNonRecursive: function (curve, a, ta, b, tb, d) {\r\n        var tc,\r\n            c,\r\n            ds,\r\n            mindepth = 0,\r\n            limes = null,\r\n            a_nan,\r\n            b_nan,\r\n            isSmooth = false,\r\n            may_be_special = \"\",\r\n            x,\r\n            y,\r\n            oc,\r\n            depth,\r\n            ds0,\r\n            stack = [],\r\n            stack_length = 0,\r\n            item;\r\n\r\n        oc = curve.board.origin.scrCoords;\r\n        stack[stack_length++] = [a, ta, b, tb, d, Infinity];\r\n        while (stack_length > 0) {\r\n            // item = stack.pop();\r\n            item = stack[--stack_length];\r\n            a = item[0];\r\n            ta = item[1];\r\n            b = item[2];\r\n            tb = item[3];\r\n            depth = item[4];\r\n            ds0 = item[5];\r\n\r\n            isSmooth = false;\r\n            may_be_special = \"\";\r\n            limes = null;\r\n            //console.log(stack.length, item)\r\n\r\n            if (curve.points.length > 65536) {\r\n                return;\r\n            }\r\n\r\n            if (depth < this.nanLevel) {\r\n                // Test if the function is undefined in the whole interval [ta, tb]\r\n                if (this._isUndefined(curve, a, ta, b, tb)) {\r\n                    continue;\r\n                }\r\n                // Test if the graph is far outside the visible are for the interval [ta, tb]\r\n                if (this._isOutside(a, ta, b, tb, curve.board)) {\r\n                    continue;\r\n                }\r\n            }\r\n\r\n            tc = (ta + tb) * 0.5;\r\n\r\n            // Screen coordinates of point at tc\r\n            x = curve.X(tc, true);\r\n            y = curve.Y(tc, true);\r\n            c = [1, oc[1] + x * curve.board.unitX, oc[2] - y * curve.board.unitY];\r\n            ds = this._triangleDists(a, b, c); // returns [d_ab, d_ac, d_cb, d_cd]\r\n\r\n            a_nan = isNaN(a[1] + a[2]);\r\n            b_nan = isNaN(b[1] + b[2]);\r\n            if ((a_nan && !b_nan) || (!a_nan && b_nan)) {\r\n                may_be_special = 'border';\r\n            } else if (\r\n                ds[0] > 0.66 * ds0 ||\r\n                ds[0] < this.cusp_threshold * (ds[1] + ds[2]) ||\r\n                ds[1] > 5 * ds[2] ||\r\n                ds[2] > 5 * ds[1]\r\n            ) {\r\n                may_be_special = 'cusp';\r\n            } else if (\r\n                ds[2] > this.jump_threshold * ds[0] ||\r\n                ds[1] > this.jump_threshold * ds[0] ||\r\n                ds[0] === Infinity ||\r\n                ds[1] === Infinity ||\r\n                ds[2] === Infinity\r\n            ) {\r\n                may_be_special = 'jump';\r\n            }\r\n            isSmooth =\r\n                may_be_special === \"\" &&\r\n                depth < this.smoothLevel &&\r\n                ds[3] < this.smooth_threshold;\r\n\r\n            if (depth < this.testLevel && !isSmooth) {\r\n                if (may_be_special === \"\") {\r\n                    isSmooth = true;\r\n                } else {\r\n                    limes = this._getLimes(curve, ta, a, tc, c, tb, b, may_be_special, depth);\r\n                }\r\n            }\r\n\r\n            if (limes !== null) {\r\n                c = [1, NaN, NaN];\r\n                this._insertPoint(curve, c, tc, depth, limes);\r\n            } else if (depth <= mindepth || isSmooth) {\r\n                this._insertPoint(curve, c, tc, depth, null);\r\n            } else {\r\n                stack[stack_length++] = [c, tc, b, tb, depth - 1, ds[0]];\r\n                stack[stack_length++] = [a, ta, c, tc, depth - 1, ds[0]];\r\n            }\r\n        }\r\n\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * Updates the data points of a parametric curve. This version is used if {@link JXG.Curve#plotVersion} is <tt>3</tt>.\r\n     * This is an experimental plot version, <b>not recommended</b> to be used.\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {Number} mi Left bound of curve\r\n     * @param {Number} ma Right bound of curve\r\n     * @returns {JXG.Curve} Reference to the curve object.\r\n     */\r\n    updateParametricCurve_v3: function (curve, mi, ma) {\r\n        var ta,\r\n            tb,\r\n            a,\r\n            b,\r\n            suspendUpdate = false,\r\n            pa = new Coords(Const.COORDS_BY_USER, [0, 0], curve.board, false),\r\n            pb = new Coords(Const.COORDS_BY_USER, [0, 0], curve.board, false),\r\n            depth,\r\n            w2, // h2,\r\n            bbox,\r\n            ret_arr;\r\n\r\n        // console.log(\"-----------------------------------------------------------\");\r\n        // console.time('plot');\r\n        if (curve.board.updateQuality === curve.board.BOARD_QUALITY_LOW) {\r\n            depth = curve.evalVisProp('recursiondepthlow') || 14;\r\n        } else {\r\n            depth = curve.evalVisProp('recursiondepthhigh') || 17;\r\n        }\r\n\r\n        // smoothLevel has to be small for graphs in a huge interval.\r\n        this.smoothLevel = 7; //depth - 10;\r\n        this.nanLevel = depth - 4;\r\n        this.testLevel = 4;\r\n        this.cusp_threshold = 0.5;\r\n        this.jump_threshold = 0.99;\r\n        this.smooth_threshold = 2;\r\n\r\n        curve.points = [];\r\n\r\n        if (curve.xterm === 'x') {\r\n            // For function graphs we can restrict the plot interval\r\n            // to the visible area +plus margin\r\n            bbox = curve.board.getBoundingBox();\r\n            w2 = (bbox[2] - bbox[0]) * 0.3;\r\n            //h2 = (bbox[1] - bbox[3]) * 0.3;\r\n            ta = Math.max(mi, bbox[0] - w2);\r\n            tb = Math.min(ma, bbox[2] + w2);\r\n        } else {\r\n            ta = mi;\r\n            tb = ma;\r\n        }\r\n        pa.setCoordinates(\r\n            Const.COORDS_BY_USER,\r\n            [curve.X(ta, suspendUpdate), curve.Y(ta, suspendUpdate)],\r\n            false\r\n        );\r\n\r\n        // The first function calls of X() and Y() are done. We can now\r\n        // switch `suspendUpdate` on. If supported by the functions, this\r\n        // avoids for the rest of the plotting algorithm, evaluation of any\r\n        // parent elements.\r\n        suspendUpdate = true;\r\n\r\n        pb.setCoordinates(\r\n            Const.COORDS_BY_USER,\r\n            [curve.X(tb, suspendUpdate), curve.Y(tb, suspendUpdate)],\r\n            false\r\n        );\r\n\r\n        // Find start and end points of the visible area (plus a certain margin)\r\n        ret_arr = this._findStartPoint(curve, pa.scrCoords, ta, pb.scrCoords, tb);\r\n        pa.setCoordinates(Const.COORDS_BY_SCREEN, ret_arr[0], false);\r\n        ta = ret_arr[1];\r\n        ret_arr = this._findStartPoint(curve, pb.scrCoords, tb, pa.scrCoords, ta);\r\n        pb.setCoordinates(Const.COORDS_BY_SCREEN, ret_arr[0], false);\r\n        tb = ret_arr[1];\r\n\r\n        // Save the visible area.\r\n        // This can be used in Curve.hasPoint().\r\n        this._visibleArea = [ta, tb];\r\n\r\n        // Start recursive plotting algorithm\r\n        a = pa.copy('scrCoords');\r\n        b = pb.copy('scrCoords');\r\n        pa._t = ta;\r\n        curve.points.push(pa);\r\n        this._lastScrCrds = pa.copy('scrCoords'); // Used in _insertPoint\r\n        this._lastUsrCrds = pa.copy('usrCoords'); // Used in _insertPoint\r\n\r\n        this._plotNonRecursive(curve, a, ta, b, tb, depth);\r\n\r\n        pb._t = tb;\r\n        curve.points.push(pb);\r\n\r\n        curve.numberPoints = curve.points.length;\r\n        // console.timeEnd('plot');\r\n        // console.log(\"number of points:\", this.numberPoints);\r\n\r\n        return curve;\r\n    },\r\n\r\n    //----------------------------------------------------------------------\r\n    // Plot algorithm v4\r\n    //----------------------------------------------------------------------\r\n\r\n    /**\r\n     * TODO\r\n     * @param {Array} vec\r\n     * @param {Number} le\r\n     * @param {Number} level\r\n     * @returns Object\r\n     * @private\r\n     */\r\n    _criticalInterval: function (vec, le, level) {\r\n        var i,\r\n            j,\r\n            le1,\r\n            med,\r\n            sgn,\r\n            sgnChange,\r\n            isGroup = false,\r\n            abs_vec,\r\n            last = -Infinity,\r\n            very_small = false,\r\n            smooth = false,\r\n            group = 0,\r\n            groups = [],\r\n            types = [],\r\n            positions = [];\r\n\r\n        abs_vec = Statistics.abs(vec);\r\n        med = Statistics.median(abs_vec);\r\n\r\n        if (med < 1.0e-7) {\r\n            med = 1.0e-7;\r\n            very_small = true;\r\n        } else {\r\n            med *= this.criticalThreshold;\r\n        }\r\n\r\n        //console.log(\"Median\", med);\r\n        for (i = 0; i < le; i++) {\r\n            // Start a group if not yet done and\r\n            // add position to group\r\n            if (abs_vec[i] > med /*&& abs_vec[i] > 0.01*/) {\r\n                positions.push({ i: i, v: vec[i], group: group });\r\n                last = i;\r\n                if (!isGroup) {\r\n                    isGroup = true;\r\n                }\r\n            } else {\r\n                if (isGroup && i > last + 4) {\r\n                    // End the group\r\n                    if (positions.length > 0) {\r\n                        groups.push(positions.slice(0));\r\n                    }\r\n                    positions = [];\r\n                    isGroup = false;\r\n                    group++;\r\n                }\r\n            }\r\n        }\r\n        if (isGroup) {\r\n            if (positions.length > 1) {\r\n                groups.push(positions.slice(0));\r\n            }\r\n        }\r\n\r\n        if (very_small && groups.length === 0) {\r\n            smooth = true;\r\n        }\r\n\r\n        // Decide if there is a singular critical point\r\n        // or if a whole interval is problematic.\r\n        // The latter is the case if the differences have many sign changes.\r\n        for (j = 0; j < groups.length; j++) {\r\n            types[j] = 'point';\r\n            le1 = groups[j].length;\r\n            if (le1 < 64) {\r\n                continue;\r\n            }\r\n            sgnChange = 0;\r\n            sgn = Math.sign(groups[j][0].v);\r\n            for (i = 1; i < le1; i++) {\r\n                if (Math.sign(groups[j][i].v) !== sgn) {\r\n                    sgnChange++;\r\n                    sgn = Math.sign(groups[j][i].v);\r\n                }\r\n            }\r\n            if (sgnChange * 6 > le1) {\r\n                types[j] = 'interval';\r\n            }\r\n        }\r\n\r\n        return { smooth: smooth, groups: groups, types: types };\r\n    },\r\n\r\n    Component: function () {\r\n        this.left_isNaN = false;\r\n        this.right_isNaN = false;\r\n        this.left_t = null;\r\n        this.right_t = null;\r\n        this.t_values = [];\r\n        this.x_values = [];\r\n        this.y_values = [];\r\n        this.len = 0;\r\n    },\r\n\r\n    findComponents: function (curve, mi, ma, steps) {\r\n        var i, t, h,\r\n            x, y,\r\n            components = [],\r\n            comp,\r\n            comp_nr = 0,\r\n            cnt = 0,\r\n            cntNaNs = 0,\r\n            comp_started = false,\r\n            suspended = false;\r\n\r\n        h = (ma - mi) / steps;\r\n        components[comp_nr] = new this.Component();\r\n        comp = components[comp_nr];\r\n\r\n        for (i = 0, t = mi; i <= steps; i++, t += h) {\r\n            x = curve.X(t, suspended);\r\n            y = curve.Y(t, suspended);\r\n\r\n            if (isNaN(x) || isNaN(y)) {\r\n                cntNaNs++;\r\n                // Wait for - at least - two consecutive NaNs\r\n                // This avoids starting a new component if\r\n                // the function value has infinity as intermediate value.\r\n                if (cntNaNs > 1 && comp_started) {\r\n                    // Finalize a component\r\n                    comp.right_isNaN = true;\r\n                    comp.right_t = t - h;\r\n                    comp.len = cnt;\r\n\r\n                    // Prepare a new component\r\n                    comp_started = false;\r\n                    comp_nr++;\r\n                    components[comp_nr] = new this.Component();\r\n                    comp = components[comp_nr];\r\n                    cntNaNs = 0;\r\n                }\r\n            } else {\r\n                // Now there is a non-NaN entry.\r\n                if (!comp_started) {\r\n                    // Start the component\r\n                    comp_started = true;\r\n                    cnt = 0;\r\n                    if (cntNaNs > 0) {\r\n                        comp.left_t = t - h;\r\n                        comp.left_isNaN = true;\r\n                    }\r\n                }\r\n                cntNaNs = 0;\r\n                // Add the value to the component\r\n                comp.t_values[cnt] = t;\r\n                comp.x_values[cnt] = x;\r\n                comp.y_values[cnt] = y;\r\n                cnt++;\r\n            }\r\n            if (i === 0) {\r\n                suspended = true;\r\n            }\r\n        }\r\n        if (comp_started) {\r\n            comp.len = cnt;\r\n        } else {\r\n            components.pop();\r\n        }\r\n\r\n        return components;\r\n    },\r\n\r\n    getPointType: function (curve, pos, t_approx, t_values, x_table, y_table, len) {\r\n        var x_values = x_table[0],\r\n            y_values = y_table[0],\r\n            full_len = t_values.length,\r\n            result = {\r\n                idx: pos,\r\n                t: t_approx, //t_values[pos],\r\n                x: x_values[pos],\r\n                y: y_values[pos],\r\n                type: \"other\"\r\n            };\r\n\r\n        if (pos < 5) {\r\n            result.type = 'borderleft';\r\n            result.idx = 0;\r\n            result.t = t_values[0];\r\n            result.x = x_values[0];\r\n            result.y = y_values[0];\r\n\r\n            // console.log('Border left', result.t);\r\n            return result;\r\n        }\r\n        if (pos > len - 6) {\r\n            result.type = 'borderright';\r\n            result.idx = full_len - 1;\r\n            result.t = t_values[full_len - 1];\r\n            result.x = x_values[full_len - 1];\r\n            result.y = y_values[full_len - 1];\r\n\r\n            // console.log('Border right', result.t, full_len - 1);\r\n            return result;\r\n        }\r\n\r\n        return result;\r\n    },\r\n\r\n    newtonApprox: function (idx, t, h, level, table) {\r\n        var i,\r\n            s = 0.0;\r\n        for (i = level; i > 0; i--) {\r\n            s = ((s + table[i][idx]) * (t - (i - 1) * h)) / i;\r\n        }\r\n        return s + table[0][idx];\r\n    },\r\n\r\n    // Thiele's interpolation formula,\r\n    // https://en.wikipedia.org/wiki/Thiele%27s_interpolation_formula\r\n    // unused\r\n    thiele: function (t, recip, t_values, idx, degree) {\r\n        var i,\r\n            v = 0.0;\r\n        for (i = degree; i > 1; i--) {\r\n            v = (t - t_values[idx + i]) / (recip[i][idx + 1] - recip[i - 2][idx + 1] + v);\r\n        }\r\n        return recip[0][idx + 1] + (t - t_values[idx + 1]) / (recip[1][idx + 1] + v);\r\n    },\r\n\r\n    differenceMethodExperiments: function (component, curve) {\r\n        var i,\r\n            level,\r\n            le,\r\n            up,\r\n            t_values = component.t_values,\r\n            x_values = component.x_values,\r\n            y_values = component.y_values,\r\n            x_diffs = [],\r\n            y_diffs = [],\r\n            x_slopes = [],\r\n            y_slopes = [],\r\n            x_table = [],\r\n            y_table = [],\r\n            x_recip = [],\r\n            y_recip = [],\r\n            h,\r\n            numerator,\r\n            // x_med, y_med,\r\n            foundCriticalPoint = 0,\r\n            pos,\r\n            ma,\r\n            j,\r\n            v,\r\n            groups,\r\n            criticalPoints = [];\r\n\r\n        h = t_values[1] - t_values[0];\r\n        x_table.push([]);\r\n        y_table.push([]);\r\n        x_recip.push([]);\r\n        y_recip.push([]);\r\n        le = y_values.length;\r\n        for (i = 0; i < le; i++) {\r\n            x_table[0][i] = x_values[i];\r\n            y_table[0][i] = y_values[i];\r\n            x_recip[0][i] = x_values[i];\r\n            y_recip[0][i] = y_values[i];\r\n        }\r\n\r\n        x_table.push([]);\r\n        y_table.push([]);\r\n        x_recip.push([]);\r\n        y_recip.push([]);\r\n        numerator = h;\r\n        le = y_values.length - 1;\r\n        for (i = 0; i < le; i++) {\r\n            x_diffs[i] = x_values[i + 1] - x_values[i];\r\n            y_diffs[i] = y_values[i + 1] - y_values[i];\r\n            x_slopes[i] = x_diffs[i];\r\n            y_slopes[i] = y_diffs[i];\r\n            x_table[1][i] = x_diffs[i];\r\n            y_table[1][i] = y_diffs[i];\r\n            x_recip[1][i] = numerator / x_diffs[i];\r\n            y_recip[1][i] = numerator / y_diffs[i];\r\n        }\r\n        le--;\r\n\r\n        up = Math.min(8, y_values.length - 1);\r\n        for (level = 1; level < up; level++) {\r\n            x_table.push([]);\r\n            y_table.push([]);\r\n            x_recip.push([]);\r\n            y_recip.push([]);\r\n            numerator *= h;\r\n            for (i = 0; i < le; i++) {\r\n                x_diffs[i] = x_diffs[i + 1] - x_diffs[i];\r\n                y_diffs[i] = y_diffs[i + 1] - y_diffs[i];\r\n                x_table[level + 1][i] = x_diffs[i];\r\n                y_table[level + 1][i] = y_diffs[i];\r\n                x_recip[level + 1][i] =\r\n                    numerator / (x_recip[level][i + 1] - x_recip[level][i]) +\r\n                    x_recip[level - 1][i + 1];\r\n                y_recip[level + 1][i] =\r\n                    numerator / (y_recip[level][i + 1] - y_recip[level][i]) +\r\n                    y_recip[level - 1][i + 1];\r\n            }\r\n\r\n            // if (level == 1) {\r\n            //     console.log(\"bends level=\", level, y_diffs.toString());\r\n            // }\r\n\r\n            // Store point location which may be centered around\r\n            // critical points.\r\n            // If the level is suitable, step out of the loop.\r\n            groups = this._criticalPoints(y_diffs, le, level);\r\n            if (groups === false) {\r\n                // Its seems, the degree of the polynomial is equal to level\r\n                console.log(\"Polynomial of degree\", level);\r\n                groups = [];\r\n                break;\r\n            }\r\n            if (groups.length > 0) {\r\n                foundCriticalPoint++;\r\n                if (foundCriticalPoint > 1 && level % 2 === 0) {\r\n                    break;\r\n                }\r\n            }\r\n            le--;\r\n        }\r\n\r\n        // console.log(\"Last diffs\", y_diffs, \"level\", level);\r\n\r\n        // Analyze the groups which have been found.\r\n        for (i = 0; i < groups.length; i++) {\r\n            // console.log(\"Group\", i, groups[i])\r\n            // Identify the maximum difference, i.e. the center of the \"problem\"\r\n            ma = -Infinity;\r\n            for (j = 0; j < groups[i].length; j++) {\r\n                v = Math.abs(groups[i][j].v);\r\n                if (v > ma) {\r\n                    ma = v;\r\n                    pos = j;\r\n                }\r\n            }\r\n            pos = Math.floor(groups[i][pos].i + level / 2);\r\n            // Analyze the critical point\r\n            criticalPoints.push(\r\n                this.getPointType(\r\n                    curve,\r\n                    pos,\r\n                    t_values,\r\n                    x_values,\r\n                    y_values,\r\n                    x_slopes,\r\n                    y_slopes,\r\n                    le + 1\r\n                )\r\n            );\r\n        }\r\n\r\n        return [criticalPoints, x_table, y_table, x_recip, y_recip];\r\n    },\r\n\r\n    getCenterOfCriticalInterval: function (group, degree, t_values) {\r\n        var ma,\r\n            j,\r\n            pos,\r\n            v,\r\n            num = 0.0,\r\n            den = 0.0,\r\n            h = t_values[1] - t_values[0],\r\n            pos_mean,\r\n            range = [];\r\n\r\n        // Identify the maximum difference, i.e. the center of the \"problem\"\r\n        // If there are several equal maxima, store the positions\r\n        // in the array range and determine the center of the array.\r\n\r\n        ma = -Infinity;\r\n        range = [];\r\n        for (j = 0; j < group.length; j++) {\r\n            v = Math.abs(group[j].v);\r\n            if (v > ma) {\r\n                range = [j];\r\n                ma = v;\r\n                pos = j;\r\n            } else if (ma === v) {\r\n                range.push(j);\r\n            }\r\n        }\r\n        if (range.length > 0) {\r\n            pos_mean =\r\n                range.reduce(function (total, val) {\r\n                    return total + val;\r\n                }, 0) / range.length;\r\n            pos = Math.floor(pos_mean);\r\n            pos_mean += group[0].i;\r\n        }\r\n\r\n        if (ma < Infinity) {\r\n            for (j = 0; j < group.length; j++) {\r\n                num += Math.abs(group[j].v) * group[j].i;\r\n                den += Math.abs(group[j].v);\r\n            }\r\n            pos_mean = num / den;\r\n        }\r\n        pos_mean += degree / 2;\r\n        return [\r\n            group[pos].i + degree / 2,\r\n            pos_mean,\r\n            t_values[Math.floor(pos_mean)] + h * (pos_mean - Math.floor(pos_mean))\r\n        ];\r\n    },\r\n\r\n    differenceMethod: function (component, curve) {\r\n        var i,\r\n            level,\r\n            le,\r\n            up,\r\n            t_values = component.t_values,\r\n            x_values = component.x_values,\r\n            y_values = component.y_values,\r\n            x_table = [],\r\n            y_table = [],\r\n            foundCriticalPoint = 0,\r\n            degree_x = -1,\r\n            degree_y = -1,\r\n            pos,\r\n            res,\r\n            res_x,\r\n            res_y,\r\n            t_approx,\r\n            groups = [],\r\n            types,\r\n            criticalPoints = [];\r\n\r\n        le = y_values.length;\r\n        // x_table.push([]);\r\n        // y_table.push([]);\r\n        // for (i = 0; i < le; i++) {\r\n        //     x_table[0][i] = x_values[i];\r\n        //     y_table[0][i] = y_values[i];\r\n        // }\r\n        x_table.push(new Float64Array(x_values));\r\n        y_table.push(new Float64Array(y_values));\r\n\r\n        le--;\r\n        up = Math.min(12, le);\r\n        for (level = 0; level < up; level++) {\r\n            // Old style method:\r\n            // x_table.push([]);\r\n            // y_table.push([]);\r\n            // for (i = 0; i < le; i++) {\r\n            //     x_table[level + 1][i] = x_table[level][i + 1] - x_table[level][i];\r\n            //     y_table[level + 1][i] = y_table[level][i + 1] - y_table[level][i];\r\n            // }\r\n            // New method:\r\n            x_table.push(new Float64Array(le));\r\n            y_table.push(new Float64Array(le));\r\n            x_table[level + 1] = x_table[level].map(function (v, idx, arr) {\r\n                return arr[idx + 1] - v;\r\n            });\r\n            y_table[level + 1] = y_table[level].map(function (v, idx, arr) {\r\n                return arr[idx + 1] - v;\r\n            });\r\n\r\n            // Store point location which may be centered around critical points.\r\n            // If the level is suitable, step out of the loop.\r\n            res_y = this._criticalInterval(y_table[level + 1], le, level);\r\n            if (res_y.smooth === true) {\r\n                // Its seems, the degree of the polynomial is equal to level\r\n                // If the values in level + 1 are zero, it might be a polynomial of degree level.\r\n                // Seems to work numerically stable until degree 6.\r\n                degree_y = level;\r\n                groups = [];\r\n            }\r\n            res_x = this._criticalInterval(x_table[level + 1], le, level);\r\n            if (degree_x === -1 && res_x.smooth === true) {\r\n                // Its seems, the degree of the polynomial is equal to level\r\n                // If the values in level + 1 are zero, it might be a polynomial of degree level.\r\n                // Seems to work numerically stable until degree 6.\r\n                degree_x = level;\r\n            }\r\n            if (degree_y >= 0) {\r\n                break;\r\n            }\r\n\r\n            if (res_y.groups.length > 0) {\r\n                foundCriticalPoint++;\r\n                if (foundCriticalPoint > 2 && (level + 1) % 2 === 0) {\r\n                    groups = res_y.groups;\r\n                    types = res_y.types;\r\n                    break;\r\n                }\r\n            }\r\n            le--;\r\n        }\r\n\r\n        // console.log(\"Last diffs\", y_table[Math.min(level + 1, up)], \"level\", level + 1);\r\n        // Analyze the groups which have been found.\r\n        for (i = 0; i < groups.length; i++) {\r\n            if (types[i] === 'interval') {\r\n                continue;\r\n            }\r\n            // console.log(\"Group\", i, groups[i], types[i], level + 1)\r\n            res = this.getCenterOfCriticalInterval(groups[i], level + 1, t_values);\r\n            pos = res_y[0];\r\n            pos = Math.floor(res[1]);\r\n            t_approx = res[2];\r\n            // console.log(\"Critical points:\", groups, res, pos)\r\n\r\n            // Analyze the type of the critical point\r\n            // Result is of type 'borderleft', borderright', 'other'\r\n            criticalPoints.push(\r\n                this.getPointType(curve, pos, t_approx, t_values, x_table, y_table, le + 1)\r\n            );\r\n        }\r\n\r\n        // if (level === up) {\r\n        //     console.log(\"No convergence!\");\r\n        // } else {\r\n        //     console.log(\"Convergence level\", level);\r\n        // }\r\n        return [criticalPoints, x_table, y_table, degree_x, degree_y];\r\n    },\r\n\r\n    _insertPoint_v4: function (curve, crds, t, doLog) {\r\n        var p,\r\n            prev = null,\r\n            x,\r\n            y,\r\n            near = 0.8;\r\n\r\n        if (curve.points.length > 0) {\r\n            prev = curve.points[curve.points.length - 1].scrCoords;\r\n        }\r\n\r\n        // Add regular point\r\n        p = new Coords(Const.COORDS_BY_USER, crds, curve.board);\r\n\r\n        if (prev !== null) {\r\n            x = p.scrCoords[1] - prev[1];\r\n            y = p.scrCoords[2] - prev[2];\r\n            if (x * x + y * y < near * near) {\r\n                // Math.abs(p.scrCoords[1] - prev[1]) < near &&\r\n                // Math.abs(p.scrCoords[2] - prev[2]) < near) {\r\n                return;\r\n            }\r\n        }\r\n\r\n        p._t = t;\r\n        curve.points.push(p);\r\n    },\r\n\r\n    getInterval: function (curve, ta, tb) {\r\n        var t_int,\r\n            // x_int,\r\n            y_int;\r\n\r\n        //console.log('critical point', ta, tb);\r\n        IntervalArithmetic.disable();\r\n\r\n        t_int = IntervalArithmetic.Interval(ta, tb);\r\n        curve.board.mathLib = IntervalArithmetic;\r\n        curve.board.mathLibJXG = IntervalArithmetic;\r\n        // x_int = curve.X(t_int, true);\r\n        y_int = curve.Y(t_int, true);\r\n        curve.board.mathLib = Math;\r\n        curve.board.mathLibJXG = JXG.Math;\r\n\r\n        //console.log(x_int, y_int);\r\n        return y_int;\r\n    },\r\n\r\n    sign: function (v) {\r\n        if (v < 0) {\r\n            return -1;\r\n        }\r\n        if (v > 0) {\r\n            return 1;\r\n        }\r\n        return 0;\r\n    },\r\n\r\n    handleBorder: function (curve, comp, group, x_table, y_table) {\r\n        var idx = group.idx,\r\n            t,\r\n            t1,\r\n            t2,\r\n            size = 32,\r\n            y_int,\r\n            x,\r\n            y,\r\n            lo,\r\n            hi,\r\n            i,\r\n            components2,\r\n            le,\r\n            h;\r\n\r\n        // console.log(\"HandleBorder at t =\", t_approx);\r\n        // console.log(\"component:\", comp)\r\n        // console.log(\"Group:\", group);\r\n\r\n        h = comp.t_values[1] - comp.t_values[0];\r\n        if (group.type === 'borderleft') {\r\n            t = comp.left_isNaN ? comp.left_t : group.t - h;\r\n            t1 = t;\r\n            t2 = t1 + h;\r\n        } else if (group.type === 'borderright') {\r\n            t = comp.right_isNaN ? comp.right_t : group.t + h;\r\n            t2 = t;\r\n            t1 = t2 - h;\r\n        } else {\r\n            console.log(\"No bordercase!!!\");\r\n        }\r\n\r\n        components2 = this.findComponents(curve, t1, t2, size);\r\n        if (components2.length === 0) {\r\n            return;\r\n        }\r\n        if (group.type === 'borderleft') {\r\n            t1 = components2[0].left_t;\r\n            t2 = components2[0].t_values[0];\r\n            h = components2[0].t_values[1] - components2[0].t_values[0];\r\n            t1 = t1 === null ? t2 - h : t1;\r\n            t = t1;\r\n            y_int = this.getInterval(curve, t1, t2);\r\n            if (Type.isObject(y_int)) {\r\n                lo = y_int.lo;\r\n                hi = y_int.hi;\r\n\r\n                x = curve.X(t, true);\r\n                y = y_table[1][idx] < 0 ? hi : lo;\r\n                this._insertPoint_v4(curve, [1, x, y], t);\r\n            }\r\n        }\r\n\r\n        le = components2[0].t_values.length;\r\n        for (i = 0; i < le; i++) {\r\n            t = components2[0].t_values[i];\r\n            x = components2[0].x_values[i];\r\n            y = components2[0].y_values[i];\r\n            this._insertPoint_v4(curve, [1, x, y], t);\r\n        }\r\n\r\n        if (group.type === 'borderright') {\r\n            t1 = components2[0].t_values[le - 1];\r\n            t2 = components2[0].right_t;\r\n            h = components2[0].t_values[1] - components2[0].t_values[0];\r\n            t2 = t2 === null ? t1 + h : t2;\r\n\r\n            t = t2;\r\n            y_int = this.getInterval(curve, t1, t2);\r\n            if (Type.isObject(y_int)) {\r\n                lo = y_int.lo;\r\n                hi = y_int.hi;\r\n                x = curve.X(t, true);\r\n                y = y_table[1][idx] > 0 ? hi : lo;\r\n                this._insertPoint_v4(curve, [1, x, y], t);\r\n            }\r\n        }\r\n    },\r\n\r\n    _seconditeration_v4: function (curve, comp, group, x_table, y_table) {\r\n        var i, t1, t2, ret, components2, comp2, idx, groups2, g, x_table2, y_table2, start, le;\r\n\r\n        // Look at two points, hopefully left and right from the critical point\r\n        t1 = comp.t_values[group.idx - 2];\r\n        t2 = comp.t_values[group.idx + 2];\r\n        components2 = this.findComponents(curve, t1, t2, 64);\r\n        for (idx = 0; idx < components2.length; idx++) {\r\n            comp2 = components2[idx];\r\n            ret = this.differenceMethod(comp2, curve);\r\n            groups2 = ret[0];\r\n            x_table2 = ret[1];\r\n            y_table2 = ret[2];\r\n            start = 0;\r\n            for (g = 0; g <= groups2.length; g++) {\r\n                if (g === groups2.length) {\r\n                    le = comp2.len;\r\n                } else {\r\n                    le = groups2[g].idx;\r\n                }\r\n\r\n                // Insert all uncritical points until next critical point\r\n                for (i = start; i < le; i++) {\r\n                    if (!isNaN(comp2.x_values[i]) && !isNaN(comp2.y_values[i])) {\r\n                        this._insertPoint_v4(\r\n                            curve,\r\n                            [1, comp2.x_values[i], comp2.y_values[i]],\r\n                            comp2.t_values[i]\r\n                        );\r\n                    }\r\n                }\r\n                // Handle next critical point\r\n                if (g < groups2.length) {\r\n                    this.handleSingularity(curve, comp2, groups2[g], x_table2, y_table2);\r\n                    start = groups2[g].idx + 1;\r\n                }\r\n            }\r\n            le = comp2.len;\r\n            if (idx < components2.length - 1) {\r\n                this._insertPoint_v4(curve, [1, NaN, NaN], comp2.right_t);\r\n            }\r\n        }\r\n        return this;\r\n    },\r\n\r\n    _recurse_v4: function (curve, t1, t2, x1, y1, x2, y2, level) {\r\n        var tol = 2,\r\n            t = (t1 + t2) * 0.5,\r\n            x = curve.X(t, true),\r\n            y = curve.Y(t, true),\r\n            dx,\r\n            dy;\r\n\r\n        //console.log(\"Level\", level)\r\n        if (level === 0) {\r\n            this._insertPoint_v4(curve, [1, NaN, NaN], t);\r\n            return;\r\n        }\r\n        // console.log(\"R\", t1, t2)\r\n        dx = (x - x1) * curve.board.unitX;\r\n        dy = (y - y1) * curve.board.unitY;\r\n        // console.log(\"D1\", Math.sqrt(dx * dx + dy * dy))\r\n        if (Mat.hypot(dx, dy) > tol) {\r\n            this._recurse_v4(curve, t1, t, x1, y1, x, y, level - 1);\r\n        } else {\r\n            this._insertPoint_v4(curve, [1, x, y], t);\r\n        }\r\n        dx = (x - x2) * curve.board.unitX;\r\n        dy = (y - y2) * curve.board.unitY;\r\n        // console.log(\"D2\", Math.sqrt(dx * dx + dy * dy), x-x2, y-y2)\r\n        if (Mat.hypot(dx, dy) > tol) {\r\n            this._recurse_v4(curve, t, t2, x, y, x2, y2, level - 1);\r\n        } else {\r\n            this._insertPoint_v4(curve, [1, x, y], t);\r\n        }\r\n    },\r\n\r\n    handleSingularity: function (curve, comp, group, x_table, y_table) {\r\n        var idx = group.idx,\r\n            t,\r\n            t1,\r\n            t2,\r\n            y_int,\r\n            i1,\r\n            i2,\r\n            x,\r\n            // y,\r\n            lo,\r\n            hi,\r\n            d_lft,\r\n            d_rgt,\r\n            d_thresh = 100,\r\n            // d1,\r\n            // d2,\r\n            di1 = 5,\r\n            di2 = 3;\r\n\r\n        t = group.t;\r\n        console.log(\"HandleSingularity at t =\", t);\r\n        // console.log(comp.t_values[idx - 1], comp.y_values[idx - 1], comp.t_values[idx + 1], comp.y_values[idx + 1]);\r\n        // console.log(group);\r\n\r\n        // Look at two points, hopefully left and right from the critical point\r\n        t1 = comp.t_values[idx - di1];\r\n        t2 = comp.t_values[idx + di1];\r\n\r\n        y_int = this.getInterval(curve, t1, t2);\r\n        if (Type.isObject(y_int)) {\r\n            lo = y_int.lo;\r\n            hi = y_int.hi;\r\n        } else {\r\n            if (y_table[0][idx - 1] < y_table[0][idx + 1]) {\r\n                lo = y_table[0][idx - 1];\r\n                hi = y_table[0][idx + 1];\r\n            } else {\r\n                lo = y_table[0][idx + 1];\r\n                hi = y_table[0][idx - 1];\r\n            }\r\n        }\r\n\r\n        x = curve.X(t, true);\r\n\r\n        d_lft =\r\n            (y_table[0][idx - di2] - y_table[0][idx - di1]) /\r\n            (comp.t_values[idx - di2] - comp.t_values[idx - di1]);\r\n        d_rgt =\r\n            (y_table[0][idx + di2] - y_table[0][idx + di1]) /\r\n            (comp.t_values[idx + di2] - comp.t_values[idx + di1]);\r\n\r\n        console.log(\":::\", d_lft, d_rgt);\r\n\r\n        //this._insertPoint_v4(curve, [1, NaN, NaN], 0);\r\n\r\n        if (d_lft < -d_thresh) {\r\n            // Left branch very steep downwards -> add the minimum\r\n            this._insertPoint_v4(curve, [1, x, lo], t, true);\r\n            if (d_rgt <= d_thresh) {\r\n                // Right branch not very steep upwards -> interrupt the curve\r\n                // I.e. it looks like -infty / (finite or infty) and not like -infty / -infty\r\n                this._insertPoint_v4(curve, [1, NaN, NaN], t);\r\n            }\r\n        } else if (d_lft > d_thresh) {\r\n            // Left branch very steep upwards -> add the maximum\r\n            this._insertPoint_v4(curve, [1, x, hi], t);\r\n            if (d_rgt >= -d_thresh) {\r\n                // Right branch not very steep downwards -> interrupt the curve\r\n                // I.e. it looks like infty / (finite or -infty) and not like infty / infty\r\n                this._insertPoint_v4(curve, [1, NaN, NaN], t);\r\n            }\r\n        } else {\r\n            if (lo === -Infinity) {\r\n                this._insertPoint_v4(curve, [1, x, lo], t, true);\r\n                this._insertPoint_v4(curve, [1, NaN, NaN], t);\r\n            }\r\n            if (hi === Infinity) {\r\n                this._insertPoint_v4(curve, [1, NaN, NaN], t);\r\n                this._insertPoint_v4(curve, [1, x, hi], t, true);\r\n            }\r\n\r\n            if (group.t < comp.t_values[idx]) {\r\n                i1 = idx - 1;\r\n                i2 = idx;\r\n            } else {\r\n                i1 = idx;\r\n                i2 = idx + 1;\r\n            }\r\n            t1 = comp.t_values[i1];\r\n            t2 = comp.t_values[i2];\r\n            this._recurse_v4(\r\n                curve,\r\n                t1,\r\n                t2,\r\n                x_table[0][i1],\r\n                y_table[0][i1],\r\n                x_table[0][i2],\r\n                y_table[0][i2],\r\n                10\r\n            );\r\n\r\n            // x = (x_table[0][idx] - x_table[0][idx - 1]) * curve.board.unitX;\r\n            // y = (y_table[0][idx] - y_table[0][idx - 1]) * curve.board.unitY;\r\n            // d1 = Math.sqrt(x * x + y * y);\r\n            // x = (x_table[0][idx + 1] - x_table[0][idx]) * curve.board.unitX;\r\n            // y = (y_table[0][idx + 1] - y_table[0][idx]) * curve.board.unitY;\r\n            // d2 = Math.sqrt(x * x + y * y);\r\n\r\n            // console.log(\"end\", t1, t2, t);\r\n            // if (true || (d1 > 2 || d2 > 2)) {\r\n\r\n            // console.log(d1, d2, y_table[0][idx])\r\n            //                     // Finite jump\r\n            //                     this._insertPoint_v4(curve, [1, NaN, NaN], t);\r\n            //                 } else {\r\n            //                     if (lo !== -Infinity && hi !== Infinity) {\r\n            //                         // Critical point which can be ignored\r\n            //                         this._insertPoint_v4(curve, [1, x_table[0][idx], y_table[0][idx]], comp.t_values[idx]);\r\n            //                     } else {\r\n            //                         if (lo === -Infinity) {\r\n            //                             this._insertPoint_v4(curve, [1, x, lo], t, true);\r\n            //                             this._insertPoint_v4(curve, [1, NaN, NaN], t);\r\n            //                         }\r\n            //                         if (hi === Infinity) {\r\n            //                             this._insertPoint_v4(curve, [1, NaN, NaN], t);\r\n            //                             this._insertPoint_v4(curve, [1, x, hi], t, true);\r\n            //                         }\r\n            //                     }\r\n            // }\r\n        }\r\n        if (d_rgt < -d_thresh) {\r\n            // Right branch very steep downwards -> add the maximum\r\n            this._insertPoint_v4(curve, [1, x, hi], t);\r\n        } else if (d_rgt > d_thresh) {\r\n            // Right branch very steep upwards -> add the minimum\r\n            this._insertPoint_v4(curve, [1, x, lo], t);\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Number of equidistant points where the function is evaluated\r\n     */\r\n    steps: 1021, //2053, // 1021,\r\n\r\n    /**\r\n     * If the absolute maximum of the set of differences is larger than\r\n     * criticalThreshold * median of these values, it is regarded as critical point.\r\n     * @see JXG.Math.Plot._criticalInterval\r\n     */\r\n    criticalThreshold: 1000,\r\n\r\n    plot_v4: function (curve, ta, tb, steps) {\r\n        var i,\r\n            // j,\r\n            le,\r\n            components,\r\n            idx,\r\n            comp,\r\n            groups,\r\n            g,\r\n            start,\r\n            ret,\r\n            x_table, y_table,\r\n            t, t1, t2,\r\n            // good,\r\n            // bad,\r\n            // x_int,\r\n            y_int,\r\n            // degree_x,\r\n            // degree_y,\r\n            h = (tb - ta) / steps,\r\n            Ypl = function (x) {\r\n                return curve.Y(x, true);\r\n            },\r\n            Ymi = function (x) {\r\n                return -curve.Y(x, true);\r\n            },\r\n            h2 = h * 0.5;\r\n\r\n        components = this.findComponents(curve, ta, tb, steps);\r\n        for (idx = 0; idx < components.length; idx++) {\r\n            comp = components[idx];\r\n            ret = this.differenceMethod(comp, curve);\r\n            groups = ret[0];\r\n            x_table = ret[1];\r\n            y_table = ret[2];\r\n\r\n            // degree_x = ret[3];\r\n            // degree_y = ret[4];\r\n            // if (degree_x >= 0) {\r\n            //     console.log(\"x polynomial of degree\", degree_x);\r\n            // }\r\n            // if (degree_y >= 0) {\r\n            //     console.log(\"y polynomial of degree\", degree_y);\r\n            // }\r\n            if (groups.length === 0 || groups[0].type !== 'borderleft') {\r\n                groups.unshift({\r\n                    idx: 0,\r\n                    t: comp.t_values[0],\r\n                    x: comp.x_values[0],\r\n                    y: comp.y_values[0],\r\n                    type: \"borderleft\"\r\n                });\r\n            }\r\n            if (groups[groups.length - 1].type !== 'borderright') {\r\n                le = comp.t_values.length;\r\n                groups.push({\r\n                    idx: le - 1,\r\n                    t: comp.t_values[le - 1],\r\n                    x: comp.x_values[le - 1],\r\n                    y: comp.y_values[le - 1],\r\n                    type: \"borderright\"\r\n                });\r\n            }\r\n\r\n            start = 0;\r\n            for (g = 0; g <= groups.length; g++) {\r\n                if (g === groups.length) {\r\n                    le = comp.len;\r\n                } else {\r\n                    le = groups[g].idx - 1;\r\n                }\r\n\r\n                // good = 0;\r\n                // bad = 0;\r\n                // Insert all uncritical points until next critical point\r\n                for (i = start; i < le - 2; i++) {\r\n                    this._insertPoint_v4(\r\n                        curve,\r\n                        [1, comp.x_values[i], comp.y_values[i]],\r\n                        comp.t_values[i]\r\n                    );\r\n                    // j = Math.max(0, i - 2);\r\n                    // Add more points in critical intervals\r\n                    if (\r\n                        //degree_y === -1 && // No polynomial\r\n                        i >= start + 3 &&\r\n                        i < le - 3 && // Do not do this if too close to a critical point\r\n                        y_table.length > 3 &&\r\n                        Math.abs(y_table[2][i]) > 0.2 * Math.abs(y_table[0][i])\r\n                    ) {\r\n                        t = comp.t_values[i];\r\n                        h2 = h * 0.25;\r\n                        y_int = this.getInterval(curve, t, t + h);\r\n                        if (Type.isObject(y_int)) {\r\n                            if (y_table[2][i] > 0) {\r\n                                this._insertPoint_v4(curve, [1, t + h2, y_int.lo], t + h2);\r\n                            } else {\r\n                                this._insertPoint_v4(\r\n                                    curve,\r\n                                    [1, t + h - h2, y_int.hi],\r\n                                    t + h - h2\r\n                                );\r\n                            }\r\n                        } else {\r\n                            t1 = Numerics.fminbr(Ypl, [t, t + h]);\r\n                            t2 = Numerics.fminbr(Ymi, [t, t + h]);\r\n                            if (t1 < t2) {\r\n                                this._insertPoint_v4(\r\n                                    curve,\r\n                                    [1, curve.X(t1, true), curve.Y(t1, true)],\r\n                                    t1\r\n                                );\r\n                                this._insertPoint_v4(\r\n                                    curve,\r\n                                    [1, curve.X(t2, true), curve.Y(t2, true)],\r\n                                    t2\r\n                                );\r\n                            } else {\r\n                                this._insertPoint_v4(\r\n                                    curve,\r\n                                    [1, curve.X(t2, true), curve.Y(t2, true)],\r\n                                    t2\r\n                                );\r\n                                this._insertPoint_v4(\r\n                                    curve,\r\n                                    [1, curve.X(t1, true), curve.Y(t1, true)],\r\n                                    t1\r\n                                );\r\n                            }\r\n                        }\r\n                        // bad++;\r\n                    // } else {\r\n                        // good++;\r\n                    }\r\n                }\r\n                // console.log(\"GOOD\", good, \"BAD\", bad);\r\n\r\n                // Handle next critical point\r\n                if (g < groups.length) {\r\n                    //console.log(\"critical point / interval\", groups[g]);\r\n\r\n                    i = groups[g].idx;\r\n                    if (groups[g].type === \"borderleft\" || groups[g].type === 'borderright') {\r\n                        this.handleBorder(curve, comp, groups[g], x_table, y_table);\r\n                    } else {\r\n                        this._seconditeration_v4(curve, comp, groups[g], x_table, y_table);\r\n                    }\r\n\r\n                    start = groups[g].idx + 1 + 1;\r\n                }\r\n            }\r\n\r\n            le = comp.len;\r\n            if (idx < components.length - 1) {\r\n                this._insertPoint_v4(curve, [1, NaN, NaN], comp.right_t);\r\n            }\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Updates the data points of a parametric curve, plotVersion 4. This version is used if {@link JXG.Curve#plotVersion} is <tt>4</tt>.\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {Number} mi Left bound of curve\r\n     * @param {Number} ma Right bound of curve\r\n     * @returns {JXG.Curve} Reference to the curve object.\r\n     */\r\n    updateParametricCurve_v4: function (curve, mi, ma) {\r\n        var ta, tb, w2, bbox;\r\n\r\n        if (curve.xterm === 'x') {\r\n            // For function graphs we can restrict the plot interval\r\n            // to the visible area +plus margin\r\n            bbox = curve.board.getBoundingBox();\r\n            w2 = (bbox[2] - bbox[0]) * 0.3;\r\n            // h2 = (bbox[1] - bbox[3]) * 0.3;\r\n            ta = Math.max(mi, bbox[0] - w2);\r\n            tb = Math.min(ma, bbox[2] + w2);\r\n        } else {\r\n            ta = mi;\r\n            tb = ma;\r\n        }\r\n\r\n        curve.points = [];\r\n\r\n        //console.log(\"--------------------\");\r\n        this.plot_v4(curve, ta, tb, this.steps);\r\n\r\n        curve.numberPoints = curve.points.length;\r\n        //console.log(curve.numberPoints);\r\n    },\r\n\r\n    //----------------------------------------------------------------------\r\n    // Plot algorithm alias\r\n    //----------------------------------------------------------------------\r\n\r\n    /**\r\n     * Updates the data points of a parametric curve, alias for {@link JXG.Curve#updateParametricCurve_v2}.\r\n     * This is needed for backwards compatibility, if this method has been\r\n     * used directly in an application.\r\n     * @param {JXG.Curve} curve JSXGraph curve element\r\n     * @param {Number} mi Left bound of curve\r\n     * @param {Number} ma Right bound of curve\r\n     * @returns {JXG.Curve} Reference to the curve object.\r\n     *\r\n     * @see JXG.Curve#updateParametricCurve_v2\r\n     */\r\n    updateParametricCurve: function (curve, mi, ma) {\r\n        return this.updateParametricCurve_v2(curve, mi, ma);\r\n    }\r\n};\r\n\r\nexport default Mat.Plot;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n\"use strict\";\r\n\r\nimport Type from \"../utils/type.js\";\r\nimport Mat from \"./math.js\";\r\nimport Geometry from \"./geometry.js\";\r\nimport Numerics from \"./numerics.js\";\r\nimport Quadtree from \"./bqdt.js\";\r\n\r\n/**\r\n * Plotting of curves which are given implicitly as the set of points solving an equation\r\n * <i>f(x,y) = 0</i>.\r\n * <p>\r\n * The main class initializes a new implicit plot instance.\r\n * <p>\r\n * The algorithm should be able to plot most implicit curves as long as the equations\r\n * are not too complex. We are aware of the paper by Oliver Labs,\r\n * <a href=\"https://link.springer.com/chapter/10.1007/978-1-4419-0999-2_6\">A List of Challenges for Real Algebraic Plane Curve Visualization Software</a>\r\n * which contains many equations where this algorithm may fail.\r\n * For example,  at the time being there is no attempt to detect <i>solitary points</i>.\r\n * Also, it is always a trade off to find all components of the curve and\r\n * keep the construction responsive.\r\n *\r\n * @name JXG.Math.ImplicitPlot\r\n * @exports Mat.ImplicitPlot as JXG.Math.ImplicitPlot\r\n * @param {Array} bbox Bounding box of the area in which solutions of the equation\r\n * are determined.\r\n * @param {Object} config Configuration object. Default:\r\n * <pre>\r\n *  {\r\n *      resolution_out: 5,    // Horizontal resolution: distance between vertical lines to search for components\r\n *      resolution_in: 5,     // Vertical resolution to search for components\r\n *      max_steps: 1024,      // Max number of points in one call of tracing\r\n *      alpha_0: 0.05,        // Angle between two successive tangents: smoothness of curve\r\n *\r\n *      tol_u0: Mat.eps,      // Tolerance to find starting points for tracing.\r\n *      tol_newton: 1.0e-7,   // Tolerance for Newton steps.\r\n *      tol_cusp: 0.05,       // Tolerance for cusp / bifurcation detection\r\n *      tol_progress: 0.0001, // If two points are closer than this value, we bail out\r\n *      qdt_box: 0.2,         // half of box size to search in qdt\r\n *      kappa_0: 0.2,         // Inverse of planned number of Newton steps\r\n *      delta_0: 0.05,        // Distance of predictor point to curve\r\n *\r\n *      h_initial: 0.1,       // Initial stepwidth\r\n *      h_critical: 0.001,    // If h is below this threshold we bail out\r\n *      h_max: 1,             // Maximal value of h (user units)\r\n *      loop_dist: 0.09,      // Allowed distance (multiplied by actual stepwidth) to detect loop\r\n *      loop_dir: 0.99,       // Should be > 0.95\r\n *      loop_detection: true, // Use Gosper's loop detector\r\n *      unitX: 10,            // unitX of board\r\n *      unitY: 10             // unitX of board\r\n *   };\r\n * </pre>\r\n * @param {function} f function from <b>R</b><sup>2</sup> to <b>R</b>\r\n * @param {function} [dfx] Optional partial derivative of <i>f</i> with regard to <i>x</i>\r\n * @param {function} [dfy] Optional partial derivative of <i>f</i> with regard to <i>y</i>\r\n *\r\n * @constructor\r\n * @example\r\n *     var f = (x, y) => x**3 - 2 * x * y + y**3;\r\n *     var c = board.create('curve', [[], []], {\r\n *             strokeWidth: 3,\r\n *             strokeColor: JXG.palette.red\r\n *         });\r\n *\r\n *     c.updateDataArray = function () {\r\n *         var bbox = this.board.getBoundingBox(),\r\n *             ip, cfg,\r\n *             ret = [],\r\n *             mgn = 1;\r\n *\r\n *         bbox[0] -= mgn;\r\n *         bbox[1] += mgn;\r\n *         bbox[2] += mgn;\r\n *         bbox[3] -= mgn;\r\n *\r\n *         cfg = {\r\n *             resolution_out: 5,\r\n *             resolution_in: 5,\r\n *             unitX: this.board.unitX,\r\n *             unitY: this.board.unitX\r\n *         };\r\n *\r\n *         this.dataX = [];\r\n *         this.dataY = [];\r\n *         ip = new JXG.Math.ImplicitPlot(bbox, cfg, f, null, null);\r\n *         ret = ip.plot();\r\n *         this.dataX = ret[0];\r\n *         this.dataY = ret[1];\r\n *     };\r\n *     board.update();\r\n * </pre><div id=\"JXGf3e8cd82-2b67-4efb-900a-471eb92b3b96\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGf3e8cd82-2b67-4efb-900a-471eb92b3b96',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *             var f = (x, y) => x**3 - 2 * x * y + y**3;\r\n *             var c = board.create('curve', [[], []], {\r\n *                     strokeWidth: 3,\r\n *                     strokeColor: JXG.palette.red\r\n *                 });\r\n *\r\n *             c.updateDataArray = function () {\r\n *                 var bbox = this.board.getBoundingBox(),\r\n *                     ip, cfg,\r\n *                     ret = [],\r\n *                     mgn = 1;\r\n *\r\n *                 bbox[0] -= mgn;\r\n *                 bbox[1] += mgn;\r\n *                 bbox[2] += mgn;\r\n *                 bbox[3] -= mgn;\r\n *\r\n *                 cfg = {\r\n *                     resolution_out: 5,\r\n *                     resolution_in: 5,\r\n *                     unitX: this.board.unitX,\r\n *                     unitY: this.board.unitX\r\n *                 };\r\n *\r\n *                 this.dataX = [];\r\n *                 this.dataY = [];\r\n *\r\n *                 ip = new JXG.Math.ImplicitPlot(bbox, cfg, f, null, null);\r\n *                 ret = ip.plot();\r\n *\r\n *                 this.dataX = ret[0];\r\n *                 this.dataY = ret[1];\r\n *             };\r\n *             board.update();\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nMat.ImplicitPlot = function (bbox, config, f, dfx, dfy) {\r\n\r\n    // Default values\r\n    var cfg_default = {\r\n        resolution_out: 5,    // Distance between vertical lines to search for components\r\n        resolution_in: 5,     // Distance between vertical lines to search for components\r\n        max_steps: 1024,      // Max number of points in one call of tracing\r\n        alpha_0: 0.05,        // Angle between two successive tangents: smoothness of curve\r\n\r\n        tol_u0: Mat.eps,      // Tolerance to find starting points for tracing.\r\n        tol_newton: 1.0e-7,   // Tolerance for Newton steps.\r\n        tol_cusp: 0.05,       // Tolerance for cusp / bifurcation detection\r\n        tol_progress: 0.0001, // If two points are closer than this value, we bail out\r\n        qdt_box: 0.2,         // half of box size to search in qdt\r\n        kappa_0: 0.2,         // Inverse of planned number of Newton steps\r\n        delta_0: 0.05,        // Distance of predictor point to curve\r\n\r\n        h_initial: 0.1,       // Initial step width\r\n        h_critical: 0.001,    // If h is below this threshold we bail out\r\n        h_max: 1,             // Maximum value of h (user units)\r\n        loop_dist: 0.09,      // Allowed distance (multiplied by actual step width) to detect loop\r\n        loop_dir: 0.99,       // Should be > 0.95\r\n        loop_detection: true, // Use Gosper's loop detector\r\n        unitX: 10,            // unitX of board\r\n        unitY: 10             // unitX of board\r\n    };\r\n\r\n    this.config = Type.merge(cfg_default, config);\r\n\r\n    this.f = f;\r\n\r\n    this.dfx = null;\r\n    this.dfy = null;\r\n\r\n    if (Type.isFunction(dfx)) {\r\n        this.dfx = dfx;\r\n    } else {\r\n        this.dfx = function (x, y) {\r\n            var h = Mat.eps * Mat.eps;\r\n            return (this.f(x + h, y) - this.f(x - h, y)) * 0.5 / h;\r\n        };\r\n    }\r\n\r\n    if (Type.isFunction(dfy)) {\r\n        this.dfy = dfy;\r\n    } else {\r\n        this.dfy = function (x, y) {\r\n            var h = Mat.eps * Mat.eps;\r\n            return (this.f(x, y + h) - this.f(x, y - h)) * 0.5 / h;\r\n        };\r\n    }\r\n\r\n    this.bbox = bbox;\r\n    this.qdt = new Quadtree(20, 5, bbox);\r\n\r\n    this.components = [];\r\n};\r\n\r\nType.extend(\r\n    Mat.ImplicitPlot.prototype,\r\n    /** @lends JXG.Math.ImplicitPlot.prototype */ {\r\n\r\n        /**\r\n         * Implicit plotting method.\r\n         *\r\n         * @returns {Array} consisting of [dataX, dataY, number_of_components]\r\n         */\r\n        plot: function () {\r\n            var // components = [],\r\n                doVerticalSearch = true,\r\n                doHorizontalSearch = true,\r\n                x, y,\r\n                mi_x, ma_x, mi_y, ma_y,\r\n                dataX = [],\r\n                dataY = [],\r\n                ret = [],\r\n                num_components = 0,\r\n\r\n                delta,\r\n                that = this,\r\n\r\n                fmi_x = function (t) {\r\n                    return that.f(x, t);\r\n                },\r\n                fma_x = function (t) {\r\n                    return -that.f(x, t);\r\n                },\r\n                fmi_y = function (t) {\r\n                    return that.f(t, y);\r\n                },\r\n                fma_y = function (t) {\r\n                    return -that.f(t, y);\r\n                };\r\n\r\n            // Vertical lines or circular search:\r\n            mi_x = Math.min(this.bbox[0], this.bbox[2]) - Mat.eps;\r\n            ma_x = Math.max(this.bbox[0], this.bbox[2]);\r\n            mi_y = Math.min(this.bbox[1], this.bbox[3]) + Mat.eps;\r\n            ma_y = Math.max(this.bbox[1], this.bbox[3]);\r\n\r\n            if (doVerticalSearch) {\r\n                delta = this.config.resolution_out / this.config.unitX;\r\n                delta *= (1 + Mat.eps);\r\n                // console.log(\"Outer delta x\", delta)\r\n\r\n                for (x = mi_x; x < ma_x; x += delta) {\r\n                    ret = this.searchLine(\r\n                        fmi_x, fma_x, x,\r\n                        [mi_y, ma_y], 'vertical',\r\n                        num_components, dataX, dataY, 20);\r\n\r\n                    if (ret !== false) {\r\n                        dataX = ret[0];\r\n                        dataY = ret[1];\r\n                        num_components = ret[2];\r\n                    }\r\n\r\n                }\r\n            }\r\n            if (doHorizontalSearch) {\r\n                delta = this.config.resolution_out / this.config.unitY;\r\n                delta *= (1 + Mat.eps);\r\n                // console.log(\"Outer delta y\", delta)\r\n\r\n                for (y = mi_y; y < ma_y; y += delta) {\r\n                    ret = this.searchLine(\r\n                        fmi_y, fma_y, y,\r\n                        [mi_x, ma_x], 'horizontal',\r\n                        num_components, dataX, dataY, 20);\r\n\r\n                    if (ret !== false) {\r\n                        dataX = ret[0];\r\n                        dataY = ret[1];\r\n                        num_components = ret[2];\r\n                    }\r\n                }\r\n            }\r\n\r\n            return [dataX, dataY, num_components];\r\n        },\r\n\r\n        /**\r\n         * Recursively search a horizontal or vertical line for points on the\r\n         * fulfilling the given equation.\r\n         *\r\n         * @param {Function} fmi Minimization function\r\n         * @param {Function} fma Maximization function\r\n         * @param {Number} fix Value of the fixed variable\r\n         * @param {Array} interval Search interval of the free variable\r\n         * @param {String} dir 'vertical' or 'horizontal'\r\n         * @param {Number} num_components Number of components before search\r\n         * @param {Array} dataX x-coordinates of points so far\r\n         * @param {Array} dataY y-coordinates of points so far\r\n         * @param {Number} level Recursion level\r\n         * @returns {Array} consisting of [dataX, dataY, number_of_components]-\r\n         * @private\r\n         */\r\n        searchLine: function (fmi, fma, fix, interval, dir,\r\n            num_components, dataX, dataY, level) {\r\n            var t_mi, t_ma, t,\r\n                ft,\r\n                mi, ma, tmp, m,\r\n                is_in,\r\n                u0, i, le,\r\n                ret,\r\n                offset,\r\n                delta,\r\n                eps = this.config.tol_u0,\r\n                DEBUG = false,\r\n                b = interval[0],\r\n                e = interval[1];\r\n\r\n            t_mi = Numerics.fminbr(fmi, [b, e]);\r\n            mi = fmi(t_mi);\r\n            t_ma = Numerics.fminbr(fma, [b, e]);\r\n            ma = fmi(t_ma);\r\n\r\n            if (mi < eps && ma > -eps) {\r\n                tmp = t_mi;\r\n                t_mi = Math.min(tmp, t_ma);\r\n                t_ma = Math.max(tmp, t_ma);\r\n\r\n                t = Numerics.fzero(fmi, [t_mi, t_ma]);\r\n                // t = Numerics.chandrupatla(fmi, [t_mi, t_ma]);\r\n\r\n                ft = fmi(t);\r\n                if (Math.abs(ft) > Math.max((ma - mi) * Mat.eps, 0.001)) {\r\n                    //console.log(\"searchLine:\",  dir, fix, t, \"no root \" + ft);\r\n                    return false;\r\n                    // throw new Error(\"searchLine: no root \" + ft);\r\n                }\r\n                if (dir === 'vertical') {\r\n                    u0 = [1, fix, t];\r\n                    delta = this.config.resolution_in / this.config.unitY;\r\n                    // console.log(\"Inner delta x\", delta)\r\n                } else {\r\n                    u0 = [1, t, fix];\r\n                    delta = this.config.resolution_in / this.config.unitX;\r\n                    // console.log(\"Inner delta y\", delta)\r\n                }\r\n                delta *= (1 + Mat.eps);\r\n\r\n                is_in = this.curveContainsPoint(u0, dataX, dataY,\r\n                    delta * 2,           // Allowed dist from segment\r\n                    this.config.qdt_box  // 0.5 of box size to search in qdt\r\n                );\r\n\r\n                if (is_in) {\r\n                    if (DEBUG) {\r\n                        console.log(\"Found in quadtree\", u0);\r\n                    }\r\n                } else {\r\n                    if (DEBUG) {\r\n                        console.log(\"Not in quadtree\", u0, dataX.length);\r\n                    }\r\n                    ret = this.traceComponent(u0, 1);\r\n                    if (ret[0].length > 0) {\r\n                        // Add jump in curve\r\n                        if (num_components > 0) {\r\n                            dataX.push(NaN);\r\n                            dataY.push(NaN);\r\n                        }\r\n\r\n                        offset = dataX.length;\r\n                        le = ret[0].length;\r\n                        for (i = 1; i < le; i++) {\r\n                            this.qdt.insertItem({\r\n                                xlb: Math.min(ret[0][i - 1], ret[0][i]),\r\n                                xub: Math.max(ret[0][i - 1], ret[0][i]),\r\n                                ylb: Math.min(ret[1][i - 1], ret[1][i]),\r\n                                yub: Math.max(ret[1][i - 1], ret[1][i]),\r\n                                idx1: offset + i - 1,\r\n                                idx2: offset + i,\r\n                                comp: num_components\r\n                            });\r\n                        }\r\n\r\n                        num_components++;\r\n                        Type.concat(dataX, ret[0]);\r\n                        Type.concat(dataY, ret[1]);\r\n                    }\r\n                }\r\n\r\n                m = t - delta * 0.01;\r\n                if (m - b > delta && level > 0) {\r\n                    ret = this.searchLine(\r\n                        fmi, fma, fix, [b, m], dir,\r\n                        num_components, dataX, dataY, level - 1);\r\n                    if (ret !== false) {\r\n                        dataX = ret[0];\r\n                        dataY = ret[1];\r\n                        num_components = ret[2];\r\n                    }\r\n                }\r\n                m = t + delta * 0.01;\r\n                if (e - m > delta  && level > 0) {\r\n                    ret = this.searchLine(\r\n                        fmi, fma, fix, [m, e], dir,\r\n                        num_components, dataX, dataY, level - 1);\r\n                    if (ret !== false) {\r\n                        dataX = ret[0];\r\n                        dataY = ret[1];\r\n                        num_components = ret[2];\r\n                    }\r\n                }\r\n\r\n                return [dataX, dataY, num_components];\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Test if the data points contain a given coordinate, i.e. if the\r\n         * given coordinate is close enough to the polygonal chain\r\n         * through the data points.\r\n         *\r\n         * @param {Array} p Homogenous coordinates [1, x, y] of the coordinate point\r\n         * @param {Array} dataX x-coordinates of points so far\r\n         * @param {Array} dataY y-coordinates of points so far\r\n         * @param {Number} tol Maximal distance of p from the polygonal chain through the data points\r\n         * @param {Number} eps Helper tolerance used for the quadtree\r\n         * @returns Boolean\r\n         */\r\n        curveContainsPoint: function (p, dataX, dataY, tol, eps) {\r\n            var i, le, hits, d,\r\n                x = p[1],\r\n                y = p[2];\r\n\r\n            hits = this.qdt.find([x - eps, y + eps, x + eps, y - eps]);\r\n\r\n            le = hits.length;\r\n            for (i = 0; i < le; i++) {\r\n                d = Geometry.distPointSegment(\r\n                    p,\r\n                    [1, dataX[hits[i].idx1], dataY[hits[i].idx1]],\r\n                    [1, dataX[hits[i].idx2], dataY[hits[i].idx2]]\r\n                );\r\n                if (d < tol) {\r\n                    return true;\r\n                }\r\n            }\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Starting at an initial point the curve is traced with a Euler-Newton method.\r\n         * After tracing in one direction the algorithm stops if the component is a closed loop.\r\n         * Otherwise, the curved is traced in the opposite direction, starting from\r\n         * the same initial point. Finally, the two components are glued together.\r\n         *\r\n         * @param {Array} u0 Initial point in homogenous coordinates [1, x, y].\r\n         * @returns Array [dataX, dataY] containing a new component.\r\n         * @private\r\n         */\r\n        traceComponent: function (u0) {\r\n            var dataX = [],\r\n                dataY = [],\r\n                arr = [];\r\n\r\n            // Trace in first direction\r\n            // console.log(\"---- Start tracing forward ---------\")\r\n            arr = this.tracing(u0, 1);\r\n\r\n            if (arr.length === 0) {\r\n                // console.log(\"Could not start tracing due to singularity\")\r\n            } else {\r\n                // console.log(\"Trace from\", [arr[0][0], arr[1][0]], \"to\", [arr[0][arr[0].length - 1], arr[1][arr[1].length - 1]],\r\n                //    \"num points:\", arr[0].length);\r\n                dataX = arr[0];\r\n                dataY = arr[1];\r\n            }\r\n\r\n            // Trace in the other direction\r\n            if (!arr[2]) {\r\n                // No loop in the first tracing step,\r\n                // now explore the other direction.\r\n\r\n                // console.log(\"---- Start tracing backward ---------\")\r\n                arr = this.tracing(u0, -1);\r\n\r\n                if (arr.length === 0) {\r\n                    // console.log(\"Could not start backward tracing due to singularity\")\r\n                } else {\r\n                    // console.log(\"Trace backwards from\", [arr[0][0], arr[1][0]], \"to\",\r\n                    //     [arr[0][arr[0].length - 1], arr[1][arr[1].length - 1]], \"num points:\", arr[0].length);\r\n                    dataX = arr[0].reverse().concat(dataX.slice(1));\r\n                    dataY = arr[1].reverse().concat(dataY.slice(1));\r\n                }\r\n            }\r\n\r\n            if (dataX.length > 0 && dataX.length < 6) {\r\n                // Solitary point\r\n                dataX.push(dataX[dataX.length - 1]);\r\n                dataY.push(dataY[dataY.length - 1]);\r\n            }\r\n\r\n            return [dataX, dataY];\r\n        },\r\n\r\n        /**\r\n         * Starting at a point <i>u0</i>, this routine traces the curve <i>f(u)=0</i> until\r\n         * a loop is detected, a critical point is reached, the curve leaves the bounding box,\r\n         * or the maximum number of points is reached.\r\n         * <p>\r\n         * The method is a predictor / corrector method consisting of Euler and Newton steps\r\n         * together with step width adaption.\r\n         * <p>\r\n         * The algorithm is an adaption of the algorithm in\r\n         * Eugene L. Allgower, Kurt Georg: <i>Introduction to Numerical Continuation methods.</i>\r\n         *\r\n         * @param {Array} u0 Starting point in homogenous coordinates  [1, x, y].\r\n         * @param {Number} direction 1 or -1\r\n         * @returns Array [pathX, pathY, loop_closed] or []\r\n         * @private\r\n         */\r\n        tracing: function (u0, direction) {\r\n            var u = [],\r\n                ulast = [],\r\n                len,\r\n                v = [],\r\n                v_start = [],\r\n                w = [],\r\n                t_u, t_v, t_u_0, tloc,\r\n                A,\r\n                grad,\r\n                nrm,\r\n                dir,\r\n                steps = 0,\r\n                k = 0,\r\n                loop_closed = false,\r\n                k0, k1, denom, dist, progress,\r\n                kappa, delta, alpha,\r\n                factor,\r\n                point_added = false,\r\n\r\n                quasi = false,\r\n                cusp_or_bifurc = false,\r\n                kappa_0 = this.config.kappa_0,  // Inverse of planned number of Newton steps\r\n                delta_0 = this.config.delta_0,  // Distance of predictor point to curve\r\n                alpha_0 = this.config.alpha_0,  // Angle between two successive tangents\r\n                h = this.config.h_initial,\r\n                max_steps = this.config.max_steps,\r\n\r\n                omega = direction,\r\n                pathX = [],\r\n                pathY = [],\r\n\r\n                T = [],            // Gosper's loop detector table\r\n                n, m, i, e;\r\n\r\n            u = u0.slice(1);\r\n            pathX.push(u[0]);\r\n            pathY.push(u[1]);\r\n\r\n            t_u = this.tangent(u);\r\n            if (t_u === false) {\r\n                // We don't want to start at a singularity.\r\n                // Get out of here and search for another starting point.\r\n                return [];\r\n            }\r\n            A = [this.dfx(u[0], u[1]), this.dfy(u[0], u[1])];\r\n\r\n            do {\r\n\r\n                if (quasi) {\r\n                    t_u = this.tangent_A(A);\r\n                } else {\r\n                    t_u = this.tangent(u);\r\n                }\r\n                if (t_u === false) {\r\n                    u = v.slice();\r\n                    pathX.push(u[0]);\r\n                    pathY.push(u[1]);\r\n                    // console.log(\"-> Bail out: t_u undefined.\");\r\n                    break;\r\n                }\r\n\r\n                if (pathX.length === 1) {\r\n                    // Store first point\r\n                    t_u_0 = t_u.slice();\r\n                } else if (pathX.length === 2) {\r\n                    T.push(pathX.length - 1);       // Put first point into Gosper table T\r\n\r\n                } else if (point_added && pathX.length > 2 && !cusp_or_bifurc) {\r\n\r\n                    // Detect if loop has been closed\r\n                    dist = Geometry.distPointSegment(\r\n                        [1, u[0], u[1]],\r\n                        [1, pathX[0], pathY[0]],\r\n                        [1, pathX[1], pathY[1]]\r\n                    );\r\n\r\n                    if (dist < this.config.loop_dist * h &&\r\n                        Mat.innerProduct(t_u, t_u_0, 2) > this.config.loop_dir\r\n                    ) {\r\n\r\n                        // console.log(\"Loop detected after\", steps, 'steps');\r\n                        // console.log(\"\\t\", \"v\", v, \"u0:\", u0)\r\n                        // console.log(\"\\t\", \"Dist(v, path0)\", dist, config.loop_dist * h)\r\n                        // console.log(\"\\t\", \"t_u\", t_u);\r\n                        // console.log(\"\\t\", \"inner:\", Mat.innerProduct(t_u, t_u_0, 2));\r\n                        // console.log(\"\\t\", \"h\", h);\r\n\r\n                        u = u0.slice(1);\r\n                        pathX.push(u[0]);\r\n                        pathY.push(u[1]);\r\n\r\n                        loop_closed = true;\r\n                        break;\r\n                    }\r\n\r\n                    // Gosper's loop detector\r\n                    if (this.config.loop_detection) {\r\n                        n = pathX.length - 1;\r\n                        // console.log(\"Check Gosper\", n);\r\n                        m = Math.floor(Mat.log2(n));\r\n\r\n                        for (i = 0; i <= m; i++) {\r\n                            dist = Geometry.distPointSegment(\r\n                                [1, u[0], u[1]],\r\n                                [1, pathX[T[i] - 1], pathY[T[i] - 1]],\r\n                                [1, pathX[T[i]], pathY[T[i]]]\r\n                            );\r\n\r\n                            if (dist < this.config.loop_dist * h) {\r\n                                // console.log(\"!!!!!!!!!!!!!!! GOSPER LOOP CLOSED !!!!\", i, n + 1,\r\n                                //     this.config.loop_dist * h\r\n                                // );\r\n\r\n                                t_v = this.tangent([pathX[T[i]], pathY[T[i]]]);\r\n                                if (Mat.innerProduct(t_u, t_v, 2) > this.config.loop_dir) {\r\n                                    // console.log(\"!!!!!!!!!!!!!!! angle is good enough\");\r\n                                    break;\r\n                                }\r\n                            }\r\n                        }\r\n                        if (i <= m) {\r\n                            loop_closed = true;\r\n                            break;\r\n                        }\r\n\r\n                        m = 1;\r\n                        e = 0;\r\n                        for (i = 0; i < 100; i++) {\r\n                            if ((n + 1) % m !== 0) {\r\n                                break;\r\n                            }\r\n                            m *= 2;\r\n                            e++;\r\n                        }\r\n                        // console.log(\"Add at e\", e);\r\n                        T[e] = n;\r\n                    }\r\n\r\n                }\r\n\r\n                // Predictor step\r\n                // if (true /*h < 2 * this.config.h_initial*/) {\r\n                // Euler\r\n                // console.log('euler')\r\n                v[0] = u[0] + h * omega * t_u[0];\r\n                v[1] = u[1] + h * omega * t_u[1];\r\n                // } else {\r\n                //     // Heun\r\n                //     // console.log('heun')\r\n                //     v[0] = u[0] + h * omega * t_u[0];\r\n                //     v[1] = u[1] + h * omega * t_u[1];\r\n\r\n                //     t_v = this.tangent(v);\r\n                //     v[0] = 0.5 * u[0] + 0.5 * (v[0] + h * omega * t_v[0]);\r\n                //     v[1] = 0.5 * u[1] + 0.5 * (v[1] + h * omega * t_v[1]);\r\n                // }\r\n                if (quasi) {\r\n                    A = this.updateA(A, u, v);\r\n                    v_start = v.slice();\r\n                }\r\n\r\n                // Corrector step: Newton\r\n                k = 0;\r\n                do {\r\n                    if (quasi) {\r\n                        grad = A;\r\n                    } else {\r\n                        grad = [this.dfx(v[0], v[1]), this.dfy(v[0], v[1])];\r\n                    }\r\n\r\n                    // Compute w = v - A(v) * f(v),\r\n                    // grad: row vector and A(v) is the Moore-Penrose inverse:\r\n                    // grad^T * (grad * grad^T)^(-1)\r\n                    denom = grad[0] * grad[0] + grad[1] * grad[1];\r\n                    nrm = this.f(v[0], v[1]) / denom;\r\n\r\n                    w[0] = v[0] - grad[0] * nrm;\r\n                    w[1] = v[1] - grad[1] * nrm;\r\n                    if (k === 0) {\r\n                        k0 = Math.abs(nrm) * Math.sqrt(denom);\r\n                    } else if (k === 1) {\r\n                        k1 = Math.abs(nrm) * Math.sqrt(denom);\r\n                    }\r\n\r\n                    v[0] = w[0];\r\n                    v[1] = w[1];\r\n                    k++;\r\n                } while (k < 20 &&\r\n                    Math.abs(this.f(v[0], v[1])) > this.config.tol_newton\r\n                );\r\n\r\n                delta = k0;\r\n                if (k > 1) {\r\n                    kappa = k1 / k0;\r\n                } else {\r\n                    kappa = 0.0;\r\n                }\r\n\r\n                if (quasi) {\r\n                    A = this.updateA(A, v_start, v);\r\n                    t_v = this.tangent_A(A);\r\n                } else {\r\n                    t_v = this.tangent(v);\r\n                }\r\n\r\n                dir = Mat.innerProduct(t_u, t_v, 2);\r\n                dir = Math.max(-1, Math.min(1, dir));\r\n                alpha = Math.acos(dir);\r\n\r\n                // Look for simple bifurcation points and cusps\r\n                cusp_or_bifurc = false;\r\n                progress = Geometry.distance(u, v, 2);\r\n                if (progress < this.config.tol_progress) {\r\n                    u = v.slice();\r\n                    pathX.push(u[0]);\r\n                    pathY.push(u[1]);\r\n                    // console.log(\"-> Bail out, no progress\", progress, steps);\r\n                    break;\r\n\r\n                } else if (dir < 0.0) {\r\n                    if (h > this.config.h_critical) {\r\n                        // console.log(\"Critical point at [\", u[0].toFixed(4), u[1].toFixed(4), \"], v: [\", v[0].toFixed(4), v[1].toFixed(4), \"], but large  h:\", h);\r\n\r\n                    } else {\r\n\r\n                        cusp_or_bifurc = true;\r\n                        if (this.isBifurcation(u, this.config.tol_cusp)) {\r\n                            // console.log(steps, \"bifurcation point between\", u, \"and\", v, \":\", dir, \"h\", h, \"alpha\", alpha);\r\n                            // A = [dfx(v[0], v[1]), dfy(v[0], v[1])];\r\n                            omega *= (-1);\r\n                            // If there is a bifurcation point, we\r\n                            // ignore the angle alpha for subsequent step length\r\n                            // adaption. Because then we might be able to\r\n                            // \"jump over the critical point\"\r\n                            alpha = 0;\r\n                        } else {\r\n                            // Cusp or something more weird\r\n                            u = v.slice();\r\n                            pathX.push(u[0]);\r\n                            pathY.push(u[1]);\r\n                            // console.log(\"-> Bail out, cusp\")\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // Adapt stepwidth\r\n                if (!cusp_or_bifurc) {\r\n                    factor = Math.max(\r\n                        Math.sqrt(kappa / kappa_0),\r\n                        Math.sqrt(delta / delta_0),\r\n                        alpha / alpha_0\r\n                    );\r\n                    if (isNaN(factor)) {\r\n                        factor = 1;\r\n                    }\r\n                    factor = Math.max(Math.min(factor, 2), 0.5);\r\n                    h /= factor;\r\n                    h = Math.min(this.config.h_max, h);\r\n\r\n                    if (factor >= 2) {\r\n                        steps++;\r\n                        if (steps >= 3 * max_steps) {\r\n                            break;\r\n                        }\r\n\r\n                        point_added = false;\r\n                        continue;\r\n                    }\r\n                }\r\n\r\n                u = v.slice();\r\n                pathX.push(u[0]);\r\n                pathY.push(u[1]);\r\n                point_added = true;\r\n\r\n                steps++;\r\n            } while (\r\n                steps < max_steps &&\r\n                u[0] >= this.bbox[0] &&\r\n                u[1] <= this.bbox[1] &&\r\n                u[0] <= this.bbox[2] &&\r\n                u[1] >= this.bbox[3]\r\n            );\r\n\r\n            // Clipping to bounding box, last may be outside, interpolate between second last und last point\r\n            len = pathX.length;\r\n            ulast = [pathX[len - 2], pathY[len - 2]];\r\n\r\n            // If u[0] is outside x-interval in bounding box, interpolate to the box.\r\n            if (u[0] < this.bbox[0]) {\r\n                if (u[0] !== ulast[0]) {\r\n                    tloc = (this.bbox[0] - ulast[0]) / (u[0] - ulast[0]);\r\n                    if (u[1] !== ulast[1]) {\r\n                        u[1] = ulast[1] + tloc * (u[1] - ulast[1]);\r\n                    }\r\n                }\r\n                u[0] = this.bbox[0];\r\n            }\r\n            if (u[0] > this.bbox[2]) {\r\n                if (u[0] !== ulast[0]) {\r\n                    tloc = (this.bbox[2] - ulast[0]) / (u[0] - ulast[0]);\r\n                    if (u[1] !== ulast[1]) {\r\n                        u[1] = ulast[1] + tloc * (u[1] - ulast[1]);\r\n                    }\r\n                }\r\n                u[0] = this.bbox[2];\r\n            }\r\n\r\n            // If u[1] is outside y-interval in bounding box, interpolate to the box.\r\n            if (u[1] < this.bbox[3]) {\r\n                if (u[1] !== ulast[1]) {\r\n                    tloc = (this.bbox[3] - ulast[1]) / (u[1] - ulast[1]);\r\n                    if (u[0] !== ulast[0]) {\r\n                        u[0] = ulast[0] + tloc * (u[0] - ulast[0]);\r\n                    }\r\n                }\r\n                u[1] = this.bbox[3];\r\n            }\r\n            if (u[1] > this.bbox[1]) {\r\n                if (u[1] !== ulast[1]) {\r\n                    tloc = (this.bbox[1] - ulast[1]) / (u[1] - ulast[1]);\r\n                    if (u[0] !== ulast[0]) {\r\n                        u[0] = ulast[0] + tloc * (u[0] - ulast[0]);\r\n                    }\r\n                }\r\n                u[1] = this.bbox[1];\r\n            }\r\n\r\n            // Update last point\r\n            pathX[len - 1] = u[0];\r\n            pathY[len - 1] = u[1];\r\n\r\n            // if (!loop_closed) {\r\n            //     console.log(\"No loop\", steps);\r\n            // } else {\r\n            //     console.log(\"Loop\", steps);\r\n            // }\r\n\r\n            return [pathX, pathY, loop_closed];\r\n        },\r\n\r\n        /**\r\n         * If both eigenvalues of the Hessian are different from zero, the critical point at u\r\n         * is a simple bifurcation point.\r\n         *\r\n         * @param {Array} u Critical point [x, y]\r\n         * @param {Number} tol Tolerance of the eigenvalues to be zero.\r\n         * @returns Boolean True if the point is a simple bifurcation point.\r\n         * @private\r\n         */\r\n        isBifurcation: function (u, tol) {\r\n            // Former experiments:\r\n            // If the Hessian has exactly one zero eigenvalue,\r\n            // we claim that there is a cusp.\r\n            // Otherwise, we decide that there is a bifurcation point.\r\n            // In the latter case, if both eigenvalues are zero\r\n            // this is a somewhat crude decision.\r\n            //\r\n            var h = Mat.eps * Mat.eps * 100,\r\n                x, y, a, b, c, d, ad,\r\n                lbda1, lbda2,\r\n                dis;\r\n\r\n            x = u[0];\r\n            y = u[1];\r\n            a = 0.5 * (this.dfx(x + h, y) - this.dfx(x - h, y)) / h;\r\n            b = 0.5 * (this.dfx(x, y + h) - this.dfx(x, y - h)) / h;\r\n            c = 0.5 * (this.dfy(x + h, y) - this.dfy(x - h, y)) / h;\r\n            d = 0.5 * (this.dfy(x, y + h) - this.dfy(x, y - h)) / h;\r\n\r\n            // c = b\r\n            ad = a + d;\r\n            dis = ad * ad - 4 * (a * d - b * c);\r\n            lbda1 = 0.5 * (ad + Math.sqrt(dis));\r\n            lbda2 = 0.5 * (ad - Math.sqrt(dis));\r\n\r\n            // console.log(a, b, c, d)\r\n            // console.log(\"Eigenvals u:\", lbda1, lbda2, tol);\r\n\r\n            if (Math.abs(lbda1) > tol && Math.abs(lbda2) > tol) {\r\n                // if (lbda1 * lbda2 > 0) {\r\n                //     console.log(\"Seems to be isolated singularity at\", u);\r\n                // }\r\n                return true;\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Search in an arc around a critical point for a further point on the curve.\r\n         * Unused for the moment.\r\n         *\r\n         * @param {Array} u Critical point [x, y]\r\n         * @param {Array} t_u Tangent at u\r\n         * @param {Number} r Radius\r\n         * @param {Number} omega angle\r\n         * @returns {Array} Coordinates [x, y] of a new point.\r\n         * @private\r\n         */\r\n        handleCriticalPoint: function (u, t_u, r, omega) {\r\n            var a = Math.atan2(omega * t_u[1], omega * t_u[0]),\r\n                // s = a - 0.75 * Math.PI,\r\n                // e = a + 0.75 * Math.PI,\r\n                f_circ = function (t) {\r\n                    var x = u[0] + r * Math.cos(t),\r\n                        y = u[1] + r * Math.sin(t);\r\n                    return this.f(x, y);\r\n                },\r\n                x, y, t0;\r\n\r\n            // t0 = Numerics.fzero(f_circ, [s, e]);\r\n            t0 = Numerics.root(f_circ, a);\r\n\r\n            x = u[0] + r * Math.cos(t0);\r\n            y = u[1] + r * Math.sin(t0);\r\n            // console.log(\"\\t\", \"result\", x, y, \"f\", f(x, y));\r\n\r\n            return [x, y];\r\n        },\r\n\r\n        /**\r\n         * Quasi-Newton update of the Moore-Penrose inverse.\r\n         * See (7.2.3) in Allgower, Georg.\r\n         *\r\n         * @param {Array} A\r\n         * @param {Array} u0\r\n         * @param {Array} u1\r\n         * @returns Array\r\n         * @private\r\n         */\r\n        updateA: function (A, u0, u1) {\r\n            var s = [u1[0] - u0[0], u1[1] - u0[1]],\r\n                y = this.f(u1[0], u1[1]) - this.f(u0[0], u0[1]),\r\n                nom, denom;\r\n\r\n            denom = s[0] * s[0] + s[1] * s[1];\r\n            nom = y - (A[0] * s[0] + A[1] * s[1]);\r\n            nom /= denom;\r\n            A[0] += nom * s[0];\r\n            A[1] += nom * s[1];\r\n\r\n            return A;\r\n        },\r\n\r\n        /**\r\n         * Approximate tangent (of norm 1) with Quasi-Newton method\r\n         * @param {Array} A\r\n         * @returns Array\r\n         * @private\r\n         */\r\n        tangent_A: function (A) {\r\n            var t = [-A[1], A[0]],\r\n                nrm = Mat.norm(t, 2);\r\n\r\n            if (nrm < Mat.eps) {\r\n                // console.log(\"Approx. Singularity\", t, \"is zero\", nrm);\r\n            }\r\n            return [t[0] / nrm, t[1] / nrm];\r\n        },\r\n\r\n        /**\r\n         * Tangent of norm 1 at point u.\r\n         * @param {Array} u Point [x, y]\r\n         * @returns Array\r\n         * @private\r\n         */\r\n        tangent: function (u) {\r\n            var t = [-this.dfy(u[0], u[1]), this.dfx(u[0], u[1])],\r\n                nrm = Mat.norm(t, 2);\r\n\r\n            if (nrm < Mat.eps * Mat.eps) {\r\n                // console.log(\"Singularity\", t, \"is zero\", \"at\", u, \":\", nrm);\r\n                return false;\r\n            }\r\n            return [t[0] / nrm, t[1] / nrm];\r\n        }\r\n    }\r\n\r\n);\r\n\r\nexport default Mat.ImplicitPlot;\r\n\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n\r\n\r\n    Metapost/Hobby curves, see e.g. https://bosker.wordpress.com/2013/11/13/beyond-bezier-curves/\r\n\r\n    * Ported to Python for the project PyX. Copyright (C) 2011 Michael Schindler <m-schindler@users.sourceforge.net>\r\n    * Ported to javascript from the PyX implementation (https://pyx-project.org/) by Vlad-X.\r\n    * Adapted to JSXGraph and some code changes by Alfred Wassermann 2020.\r\n\r\n    This program is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU General Public License for more details.\r\n\r\n    You should have received a copy of the GNU General Public License\r\n    along with this program; if not, write to the Free Software\r\n    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.\r\n\r\n    Internal functions of MetaPost\r\n    This file re-implements some of the functionality of MetaPost\r\n    (https://tug.org/metapost.html). MetaPost was developed by John D. Hobby and\r\n    others. The code of Metapost is in the public domain, which we understand as\r\n    an implicit permission to reuse the code here (see the comment at\r\n    https://www.gnu.org/licenses/license-list.html)\r\n\r\n    This file is based on the MetaPost version distributed by TeXLive:\r\n    svn://tug.org/texlive/trunk/Build/source/texk/web2c/mplibdir revision 22737 #\r\n    (2011-05-31)\r\n*/\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview In this file the namespace Math.Metapost is defined which holds algorithms translated from Metapost\r\n * by D.E. Knuth and J.D. Hobby.\r\n */\r\n\r\nimport Type from \"../utils/type.js\";\r\nimport Mat from \"./math.js\";\r\n\r\n/**\r\n * The JXG.Math.Metapost namespace holds algorithms translated from Metapost\r\n * by D.E. Knuth and J.D. Hobby.\r\n *\r\n * @name JXG.Math.Metapost\r\n * @exports Mat.Metapost as JXG.Math.Metapost\r\n * @namespace\r\n */\r\nMat.Metapost = {\r\n    MP_ENDPOINT: 0,\r\n    MP_EXPLICIT: 1,\r\n    MP_GIVEN: 2,\r\n    MP_CURL: 3,\r\n    MP_OPEN: 4,\r\n    MP_END_CYCLE: 5,\r\n\r\n    UNITY: 1.0,\r\n    // two: 2,\r\n    // fraction_half: 0.5,\r\n    FRACTION_ONE: 1.0,\r\n    FRACTION_THREE: 3.0,\r\n    ONE_EIGHTY_DEG: Math.PI,\r\n    THREE_SIXTY_DEG: 2 * Math.PI,\r\n    // EPSILON: 1e-5,\r\n    EPS_SQ: 1e-5 * 1e-5,\r\n\r\n    /**\r\n     * @private\r\n     */\r\n    make_choices: function (knots) {\r\n        var dely, h, k, delx, n, q, p, s, cosine, t, sine, delta_x, delta_y, delta, psi,\r\n            endless = true;\r\n\r\n        p = knots[0];\r\n        do {\r\n            if (!p) {\r\n                break;\r\n            }\r\n            q = p.next;\r\n\r\n            // Join two identical knots by setting the control points to the same\r\n            // coordinates.\r\n            // MP 291\r\n            if (\r\n                p.rtype > this.MP_EXPLICIT &&\r\n                (p.x - q.x) * (p.x - q.x) + (p.y - q.y) * (p.y - q.y) < this.EPS_SQ\r\n            ) {\r\n                p.rtype = this.MP_EXPLICIT;\r\n                if (p.ltype === this.MP_OPEN) {\r\n                    p.ltype = this.MP_CURL;\r\n                    p.set_left_curl(this.UNITY);\r\n                }\r\n\r\n                q.ltype = this.MP_EXPLICIT;\r\n                if (q.rtype === this.MP_OPEN) {\r\n                    q.rtype = this.MP_CURL;\r\n                    q.set_right_curl(this.UNITY);\r\n                }\r\n\r\n                p.rx = p.x;\r\n                q.lx = p.x;\r\n                p.ry = p.y;\r\n                q.ly = p.y;\r\n            }\r\n            p = q;\r\n        } while (p !== knots[0]);\r\n\r\n        // Find the first breakpoint, h, on the path\r\n        // MP 292\r\n        h = knots[0];\r\n        while (endless) {\r\n            if (h.ltype !== this.MP_OPEN || h.rtype !== this.MP_OPEN) {\r\n                break;\r\n            }\r\n            h = h.next;\r\n            if (h === knots[0]) {\r\n                h.ltype = this.MP_END_CYCLE;\r\n                break;\r\n            }\r\n        }\r\n\r\n        p = h;\r\n        while (endless) {\r\n            if (!p) {\r\n                break;\r\n            }\r\n\r\n            // Fill in the control points between p and the next breakpoint,\r\n            // then advance p to that breakpoint\r\n            // MP 299\r\n            q = p.next;\r\n            if (p.rtype >= this.MP_GIVEN) {\r\n                while (q.ltype === this.MP_OPEN && q.rtype === this.MP_OPEN) {\r\n                    q = q.next;\r\n                }\r\n\r\n                // Calculate the turning angles psi_ k and the distances d_{k,k+1};\r\n                // set n to the length of the path\r\n                // MP 302\r\n                k = 0;\r\n                s = p;\r\n                n = knots.length;\r\n\r\n                delta_x = [];\r\n                delta_y = [];\r\n                delta = [];\r\n                psi = [null];\r\n\r\n                // tuple([]) = tuple([[], [], [], [null]]);\r\n                while (endless) {\r\n                    t = s.next;\r\n                    // None;\r\n                    delta_x.push(t.x - s.x);\r\n                    delta_y.push(t.y - s.y);\r\n                    delta.push(this.mp_pyth_add(delta_x[k], delta_y[k]));\r\n                    if (k > 0) {\r\n                        sine = delta_y[k - 1] / delta[k - 1];\r\n                        cosine = delta_x[k - 1] / delta[k - 1];\r\n                        psi.push(\r\n                            Math.atan2(\r\n                                delta_y[k] * cosine - delta_x[k] * sine,\r\n                                delta_x[k] * cosine + delta_y[k] * sine\r\n                            )\r\n                        );\r\n                    }\r\n                    k++;\r\n                    s = t;\r\n                    if (s === q) {\r\n                        n = k;\r\n                    }\r\n                    if (k >= n && s.ltype !== this.MP_END_CYCLE) {\r\n                        break;\r\n                    }\r\n                }\r\n                if (k === n) {\r\n                    psi.push(0);\r\n                } else {\r\n                    psi.push(psi[1]);\r\n                }\r\n\r\n                // Remove open types at the breakpoints\r\n                // MP 303\r\n                if (q.ltype === this.MP_OPEN) {\r\n                    delx = q.rx - q.x;\r\n                    dely = q.ry - q.y;\r\n                    if (delx * delx + dely * dely < this.EPS_SQ) {\r\n                        q.ltype = this.MP_CURL;\r\n                        q.set_left_curl(this.UNITY);\r\n                    } else {\r\n                        q.ltype = this.MP_GIVEN;\r\n                        q.set_left_given(Math.atan2(dely, delx));\r\n                    }\r\n                }\r\n                if (p.rtype === this.MP_OPEN && p.ltype === this.MP_EXPLICIT) {\r\n                    delx = p.x - p.lx;\r\n                    dely = p.y - p.ly;\r\n                    if (delx * delx + dely * dely < this.EPS_SQ) {\r\n                        p.rtype = this.MP_CURL;\r\n                        p.set_right_curl(this.UNITY);\r\n                    } else {\r\n                        p.rtype = this.MP_GIVEN;\r\n                        p.set_right_given(Math.atan2(dely, delx));\r\n                    }\r\n                }\r\n                this.mp_solve_choices(p, q, n, delta_x, delta_y, delta, psi);\r\n            } else if (p.rtype === this.MP_ENDPOINT) {\r\n                // MP 294\r\n                p.rx = p.x;\r\n                p.ry = p.y;\r\n                q.lx = q.x;\r\n                q.ly = q.y;\r\n            }\r\n            p = q;\r\n\r\n            if (p === h) {\r\n                break;\r\n            }\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Implements solve_choices form metapost\r\n     * MP 305\r\n     * @private\r\n     */\r\n    mp_solve_choices: function (p, q, n, delta_x, delta_y, delta, psi) {\r\n        var aa, acc, vv, bb, ldelta, ee, k,\r\n            s, ww, uu, lt, r, t, ff,\r\n            theta, rt, dd, cc, ct_st,\r\n            ct, st, cf_sf, cf, sf, i, k_idx,\r\n            endless = true;\r\n\r\n        ldelta = delta.length + 1;\r\n        uu = new Array(ldelta);\r\n        ww = new Array(ldelta);\r\n        vv = new Array(ldelta);\r\n        theta = new Array(ldelta);\r\n        for (i = 0; i < ldelta; i++) {\r\n            theta[i] = vv[i] = ww[i] = uu[i] = 0;\r\n        }\r\n        k = 0;\r\n        s = p;\r\n        r = 0;\r\n        while (endless) {\r\n            t = s.next;\r\n            if (k === 0) {\r\n                // MP 306\r\n                if (s.rtype === this.MP_GIVEN) {\r\n                    // MP 314\r\n                    if (t.ltype === this.MP_GIVEN) {\r\n                        aa = Math.atan2(delta_y[0], delta_x[0]);\r\n                        ct_st = this.mp_n_sin_cos(p.right_given() - aa);\r\n                        ct = ct_st[0];\r\n                        st = ct_st[1];\r\n                        cf_sf = this.mp_n_sin_cos(q.left_given() - aa);\r\n                        cf = cf_sf[0];\r\n                        sf = cf_sf[1];\r\n                        this.mp_set_controls(p, q, delta_x[0], delta_y[0], st, ct, -sf, cf);\r\n                        return;\r\n                    }\r\n                    vv[0] = s.right_given() - Math.atan2(delta_y[0], delta_x[0]);\r\n                    vv[0] = this.reduce_angle(vv[0]);\r\n                    uu[0] = 0;\r\n                    ww[0] = 0;\r\n                } else if (s.rtype === this.MP_CURL) {\r\n                    // MP 315\r\n                    if (t.ltype === this.MP_CURL) {\r\n                        p.rtype = this.MP_EXPLICIT;\r\n                        q.ltype = this.MP_EXPLICIT;\r\n                        lt = Math.abs(q.left_tension());\r\n                        rt = Math.abs(p.right_tension());\r\n                        ff = this.UNITY / (3.0 * rt);\r\n                        p.rx = p.x + delta_x[0] * ff;\r\n                        p.ry = p.y + delta_y[0] * ff;\r\n                        ff = this.UNITY / (3.0 * lt);\r\n                        q.lx = q.x - delta_x[0] * ff;\r\n                        q.ly = q.y - delta_y[0] * ff;\r\n                        return;\r\n                    }\r\n                    cc = s.right_curl();\r\n                    lt = Math.abs(t.left_tension());\r\n                    rt = Math.abs(s.right_tension());\r\n                    uu[0] = this.mp_curl_ratio(cc, rt, lt);\r\n                    vv[0] = -psi[1] * uu[0];\r\n                    ww[0] = 0;\r\n                } else {\r\n                    if (s.rtype === this.MP_OPEN) {\r\n                        uu[0] = 0;\r\n                        vv[0] = 0;\r\n                        ww[0] = this.FRACTION_ONE;\r\n                    }\r\n                }\r\n            } else {\r\n                if (s.ltype === this.MP_END_CYCLE || s.ltype === this.MP_OPEN) {\r\n                    // MP 308\r\n                    aa = this.UNITY / (3.0 * Math.abs(r.right_tension()) - this.UNITY);\r\n                    dd =\r\n                        delta[k] *\r\n                        (this.FRACTION_THREE - this.UNITY / Math.abs(r.right_tension()));\r\n                    bb = this.UNITY / (3 * Math.abs(t.left_tension()) - this.UNITY);\r\n                    ee =\r\n                        delta[k - 1] *\r\n                        (this.FRACTION_THREE - this.UNITY / Math.abs(t.left_tension()));\r\n                    cc = this.FRACTION_ONE - uu[k - 1] * aa;\r\n                    dd = dd * cc;\r\n                    lt = Math.abs(s.left_tension());\r\n                    rt = Math.abs(s.right_tension());\r\n                    if (lt < rt) {\r\n                        dd *= Math.pow(lt / rt, 2);\r\n                    } else {\r\n                        if (lt > rt) {\r\n                            ee *= Math.pow(rt / lt, 2);\r\n                        }\r\n                    }\r\n                    ff = ee / (ee + dd);\r\n                    uu[k] = ff * bb;\r\n                    acc = -psi[k + 1] * uu[k];\r\n                    if (r.rtype === this.MP_CURL) {\r\n                        ww[k] = 0;\r\n                        vv[k] = acc - psi[1] * (this.FRACTION_ONE - ff);\r\n                    } else {\r\n                        ff = (this.FRACTION_ONE - ff) / cc;\r\n                        acc = acc - psi[k] * ff;\r\n                        ff = ff * aa;\r\n                        vv[k] = acc - vv[k - 1] * ff;\r\n                        ww[k] = -ww[k - 1] * ff;\r\n                    }\r\n                    if (s.ltype === this.MP_END_CYCLE) {\r\n                        aa = 0;\r\n                        bb = this.FRACTION_ONE;\r\n                        while (endless) {\r\n                            k -= 1;\r\n                            if (k === 0) {\r\n                                k = n;\r\n                            }\r\n                            aa = vv[k] - aa * uu[k];\r\n                            bb = ww[k] - bb * uu[k];\r\n                            if (k === n) {\r\n                                break;\r\n                            }\r\n                        }\r\n                        aa = aa / (this.FRACTION_ONE - bb);\r\n                        theta[n] = aa;\r\n                        vv[0] = aa;\r\n                        // k_val = range(1, n);\r\n                        // for (k_idx in k_val) {\r\n                        // k = k_val[k_idx];\r\n                        for (k_idx = 1; k_idx < n; k_idx++) {\r\n                            vv[k_idx] = vv[k_idx] + aa * ww[k_idx];\r\n                        }\r\n                        break;\r\n                    }\r\n                } else {\r\n                    if (s.ltype === this.MP_CURL) {\r\n                        cc = s.left_curl();\r\n                        lt = Math.abs(s.left_tension());\r\n                        rt = Math.abs(r.right_tension());\r\n                        ff = this.mp_curl_ratio(cc, lt, rt);\r\n                        theta[n] = -(vv[n - 1] * ff) / (this.FRACTION_ONE - ff * uu[n - 1]);\r\n                        break;\r\n                    }\r\n                    if (s.ltype === this.MP_GIVEN) {\r\n                        theta[n] = s.left_given() - Math.atan2(delta_y[n - 1], delta_x[n - 1]);\r\n                        theta[n] = this.reduce_angle(theta[n]);\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n            r = s;\r\n            s = t;\r\n            k += 1;\r\n        }\r\n\r\n        // MP 318\r\n        for (k = n - 1; k > -1; k--) {\r\n            theta[k] = vv[k] - theta[k + 1] * uu[k];\r\n        }\r\n\r\n        s = p;\r\n        k = 0;\r\n        while (endless) {\r\n            t = s.next;\r\n            ct_st = this.mp_n_sin_cos(theta[k]);\r\n            ct = ct_st[0];\r\n            st = ct_st[1];\r\n            cf_sf = this.mp_n_sin_cos(-psi[k + 1] - theta[k + 1]);\r\n            cf = cf_sf[0];\r\n            sf = cf_sf[1];\r\n            this.mp_set_controls(s, t, delta_x[k], delta_y[k], st, ct, sf, cf);\r\n            k++;\r\n            s = t;\r\n            if (k === n) {\r\n                break;\r\n            }\r\n        }\r\n    },\r\n\r\n    /**\r\n     * @private\r\n     */\r\n    mp_n_sin_cos: function (z) {\r\n        return [Math.cos(z), Math.sin(z)];\r\n    },\r\n\r\n    /**\r\n     * @private\r\n     */\r\n    mp_set_controls: function (p, q, delta_x, delta_y, st, ct, sf, cf) {\r\n        var rt, ss, lt, sine, rr;\r\n        lt = Math.abs(q.left_tension());\r\n        rt = Math.abs(p.right_tension());\r\n        rr = this.mp_velocity(st, ct, sf, cf, rt);\r\n        ss = this.mp_velocity(sf, cf, st, ct, lt);\r\n\r\n        // console.log('lt rt rr ss', lt, rt, rr, ss);\r\n        if (p.right_tension() < 0 || q.left_tension() < 0) {\r\n            if ((st >= 0 && sf >= 0) || (st <= 0 && sf <= 0)) {\r\n                sine = Math.abs(st) * cf + Math.abs(sf) * ct;\r\n                if (sine > 0) {\r\n                    sine *= 1.00024414062;\r\n                    if (p.right_tension() < 0) {\r\n                        if (this.mp_ab_vs_cd(Math.abs(sf), this.FRACTION_ONE, rr, sine) < 0) {\r\n                            rr = Math.abs(sf) / sine;\r\n                        }\r\n                    }\r\n                    if (q.left_tension() < 0) {\r\n                        if (this.mp_ab_vs_cd(Math.abs(st), this.FRACTION_ONE, ss, sine) < 0) {\r\n                            ss = Math.abs(st) / sine;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n        p.rx = p.x + (delta_x * ct - delta_y * st) * rr;\r\n        p.ry = p.y + (delta_y * ct + delta_x * st) * rr;\r\n        q.lx = q.x - (delta_x * cf + delta_y * sf) * ss;\r\n        q.ly = q.y - (delta_y * cf - delta_x * sf) * ss;\r\n        p.rtype = this.MP_EXPLICIT;\r\n        q.ltype = this.MP_EXPLICIT;\r\n    },\r\n\r\n    /**\r\n     * @private\r\n     */\r\n    mp_pyth_add: function (a, b) {\r\n        return Mat.hypot(a, b);\r\n    },\r\n\r\n    /**\r\n     *\r\n     * @private\r\n     */\r\n    mp_curl_ratio: function (gamma, a_tension, b_tension) {\r\n        var alpha = 1.0 / a_tension,\r\n            beta = 1.0 / b_tension;\r\n\r\n        return Math.min(\r\n            4.0,\r\n            ((3.0 - alpha) * alpha * alpha * gamma + beta * beta * beta) /\r\n            (alpha * alpha * alpha * gamma + (3.0 - beta) * beta * beta)\r\n        );\r\n    },\r\n\r\n    /**\r\n     * @private\r\n     */\r\n    mp_ab_vs_cd: function (a, b, c, d) {\r\n        if (a * b === c * d) {\r\n            return 0;\r\n        }\r\n        if (a * b > c * d) {\r\n            return 1;\r\n        }\r\n        return -1;\r\n    },\r\n\r\n    /**\r\n     * @private\r\n     */\r\n    mp_velocity: function (st, ct, sf, cf, t) {\r\n        return Math.min(\r\n            4.0,\r\n            (2.0 + Math.sqrt(2) * (st - sf / 16.0) * (sf - st / 16.0) * (ct - cf)) /\r\n            (1.5 * t * (2 + (Math.sqrt(5) - 1) * ct + (3 - Math.sqrt(5)) * cf))\r\n        );\r\n    },\r\n\r\n    /**\r\n     * @private\r\n     * @param {Number} A\r\n     */\r\n    reduce_angle: function (A) {\r\n        if (Math.abs(A) > this.ONE_EIGHTY_DEG) {\r\n            if (A > 0) {\r\n                A -= this.THREE_SIXTY_DEG;\r\n            } else {\r\n                A += this.THREE_SIXTY_DEG;\r\n            }\r\n        }\r\n        return A;\r\n    },\r\n\r\n    /**\r\n     *\r\n     * @private\r\n     * @param {Array} p\r\n     * @param {Number} tension\r\n     * @param {Boolean} cycle\r\n     */\r\n    makeknots: function (p, tension) {\r\n        var i, len,\r\n            knots = [];\r\n\r\n        len = p.length;\r\n        for (i = 0; i < len; i++) {\r\n            knots.push({\r\n                x: p[i][0],\r\n                y: p[i][1],\r\n                ltype: this.MP_OPEN,\r\n                rtype: this.MP_OPEN,\r\n                lx: false,\r\n                rx: false,\r\n                ly: tension,\r\n                ry: tension,\r\n                left_curl: function () {\r\n                    return this.lx || 0;\r\n                },\r\n                right_curl: function () {\r\n                    return this.rx || 0;\r\n                },\r\n                left_tension: function () {\r\n                    return this.ly || 1;\r\n                },\r\n                right_tension: function () {\r\n                    return this.ry || 1;\r\n                },\r\n                set_right_curl: function (v) {\r\n                    this.rx = v || 0;\r\n                },\r\n                set_left_curl: function (v) {\r\n                    this.lx = v || 0;\r\n                }\r\n            });\r\n        }\r\n\r\n        len = knots.length;\r\n        for (i = 0; i < len; i++) {\r\n            knots[i].next = knots[i + 1] || knots[i];\r\n            knots[i].set_right_given = knots[i].set_right_curl;\r\n            knots[i].set_left_given = knots[i].set_left_curl;\r\n            knots[i].right_given = knots[i].right_curl;\r\n            knots[i].left_given = knots[i].left_curl;\r\n        }\r\n        knots[len - 1].next = knots[0];\r\n\r\n        return knots;\r\n    },\r\n\r\n    /**\r\n     *\r\n     * @param {Array} point_list\r\n     * @param {Object} controls\r\n     *\r\n     * @returns {Array}\r\n     */\r\n    curve: function (point_list, controls) {\r\n        var knots, len, i, ii,\r\n            val, obj,\r\n            isClosed = false,\r\n            x = [],\r\n            y = [];\r\n\r\n        controls = controls || {\r\n            tension: 1,\r\n            direction: {},\r\n            curl: {},\r\n            isClosed: false\r\n        };\r\n\r\n        // Change default tension\r\n        val = 1;\r\n        if (controls.hasOwnProperty('tension')) {\r\n            val = Type.evaluate(controls.tension);\r\n        }\r\n\r\n        knots = this.makeknots(point_list, val);\r\n\r\n        len = knots.length;\r\n        if (Type.exists(controls.isClosed) && Type.evaluate(controls.isClosed)) {\r\n            isClosed = true;\r\n        }\r\n\r\n        if (!isClosed) {\r\n            knots[0].ltype = this.MP_ENDPOINT;\r\n            knots[0].rtype = this.MP_CURL;\r\n            knots[len - 1].rtype = this.MP_ENDPOINT;\r\n            knots[len - 1].ltype = this.MP_CURL;\r\n        }\r\n\r\n        // for (i in controls.direction) {\r\n        //     if (controls.direction.hasOwnProperty(i)) {\r\n        //         val = Type.evaluate(controls.direction[i]);\r\n        //         if (Type.isArray(val)) {\r\n        //             if (val[0] !== false) {\r\n        //                 knots[i].lx = (val[0] * Math.PI) / 180;\r\n        //                 knots[i].ltype = this.MP_GIVEN;\r\n        //             }\r\n        //             if (val[1] !== false) {\r\n        //                 knots[i].rx = (val[1] * Math.PI) / 180;\r\n        //                 knots[i].rtype = this.MP_GIVEN;\r\n        //             }\r\n        //         } else {\r\n        //             knots[i].lx = (val * Math.PI) / 180;\r\n        //             knots[i].rx = (val * Math.PI) / 180;\r\n        //             knots[i].ltype = knots[i].rtype = this.MP_GIVEN;\r\n        //         }\r\n        //     }\r\n        // }\r\n\r\n        // for (i in controls.curl) {\r\n        //     if (controls.curl.hasOwnProperty(i)) {\r\n        //         val = Type.evaluate(controls.curl[i]);\r\n        //         if (parseInt(i, 10) === 0) {\r\n        //             knots[i].rtype = this.MP_CURL;\r\n        //             knots[i].set_right_curl(val);\r\n        //         } else if (parseInt(i, 10) === len - 1) {\r\n        //             knots[i].ltype = this.MP_CURL;\r\n        //             knots[i].set_left_curl(val);\r\n        //         }\r\n        //     }\r\n        // }\r\n\r\n        // Set individual point control values\r\n        for (ii in controls) {\r\n            if (controls.hasOwnProperty(ii)) {\r\n                i = parseInt(ii, 10);\r\n                if (isNaN(i) || i < 0 || i >= len) {\r\n                    continue;\r\n                }\r\n\r\n                // Handle individual curl\r\n                obj = controls[i];\r\n                if (Type.exists(obj.type)) {\r\n                    switch (obj.type) {\r\n                        case 'curl':\r\n                            val = Type.evaluate(obj.curl);\r\n                            if (i === 0) {\r\n                                knots[i].rtype = this.MP_CURL;\r\n                                knots[i].set_right_curl(val);\r\n                            } else if (i === len - 1) {\r\n                                knots[i].ltype = this.MP_CURL;\r\n                                knots[i].set_left_curl(val);\r\n                            } else {\r\n                                knots[i].ltype = this.MP_CURL;\r\n                                knots[i].rtype = this.MP_CURL;\r\n                                knots[i].lx = val;\r\n                                knots[i].rx = val;\r\n                            }\r\n                            break;\r\n                        }\r\n                    }\r\n\r\n                    // Handle individual directions\r\n                    if (Type.exists(obj.direction)) {\r\n                        val = Type.evaluate(obj.direction);\r\n                        if (Type.isArray(val)) {\r\n                            if (val[0] !== false) {\r\n                                knots[i].lx = (val[0] * Math.PI) / 180;\r\n                                knots[i].ltype = this.MP_GIVEN;\r\n                            }\r\n                            if (val[1] !== false) {\r\n                                knots[i].rx = (val[1] * Math.PI) / 180;\r\n                                knots[i].rtype = this.MP_GIVEN;\r\n                            }\r\n                        } else {\r\n                            knots[i].lx = (val * Math.PI) / 180;\r\n                            knots[i].rx = (val * Math.PI) / 180;\r\n                            knots[i].ltype = knots[i].rtype = this.MP_GIVEN;\r\n                        }\r\n                    }\r\n\r\n                    // Handle individual tension\r\n                    if (Type.exists(obj.tension)) {\r\n                        val = Type.evaluate(obj.tension);\r\n                        if (Type.isArray(val)) {\r\n                            if (val[0] !== false) {\r\n                                knots[i].ly = Type.evaluate(val[0]);\r\n                            }\r\n                            if (val[1] !== false) {\r\n                                knots[i].ry = Type.evaluate(val[1]);\r\n                            }\r\n                        } else {\r\n                            knots[i].ly = val;\r\n                            knots[i].ry = val;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Generate ths Bezier curve\r\n            this.make_choices(knots);\r\n\r\n            // Return the coordinates\r\n            for (i = 0; i < len - 1; i++) {\r\n                x.push(knots[i].x);\r\n                x.push(knots[i].rx);\r\n                x.push(knots[i + 1].lx);\r\n                y.push(knots[i].y);\r\n                y.push(knots[i].ry);\r\n                y.push(knots[i + 1].ly);\r\n            }\r\n            x.push(knots[len - 1].x);\r\n            y.push(knots[len - 1].y);\r\n\r\n            if (isClosed) {\r\n                x.push(knots[len - 1].rx);\r\n                y.push(knots[len - 1].ry);\r\n                x.push(knots[0].lx);\r\n                y.push(knots[0].ly);\r\n                x.push(knots[0].x);\r\n                y.push(knots[0].y);\r\n            }\r\n\r\n            return [x, y];\r\n        }\r\n};\r\n\r\nexport default Mat.Metapost;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview This file contains the Math.Clip namespace for clipping and computing boolean operations\r\n * on polygons and curves\r\n *\r\n * // TODO:\r\n * * Check if input polygons are closed. If not, handle this case.\r\n */\r\n\r\n// import JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Coords from \"../base/coords.js\";\r\nimport Mat from \"./math.js\";\r\nimport Geometry from \"./geometry.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Math.Clip namespace definition. This namespace contains algorithms for Boolean operations on paths, i.e.\r\n * intersection, union and difference of paths. Base is the Greiner-Hormann algorithm.\r\n * @name JXG.Math.Clip\r\n * @exports Mat.Clip as JXG.Math.Clip\r\n * @namespace\r\n */\r\nMat.Clip = {\r\n    _isSeparator: function (node) {\r\n        return isNaN(node.coords.usrCoords[1]) && isNaN(node.coords.usrCoords[2]);\r\n    },\r\n\r\n    /**\r\n     * Add pointers to an array S such that it is a circular doubly-linked list.\r\n     *\r\n     * @private\r\n     * @param  {Array} S Array\r\n     * @return {Array} return containing the starter indices of each component.\r\n     */\r\n    makeDoublyLinkedList: function (S) {\r\n        var i,\r\n            first = null,\r\n            components = [],\r\n            le = S.length;\r\n\r\n        if (le > 0) {\r\n            for (i = 0; i < le; i++) {\r\n                // S[i]._next = S[(i + 1) % le];\r\n                // S[i]._prev = S[(le + i - 1) % le];\r\n\r\n                // If S[i] is component separator we proceed with the next node.\r\n                if (this._isSeparator(S[i])) {\r\n                    S[i]._next = S[(i + 1) % le];\r\n                    S[i]._prev = S[(le + i - 1) % le];\r\n                    continue;\r\n                }\r\n\r\n                // Now we know that S[i] is a path component\r\n                if (first === null) {\r\n                    // Start the component if it is not yet started.\r\n                    first = i;\r\n                    components.push(first);\r\n                }\r\n                if (this._isSeparator(S[(i + 1) % le]) || i === le - 1) {\r\n                    // If the next node is a component separator or if the node is the last node,\r\n                    // then we close the loop\r\n\r\n                    S[i]._next = S[first];\r\n                    S[first]._prev = S[i];\r\n                    S[i]._end = true;\r\n                    first = null;\r\n                } else {\r\n                    // Here, we are not at the end of component\r\n                    S[i]._next = S[(i + 1) % le];\r\n                    S[first]._prev = S[i];\r\n                }\r\n                if (!this._isSeparator(S[(le + i - 1) % le])) {\r\n                    S[i]._prev = S[(le + i - 1) % le];\r\n                }\r\n            }\r\n        }\r\n        return components;\r\n    },\r\n\r\n    /**\r\n     * JavaScript object containing the intersection of two paths. Every intersection point is on one path, but\r\n     * comes with a neighbour point having the same coordinates and being on the other path.\r\n     *\r\n     * The intersection point is inserted into the doubly linked list of the path.\r\n     *\r\n     * @private\r\n     * @param  {JXG.Coords} coords JSXGraph Coords object containing the coordinates of the intersection\r\n     * @param  {Number} i        Number of the segment of the subject path (first path) containing the intersection.\r\n     * @param  {Number} alpha    The intersection is a p_1 + alpha*(p_2 - p_1), where p_1 and p_2 are the end points\r\n     *      of the i-th segment.\r\n     * @param  {Array} path      Pointer to the path containing the intersection point\r\n     * @param  {String} pathname Name of the path: 'S' or 'C'.\r\n     */\r\n    Vertex: function (coords, i, alpha, path, pathname, type) {\r\n        this.pos = i;\r\n        this.intersection = true;\r\n        this.coords = coords;\r\n        this.elementClass = Const.OBJECT_CLASS_POINT;\r\n\r\n        this.data = {\r\n            alpha: alpha,\r\n            path: path,\r\n            pathname: pathname,\r\n            done: false,\r\n            type: type,\r\n            idx: 0\r\n        };\r\n\r\n        // Set after initialisation\r\n        this.neighbour = null;\r\n        this.entry_exit = false;\r\n    },\r\n\r\n    _addToList: function (list, coords, pos) {\r\n        var len = list.length,\r\n            eps = Mat.eps * Mat.eps;\r\n\r\n        if (\r\n            len > 0 &&\r\n            Math.abs(list[len - 1].coords.usrCoords[0] - coords.usrCoords[0]) < eps &&\r\n            Math.abs(list[len - 1].coords.usrCoords[1] - coords.usrCoords[1]) < eps &&\r\n            Math.abs(list[len - 1].coords.usrCoords[2] - coords.usrCoords[2]) < eps\r\n        ) {\r\n            // Skip point\r\n            return;\r\n        }\r\n        list.push({\r\n            pos: pos,\r\n            intersection: false,\r\n            coords: coords,\r\n            elementClass: Const.OBJECT_CLASS_POINT\r\n        });\r\n    },\r\n\r\n    /**\r\n     * Sort the intersection points into their path.\r\n     * @private\r\n     * @param  {Array} P_crossings Array of arrays. Each array contains the intersections of the path\r\n     *      with one segment of the other path.\r\n     * @return {Array}  Array of intersection points ordered by first occurrence in the path.\r\n     */\r\n    sortIntersections: function (P_crossings) {\r\n        var i,\r\n            j,\r\n            P,\r\n            Q,\r\n            last,\r\n            next_node,\r\n            P_intersect = [],\r\n            P_le = P_crossings.length;\r\n\r\n        for (i = 0; i < P_le; i++) {\r\n            P_crossings[i].sort(function (a, b) {\r\n                return a.data.alpha > b.data.alpha ? 1 : -1;\r\n            });\r\n\r\n            if (P_crossings[i].length > 0) {\r\n                // console.log(\"Crossings\", P_crossings[i])\r\n                last = P_crossings[i].length - 1;\r\n                P = P_crossings[i][0];\r\n\r\n                //console.log(\"SORT\", P.coords.usrCoords)\r\n                Q = P.data.path[P.pos];\r\n                next_node = Q._next; // Store the next \"normal\" node\r\n\r\n                if (i === P_le - 1) {\r\n                    Q._end = false;\r\n                }\r\n\r\n                if (P.data.alpha === 0.0 && P.data.type === 'T') {\r\n                    // console.log(\"SKIP\", P.coords.usrCoords, P.data.type, P.neighbour.data.type);\r\n                    Q.intersection = true;\r\n                    Q.data = P.data;\r\n                    Q.neighbour = P.neighbour;\r\n                    Q.neighbour.neighbour = Q;\r\n                    Q.entry_exit = false;\r\n                    P_crossings[i][0] = Q;\r\n                } else {\r\n                    // Insert the first intersection point\r\n                    P._prev = Q;\r\n                    P._prev._next = P;\r\n                }\r\n\r\n                // Insert the other intersection points, but the last\r\n                for (j = 1; j <= last; j++) {\r\n                    P = P_crossings[i][j];\r\n                    P._prev = P_crossings[i][j - 1];\r\n                    P._prev._next = P;\r\n                }\r\n\r\n                // Link last intersection point to the next node\r\n                P = P_crossings[i][last];\r\n                P._next = next_node;\r\n                P._next._prev = P;\r\n\r\n                if (i === P_le - 1) {\r\n                    P._end = true;\r\n                    //console.log(\"END\", P._end, P.coords.usrCoords, P._prev.coords.usrCoords, P._next.coords.usrCoords);\r\n                }\r\n\r\n                P_intersect = P_intersect.concat(P_crossings[i]);\r\n            }\r\n        }\r\n        return P_intersect;\r\n    },\r\n\r\n    _inbetween: function (q, p1, p2) {\r\n        var alpha,\r\n            eps = Mat.eps * Mat.eps,\r\n            px = p2[1] - p1[1],\r\n            py = p2[2] - p1[2],\r\n            qx = q[1] - p1[1],\r\n            qy = q[2] - p1[2];\r\n\r\n        if (px === 0 && py === 0 && qx === 0 && qy === 0) {\r\n            // All three points are equal\r\n            return true;\r\n        }\r\n        if (Math.abs(qx) < eps && Math.abs(px) < eps) {\r\n            alpha = qy / py;\r\n        } else {\r\n            alpha = qx / px;\r\n        }\r\n        if (Math.abs(alpha) < eps) {\r\n            alpha = 0.0;\r\n        }\r\n        return alpha;\r\n    },\r\n\r\n    _print_array: function (arr) {\r\n        var i, end;\r\n        for (i = 0; i < arr.length; i++) {\r\n            //console.log(i, arr[i].coords.usrCoords,  arr[i].data.type);\r\n            try {\r\n                end = \"\";\r\n                if (arr[i]._end) {\r\n                    end = \" end\";\r\n                }\r\n                console.log(\r\n                    i,\r\n                    arr[i].coords.usrCoords,\r\n                    arr[i].data.type,\r\n                    \"\\t\",\r\n                    \"prev\",\r\n                    arr[i]._prev.coords.usrCoords,\r\n                    \"next\",\r\n                    arr[i]._next.coords.usrCoords + end\r\n                );\r\n            } catch (e) {\r\n                console.log(i, arr[i].coords.usrCoords);\r\n            }\r\n        }\r\n    },\r\n\r\n    _print_list: function (P) {\r\n        var cnt = 0,\r\n            alpha;\r\n        while (cnt < 100) {\r\n            if (P.data) {\r\n                alpha = P.data.alpha;\r\n            } else {\r\n                alpha = \"-\";\r\n            }\r\n            console.log(\r\n                \"\\t\",\r\n                P.coords.usrCoords,\r\n                \"\\n\\t\\tis:\",\r\n                P.intersection,\r\n                \"end:\",\r\n                P._end,\r\n                alpha,\r\n                \"\\n\\t\\t-:\",\r\n                P._prev.coords.usrCoords,\r\n                \"\\n\\t\\t+:\",\r\n                P._next.coords.usrCoords,\r\n                \"\\n\\t\\tn:\",\r\n                P.intersection ? P.neighbour.coords.usrCoords : \"-\"\r\n            );\r\n            if (P._end) {\r\n                break;\r\n            }\r\n            P = P._next;\r\n            cnt++;\r\n        }\r\n    },\r\n\r\n    _noOverlap: function (p1, p2, q1, q2) {\r\n        var k,\r\n            eps = Math.sqrt(Mat.eps),\r\n            minp,\r\n            maxp,\r\n            minq,\r\n            maxq,\r\n            no_overlap = false;\r\n\r\n        for (k = 0; k < 3; k++) {\r\n            minp = Math.min(p1[k], p2[k]);\r\n            maxp = Math.max(p1[k], p2[k]);\r\n            minq = Math.min(q1[k], q2[k]);\r\n            maxq = Math.max(q1[k], q2[k]);\r\n            if (maxp < minq - eps || minp > maxq + eps) {\r\n                no_overlap = true;\r\n                break;\r\n            }\r\n        }\r\n        return no_overlap;\r\n    },\r\n\r\n    /**\r\n     * Find all intersections between two paths.\r\n     * @private\r\n     * @param  {Array} S     Subject path\r\n     * @param  {Array} C     Clip path\r\n     * @param  {JXG.Board} board JSXGraph board object. It is needed to convert between\r\n     * user coordinates and screen coordinates.\r\n     * @return {Array}  Array containing two arrays. The first array contains the intersection vertices\r\n     * of the subject path and the second array contains the intersection vertices of the clip path.\r\n     * @see JXG.Math.Clip.Vertex\r\n     */\r\n    findIntersections: function (S, C, board) {\r\n        var res = [], eps = Mat.eps * 100,\r\n            i, j, crds,\r\n            S_le = S.length,\r\n            C_le = C.length,\r\n            Si, Si1, Cj, Cj1, d1, d2,\r\n            alpha, type, IS, IC,\r\n            S_intersect = [],\r\n            C_intersect = [],\r\n            S_crossings = [],\r\n            C_crossings = [],\r\n            hasMultCompsS = false,\r\n            hasMultCompsC = false,\r\n            DEBUG = false;\r\n\r\n        for (j = 0; j < C_le; j++) {\r\n            C_crossings.push([]);\r\n        }\r\n\r\n        // Run through the subject path.\r\n        for (i = 0; i < S_le; i++) {\r\n            S_crossings.push([]);\r\n\r\n            // Test if S[i] or its successor is a path separator.\r\n            // If yes, we know that the path consists of multiple components.\r\n            // We immediately jump to the next segment.\r\n            if (this._isSeparator(S[i]) || this._isSeparator(S[(i + 1) % S_le])) {\r\n                hasMultCompsS = true;\r\n                continue;\r\n            }\r\n\r\n            // If the path consists of multiple components then there is\r\n            // no path-closing segment between the last node and the first\r\n            // node. In this case we can leave the loop now.\r\n            if (hasMultCompsS && i === S_le - 1) {\r\n                break;\r\n            }\r\n\r\n            Si = S[i].coords.usrCoords;\r\n            Si1 = S[(i + 1) % S_le].coords.usrCoords;\r\n            // Run through the clip path.\r\n            for (j = 0; j < C_le; j++) {\r\n                // Test if C[j] or its successor is a path separator.\r\n                // If yes, we know that the path consists of multiple components.\r\n                // We immediately jump to the next segment.\r\n                if (this._isSeparator(C[j]) || this._isSeparator(C[(j + 1) % C_le])) {\r\n                    hasMultCompsC = true;\r\n                    continue;\r\n                }\r\n\r\n                // If the path consists of multiple components then there is\r\n                // no path-closing segment between the last node and the first\r\n                // node. In this case we can leave the loop now.\r\n                if (hasMultCompsC && j === C_le - 1) {\r\n                    break;\r\n                }\r\n\r\n                // Test if bounding boxes of the two curve segments overlap\r\n                // If not, the expensive intersection test can be skipped.\r\n                Cj = C[j].coords.usrCoords;\r\n                Cj1 = C[(j + 1) % C_le].coords.usrCoords;\r\n\r\n                if (this._noOverlap(Si, Si1, Cj, Cj1)) {\r\n                    continue;\r\n                }\r\n\r\n                // Intersection test\r\n                res = Geometry.meetSegmentSegment(Si, Si1, Cj, Cj1);\r\n\r\n                d1 = Geometry.distance(Si, Si1, 3);\r\n                d2 = Geometry.distance(Cj, Cj1, 3);\r\n\r\n                // Found an intersection point\r\n                if (\r\n                    // \"Regular\" intersection\r\n                    (res[1] * d1 > -eps &&\r\n                        res[1] < 1 - eps / d1 &&\r\n                        res[2] * d2 > -eps &&\r\n                        res[2] < 1 - eps / d2) ||\r\n                    // Collinear segments\r\n                    (res[1] === Infinity && res[2] === Infinity && Mat.norm(res[0], 3) < eps)\r\n                ) {\r\n                    crds = new Coords(Const.COORDS_BY_USER, res[0], board);\r\n                    type = 'X';\r\n\r\n                    // Handle degenerated cases\r\n                    if (Math.abs(res[1]) * d1 < eps || Math.abs(res[2]) * d2 < eps) {\r\n                        // Crossing / bouncing at vertex or\r\n                        // end of delayed crossing / bouncing\r\n                        type = 'T';\r\n                        if (Math.abs(res[1]) * d1 < eps) {\r\n                            res[1] = 0;\r\n                        }\r\n                        if (Math.abs(res[2]) * d2 < eps) {\r\n                            res[2] = 0;\r\n                        }\r\n                        if (res[1] === 0) {\r\n                            crds = new Coords(Const.COORDS_BY_USER, Si, board);\r\n                        } else {\r\n                            crds = new Coords(Const.COORDS_BY_USER, Cj, board);\r\n                        }\r\n\r\n                        if (DEBUG) {\r\n                            console.log(\r\n                                \"Degenerate case I\",\r\n                                res[1],\r\n                                res[2],\r\n                                crds.usrCoords,\r\n                                \"type\",\r\n                                type\r\n                            );\r\n                        }\r\n                    } else if (\r\n                        res[1] === Infinity &&\r\n                        res[2] === Infinity &&\r\n                        Mat.norm(res[0], 3) < eps\r\n                    ) {\r\n                        // console.log(C_intersect);\r\n\r\n                        // Collinear segments\r\n                        // Here, there might be two intersection points to be added\r\n\r\n                        alpha = this._inbetween(Si, Cj, Cj1);\r\n                        if (DEBUG) {\r\n                            // console.log(\"alpha Si\", alpha, Si);\r\n                            // console.log(j, Cj)\r\n                            // console.log((j + 1) % C_le, Cj1)\r\n                        }\r\n                        if (alpha >= 0 && alpha < 1) {\r\n                            type = 'T';\r\n                            crds = new Coords(Const.COORDS_BY_USER, Si, board);\r\n                            res[1] = 0;\r\n                            res[2] = alpha;\r\n                            IS = new this.Vertex(crds, i, res[1], S, \"S\", type);\r\n                            IC = new this.Vertex(crds, j, res[2], C, \"C\", type);\r\n                            IS.neighbour = IC;\r\n                            IC.neighbour = IS;\r\n                            S_crossings[i].push(IS);\r\n                            C_crossings[j].push(IC);\r\n                            if (DEBUG) {\r\n                                console.log(\r\n                                    \"Degenerate case II\",\r\n                                    res[1],\r\n                                    res[2],\r\n                                    crds.usrCoords,\r\n                                    \"type T\"\r\n                                );\r\n                            }\r\n                        }\r\n                        alpha = this._inbetween(Cj, Si, Si1);\r\n                        if (DEBUG) {\r\n                            // console.log(\"alpha Cj\", alpha, Si, Geometry.distance(Si, Cj, 3));\r\n                        }\r\n                        if (Geometry.distance(Si, Cj, 3) > eps && alpha >= 0 && alpha < 1) {\r\n                            type = 'T';\r\n                            crds = new Coords(Const.COORDS_BY_USER, Cj, board);\r\n                            res[1] = alpha;\r\n                            res[2] = 0;\r\n                            IS = new this.Vertex(crds, i, res[1], S, \"S\", type);\r\n                            IC = new this.Vertex(crds, j, res[2], C, \"C\", type);\r\n                            IS.neighbour = IC;\r\n                            IC.neighbour = IS;\r\n                            S_crossings[i].push(IS);\r\n                            C_crossings[j].push(IC);\r\n                            if (DEBUG) {\r\n                                console.log(\r\n                                    \"Degenerate case III\",\r\n                                    res[1],\r\n                                    res[2],\r\n                                    crds.usrCoords,\r\n                                    \"type T\"\r\n                                );\r\n                            }\r\n                        }\r\n                        continue;\r\n                    }\r\n                    if (DEBUG) {\r\n                        console.log(\"IS\", i, j, crds.usrCoords, type);\r\n                    }\r\n\r\n                    IS = new this.Vertex(crds, i, res[1], S, \"S\", type);\r\n                    IC = new this.Vertex(crds, j, res[2], C, \"C\", type);\r\n                    IS.neighbour = IC;\r\n                    IC.neighbour = IS;\r\n\r\n                    S_crossings[i].push(IS);\r\n                    C_crossings[j].push(IC);\r\n                }\r\n            }\r\n        }\r\n\r\n        // For both paths, sort their intersection points\r\n        S_intersect = this.sortIntersections(S_crossings);\r\n\r\n        if (DEBUG) {\r\n            console.log(\">>>>>> Intersections \");\r\n            console.log(\"S_intersect\");\r\n            this._print_array(S_intersect);\r\n            console.log(\"----------\");\r\n        }\r\n        for (i = 0; i < S_intersect.length; i++) {\r\n            S_intersect[i].data.idx = i;\r\n            S_intersect[i].neighbour.data.idx = i;\r\n        }\r\n        C_intersect = this.sortIntersections(C_crossings);\r\n\r\n        if (DEBUG) {\r\n            console.log(\"C_intersect\");\r\n            this._print_array(C_intersect);\r\n            console.log(\"<<<<<< Phase 1 done\");\r\n        }\r\n        return [S_intersect, C_intersect];\r\n    },\r\n\r\n    /**\r\n     * It is testedd if the point q lies to the left or right\r\n     * of the poylgonal chain [p1, p2, p3].\r\n     * @param {Array} q User coords array\r\n     * @param {Array} p1 User coords array\r\n     * @param {Array} p2 User coords array\r\n     * @param {Array} p3 User coords array\r\n     * @returns string 'left' or 'right'\r\n     * @private\r\n     */\r\n    _getPosition: function (q, p1, p2, p3) {\r\n        var s1 = Geometry.det3p(q, p1, p2),\r\n            s2 = Geometry.det3p(q, p2, p3),\r\n            s3 = Geometry.det3p(p1, p2, p3);\r\n\r\n        // Left turn\r\n        if (s3 >= 0) {\r\n            if (s1 >= 0 && s2 >= 0) {\r\n                return 'left';\r\n            }\r\n            return 'right';\r\n        }\r\n        // Right turn\r\n        if (s1 >= 0 || s2 >= 0) {\r\n            return 'left';\r\n        }\r\n        return 'right';\r\n    },\r\n\r\n    /**\r\n     * Determine the delayed status of degenerated intersection points.\r\n     * It is of the form\r\n     *   ['on|left|right', 'on|left|right']\r\n     * <p>\r\n     * If all four determinants are zero, we add random noise to the point.\r\n     *\r\n     * @param {JXG.Math.Clip.Vertex} P Start of path\r\n     * @private\r\n     * @see JXG.Math.Clip.markEntryExit\r\n     * @see JXG.Math.Clip._handleIntersectionChains\r\n     */\r\n    _classifyDegenerateIntersections: function (P) {\r\n        var Pp, Pm, Qp, Qm,  Q,\r\n            side, cnt, tmp, det,\r\n            oppositeDir,\r\n            s1, s2, s3, s4,\r\n            endless = true,\r\n            DEBUG = false;\r\n\r\n        if (DEBUG) {\r\n            console.log(\r\n                \"\\n-------------- _classifyDegenerateIntersections()\",\r\n                Type.exists(P.data) ? P.data.pathname : \" \"\r\n            );\r\n        }\r\n        det = Geometry.det3p;\r\n        cnt = 0;\r\n        P._tours = 0;\r\n        while (endless) {\r\n            if (DEBUG) {\r\n                console.log(\"Inspect P:\", P.coords.usrCoords, P.data ? P.data.type : \" \");\r\n            }\r\n            if (P.intersection && P.data.type === 'T') {\r\n                // Handle the degenerate cases\r\n                // Decide if they are (delayed) bouncing or crossing intersections\r\n                Pp = P._next.coords.usrCoords; // P+\r\n                Pm = P._prev.coords.usrCoords; // P-\r\n\r\n                // If the intersection point is degenerated and\r\n                // equal to the start and end of one component,\r\n                // then there will be two adjacent points with\r\n                // the same coordinate.\r\n                // In that case, we proceed to the next node.\r\n                if (Geometry.distance(P.coords.usrCoords, Pp, 3) < Mat.eps) {\r\n                    Pp = P._next._next.coords.usrCoords;\r\n                }\r\n                if (Geometry.distance(P.coords.usrCoords, Pm, 3) < Mat.eps) {\r\n                    Pm = P._prev._prev.coords.usrCoords;\r\n                }\r\n\r\n                Q = P.neighbour;\r\n                Qm = Q._prev.coords.usrCoords; // Q-\r\n                Qp = Q._next.coords.usrCoords; // Q+\r\n                if (Geometry.distance(Q.coords.usrCoords, Qp, 3) < Mat.eps) {\r\n                    Qp = Q._next._next.coords.usrCoords;\r\n                }\r\n                if (Geometry.distance(Q.coords.usrCoords, Qm, 3) < Mat.eps) {\r\n                    Qm = Q._prev._prev.coords.usrCoords;\r\n                }\r\n\r\n                if (DEBUG) {\r\n                    console.log(\"P chain:\", Pm, P.coords.usrCoords, Pp);\r\n                    console.log(\"Q chain:\", Qm, P.neighbour.coords.usrCoords, Qp);\r\n                    console.log(\"Pm\", this._getPosition(Pm, Qm, Q.coords.usrCoords, Qp));\r\n                    console.log(\"Pp\", this._getPosition(Pp, Qm, Q.coords.usrCoords, Qp));\r\n                }\r\n\r\n                s1 = det(P.coords.usrCoords, Pm, Qm);\r\n                s2 = det(P.coords.usrCoords, Pp, Qp);\r\n                s3 = det(P.coords.usrCoords, Pm, Qp);\r\n                s4 = det(P.coords.usrCoords, Pp, Qm);\r\n\r\n                if (s1 === 0 && s2 === 0 && s3 === 0 && s4 === 0) {\r\n                    P.coords.usrCoords[1] *= 1 + Math.random() * Mat.eps;\r\n                    P.coords.usrCoords[2] *= 1 + Math.random() * Mat.eps;\r\n                    Q.coords.usrCoords[1] = P.coords.usrCoords[1];\r\n                    Q.coords.usrCoords[2] = P.coords.usrCoords[2];\r\n                    s1 = det(P.coords.usrCoords, Pm, Qm);\r\n                    s2 = det(P.coords.usrCoords, Pp, Qp);\r\n                    s3 = det(P.coords.usrCoords, Pm, Qp);\r\n                    s4 = det(P.coords.usrCoords, Pp, Qm);\r\n                    if (DEBUG) {\r\n                        console.log(\"Random shift\", P.coords.usrCoords);\r\n                        console.log(s1, s2, s3, s4, s2 === 0);\r\n                        console.log(\r\n                            this._getPosition(Pm, Qm, Q.coords.usrCoords, Qp),\r\n                            this._getPosition(Pp, Qm, Q.coords.usrCoords, Qp)\r\n                        );\r\n                    }\r\n                }\r\n                oppositeDir = false;\r\n                if (s1 === 0) {\r\n                    // Q-, Q=P, P- on straight line\r\n                    if (Geometry.affineRatio(P.coords.usrCoords, Pm, Qm) < 0) {\r\n                        oppositeDir = true;\r\n                    }\r\n                } else if (s2 === 0) {\r\n                    if (Geometry.affineRatio(P.coords.usrCoords, Pp, Qp) < 0) {\r\n                        oppositeDir = true;\r\n                    }\r\n                } else if (s3 === 0) {\r\n                    if (Geometry.affineRatio(P.coords.usrCoords, Pm, Qp) > 0) {\r\n                        oppositeDir = true;\r\n                    }\r\n                } else if (s4 === 0) {\r\n                    if (Geometry.affineRatio(P.coords.usrCoords, Pp, Qm) > 0) {\r\n                        oppositeDir = true;\r\n                    }\r\n                }\r\n                if (oppositeDir) {\r\n                    // Swap Qm and Qp\r\n                    // Then Qm Q Qp has the same direction as Pm P Pp\r\n                    tmp = Qm;\r\n                    Qm = Qp;\r\n                    Qp = tmp;\r\n                    tmp = s1;\r\n                    s1 = s3;\r\n                    s3 = tmp;\r\n                    tmp = s2;\r\n                    s2 = s4;\r\n                    s4 = tmp;\r\n                }\r\n\r\n                if (DEBUG) {\r\n                    console.log(s1, s2, s3, s4, oppositeDir);\r\n                }\r\n\r\n                if (!Type.exists(P.delayedStatus)) {\r\n                    P.delayedStatus = [];\r\n                }\r\n\r\n                if (s1 === 0 && s2 === 0) {\r\n                    // Line [P-,P] equals [Q-,Q] and line [P,P+] equals [Q,Q+]\r\n                    // Interior of delayed crossing / bouncing\r\n                    P.delayedStatus = [\"on\", \"on\"];\r\n                } else if (s1 === 0) {\r\n                    // P- on line [Q-,Q], P+ not on line [Q,Q+]\r\n                    // Begin / end of delayed crossing / bouncing\r\n                    side = this._getPosition(Pp, Qm, Q.coords.usrCoords, Qp);\r\n                    P.delayedStatus = [\"on\", side];\r\n                } else if (s2 === 0) {\r\n                    // P+ on line [Q,Q+], P- not on line [Q-,Q]\r\n                    // Begin / end of delayed crossing / bouncing\r\n                    side = this._getPosition(Pm, Qm, Q.coords.usrCoords, Qp);\r\n                    P.delayedStatus = [side, \"on\"];\r\n                } else {\r\n                    // Neither P+ on line [Q,Q+], nor P- on line [Q-,Q]\r\n                    // No delayed crossing / bouncing\r\n                    if (P.delayedStatus.length === 0) {\r\n                        if (\r\n                            this._getPosition(Pm, Qm, Q.coords.usrCoords, Qp) !==\r\n                            this._getPosition(Pp, Qm, Q.coords.usrCoords, Qp)\r\n                        ) {\r\n                            P.data.type = 'X';\r\n                        } else {\r\n                            P.data.type = 'B';\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (DEBUG) {\r\n                    console.log(\r\n                        \">>>> P:\",\r\n                        P.coords.usrCoords,\r\n                        \"delayedStatus:\",\r\n                        P.delayedStatus.toString(),\r\n                        P.data ? P.data.type : \" \",\r\n                        \"\\n---\"\r\n                    );\r\n                }\r\n            }\r\n\r\n            if (Type.exists(P._tours)) {\r\n                P._tours++;\r\n            }\r\n\r\n            if (P._tours > 3 || P._end || cnt > 1000) {\r\n                // Jump out if either\r\n                // - we reached the end\r\n                // - there are more than 1000 intersection points\r\n                // - P._tours > 3: We went already 4 times through this path.\r\n                if (cnt > 1000) {\r\n                    console.log(\"Clipping: _classifyDegenerateIntersections exit\");\r\n                }\r\n                if (Type.exists(P._tours)) {\r\n                    delete P._tours;\r\n                }\r\n                break;\r\n            }\r\n            if (P.intersection) {\r\n                cnt++;\r\n            }\r\n            P = P._next;\r\n        }\r\n        if (DEBUG) {\r\n            console.log(\"------------------------\");\r\n        }\r\n    },\r\n\r\n    /**\r\n     * At this point the degenerated intersections have been classified.\r\n     * Now we decide if the intersection chains of the given path\r\n     * ultimatively cross the other path or bounce.\r\n     *\r\n     * @param {JXG.Math.Clip.Vertex} P Start of path\r\n     *\r\n     * @see JXG.Math.Clip.markEntryExit\r\n     * @see JXG.Math.Clip._classifyDegenerateIntersections\r\n     * @private\r\n     */\r\n    _handleIntersectionChains: function (P) {\r\n        var cnt = 0,\r\n            start_status = \"Null\",\r\n            P_start,\r\n            endless = true,\r\n            intersection_chain = false,\r\n            wait_for_exit = false,\r\n            DEBUG = false;\r\n\r\n        if (DEBUG) {\r\n            console.log(\r\n                \"\\n-------------- _handleIntersectionChains()\",\r\n                Type.exists(P.data) ? P.data.pathname : \" \"\r\n            );\r\n        }\r\n        while (endless) {\r\n            if (P.intersection === true) {\r\n                if (DEBUG) {\r\n                    if (P.data.type === 'T') {\r\n                        console.log(\r\n                            \"Degenerate point\",\r\n                            P.coords.usrCoords,\r\n                            P.data.type,\r\n                            P.data.type === \"T\" ? P.delayedStatus : \" \"\r\n                        );\r\n                    } else {\r\n                        console.log(\"Intersection point\", P.coords.usrCoords, P.data.type);\r\n                    }\r\n                }\r\n                if (P.data.type === 'T') {\r\n                    if (P.delayedStatus[0] !== \"on\" && P.delayedStatus[1] === 'on') {\r\n                        // First point of intersection chain\r\n                        intersection_chain = true;\r\n                        P_start = P;\r\n                        start_status = P.delayedStatus[0];\r\n                    } else if (\r\n                        intersection_chain &&\r\n                        P.delayedStatus[0] === \"on\" &&\r\n                        P.delayedStatus[1] === \"on\"\r\n                    ) {\r\n                        // Interior of intersection chain\r\n                        P.data.type = 'B';\r\n                        if (DEBUG) {\r\n                            console.log(\"Interior\", P.coords.usrCoords);\r\n                        }\r\n                    } else if (\r\n                        intersection_chain &&\r\n                        P.delayedStatus[0] === \"on\" &&\r\n                        P.delayedStatus[1] !== \"on\"\r\n                    ) {\r\n                        // Last point of intersection chain\r\n                        intersection_chain = false;\r\n                        if (start_status === P.delayedStatus[1]) {\r\n                            // Intersection chain is delayed bouncing\r\n                            P_start.data.type = 'DB';\r\n                            P.data.type = 'DB';\r\n                            if (DEBUG) {\r\n                                console.log(\r\n                                    \"Chain: delayed bouncing\",\r\n                                    P_start.coords.usrCoords,\r\n                                    \"...\",\r\n                                    P.coords.usrCoords\r\n                                );\r\n                            }\r\n                        } else {\r\n                            // Intersection chain is delayed crossing\r\n                            P_start.data.type = 'DX';\r\n                            P.data.type = 'DX';\r\n                            if (DEBUG) {\r\n                                console.log(\r\n                                    \"Chain: delayed crossing\",\r\n                                    P_start.coords.usrCoords,\r\n                                    \"...\",\r\n                                    P.coords.usrCoords\r\n                                );\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n                cnt++;\r\n            }\r\n            if (P._end) {\r\n                wait_for_exit = true;\r\n            }\r\n            if (wait_for_exit && !intersection_chain) {\r\n                break;\r\n            }\r\n            if (cnt > 1000) {\r\n                console.log(\r\n                    \"Warning: _handleIntersectionChains: intersection chain reached maximum numbers of iterations\"\r\n                );\r\n                break;\r\n            }\r\n            P = P._next;\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Handle the case that all vertices of one path are contained\r\n     * in the other path. In this case we search for a midpoint of an edge\r\n     * which is not contained in the other path and add it to the path.\r\n     * It will be used as starting point for the entry/exit algorithm.\r\n     *\r\n     * @private\r\n     * @param {Array} S Subject path\r\n     * @param {Array} C Clip path\r\n     * @param {JXG.board} board JSXGraph board object. It is needed to convert between\r\n     * user coordinates and screen coordinates.\r\n     */\r\n    _handleFullyDegenerateCase: function (S, C, board) {\r\n        var P, Q, l, M, crds,\r\n            q1, q2, node, i, j,\r\n            leP, leQ, is_on_Q,\r\n            tmp, is_fully_degenerated,\r\n            arr = [S, C];\r\n\r\n        for (l = 0; l < 2; l++) {\r\n            P = arr[l];\r\n            leP = P.length;\r\n            for (i = 0, is_fully_degenerated = true; i < leP; i++) {\r\n                if (!P[i].intersection) {\r\n                    is_fully_degenerated = false;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if (is_fully_degenerated) {\r\n                // All nodes of P are also on the other path.\r\n                Q = arr[(l + 1) % 2];\r\n                leQ = Q.length;\r\n\r\n                // We search for a midpoint of one edge of P which is not the other path and\r\n                // we add that midpoint to P.\r\n                for (i = 0; i < leP; i++) {\r\n                    q1 = P[i].coords.usrCoords;\r\n                    q2 = P[i]._next.coords.usrCoords;\r\n\r\n                    // M is the midpoint\r\n                    M = [(q1[0] + q2[0]) * 0.5, (q1[1] + q2[1]) * 0.5, (q1[2] + q2[2]) * 0.5];\r\n\r\n                    // Test if M is on path Q. If this is not the case,\r\n                    // we take M as additional point of P.\r\n                    for (j = 0, is_on_Q = false; j < leQ; j++) {\r\n                        if (\r\n                            Math.abs(\r\n                                Geometry.det3p(\r\n                                    Q[j].coords.usrCoords,\r\n                                    Q[(j + 1) % leQ].coords.usrCoords,\r\n                                    M\r\n                                )\r\n                            ) < Mat.eps\r\n                        ) {\r\n                            is_on_Q = true;\r\n                            break;\r\n                        }\r\n                    }\r\n                    if (!is_on_Q) {\r\n                        // The midpoint is added to the doubly-linked list.\r\n                        crds = new Coords(Const.COORDS_BY_USER, M, board);\r\n                        node = {\r\n                            pos: i,\r\n                            intersection: false,\r\n                            coords: crds,\r\n                            elementClass: Const.OBJECT_CLASS_POINT\r\n                        };\r\n\r\n                        tmp = P[i]._next;\r\n                        P[i]._next = node;\r\n                        node._prev = P[i];\r\n                        node._next = tmp;\r\n                        tmp._prev = node;\r\n\r\n                        if (P[i]._end) {\r\n                            P[i]._end = false;\r\n                            node._end = true;\r\n                        }\r\n\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    },\r\n\r\n    _getStatus: function (P, path) {\r\n        var status;\r\n        while (P.intersection) {\r\n            if (P._end) {\r\n                break;\r\n            }\r\n            P = P._next;\r\n        }\r\n        if (Geometry.windingNumber(P.coords.usrCoords, path) === 0) {\r\n            // Outside\r\n            status = 'entry';\r\n            // console.log(P.coords.usrCoords, ' is outside')\r\n        } else {\r\n            // Inside\r\n            status = 'exit';\r\n            // console.log(P.coords.usrCoords, ' is inside')\r\n        }\r\n\r\n        return [P, status];\r\n    },\r\n\r\n    /**\r\n     * Mark the intersection vertices of path1 as entry points or as exit points\r\n     * in respect to path2.\r\n     * <p>\r\n     * This is the simple algorithm as in\r\n     * Greiner, Günther; Kai Hormann (1998). \"Efficient clipping of arbitrary polygons\".\r\n     * ACM Transactions on Graphics. 17 (2): 71–83\r\n     * <p>\r\n     * The algorithm handles also \"delayed crossings\" from\r\n     * Erich, L. Foster, and Kai Hormann, Kai, and Romeo Traaian Popa (2019),\r\n     * \"Clipping simple polygons with degenerate intersections\", Computers & Graphics:X, 2.\r\n     * and - as an additional improvement -\r\n     * handles self intersections of delayed crossings (A.W. 2021).\r\n     *\r\n     * @private\r\n     * @param  {Array} path1 First path\r\n     * @param  {Array} path2 Second path\r\n     */\r\n    markEntryExit: function (path1, path2, starters) {\r\n        var status, P, cnt, res,\r\n            i, len, start,\r\n            endless = true,\r\n            chain_start = null,\r\n            intersection_chain = 0,\r\n            DEBUG = false;\r\n\r\n        len = starters.length;\r\n        for (i = 0; i < len; i++) {\r\n            start = starters[i];\r\n            if (DEBUG) {\r\n                console.log(\r\n                    \"\\n;;;;;;;;;; Labelling phase\",\r\n                    Type.exists(path1[start].data) ? path1[start].data.pathname : \" \",\r\n                    path1[start].coords.usrCoords\r\n                );\r\n            }\r\n            this._classifyDegenerateIntersections(path1[start]);\r\n            this._handleIntersectionChains(path1[start]);\r\n            if (DEBUG) {\r\n                console.log(\"\\n---- back to markEntryExit\");\r\n            }\r\n\r\n            // Decide if the first point of the component is inside or outside\r\n            // of the other path.\r\n            res = this._getStatus(path1[start], path2);\r\n            P = res[0];\r\n            status = res[1];\r\n            if (DEBUG) {\r\n                console.log(\"Start node:\", P.coords.usrCoords, status);\r\n            }\r\n\r\n            P._starter = true;\r\n\r\n            // Greiner-Hormann entry/exit algorithm\r\n            // with additional handling of delayed crossing / bouncing\r\n            cnt = 0;\r\n            chain_start = null;\r\n            intersection_chain = 0;\r\n\r\n            while (endless) {\r\n                if (P.intersection === true) {\r\n                    if (P.data.type === \"X\" && intersection_chain === 1) {\r\n                        // While we are in an intersection chain, i.e. a delayed crossing,\r\n                        // we stumble on a crossing intersection.\r\n                        // Probably, the other path is self intersecting.\r\n                        // We end the intersection chain here and\r\n                        // mark this event by setting intersection_chain = 2.\r\n                        chain_start.entry_exit = status;\r\n                        if (status === 'exit') {\r\n                            chain_start.data.type = 'X';\r\n                        }\r\n                        intersection_chain = 2;\r\n                    }\r\n\r\n                    if (P.data.type === \"X\" || P.data.type === 'DB') {\r\n                        P.entry_exit = status;\r\n                        status = status === \"entry\" ? \"exit\" : 'entry';\r\n                        if (DEBUG) {\r\n                            console.log(\"mark:\", P.coords.usrCoords, P.data.type, P.entry_exit);\r\n                        }\r\n                    }\r\n\r\n                    if (P.data.type === 'DX') {\r\n                        if (intersection_chain === 0) {\r\n                            // Start of intersection chain.\r\n                            // No active intersection chain yet,\r\n                            // i.e. we did not pass a the first node of a delayed crossing.\r\n                            chain_start = P;\r\n                            intersection_chain = 1;\r\n                            if (DEBUG) {\r\n                                console.log(\r\n                                    \"Start intersection chain:\",\r\n                                    P.coords.usrCoords,\r\n                                    P.data.type,\r\n                                    status\r\n                                );\r\n                            }\r\n                        } else if (intersection_chain === 1) {\r\n                            // Active intersection chain (intersection_chain===1)!\r\n                            // End of delayed crossing chain reached\r\n                            P.entry_exit = status;\r\n                            chain_start.entry_exit = status;\r\n                            if (status === 'exit') {\r\n                                chain_start.data.type = 'X';\r\n                            } else {\r\n                                P.data.type = 'X';\r\n                            }\r\n                            status = status === \"entry\" ? \"exit\" : 'entry';\r\n\r\n                            if (DEBUG) {\r\n                                console.log(\r\n                                    \"mark':\",\r\n                                    chain_start.coords.usrCoords,\r\n                                    chain_start.data.type,\r\n                                    chain_start.entry_exit\r\n                                );\r\n                                console.log(\r\n                                    \"mark:\",\r\n                                    P.coords.usrCoords,\r\n                                    P.data.type,\r\n                                    P.entry_exit\r\n                                );\r\n                            }\r\n                            chain_start = null;\r\n                            intersection_chain = 0;\r\n                        } else if (intersection_chain === 2) {\r\n                            // The delayed crossing had been interrupted by a crossing intersection.\r\n                            // Now we treat the end of the delayed crossing as regular crossing.\r\n                            P.entry_exit = status;\r\n                            P.data.type = 'X';\r\n                            status = status === \"entry\" ? \"exit\" : 'entry';\r\n                            chain_start = null;\r\n                            intersection_chain = 0;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                P = P._next;\r\n                if (Type.exists(P._starter) || cnt > 10000) {\r\n                    break;\r\n                }\r\n\r\n                cnt++;\r\n            }\r\n        }\r\n    },\r\n\r\n    /**\r\n     *\r\n     * @private\r\n     * @param {Array} P\r\n     * @param {Boolean} isBackward\r\n     * @returns {Boolean} True, if the node is an intersection and is of type 'X'\r\n     */\r\n    _stayOnPath: function (P, status) {\r\n        var stay = true;\r\n\r\n        if (P.intersection && P.data.type !== 'B') {\r\n            stay = status === P.entry_exit;\r\n        }\r\n        return stay;\r\n    },\r\n\r\n    /**\r\n     * Add a point to the clipping path and returns if the algorithms\r\n     * arrived at an intersection point which has already been visited.\r\n     * In this case, true is returned.\r\n     *\r\n     * @param {Array} path Resulting path\r\n     * @param {JXG.Math.Clip.Vertex} vertex Point to be added\r\n     * @param {Boolean} DEBUG debug output to console.log\r\n     * @returns {Boolean} true: point has been visited before, false otherwise\r\n     * @private\r\n     */\r\n    _addVertex: function (path, vertex, DEBUG) {\r\n        if (!isNaN(vertex.coords.usrCoords[1]) && !isNaN(vertex.coords.usrCoords[2])) {\r\n            path.push(vertex);\r\n        }\r\n        if (vertex.intersection && vertex.data.done) {\r\n            if (DEBUG) {\r\n                console.log(\r\n                    \"Add last intersection point\",\r\n                    vertex.coords.usrCoords,\r\n                    \"on\",\r\n                    vertex.data.pathname,\r\n                    vertex.entry_exit,\r\n                    vertex.data.type\r\n                );\r\n            }\r\n            return true;\r\n        }\r\n        if (vertex.intersection) {\r\n            vertex.data.done = true;\r\n\r\n            if (DEBUG) {\r\n                console.log(\r\n                    \"Add intersection point\",\r\n                    vertex.coords.usrCoords,\r\n                    \"on\",\r\n                    vertex.data.pathname,\r\n                    vertex.entry_exit,\r\n                    vertex.data.type\r\n                );\r\n            }\r\n        }\r\n        return false;\r\n    },\r\n\r\n    /**\r\n     * Tracing phase of the Greiner-Hormann algorithm, see\r\n     * Greiner, Günther; Kai Hormann (1998).\r\n     * \"Efficient clipping of arbitrary polygons\". ACM Transactions on Graphics. 17 (2): 71–83\r\n     *\r\n     * Boolean operations on polygons are distinguished: 'intersection', 'union', 'difference'.\r\n     *\r\n     * @private\r\n     * @param  {Array} S           Subject path\r\n     * @param  {Array} S_intersect Array containing the intersection vertices of the subject path\r\n     * @param  {String} clip_type  contains the Boolean operation: 'intersection', 'union', or 'difference'\r\n     * @return {Array}             Array consisting of two arrays containing the x-coordinates and the y-coordintaes of\r\n     *      the resulting path.\r\n     */\r\n    tracing: function (S, S_intersect, clip_type) {\r\n        var P, status, current, start,\r\n            cnt = 0,\r\n            maxCnt = 10000,\r\n            S_idx = 0,\r\n            path = [],\r\n            done = false,\r\n            DEBUG = false;\r\n\r\n        if (DEBUG) {\r\n            console.log(\"\\n------ Start Phase 3\");\r\n        }\r\n\r\n        // reverse = (clip_type === 'difference' || clip_type === 'union') ? true : false;\r\n        while (S_idx < S_intersect.length && cnt < maxCnt) {\r\n            // Take the first intersection node of the subject path\r\n            // which is not yet included as start point.\r\n            current = S_intersect[S_idx];\r\n            if (\r\n                current.data.done ||\r\n                current.data.type !== \"X\" /*|| !this._isCrossing(current, reverse)*/\r\n            ) {\r\n                S_idx++;\r\n                continue;\r\n            }\r\n\r\n            if (DEBUG) {\r\n                console.log(\r\n                    \"\\nStart\",\r\n                    current.data.pathname,\r\n                    current.coords.usrCoords,\r\n                    current.data.type,\r\n                    current.entry_exit,\r\n                    S_idx\r\n                );\r\n            }\r\n            if (path.length > 0) {\r\n                // Add a new path\r\n                path.push([NaN, NaN]);\r\n            }\r\n\r\n            // Start now the tracing with that node of the subject path\r\n            start = current.data.idx;\r\n            P = S;\r\n\r\n            done = this._addVertex(path, current, DEBUG);\r\n            status = current.entry_exit;\r\n            do {\r\n                if (done) {\r\n                    break;\r\n                }\r\n                //\r\n                // Decide if we follow the current path forward or backward.\r\n                // for example, in case the clipping is of type \"intersection\"\r\n                // and the current intersection node is of type entry, we go forward.\r\n                //\r\n                if (\r\n                    (clip_type === \"intersection\" && current.entry_exit === 'entry') ||\r\n                    (clip_type === \"union\" && current.entry_exit === 'exit') ||\r\n                    (clip_type === \"difference\" &&\r\n                        (P === S) === (current.entry_exit === 'exit'))\r\n                ) {\r\n                    if (DEBUG) {\r\n                        console.log(\"Go forward on\", current.data.pathname, current.entry_exit);\r\n                    }\r\n\r\n                    //\r\n                    // Take the next nodes and add them to the path\r\n                    // as long as they are not intersection nodes of type 'X'.\r\n                    //\r\n                    do {\r\n                        current = current._next;\r\n                        done = this._addVertex(path, current, DEBUG);\r\n                        if (done) {\r\n                            break;\r\n                        }\r\n                    } while (this._stayOnPath(current, status));\r\n                    cnt++;\r\n                } else {\r\n                    if (DEBUG) {\r\n                        console.log(\"Go backward on\", current.data.pathname);\r\n                    }\r\n                    //\r\n                    // Here, we go backward:\r\n                    // Take the previous nodes and add them to the path\r\n                    // as long as they are not intersection nodes of type 'X'.\r\n                    //\r\n                    do {\r\n                        current = current._prev;\r\n                        done = this._addVertex(path, current, DEBUG);\r\n                        if (done) {\r\n                            break;\r\n                        }\r\n                    } while (this._stayOnPath(current, status));\r\n                    cnt++;\r\n                }\r\n\r\n                if (done) {\r\n                    break;\r\n                }\r\n\r\n                if (!current.neighbour) {\r\n                    console.log(\r\n                        \"Tracing: emergency break - no neighbour!!!!!!!!!!!!!!!!!\",\r\n                        cnt\r\n                    );\r\n                    return [[0], [0]];\r\n                }\r\n                //\r\n                // We stopped the forward or backward loop, because we've\r\n                // arrived at a crossing intersection node, i.e. we have to\r\n                // switch to the other path now.\r\n                if (DEBUG) {\r\n                    console.log(\r\n                        \"Switch from\",\r\n                        current.coords.usrCoords,\r\n                        current.data.pathname,\r\n                        \"to\",\r\n                        current.neighbour.coords.usrCoords,\r\n                        \"on\",\r\n                        current.neighbour.data.pathname\r\n                    );\r\n                }\r\n                current = current.neighbour;\r\n                if (current.data.done) {\r\n                    break;\r\n                }\r\n                current.data.done = true;\r\n                status = current.entry_exit;\r\n\r\n                // if (current.data.done) {\r\n                //     // We arrived at an intersection node which is already\r\n                //     // added to the clipping path.\r\n                //     // We add it again to close the clipping path and jump out of the\r\n                //     // loop.\r\n                //     path.push(current);\r\n                //     if (DEBUG) {\r\n                //         console.log(\"Push last\", current.coords.usrCoords);\r\n                //     }\r\n                //     break;\r\n                // }\r\n                P = current.data.path;\r\n\r\n                // Polygon closed:\r\n                // if (DEBUG) {\r\n                //     console.log(\"End of loop:\", \"start=\", start, \"idx=\", current.data.idx);\r\n                // }\r\n                // } while (!(current.data.pathname === 'S' && current.data.idx === start) && cnt < maxCnt);\r\n            } while (current.data.idx !== start && cnt < maxCnt);\r\n\r\n            if (cnt >= maxCnt) {\r\n                console.log(\"Tracing: stopping an infinite loop!\", cnt);\r\n            }\r\n\r\n            S_idx++;\r\n        }\r\n        return this._getCoordsArrays(path, false);\r\n    },\r\n\r\n    /**\r\n     * Handle path clipping if one of the two paths is empty.\r\n     * @private\r\n     * @param  {Array} S        First path, array of JXG.Coords\r\n     * @param  {Array} C        Second path, array of JXG.Coords\r\n     * @param  {String} clip_type Type of Boolean operation: 'intersection', 'union', 'differrence'.\r\n     * @return {Boolean}        true, if one of the input paths is empty, false otherwise.\r\n     */\r\n    isEmptyCase: function (S, C, clip_type) {\r\n        if (clip_type === \"intersection\" && (S.length === 0 || C.length === 0)) {\r\n            return true;\r\n        }\r\n        if (clip_type === \"union\" && S.length === 0 && C.length === 0) {\r\n            return true;\r\n        }\r\n        if (clip_type === \"difference\" && S.length === 0) {\r\n            return true;\r\n        }\r\n\r\n        return false;\r\n    },\r\n\r\n    _getCoordsArrays: function (path, doClose) {\r\n        var pathX = [],\r\n            pathY = [],\r\n            i,\r\n            le = path.length;\r\n\r\n        for (i = 0; i < le; i++) {\r\n            if (path[i].coords) {\r\n                pathX.push(path[i].coords.usrCoords[1]);\r\n                pathY.push(path[i].coords.usrCoords[2]);\r\n            } else {\r\n                pathX.push(path[i][0]);\r\n                pathY.push(path[i][1]);\r\n            }\r\n        }\r\n        if (doClose && le > 0) {\r\n            if (path[0].coords) {\r\n                pathX.push(path[0].coords.usrCoords[1]);\r\n                pathY.push(path[0].coords.usrCoords[2]);\r\n            } else {\r\n                pathX.push(path[0][0]);\r\n                pathY.push(path[0][1]);\r\n            }\r\n        }\r\n\r\n        return [pathX, pathY];\r\n    },\r\n\r\n    /**\r\n     * Handle cases when there are no intersection points of the two paths. This is the case if the\r\n     * paths are disjoint or one is contained in the other.\r\n     * @private\r\n     * @param  {Array} S        First path, array of JXG.Coords\r\n     * @param  {Array} C        Second path, array of JXG.Coords\r\n     * @param  {String} clip_type Type of Boolean operation: 'intersection', 'union', 'differrence'.\r\n     * @return {Array}          Array consisting of two arrays containing the x-coordinates and the y-coordinates of\r\n     *      the resulting path.\r\n     */\r\n    handleEmptyIntersection: function (S, C, clip_type) {\r\n        var P,\r\n            Q,\r\n            doClose = false,\r\n            path = [];\r\n\r\n        // Handle trivial cases\r\n        if (S.length === 0) {\r\n            if (clip_type === 'union') {\r\n                // S cup C = C\r\n                path = C;\r\n            } else {\r\n                // S cap C = S \\ C = {}\r\n                path = [];\r\n            }\r\n            return this._getCoordsArrays(path, true);\r\n        }\r\n        if (C.length === 0) {\r\n            if (clip_type === 'intersection') {\r\n                // S cap C = {}\r\n                path = [];\r\n            } else {\r\n                // S cup C = S \\ C = S\r\n                path = S;\r\n            }\r\n            return this._getCoordsArrays(path, true);\r\n        }\r\n\r\n        // From now on, both paths have non-zero length.\r\n        // The two paths have no crossing intersections,\r\n        // but there might be bouncing intersections.\r\n\r\n        // First, we find -- if possible -- on each path a point which is not an intersection point.\r\n        if (S.length > 0) {\r\n            P = S[0];\r\n            while (P.intersection) {\r\n                P = P._next;\r\n                if (P._end) {\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n        if (C.length > 0) {\r\n            Q = C[0];\r\n            while (Q.intersection) {\r\n                Q = Q._next;\r\n                if (Q._end) {\r\n                    break;\r\n                }\r\n            }\r\n        }\r\n\r\n        // Test if one curve is contained by the other\r\n        if (Geometry.windingNumber(P.coords.usrCoords, C) === 0) {\r\n            // P is outside of C:\r\n            // Either S is disjoint from C or C is inside of S\r\n            if (Geometry.windingNumber(Q.coords.usrCoords, S) !== 0) {\r\n                // C is inside of S, i.e. C subset of S\r\n\r\n                if (clip_type === 'union') {\r\n                    Type.concat(path, S);\r\n                    path.push(S[0]);\r\n                } else if (clip_type === 'difference') {\r\n                    Type.concat(path, S);\r\n                    path.push(S[0]);\r\n                    if (Geometry.signedPolygon(S) * Geometry.signedPolygon(C) > 0) {\r\n                        // Pathes have same orientation, we have to revert one.\r\n                        path.reverse();\r\n                    }\r\n                    path.push([NaN, NaN]);\r\n                }\r\n                if (clip_type === \"difference\" || clip_type === 'intersection') {\r\n                    Type.concat(path, C);\r\n                    path.push(C[0]);\r\n                    doClose = false;\r\n                }\r\n            } else {\r\n                // The curves are disjoint\r\n                if (clip_type === 'difference') {\r\n                    Type.concat(path, S);\r\n                    doClose = true;\r\n                } else if (clip_type === 'union') {\r\n                    Type.concat(path, S);\r\n                    path.push(S[0]);\r\n                    path.push([NaN, NaN]);\r\n                    Type.concat(path, C);\r\n                    path.push(C[0]);\r\n                }\r\n            }\r\n        } else {\r\n            // S inside of C, i.e. S subset of C\r\n            if (clip_type === 'intersection') {\r\n                Type.concat(path, S);\r\n                doClose = true;\r\n            } else if (clip_type === 'union') {\r\n                Type.concat(path, C);\r\n                path.push(C[0]);\r\n            }\r\n\r\n            // 'difference': path is empty\r\n        }\r\n\r\n        return this._getCoordsArrays(path, doClose);\r\n    },\r\n\r\n    /**\r\n     * Count intersection points of type 'X'.\r\n     * @param {JXG.Mat.Clip.Vertex} intersections\r\n     * @returns Number\r\n     * @private\r\n     */\r\n    _countCrossingIntersections: function (intersections) {\r\n        var i,\r\n            le = intersections.length,\r\n            sum = 0;\r\n\r\n        for (i = 0; i < le; i++) {\r\n            if (intersections[i].data.type === 'X') {\r\n                sum++;\r\n            }\r\n        }\r\n        return sum;\r\n    },\r\n\r\n    /**\r\n     * Create path from all sorts of input elements and convert it\r\n     * to a suitable input path for greinerHormann().\r\n     *\r\n     * @private\r\n     * @param {Object} obj Maybe curve, arc, sector, circle, polygon, array of points, array of JXG.Coords,\r\n     * array of coordinate pairs.\r\n     * @param  {JXG.Board} board   JSXGraph board object. It is needed to convert between\r\n     * user coordinates and screen coordinates.\r\n     * @returns {Array} Array of JXG.Coords elements containing a path.\r\n     * @see JXG.Math.Clip.greinerHormann\r\n     */\r\n    _getPath: function (obj, board) {\r\n        var i, len, r,\r\n            rad, angle, alpha, steps,\r\n            S = [];\r\n\r\n        // Collect all points into path array S\r\n        if (\r\n            obj.elementClass === Const.OBJECT_CLASS_CURVE &&\r\n            (obj.type === Const.OBJECT_TYPE_ARC || obj.type === Const.OBJECT_TYPE_SECTOR)\r\n        ) {\r\n            angle = Geometry.rad(obj.radiuspoint, obj.center, obj.anglepoint);\r\n            steps = Math.floor((angle * 180) / Math.PI);\r\n            r = obj.Radius();\r\n            rad = angle / steps;\r\n            alpha = Math.atan2(\r\n                obj.radiuspoint.coords.usrCoords[2] - obj.center.coords.usrCoords[2],\r\n                obj.radiuspoint.coords.usrCoords[1] - obj.center.coords.usrCoords[1]\r\n            );\r\n\r\n            if (obj.type === Const.OBJECT_TYPE_SECTOR) {\r\n                this._addToList(S, obj.center.coords, 0);\r\n            }\r\n            for (i = 0; i <= steps; i++) {\r\n                this._addToList(\r\n                    S,\r\n                    new Coords(\r\n                        Const.COORDS_BY_USER,\r\n                        [\r\n                            obj.center.coords.usrCoords[0],\r\n                            obj.center.coords.usrCoords[1] + Math.cos(i * rad + alpha) * r,\r\n                            obj.center.coords.usrCoords[2] + Math.sin(i * rad + alpha) * r\r\n                        ],\r\n                        board\r\n                    ),\r\n                    i + 1\r\n                );\r\n            }\r\n            if (obj.type === Const.OBJECT_TYPE_SECTOR) {\r\n                this._addToList(S, obj.center.coords, steps + 2);\r\n            }\r\n        } else if (obj.elementClass === Const.OBJECT_CLASS_CURVE && Type.exists(obj.points)) {\r\n            len = obj.numberPoints;\r\n            for (i = 0; i < len; i++) {\r\n                this._addToList(S, obj.points[i], i);\r\n            }\r\n        } else if (obj.type === Const.OBJECT_TYPE_POLYGON) {\r\n            for (i = 0; i < obj.vertices.length; i++) {\r\n                this._addToList(S, obj.vertices[i].coords, i);\r\n            }\r\n        } else if (obj.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n            steps = 359;\r\n            r = obj.Radius();\r\n            rad = (2 * Math.PI) / steps;\r\n            for (i = 0; i <= steps; i++) {\r\n                this._addToList(\r\n                    S,\r\n                    new Coords(\r\n                        Const.COORDS_BY_USER,\r\n                        [\r\n                            obj.center.coords.usrCoords[0],\r\n                            obj.center.coords.usrCoords[1] + Math.cos(i * rad) * r,\r\n                            obj.center.coords.usrCoords[2] + Math.sin(i * rad) * r\r\n                        ],\r\n                        board\r\n                    ),\r\n                    i\r\n                );\r\n            }\r\n        } else if (Type.isArray(obj)) {\r\n            len = obj.length;\r\n            for (i = 0; i < len; i++) {\r\n                if (Type.exists(obj[i].coords)) {\r\n                    // Point type\r\n                    this._addToList(S, obj[i].coords, i);\r\n                } else if (Type.isArray(obj[i])) {\r\n                    // Coordinate pair\r\n                    this._addToList(S, new Coords(Const.COORDS_BY_USER, obj[i], board), i);\r\n                } else if (Type.exists(obj[i].usrCoords)) {\r\n                    // JXG.Coordinates\r\n                    this._addToList(S, obj[i], i);\r\n                }\r\n            }\r\n        }\r\n\r\n        return S;\r\n    },\r\n\r\n    /**\r\n     * Determine the intersection, union or difference of two closed paths.\r\n     * <p>\r\n     * This is an implementation of the Greiner-Hormann algorithm, see\r\n     * Günther Greiner and Kai Hormann (1998).\r\n     * \"Efficient clipping of arbitrary polygons\". ACM Transactions on Graphics. 17 (2): 71–83.\r\n     * and\r\n     * Erich, L. Foster, and Kai Hormann, Kai, and Romeo Traaian Popa (2019),\r\n     * \"Clipping simple polygons with degenerate intersections\", Computers & Graphics:X, 2.\r\n     * <p>\r\n     * It is assumed that the pathes are closed, whereby it does not matter if the last point indeed\r\n     * equals the first point. In contrast to the original Greiner-Hormann algorithm,\r\n     * this algorithm can cope with many degenerate cases. A degenerate case is a vertext of one path\r\n     * which is contained in the other path.\r\n     * <p>\r\n     *\r\n     * <p>Problematic are:\r\n     * <ul>\r\n     *   <li>degenerate cases where one path additionally has self-intersections\r\n     *   <li>differences with one path having self-intersections.\r\n     * </ul>\r\n     *\r\n     * @param  {JXG.Circle|JXG.Curve|JXG.Polygon} subject   First closed path, usually called 'subject'.\r\n     * Maybe curve, arc, sector, circle, polygon, array of points, array of JXG.Coords,\r\n     * array of coordinate pairs.\r\n     * @param  {JXG.Circle|JXG.Curve|JXG.Polygon} clip      Second closed path, usually called 'clip'.\r\n     * Maybe curve, arc, sector, circle, polygon, array of points, array of JXG.Coords,\r\n     * array of coordinate pairs.\r\n     * @param  {String} clip_type Determines the type of boolean operation on the two paths.\r\n     *  Possible values are 'intersection', 'union', or 'difference'.\r\n     * @param  {JXG.Board} board   JSXGraph board object. It is needed to convert between\r\n     * user coordinates and screen coordinates.\r\n     * @return {Array}          Array consisting of two arrays containing the x-coordinates and the y-coordinates of\r\n     *      the resulting path.\r\n     *\r\n     * @see JXG.Math.Clip.intersection\r\n     * @see JXG.Math.Clip.union\r\n     * @see JXG.Math.Clip.difference\r\n     *\r\n     * @example\r\n     *     var curve1 = board.create('curve', [\r\n     *             [-3, 3, 0, -3],\r\n     *             [3, 3, 0, 3]\r\n     *         ],\r\n     *         {strokeColor: 'black'});\r\n     *\r\n     *     var curve2 = board.create('curve', [\r\n     *             [-4, 4, 0, -4],\r\n     *             [2, 2, 4, 2]\r\n     *         ],\r\n     *         {strokeColor: 'blue'});\r\n     *\r\n     *     var clip_path = board.create('curve', [[], []], {strokeWidth: 3, fillColor: 'yellow', fillOpacity: 0.6});\r\n     *     clip_path.updateDataArray = function() {\r\n     *         var a = JXG.Math.Clip.greinerHormann(curve2, curve1, 'intersection', this.board);\r\n     *\r\n     *         this.dataX = a[0];\r\n     *         this.dataY = a[1];\r\n     *     };\r\n     *\r\n     *     board.update();\r\n     *\r\n     * </pre><div id=\"JXG9d2a6acf-a43b-4035-8f8a-9b1bee580210\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXG9d2a6acf-a43b-4035-8f8a-9b1bee580210',\r\n     *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n     *\r\n     *         var curve1 = board.create('curve', [\r\n     *                 [-3, 3, 0, -3],\r\n     *                 [3, 3, 0, 3]\r\n     *             ],\r\n     *             {strokeColor: 'black'});\r\n     *\r\n     *         var curve2 = board.create('curve', [\r\n     *                 [-4, 4, 0, -4],\r\n     *                 [2, 2, 4, 2]\r\n     *             ],\r\n     *             {strokeColor: 'blue'});\r\n     *\r\n     *         var clip_path = board.create('curve', [[], []], {strokeWidth: 3, fillColor: 'yellow', fillOpacity: 0.6});\r\n     *         clip_path.updateDataArray = function() {\r\n     *             var a = JXG.Math.Clip.greinerHormann(curve2, curve1, 'intersection', this.board);\r\n     *\r\n     *             this.dataX = a[0];\r\n     *             this.dataY = a[1];\r\n     *         };\r\n     *\r\n     *         board.update();\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     * @example\r\n     *     var curve1 = board.create('curve', [\r\n     *             [-3, 3, 0, -3],\r\n     *             [3, 3, 0, 3]\r\n     *         ],\r\n     *         {strokeColor: 'black', fillColor: 'none', fillOpacity: 0.8});\r\n     *\r\n     *     var curve2 = board.create('polygon', [[3, 4], [-4, 0], [-4, 4]],\r\n     *             {strokeColor: 'blue', fillColor: 'none'});\r\n     *\r\n     *     var clip_path = board.create('curve', [[], []], {strokeWidth: 3, fillColor: 'yellow', fillOpacity: 0.6});\r\n     *     clip_path.updateDataArray = function() {\r\n     *         var a = JXG.Math.Clip.greinerHormann(curve1, curve2, 'union', this.board);\r\n     *         this.dataX = a[0];\r\n     *         this.dataY = a[1];\r\n     *     };\r\n     *\r\n     *     board.update();\r\n     *\r\n     * </pre><div id=\"JXG6075c918-4d57-4b72-b600-6597a6a4f44e\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXG6075c918-4d57-4b72-b600-6597a6a4f44e',\r\n     *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n     *         var curve1 = board.create('curve', [\r\n     *                 [-3, 3, 0, -3],\r\n     *                 [3, 3, 0, 3]\r\n     *             ],\r\n     *             {strokeColor: 'black', fillColor: 'none', fillOpacity: 0.8});\r\n     *\r\n     *         var curve2 = board.create('polygon', [[3, 4], [-4, 0], [-4, 4]],\r\n     *                 {strokeColor: 'blue', fillColor: 'none'});\r\n     *\r\n     *\r\n     *         var clip_path = board.create('curve', [[], []], {strokeWidth: 3, fillColor: 'yellow', fillOpacity: 0.6});\r\n     *         clip_path.updateDataArray = function() {\r\n     *             var a = JXG.Math.Clip.greinerHormann(curve1, curve2, 'union', this.board);\r\n     *             this.dataX = a[0];\r\n     *             this.dataY = a[1];\r\n     *         };\r\n     *\r\n     *         board.update();\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     * @example\r\n     *     var curve1 = board.create('curve', [\r\n     *             [-4, 4, 0, -4],\r\n     *             [4, 4, -2, 4]\r\n     *         ],\r\n     *         {strokeColor: 'black', fillColor: 'none', fillOpacity: 0.8});\r\n     *\r\n     *     var curve2 = board.create('circle', [[0, 0], [0, -2]],\r\n     *             {strokeColor: 'blue', strokeWidth: 1, fillColor: 'red', fixed: true, fillOpacity: 0.3,\r\n     *             center: {visible: true, size: 5}, point2: {size: 5}});\r\n     *\r\n     *     var clip_path = board.create('curve', [[], []], {strokeWidth: 3, fillColor: 'yellow', fillOpacity: 0.6});\r\n     *     clip_path.updateDataArray = function() {\r\n     *         var a = JXG.Math.Clip.greinerHormann(curve1, curve2, 'difference', this.board);\r\n     *\r\n     *         this.dataX = a[0];\r\n     *         this.dataY = a[1];\r\n     *     };\r\n     *\r\n     *     board.update();\r\n     *\r\n     * </pre><div id=\"JXG46b3316b-5ab9-4928-9473-ccb476ca4185\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXG46b3316b-5ab9-4928-9473-ccb476ca4185',\r\n     *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n     *         var curve1 = board.create('curve', [\r\n     *                 [-4, 4, 0, -4],\r\n     *                 [4, 4, -2, 4]\r\n     *             ],\r\n     *             {strokeColor: 'black', fillColor: 'none', fillOpacity: 0.8});\r\n     *\r\n     *         var curve2 = board.create('circle', [[0, 0], [0, -2]],\r\n     *                 {strokeColor: 'blue', strokeWidth: 1, fillColor: 'red', fixed: true, fillOpacity: 0.3,\r\n     *                 center: {visible: true, size: 5}, point2: {size: 5}});\r\n     *\r\n     *\r\n     *         var clip_path = board.create('curve', [[], []], {strokeWidth: 3, fillColor: 'yellow', fillOpacity: 0.6});\r\n     *         clip_path.updateDataArray = function() {\r\n     *             var a = JXG.Math.Clip.greinerHormann(curve1, curve2, 'difference', this.board);\r\n     *\r\n     *             this.dataX = a[0];\r\n     *             this.dataY = a[1];\r\n     *         };\r\n     *\r\n     *         board.update();\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     * @example\r\n     * var clip_path = board.create('curve', [[], []], {strokeWidth: 1, fillColor: 'yellow', fillOpacity: 0.6});\r\n     * clip_path.updateDataArray = function() {\r\n     *     var bbox = this.board.getBoundingBox(),\r\n     *         canvas, triangle;\r\n     *\r\n     *     canvas = [[bbox[0], bbox[1]], // ul\r\n     *          [bbox[0], bbox[3]], // ll\r\n     *          [bbox[2], bbox[3]], // lr\r\n     *          [bbox[2], bbox[1]], // ur\r\n     *          [bbox[0], bbox[1]]] // ul\r\n     *     triangle = [[-1,1], [1,1], [0,-1], [-1,1]];\r\n     *\r\n     *     var a = JXG.Math.Clip.greinerHormann(canvas, triangle, 'difference', this.board);\r\n     *     this.dataX = a[0];\r\n     *     this.dataY = a[1];\r\n     * };\r\n     *\r\n     * </pre><div id=\"JXGe94da07a-2a01-4498-ad62-f71a327f8e25\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXGe94da07a-2a01-4498-ad62-f71a327f8e25',\r\n     *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n     *     var clip_path = board.create('curve', [[], []], {strokeWidth: 1, fillColor: 'yellow', fillOpacity: 0.6});\r\n     *     clip_path.updateDataArray = function() {\r\n     *         var bbox = this.board.getBoundingBox(),\r\n     *             canvas, triangle;\r\n     *\r\n     *         canvas = [[bbox[0], bbox[1]], // ul\r\n     *              [bbox[0], bbox[3]], // ll\r\n     *              [bbox[2], bbox[3]], // lr\r\n     *              [bbox[2], bbox[1]], // ur\r\n     *              [bbox[0], bbox[1]]] // ul\r\n     *         triangle = [[-1,1], [1,1], [0,-1], [-1,1]];\r\n     *\r\n     *         var a = JXG.Math.Clip.greinerHormann(canvas, triangle, 'difference', this.board);\r\n     *         this.dataX = a[0];\r\n     *         this.dataY = a[1];\r\n     *     };\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     */\r\n    greinerHormann: function (subject, clip, clip_type, board) {\r\n        //},\r\n        // subject_first_point_type, clip_first_point_type) {\r\n\r\n        var len,\r\n            S = [],\r\n            C = [],\r\n            S_intersect = [],\r\n            // C_intersect = [],\r\n            S_starters,\r\n            C_starters,\r\n            res = [],\r\n            DEBUG = false;\r\n\r\n        if (DEBUG) {\r\n            console.log(\"\\n------------ GREINER-HORMANN --------------\");\r\n        }\r\n        // Collect all subject points into subject array S\r\n        S = this._getPath(subject, board);\r\n        len = S.length;\r\n        if (\r\n            len > 0 &&\r\n            Geometry.distance(S[0].coords.usrCoords, S[len - 1].coords.usrCoords, 3) < Mat.eps\r\n        ) {\r\n            S.pop();\r\n        }\r\n\r\n        // Collect all points into clip array C\r\n        C = this._getPath(clip, board);\r\n        len = C.length;\r\n        if (\r\n            len > 0 &&\r\n            Geometry.distance(C[0].coords.usrCoords, C[len - 1].coords.usrCoords, 3) <\r\n                Mat.eps * Mat.eps\r\n        ) {\r\n            C.pop();\r\n        }\r\n\r\n        // Handle cases where at least one of the paths is empty\r\n        if (this.isEmptyCase(S, C, clip_type)) {\r\n            return [[], []];\r\n        }\r\n\r\n        // Add pointers for doubly linked lists\r\n        S_starters = this.makeDoublyLinkedList(S);\r\n        C_starters = this.makeDoublyLinkedList(C);\r\n\r\n        if (DEBUG) {\r\n            this._print_array(S);\r\n            console.log(\"Components:\", S_starters);\r\n            this._print_array(C);\r\n            console.log(\"Components:\", C_starters);\r\n        }\r\n\r\n        res = this.findIntersections(S, C, board);\r\n        S_intersect = res[0];\r\n\r\n        this._handleFullyDegenerateCase(S, C, board);\r\n\r\n        // Phase 2: mark intersection points as entry or exit points\r\n        this.markEntryExit(S, C, S_starters);\r\n\r\n        // if (S[0].coords.distance(Const.COORDS_BY_USER, C[0].coords) === 0) {\r\n        //     // Randomly disturb the first point of the second path\r\n        //     // if both paths start at the same point.\r\n        //     C[0].usrCoords[1] *= 1 + Math.random() * 0.0001 - 0.00005;\r\n        //     C[0].usrCoords[2] *= 1 + Math.random() * 0.0001 - 0.00005;\r\n        // }\r\n        this.markEntryExit(C, S, C_starters);\r\n\r\n        // Handle cases without intersections\r\n        if (this._countCrossingIntersections(S_intersect) === 0) {\r\n            return this.handleEmptyIntersection(S, C, clip_type);\r\n        }\r\n\r\n        // Phase 3: tracing\r\n        return this.tracing(S, S_intersect, clip_type);\r\n    },\r\n\r\n    /**\r\n     * Union of two closed paths. The paths could be JSXGraph elements circle, curve, or polygon.\r\n     * Computed by the Greiner-Hormann algorithm.\r\n     *\r\n     * @param  {JXG.Circle|JXG.Curve|JXG.Polygon} subject   First closed path.\r\n     * @param  {JXG.Circle|JXG.Curve|JXG.Polygon} clip      Second closed path.\r\n     * @param  {JXG.Board} board   JSXGraph board object. It is needed to convert between\r\n     * user coordinates and screen coordinates.\r\n     * @return {Array}          Array consisting of two arrays containing the x-coordinates and the y-coordinates of\r\n     *      the resulting path.\r\n     *\r\n     * @see JXG.Math.Clip.greinerHormann\r\n     * @see JXG.Math.Clip.intersection\r\n     * @see JXG.Math.Clip.difference\r\n     *\r\n     * @example\r\n     *     var curve1 = board.create('curve', [\r\n     *             [-3, 3, 0, -3],\r\n     *             [3, 3, 0, 3]\r\n     *         ],\r\n     *         {strokeColor: 'black'});\r\n     *\r\n     *     var curve2 = board.create('polygon', [[3, 4], [-4, 0], [-4, 4]],\r\n     *             {strokeColor: 'blue', fillColor: 'none'});\r\n     *\r\n     *     var clip_path = board.create('curve', [[], []], {strokeWidth: 3, fillColor: 'yellow', fillOpacity: 0.3});\r\n     *     clip_path.updateDataArray = function() {\r\n     *         var a = JXG.Math.Clip.union(curve1, curve2, this.board);\r\n     *         this.dataX = a[0];\r\n     *         this.dataY = a[1];\r\n     *     };\r\n     *\r\n     *     board.update();\r\n     *\r\n     * </pre><div id=\"JXG7c5204aa-3824-4464-819c-80df7bf1d917\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXG7c5204aa-3824-4464-819c-80df7bf1d917',\r\n     *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n     *         var curve1 = board.create('curve', [\r\n     *                 [-3, 3, 0, -3],\r\n     *                 [3, 3, 0, 3]\r\n     *             ],\r\n     *             {strokeColor: 'black'});\r\n     *\r\n     *         var curve2 = board.create('polygon', [[3, 4], [-4, 0], [-4, 4]],\r\n     *                 {strokeColor: 'blue', fillColor: 'none'});\r\n     *\r\n     *\r\n     *         var clip_path = board.create('curve', [[], []], {strokeWidth: 3, fillColor: 'yellow', fillOpacity: 0.3});\r\n     *         clip_path.updateDataArray = function() {\r\n     *             var a = JXG.Math.Clip.union(curve1, curve2, this.board);\r\n     *             this.dataX = a[0];\r\n     *             this.dataY = a[1];\r\n     *         };\r\n     *\r\n     *         board.update();\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     */\r\n    union: function (path1, path2, board) {\r\n        return this.greinerHormann(path1, path2, \"union\", board);\r\n    },\r\n\r\n    /**\r\n     * Intersection of two closed paths. The paths could be JSXGraph elements circle, curve, or polygon.\r\n     * Computed by the Greiner-Hormann algorithm.\r\n     *\r\n     * @param  {JXG.Circle|JXG.Curve|JXG.Polygon} subject   First closed path.\r\n     * @param  {JXG.Circle|JXG.Curve|JXG.Polygon} clip      Second closed path.\r\n     * @param  {JXG.Board} board   JSXGraph board object. It is needed to convert between\r\n     * user coordinates and screen coordinates.\r\n     * @return {Array}          Array consisting of two arrays containing the x-coordinates and the y-coordinates of\r\n     *      the resulting path.\r\n     *\r\n     * @see JXG.Math.Clip.greinerHormann\r\n     * @see JXG.Math.Clip.union\r\n     * @see JXG.Math.Clip.difference\r\n     *\r\n     * @example\r\n     * var p = [];\r\n     * p.push(board.create('point', [0, -5]));\r\n     * p.push(board.create('point', [-5, 0]));\r\n     * p.push(board.create('point', [-3, 3]));\r\n     *\r\n     * var curve1 = board.create('ellipse', p,\r\n     *                 {strokeColor: 'black'});\r\n     *\r\n     * var curve2 = board.create('curve', [function(phi){return 4 * Math.cos(2*phi); },\r\n     *                                     [0, 0],\r\n     *                                     0, 2 * Math.PI],\r\n     *                       {curveType:'polar', strokeColor: 'blue', strokewidth:1});\r\n     *\r\n     * var clip_path = board.create('curve', [[], []], {strokeWidth: 3, fillColor: 'yellow', fillOpacity: 0.3});\r\n     * clip_path.updateDataArray = function() {\r\n     *     var a = JXG.Math.Clip.intersection(curve2, curve1, this.board);\r\n     *\r\n     *     this.dataX = a[0];\r\n     *     this.dataY = a[1];\r\n     * };\r\n     *\r\n     * board.update();\r\n     *\r\n     * </pre><div id=\"JXG7ad547eb-7b6c-4a1a-a4d4-4ed298fc7998\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXG7ad547eb-7b6c-4a1a-a4d4-4ed298fc7998',\r\n     *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n     *     var p = [];\r\n     *     p.push(board.create('point', [0, -5]));\r\n     *     p.push(board.create('point', [-5, 0]));\r\n     *     p.push(board.create('point', [-3, 3]));\r\n     *\r\n     *     var curve1 = board.create('ellipse', p,\r\n     *                     {strokeColor: 'black'});\r\n     *\r\n     *     var curve2 = board.create('curve', [function(phi){return 4 * Math.cos(2*phi); },\r\n     *                                         [0, 0],\r\n     *                                         0, 2 * Math.PI],\r\n     *                           {curveType:'polar', strokeColor: 'blue', strokewidth:1});\r\n     *\r\n     *\r\n     *     var clip_path = board.create('curve', [[], []], {strokeWidth: 3, fillColor: 'yellow', fillOpacity: 0.3});\r\n     *     clip_path.updateDataArray = function() {\r\n     *         var a = JXG.Math.Clip.intersection(curve2, curve1, this.board);\r\n     *\r\n     *         this.dataX = a[0];\r\n     *         this.dataY = a[1];\r\n     *     };\r\n     *\r\n     *     board.update();\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     *\r\n     */\r\n    intersection: function (path1, path2, board) {\r\n        return this.greinerHormann(path1, path2, \"intersection\", board);\r\n    },\r\n\r\n    /**\r\n     * Difference of two closed paths, i.e. path1 minus path2.\r\n     * The paths could be JSXGraph elements circle, curve, or polygon.\r\n     * Computed by the Greiner-Hormann algorithm.\r\n     *\r\n     * @param  {JXG.Circle|JXG.Curve|JXG.Polygon} subject   First closed path.\r\n     * @param  {JXG.Circle|JXG.Curve|JXG.Polygon} clip      Second closed path.\r\n     * @param  {JXG.Board} board   JSXGraph board object. It is needed to convert between\r\n     * user coordinates and screen coordinates.\r\n     * @return {Array}          Array consisting of two arrays containing the x-coordinates and the y-coordinates of\r\n     *      the resulting path.\r\n     *\r\n     * @see JXG.Math.Clip.greinerHormann\r\n     * @see JXG.Math.Clip.intersection\r\n     * @see JXG.Math.Clip.union\r\n     *\r\n     * @example\r\n     *     var curve1 = board.create('polygon', [[-4, 4], [4, 4], [0, -1]],\r\n     *             {strokeColor: 'blue', fillColor: 'none'});\r\n     *\r\n     *     var curve2 = board.create('curve', [\r\n     *             [-1, 1, 0, -1],\r\n     *             [1, 1, 3, 1]\r\n     *         ],\r\n     *         {strokeColor: 'black', fillColor: 'none', fillOpacity: 0.8});\r\n     *\r\n     *     var clip_path = board.create('curve', [[], []], {strokeWidth: 3, fillColor: 'yellow', fillOpacity: 0.3});\r\n     *     clip_path.updateDataArray = function() {\r\n     *         var a = JXG.Math.Clip.difference(curve1, curve2, this.board);\r\n     *         this.dataX = a[0];\r\n     *         this.dataY = a[1];\r\n     *     };\r\n     *\r\n     *     board.update();\r\n     *\r\n     * </pre><div id=\"JXGc5ce6bb3-146c-457f-a48b-6b9081fb68a3\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXGc5ce6bb3-146c-457f-a48b-6b9081fb68a3',\r\n     *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n     *         var curve1 = board.create('polygon', [[-4, 4], [4, 4], [0, -1]],\r\n     *                 {strokeColor: 'blue', fillColor: 'none'});\r\n     *\r\n     *         var curve2 = board.create('curve', [\r\n     *                 [-1, 1, 0, -1],\r\n     *                 [1, 1, 3, 1]\r\n     *             ],\r\n     *             {strokeColor: 'black', fillColor: 'none', fillOpacity: 0.8});\r\n     *\r\n     *\r\n     *         var clip_path = board.create('curve', [[], []], {strokeWidth: 3, fillColor: 'yellow', fillOpacity: 0.3});\r\n     *         clip_path.updateDataArray = function() {\r\n     *             var a = JXG.Math.Clip.difference(curve1, curve2, this.board);\r\n     *             this.dataX = a[0];\r\n     *             this.dataY = a[1];\r\n     *         };\r\n     *\r\n     *         board.update();\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     */\r\n    difference: function (path1, path2, board) {\r\n        return this.greinerHormann(path1, path2, \"difference\", board);\r\n    }\r\n};\r\n\r\n// JXG.extend(Mat.Clip, /** @lends JXG.Math.Clip */ {});\r\n\r\nexport default Mat.Clip;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview In this file the namespace Math.Poly is defined, which holds algorithms to create and\r\n * manipulate polynomials.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Mat from \"./math.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * The JXG.Math.Poly namespace holds algorithms to create and manipulate polynomials.\r\n * @name JXG.Math.Poly\r\n * @exports Mat.Poly as JXG.Math.Poly\r\n * @namespace\r\n */\r\nMat.Poly = {};\r\n\r\n/**\r\n * Define a polynomial ring over R.\r\n * @class\r\n * @name JXG.Math.Poly.Ring\r\n * @param {Array} variables List of indeterminates.\r\n */\r\nMat.Poly.Ring = function (variables) {\r\n    /**\r\n     * A list of variables in this polynomial ring.\r\n     * @type Array\r\n     */\r\n    this.vars = variables;\r\n};\r\n\r\nJXG.extend(\r\n    Mat.Poly.Ring.prototype,\r\n    /** @lends JXG.Math.Poly.Ring.prototype */ {\r\n        // nothing yet.\r\n    }\r\n);\r\n\r\n/**\r\n * Define a monomial over the polynomial ring <tt>ring</tt>.\r\n * @class\r\n * @name JXG.Math.Poly.Monomial\r\n * @param {JXG.Math.Poly.Ring} ring\r\n * @param {Number} coefficient\r\n * @param {Array} exponents An array of exponents, corresponding to ring\r\n */\r\nMat.Poly.Monomial = function (ring, coefficient, exponents) {\r\n    var i;\r\n\r\n    if (!Type.exists(ring)) {\r\n        throw new Error(\"JSXGraph error: In JXG.Math.Poly.monomial missing parameter 'ring'.\");\r\n    }\r\n\r\n    if (!Type.isArray(exponents)) {\r\n        exponents = [];\r\n    }\r\n\r\n    exponents = exponents.slice(0, ring.vars.length);\r\n\r\n    for (i = exponents.length; i < ring.vars.length; i++) {\r\n        exponents.push(0);\r\n    }\r\n\r\n    /**\r\n     * A polynomial ring.\r\n     * @type JXG.Math.Poly.Ring\r\n     */\r\n    this.ring = ring;\r\n\r\n    /**\r\n     * The monomial's coefficient\r\n     * @type Number\r\n     */\r\n    this.coefficient = coefficient || 0;\r\n\r\n    /**\r\n     * Exponent vector, the order depends on the order of the variables\r\n     * in the ring definition.\r\n     * @type Array\r\n     */\r\n    this.exponents = Type.deepCopy(exponents);\r\n};\r\n\r\nJXG.extend(\r\n    Mat.Poly.Monomial.prototype,\r\n    /** @lends JXG.Math.Poly.Monomial.prototype */ {\r\n        /**\r\n         * Creates a deep copy of the monomial.\r\n         *\r\n         * @returns {JXG.Math.Poly.Monomial}\r\n         *\r\n         * @memberof JXG.Math.Poly.Monomial\r\n         */\r\n        copy: function () {\r\n            return new Mat.Poly.Monomial(this.ring, this.coefficient, this.exponents);\r\n        },\r\n\r\n        /**\r\n         * Print the monomial.\r\n         * @returns {String} String representation of the monomial\r\n\r\n         * @memberof JXG.Math.Poly.Monomial\r\n         */\r\n        print: function () {\r\n            var s = [],\r\n                i;\r\n\r\n            for (i = 0; i < this.ring.vars.length; i++) {\r\n                s.push(this.ring.vars[i] + \"^\" + this.exponents[i]);\r\n            }\r\n\r\n            return this.coefficient + \"*\" + s.join(\"*\");\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * A polynomial is a sum of monomials.\r\n * @class\r\n * @name JXG.Math.Poly.Polynomial\r\n * @param {JXG.Math.Poly.Ring} ring A polynomial ring.\r\n * @param {String} str TODO String representation of the polynomial, will be parsed.\r\n */\r\nMat.Poly.Polynomial = function (ring, str) {\r\n    var parse = function () {},\r\n        mons;\r\n\r\n    if (!Type.exists(ring)) {\r\n        throw new Error(\r\n            \"JSXGraph error: In JXG.Math.Poly.polynomial missing parameter 'ring'.\"\r\n        );\r\n    }\r\n\r\n    if (Type.exists(str) && Type.isString(str)) {\r\n        mons = parse(str);\r\n    } else {\r\n        mons = [];\r\n    }\r\n\r\n    /**\r\n     * A polynomial ring.\r\n     * @type JXG.Math.Poly.Ring\r\n     */\r\n    this.ring = ring;\r\n\r\n    /**\r\n     * List of monomials.\r\n     * @type Array\r\n     */\r\n    this.monomials = mons;\r\n};\r\n\r\nJXG.extend(\r\n    Mat.Poly.Polynomial.prototype,\r\n    /** @lends JXG.Math.Poly.Polynomial.prototype */ {\r\n        /**\r\n         * Find a monomial with the given signature, i.e. exponent vector.\r\n         * @param {Array} sig An array of numbers\r\n         * @returns {Number} The index of the first monomial with the given signature, or -1\r\n         * if no monomial could be found.\r\n         * @memberof JXG.Math.Poly.Polynomial\r\n         */\r\n        findSignature: function (sig) {\r\n            var i;\r\n\r\n            for (i = 0; i < this.monomials.length; i++) {\r\n                if (Type.cmpArrays(this.monomials[i].exponents, sig)) {\r\n                    return i;\r\n                }\r\n            }\r\n\r\n            return -1;\r\n        },\r\n\r\n        /**\r\n         * Adds a monomial to the polynomial. Checks the existing monomials for the added\r\n         * monomial's signature and just adds the coefficient if one is found.\r\n         * @param {JXG.Math.Poly.Monomial} m\r\n         * @param {Number} factor Either <tt>1</tt> or <tt>-1</tt>.\r\n         * @memberof JXG.Math.Poly.Polynomial\r\n         */\r\n        addSubMonomial: function (m, factor) {\r\n            var i;\r\n\r\n            i = this.findSignature(m.exponents);\r\n            if (i > -1) {\r\n                this.monomials[i].coefficient += factor * m.coefficient;\r\n            } else {\r\n                m.coefficient *= factor;\r\n                this.monomials.push(m);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Adds another polynomial or monomial to this one and merges them by checking for the\r\n         * signature of each new monomial in the existing monomials.\r\n         * @param {JXG.Math.Poly.Polynomial|JXG.Math.Poly.Monomial} mp\r\n         * @memberof JXG.Math.Poly.Polynomial\r\n         */\r\n        add: function (mp) {\r\n            var i;\r\n\r\n            if (Type.exists(mp) && mp.ring === this.ring) {\r\n                if (Type.isArray(mp.exponents)) {\r\n                    // mp is a monomial\r\n                    this.addSubMonomial(mp, 1);\r\n                } else {\r\n                    // mp is a polynomial\r\n                    for (i = 0; i < mp.monomials.length; i++) {\r\n                        this.addSubMonomial(mp.monomials[i], 1);\r\n                    }\r\n                }\r\n            } else {\r\n                throw new Error(\r\n                    \"JSXGraph error: In JXG.Math.Poly.polynomial.add either summand is undefined or rings don't match.\"\r\n                );\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Subtracts another polynomial or monomial from this one and merges them by checking for the\r\n         * signature of each new monomial in the existing monomials.\r\n         * @param {JXG.Math.Poly.Polynomial|JXG.Math.Poly.Monomial} mp\r\n         * @memberof JXG.Math.Poly.Polynomial\r\n         */\r\n        sub: function (mp) {\r\n            var i;\r\n\r\n            if (Type.exists(mp) && mp.ring === this.ring) {\r\n                if (Type.isArray(mp.exponents)) {\r\n                    // mp is a monomial\r\n                    this.addSubMonomial(mp, -1);\r\n                } else {\r\n                    // mp is a polynomial\r\n                    for (i = 0; i < mp.monomials.length; i++) {\r\n                        this.addSubMonomial(mp.monomials[i], -1);\r\n                    }\r\n                }\r\n            } else {\r\n                throw new Error(\r\n                    \"JSXGraph error: In JXG.Math.Poly.polynomial.sub either summand is undefined or rings don't match.\"\r\n                );\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Creates a deep copy of the polynomial.\r\n         * @returns {JXG.Math.Poly.Polynomial}\r\n         * @memberof JXG.Math.Poly.Polynomial\r\n         */\r\n        copy: function () {\r\n            var i, p;\r\n\r\n            p = new Mat.Poly.Polynomial(this.ring);\r\n\r\n            for (i = 0; i < this.monomials.length; i++) {\r\n                p.monomials.push(this.monomials[i].copy());\r\n            }\r\n            return p;\r\n        },\r\n\r\n        /**\r\n         * Prints the polynomial.\r\n         * @returns {String} A string representation of the polynomial.\r\n         * @memberof JXG.Math.Poly.Polynomial\r\n         */\r\n        print: function () {\r\n            var s = [],\r\n                i;\r\n\r\n            for (i = 0; i < this.monomials.length; i++) {\r\n                s.push(\"(\" + this.monomials[i].print() + \")\");\r\n            }\r\n\r\n            return s.join(\"+\");\r\n        }\r\n    }\r\n);\r\n\r\nexport default Mat.Poly;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview A class for complex arithmetics JXG.Complex is defined in this\r\n * file. Also a namespace JXG.C is included to provide instance-independent\r\n * arithmetic functions.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Creates a new complex number. See also {@link JXG.C}.\r\n * @class This class is for calculating with complex numbers, see also {@link JXG.C} for more methods.\r\n * @constructor\r\n * @param {Number} [x=0] Real part.\r\n * @param {Number} [y=0] Imaginary part.\r\n * @see JXG.C\r\n */\r\nJXG.Complex = function (x, y) {\r\n    /**\r\n     * This property is only to signalize that this object is of type JXG.Complex. Only\r\n     * used internally to distinguish between normal JavaScript numbers and JXG.Complex numbers.\r\n     * @type Boolean\r\n     * @default true\r\n     * @private\r\n     */\r\n    this.isComplex = true;\r\n\r\n    /* is the first argument a complex number? if it is,\r\n     * extract real and imaginary part. */\r\n    if (x && x.isComplex) {\r\n        y = x.imaginary;\r\n        x = x.real;\r\n    }\r\n\r\n    /**\r\n     * Real part of the complex number.\r\n     * @type Number\r\n     * @default 0\r\n     */\r\n    this.real = x || 0;\r\n\r\n    /**\r\n     * Imaginary part of the complex number.\r\n     * @type Number\r\n     * @default 0\r\n     */\r\n    this.imaginary = y || 0;\r\n\r\n    // /**\r\n    //  * Absolute value in the polar form of the complex number. Currently unused.\r\n    //  * @type Number\r\n    //  */\r\n    // this.absval = 0;\r\n\r\n    // /**\r\n    //  * Angle value in the polar form of the complex number. Currently unused.\r\n    //  * @type Number\r\n    //  */\r\n    // this.angle = 0;\r\n};\r\n\r\nJXG.extend(\r\n    JXG.Complex.prototype,\r\n    /** @lends JXG.Complex.prototype */ {\r\n        /**\r\n         * Converts a complex number into a string.\r\n         * @returns {String} Formatted string containing the complex number in human readable form (algebraic form).\r\n         */\r\n        toString: function () {\r\n            return this.real + \" + \" + this.imaginary + 'i';\r\n        },\r\n\r\n        /**\r\n         * Add another complex number to this complex number.\r\n         * @param {JXG.Complex|Number} c A JavaScript number or a JXG.Complex object to be added to the current object.\r\n         * @returns {JXG.Complex} Reference to this complex number\r\n         */\r\n        add: function (c) {\r\n            if (Type.isNumber(c)) {\r\n                this.real += c;\r\n            } else {\r\n                this.real += c.real;\r\n                this.imaginary += c.imaginary;\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Subtract another complex number from this complex number.\r\n         * @param {JXG.Complex|Number} c A JavaScript number or a JXG.Complex object to subtract from the current object.\r\n         * @returns {JXG.Complex} Reference to this complex number\r\n         */\r\n        sub: function (c) {\r\n            if (Type.isNumber(c)) {\r\n                this.real -= c;\r\n            } else {\r\n                this.real -= c.real;\r\n                this.imaginary -= c.imaginary;\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Multiply another complex number to this complex number.\r\n         * @param {JXG.Complex|Number} c A JavaScript number or a JXG.Complex object to\r\n         * multiply with the current object.\r\n         * @returns {JXG.Complex} Reference to this complex number\r\n         */\r\n        mult: function (c) {\r\n            var re, im;\r\n\r\n            if (Type.isNumber(c)) {\r\n                this.real *= c;\r\n                this.imaginary *= c;\r\n            } else {\r\n                re = this.real;\r\n                im = this.imaginary;\r\n\r\n                //  (a+ib)(x+iy) = ax-by + i(xb+ay)\r\n                this.real = re * c.real - im * c.imaginary;\r\n                this.imaginary = re * c.imaginary + im * c.real;\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Divide this complex number by the given complex number.\r\n         * @param {JXG.Complex|Number} c A JavaScript number or a JXG.Complex object to\r\n         * divide the current object by.\r\n         * @returns {JXG.Complex} Reference to this complex number\r\n         */\r\n        div: function (c) {\r\n            var denom, im, re;\r\n\r\n            if (Type.isNumber(c)) {\r\n                if (Math.abs(c) < Math.eps) {\r\n                    this.real = Infinity;\r\n                    this.imaginary = Infinity;\r\n\r\n                    return this;\r\n                }\r\n\r\n                this.real /= c;\r\n                this.imaginary /= c;\r\n            } else {\r\n                //  (a+ib)(x+iy) = ax-by + i(xb+ay)\r\n                if (Math.abs(c.real) < Math.eps && Math.abs(c.imaginary) < Math.eps) {\r\n                    this.real = Infinity;\r\n                    this.imaginary = Infinity;\r\n\r\n                    return this;\r\n                }\r\n\r\n                denom = c.real * c.real + c.imaginary * c.imaginary;\r\n\r\n                re = this.real;\r\n                im = this.imaginary;\r\n                this.real = (re * c.real + im * c.imaginary) / denom;\r\n                this.imaginary = (im * c.real - re * c.imaginary) / denom;\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Conjugate a complex number in place.\r\n         * @returns {JXG.Complex} Reference to this complex number\r\n         */\r\n        conj: function () {\r\n            this.imaginary *= -1;\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Absolute value in the polar form, i.e. |z| of the complex number z.\r\n         * @returns Number\r\n         */\r\n        abs: function() {\r\n            var x = this.real,\r\n                y = this.imaginary;\r\n            return Math.sqrt(x * x + y * y);\r\n        },\r\n\r\n        /**\r\n         * Angle value in the polar form of the complex number (in radians).\r\n         * @returns Number\r\n         */\r\n        angle: function() {\r\n            return Math.atan2(this.imaginary, this.real);\r\n        }\r\n\r\n    }\r\n);\r\n\r\n/**\r\n * @namespace Namespace for the complex number arithmetic functions, see also {@link JXG.Complex}.\r\n * @description\r\n * JXG.C is the complex number (name)space. It provides functions to calculate with\r\n * complex numbers (defined in {@link JXG.Complex}). With this namespace you don't have to modify\r\n * your existing complex numbers, e.g. to add two complex numbers:\r\n * <pre class=\"code\">   var z1 = new JXG.Complex(1, 0);\r\n *    var z2 = new JXG.Complex(0, 1);\r\n *    z = JXG.C.add(z1, z1);</pre>\r\n * z1 and z2 here remain unmodified. With the object oriented approach above this\r\n * section the code would look like:\r\n * <pre class=\"code\">\r\n *    var z1 = new JXG.Complex(1, 0);\r\n *    var z2 = new JXG.Complex(0, 1);\r\n *    var z = new JXG.Complex(z1);\r\n *    z.add(z2);</pre>\r\n * @see JXG.Complex\r\n */\r\nJXG.C = {};\r\n\r\n/**\r\n * Add two (complex) numbers z1 and z2 and return the result as a (complex) number.\r\n * @param {JXG.Complex|Number} z1 Summand\r\n * @param {JXG.Complex|Number} z2 Summand\r\n * @returns {JXG.Complex} A complex number equal to the sum of the given parameters.\r\n */\r\nJXG.C.add = function (z1, z2) {\r\n    var z = new JXG.Complex(z1);\r\n    z.add(z2);\r\n    return z;\r\n};\r\n\r\n/**\r\n * Subtract two (complex) numbers z1 and z2 and return the result as a (complex) number.\r\n * @param {JXG.Complex|Number} z1 Minuend\r\n * @param {JXG.Complex|Number} z2 Subtrahend\r\n * @returns {JXG.Complex} A complex number equal to the difference of the given parameters.\r\n */\r\nJXG.C.sub = function (z1, z2) {\r\n    var z = new JXG.Complex(z1);\r\n    z.sub(z2);\r\n    return z;\r\n};\r\n\r\n/**\r\n * Multiply two (complex) numbers z1 and z2 and return the result as a (complex) number.\r\n * @param {JXG.Complex|Number} z1 Factor\r\n * @param {JXG.Complex|Number} z2 Factor\r\n * @returns {JXG.Complex} A complex number equal to the product of the given parameters.\r\n */\r\nJXG.C.mult = function (z1, z2) {\r\n    var z = new JXG.Complex(z1);\r\n    z.mult(z2);\r\n    return z;\r\n};\r\n\r\n/**\r\n * Divide two (complex) numbers z1 and z2 and return the result as a (complex) number.\r\n * @param {JXG.Complex|Number} z1 Dividend\r\n * @param {JXG.Complex|Number} z2 Divisor\r\n * @returns {JXG.Complex} A complex number equal to the quotient of the given parameters.\r\n */\r\nJXG.C.div = function (z1, z2) {\r\n    var z = new JXG.Complex(z1);\r\n    z.div(z2);\r\n    return z;\r\n};\r\n\r\n/**\r\n * Conjugate a complex number and return the result.\r\n * @param {JXG.Complex|Number} z1 Complex number\r\n * @returns {JXG.Complex} A complex number equal to the conjugate of the given parameter.\r\n */\r\nJXG.C.conj = function (z1) {\r\n    var z = new JXG.Complex(z1);\r\n    z.conj();\r\n    return z;\r\n};\r\n\r\n/**\r\n * Absolute value of a complex number.\r\n * @param {JXG.Complex|Number} z1 Complex number\r\n * @returns {Number} real number equal to the absolute value of the given parameter.\r\n */\r\nJXG.C.abs = function (z1) {\r\n    var z = new JXG.Complex(z1);\r\n    // z.conj();\r\n    // z.mult(z1);\r\n    // return Math.sqrt(z.real);\r\n    return z.abs();\r\n};\r\n\r\n/**\r\n * Angle of a complex number (in radians).\r\n * @param {JXG.Complex|Number} z1 Complex number\r\n * @returns {Number} real number equal to the angle value of the given parameter.\r\n */\r\nJXG.C.angle = function (z1) {\r\n    var z = new JXG.Complex(z1);\r\n    return z.angle();\r\n};\r\n\r\n/**\r\n * Create copy of complex number.\r\n *\r\n * @param {JXG.Complex|Number} z\r\n * @returns {JXG.Complex}\r\n */\r\nJXG.C.copy = function(z) {\r\n    return new JXG.Complex(z);\r\n};\r\n\r\nJXG.Complex.C = JXG.C;\r\n\r\nexport default JXG.Complex;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, AMprocessNode: true, MathJax: true, document: true, window: true */\r\n\r\n/*\r\n    nomen:    Allow underscores to indicate private class members. Might be replaced by local variables.\r\n    plusplus: Only allowed in for-loops\r\n    newcap:   AsciiMathMl exposes non-constructor functions beginning with upper case letters\r\n*/\r\n/*jslint nomen: true, plusplus: true, newcap: true, unparam: true*/\r\n/*eslint no-unused-vars: \"off\"*/\r\n\r\n/**\r\n * @fileoverview JSXGraph can use various technologies to render the contents of a construction, e.g.\r\n * SVG, VML, and HTML5 Canvas. To accomplish this, The rendering and the logic and control mechanisms\r\n * are completely separated from each other. Every rendering technology has it's own class, called\r\n * Renderer, e.g. SVGRenderer for SVG, the same for VML and Canvas. The common base for all available\r\n * renderers is the class AbstractRenderer defined in this file.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Options from \"../options.js\";\r\nimport Coords from \"../base/coords.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Env from \"../utils/env.js\";\r\n\r\n/**\r\n * <p>This class defines the interface to the graphics part of JSXGraph. This class is an abstract class, it\r\n * actually does not render anything. This is up to the {@link JXG.SVGRenderer}, {@link JXG.VMLRenderer},\r\n * and {@link JXG.CanvasRenderer} classes. We strongly discourage you from using the methods in these classes\r\n * directly. Only the methods which are defined in this class and are not marked as private are guaranteed\r\n * to exist in any renderer instance you can access via {@link JXG.Board#renderer}. But not all methods may\r\n * work as expected.</p>\r\n * <p>The methods of this renderer can be divided into different categories:\r\n * <dl>\r\n *     <dt>Draw basic elements</dt>\r\n *     <dd>In this category we find methods to draw basic elements like {@link JXG.Point}, {@link JXG.Line},\r\n *     and {@link JXG.Curve} as well as assisting methods tightly bound to these basic painters. You do not\r\n *     need to implement these methods in a descendant renderer but instead implement the primitive drawing\r\n *     methods described below. This approach is encouraged when you're using a XML based rendering engine\r\n *     like VML and SVG. If you want to use a bitmap based rendering technique you are supposed to override\r\n *     these methods instead of the primitive drawing methods.</dd>\r\n *     <dt>Draw primitives</dt>\r\n *     <dd>This category summarizes methods to handle primitive nodes. As creation and management of these nodes\r\n *     is different among different the rendering techniques most of these methods are purely virtual and need\r\n *     proper implementation if you choose to not overwrite the basic element drawing methods.</dd>\r\n *     <dt>Attribute manipulation</dt>\r\n *     <dd>In XML based renders you have to manipulate XML nodes and their attributes to change the graphics.\r\n *     For that purpose attribute manipulation methods are defined to set the color, opacity, and other things.\r\n *     Please note that some of these methods are required in bitmap based renderers, too, because some elements\r\n *     like {@link JXG.Text} can be HTML nodes floating over the construction.</dd>\r\n *     <dt>Renderer control</dt>\r\n *     <dd>Methods to clear the drawing board or to stop and to resume the rendering engine.</dd>\r\n * </dl></p>\r\n * @class JXG.AbstractRenderer\r\n * @constructor\r\n * @see JXG.SVGRenderer\r\n * @see JXG.VMLRenderer\r\n * @see JXG.CanvasRenderer\r\n */\r\nJXG.AbstractRenderer = function () {\r\n    // WHY THIS IS A CLASS INSTEAD OF A SINGLETON OBJECT:\r\n    //\r\n    // The renderers need to keep track of some stuff which is not always the same on different boards,\r\n    // like enhancedRendering, reference to the container object, and resolution in VML. Sure, those\r\n    // things could be stored in board. But they are rendering related and JXG.Board is already very\r\n    // very big.\r\n    //\r\n    // And we can't save the rendering related data in {SVG,VML,Canvas}Renderer and make only the\r\n    // JXG.AbstractRenderer a singleton because of that:\r\n    //\r\n    // Given an object o with property a set to true\r\n    //     var o = {a: true};\r\n    // and a class c doing nothing\r\n    //     c = function() {};\r\n    // Set c's prototype to o\r\n    //     c.prototype = o;\r\n    // and create an instance of c we get i.a to be true\r\n    //     i = new c();\r\n    //     i.a;\r\n    //     > true\r\n    // But we can overwrite this property via\r\n    //     c.prototype.a = false;\r\n    //     i.a;\r\n    //     > false\r\n\r\n    /**\r\n     * The vertical offset for {@link Text} elements. Every {@link Text} element will\r\n     * be placed this amount of pixels below the user given coordinates.\r\n     * @type Number\r\n     * @default 0\r\n     */\r\n    this.vOffsetText = 0;\r\n\r\n    /**\r\n     * If this property is set to <tt>true</tt> the visual properties of the elements are updated\r\n     * on every update. Visual properties means: All the stuff stored in the\r\n     * {@link JXG.GeometryElement#visProp} property won't be set if enhancedRendering is <tt>false</tt>\r\n     * @type Boolean\r\n     * @default true\r\n     */\r\n    this.enhancedRendering = true;\r\n\r\n    /**\r\n     * The HTML element that stores the JSXGraph board in it.\r\n     * @type Node\r\n     */\r\n    this.container = null;\r\n\r\n    /**\r\n     * This is used to easily determine which renderer we are using\r\n     * @example if (board.renderer.type === 'vml') {\r\n     *     // do something\r\n     * }\r\n     * @type String\r\n     */\r\n    this.type = \"\";\r\n\r\n    /**\r\n     * True if the browsers' SVG engine supports foreignObject.\r\n     * Not supported browsers are IE 9 - 11.\r\n     * It is tested in svg renderer.\r\n     *\r\n     * @type Boolean\r\n     * @private\r\n     */\r\n    this.supportsForeignObject = false;\r\n\r\n    /**\r\n     * Defines dash patterns. Sizes are in pixel.\r\n     * Defined styles are:\r\n     * <ol>\r\n     * <li> 2 dash, 2 space</li>\r\n     * <li> 5 dash, 5 space</li>\r\n     * <li> 10 dash, 10 space</li>\r\n     * <li> 20 dash, 20 space</li>\r\n     * <li> 20 dash, 10 space, 10 dash, 10 space</li>\r\n     * <li> 20 dash, 5 space, 10 dash, 5 space</li>\r\n     * <li> 0 dash, 5 space (dotted line)</li>\r\n     * </ol>\r\n     * This means, the numbering is <b>1-based</b>.\r\n     * Solid lines are set with dash:0.\r\n     * If the object's attribute \"dashScale:true\" the dash pattern is multiplied by\r\n     * strokeWidth / 2.\r\n     *\r\n     * @type Array\r\n     * @default [[2, 2], [5, 5], [10, 10], [20, 20], [20, 10, 10, 10], [20, 5, 10, 5], [0, 5]]\r\n     * @see JXG.GeometryElement#dash\r\n     * @see JXG.GeometryElement#dashScale\r\n     */\r\n    this.dashArray = [\r\n        [2, 2],\r\n        [5, 5],\r\n        [10, 10],\r\n        [20, 20],\r\n        [20, 10, 10, 10],\r\n        [20, 5, 10, 5],\r\n        [0, 5]\r\n    ];\r\n};\r\n\r\nJXG.extend(\r\n    JXG.AbstractRenderer.prototype,\r\n    /** @lends JXG.AbstractRenderer.prototype */ {\r\n\r\n        /* ********* Private methods *********** */\r\n\r\n        /**\r\n         * Update visual properties, but only if {@link JXG.AbstractRenderer#enhancedRendering} or <tt>enhanced</tt> is set to true.\r\n         * @param {JXG.GeometryElement} el The element to update\r\n         * @param {Object} [not={}] Select properties you don't want to be updated: <tt>{fill: true, dash: true}</tt> updates\r\n         * everything except for fill and dash. Possible values are <tt>stroke, fill, dash, shadow, gradient</tt>.\r\n         * @param {Boolean} [enhanced=false] If true, {@link JXG.AbstractRenderer#enhancedRendering} is assumed to be true.\r\n         * @private\r\n         */\r\n        _updateVisual: function (el, not, enhanced) {\r\n            if (enhanced || this.enhancedRendering) {\r\n                not = not || {};\r\n\r\n                this.setObjectTransition(el);\r\n                if (!el.evalVisProp('draft')) {\r\n                    if (!not.stroke) {\r\n                        if (el.highlighted) {\r\n                            this.setObjectStrokeColor(\r\n                                el,\r\n                                el.evalVisProp('highlightstrokecolor'),\r\n                                el.evalVisProp('highlightstrokeopacity')\r\n                            );\r\n                            this.setObjectStrokeWidth(el, el.evalVisProp('highlightstrokewidth'));\r\n                        } else {\r\n                            this.setObjectStrokeColor(\r\n                                el,\r\n                                el.evalVisProp('strokecolor'),\r\n                                el.evalVisProp('strokeopacity')\r\n                            );\r\n                            this.setObjectStrokeWidth(el, el.evalVisProp('strokewidth'));\r\n                        }\r\n                    }\r\n\r\n                    if (!not.fill) {\r\n                        if (el.highlighted) {\r\n                            this.setObjectFillColor(\r\n                                el,\r\n                                el.evalVisProp('highlightfillcolor'),\r\n                                el.evalVisProp('highlightfillopacity')\r\n                            );\r\n                        } else {\r\n                            this.setObjectFillColor(\r\n                                el,\r\n                                el.evalVisProp('fillcolor'),\r\n                                el.evalVisProp('fillopacity')\r\n                            );\r\n                        }\r\n                    }\r\n\r\n                    if (!not.dash) {\r\n                        this.setDashStyle(el, el.visProp);\r\n                    }\r\n\r\n                    if (!not.shadow) {\r\n                        this.setShadow(el);\r\n                    }\r\n\r\n                    // if (!not.gradient) {\r\n                    //     // this.setGradient(el);\r\n                    //     this.setShadow(el);\r\n                    // }\r\n\r\n                    if (!not.tabindex) {\r\n                        this.setTabindex(el);\r\n                    }\r\n                } else {\r\n                    this.setDraft(el);\r\n                }\r\n\r\n                if (el.highlighted) {\r\n                    this.setCssClass(el, el.evalVisProp('highlightcssclass'));\r\n                } else {\r\n                    this.setCssClass(el, el.evalVisProp('cssclass'));\r\n                }\r\n\r\n                if (el.evalVisProp('aria.enabled')) {\r\n                    this.setARIA(el);\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Get information if element is highlighted.\r\n         * @param {JXG.GeometryElement} el The element which is tested for being highlighted.\r\n         * @returns {String} 'highlight' if highlighted, otherwise the ampty string '' is returned.\r\n         * @private\r\n         */\r\n        _getHighlighted: function (el) {\r\n            var isTrace = false,\r\n                hl;\r\n\r\n            if (!Type.exists(el.board) || !Type.exists(el.board.highlightedObjects)) {\r\n                // This case handles trace elements.\r\n                // To make them work, we simply neglect highlighting.\r\n                isTrace = true;\r\n            }\r\n\r\n            if (!isTrace && Type.exists(el.board.highlightedObjects[el.id])) {\r\n                hl = 'highlight';\r\n            } else {\r\n                hl = \"\";\r\n            }\r\n            return hl;\r\n        },\r\n\r\n        /* ********* Point related stuff *********** */\r\n\r\n        /**\r\n         * Draws a point on the {@link JXG.Board}.\r\n         * @param {JXG.Point} el Reference to a {@link JXG.Point} object that has to be drawn.\r\n         * @see Point\r\n         * @see JXG.Point\r\n         * @see JXG.AbstractRenderer#updatePoint\r\n         * @see JXG.AbstractRenderer#changePointStyle\r\n         */\r\n        drawPoint: function (el) {\r\n            var prim,\r\n                // Sometimes el is not a real point and lacks the methods of a JXG.Point instance,\r\n                // in these cases to not use el directly.\r\n                face = Options.normalizePointFace(el.evalVisProp('face'));\r\n\r\n            // Determine how the point looks like\r\n            if (face === 'o') {\r\n                prim = 'ellipse';\r\n            } else if (face === \"[]\") {\r\n                prim = 'rect';\r\n            } else {\r\n                // cross/x, diamond/<>, triangleup/A/^, triangledown/v, triangleleft/<,\r\n                // triangleright/>, plus/+, |, -\r\n                prim = 'path';\r\n            }\r\n\r\n            el.rendNode = this.appendChildPrim(\r\n                this.createPrim(prim, el.id),\r\n                el.evalVisProp('layer')\r\n            );\r\n            this.appendNodesToElement(el, prim);\r\n\r\n            // Adjust visual properties\r\n            this._updateVisual(el, { dash: true, shadow: true }, true);\r\n\r\n            // By now we only created the xml nodes and set some styles, in updatePoint\r\n            // the attributes are filled with data.\r\n            this.updatePoint(el);\r\n        },\r\n\r\n        /**\r\n         * Updates visual appearance of the renderer element assigned to the given {@link JXG.Point}.\r\n         * @param {JXG.Point} el Reference to a {@link JXG.Point} object, that has to be updated.\r\n         * @see Point\r\n         * @see JXG.Point\r\n         * @see JXG.AbstractRenderer#drawPoint\r\n         * @see JXG.AbstractRenderer#changePointStyle\r\n         */\r\n        updatePoint: function (el) {\r\n            var size = el.evalVisProp('size'),\r\n                // sometimes el is not a real point and lacks the methods of a JXG.Point instance,\r\n                // in these cases to not use el directly.\r\n                face = Options.normalizePointFace(el.evalVisProp('face')),\r\n                unit = el.evalVisProp('sizeunit'),\r\n                zoom = el.evalVisProp('zoom'),\r\n                s1;\r\n\r\n            if (!isNaN(el.coords.scrCoords[2] + el.coords.scrCoords[1])) {\r\n                if (unit === 'user') {\r\n                    size *= Math.sqrt(Math.abs(el.board.unitX * el.board.unitY));\r\n                }\r\n                size *= !el.board || !zoom ? 1.0 : Math.sqrt(el.board.zoomX * el.board.zoomY);\r\n                s1 = size === 0 ? 0 : size + 1;\r\n\r\n                if (face === 'o') {\r\n                    // circle\r\n                    this.updateEllipsePrim(\r\n                        el.rendNode,\r\n                        el.coords.scrCoords[1],\r\n                        el.coords.scrCoords[2],\r\n                        s1,\r\n                        s1\r\n                    );\r\n                } else if (face === \"[]\") {\r\n                    // rectangle\r\n                    this.updateRectPrim(\r\n                        el.rendNode,\r\n                        el.coords.scrCoords[1] - size,\r\n                        el.coords.scrCoords[2] - size,\r\n                        size * 2,\r\n                        size * 2\r\n                    );\r\n                } else {\r\n                    // x, +, <>, <<>>, ^, v, <, >\r\n                    this.updatePathPrim(\r\n                        el.rendNode,\r\n                        this.updatePathStringPoint(el, size, face),\r\n                        el.board\r\n                    );\r\n                }\r\n                this._updateVisual(el, { dash: false, shadow: false });\r\n                this.setShadow(el);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Changes the style of a {@link JXG.Point}. This is required because the point styles differ in what\r\n         * elements have to be drawn, e.g. if the point is marked by a \"x\" or a \"+\" two lines are drawn, if\r\n         * it's marked by spot a circle is drawn. This method removes the old renderer element(s) and creates\r\n         * the new one(s).\r\n         * @param {JXG.Point} el Reference to a {@link JXG.Point} object, that's style is changed.\r\n         * @see Point\r\n         * @see JXG.Point\r\n         * @see JXG.AbstractRenderer#updatePoint\r\n         * @see JXG.AbstractRenderer#drawPoint\r\n         */\r\n        changePointStyle: function (el) {\r\n            var node = this.getElementById(el.id);\r\n\r\n            // remove the existing point rendering node\r\n            if (Type.exists(node)) {\r\n                this.remove(node);\r\n            }\r\n\r\n            // and make a new one\r\n            this.drawPoint(el);\r\n            Type.clearVisPropOld(el);\r\n\r\n            if (!el.visPropCalc.visible) {\r\n                this.display(el, false);\r\n            }\r\n\r\n            if (el.evalVisProp('draft')) {\r\n                this.setDraft(el);\r\n            }\r\n        },\r\n\r\n        /* ********* Line related stuff *********** */\r\n\r\n        /**\r\n         * Draws a line on the {@link JXG.Board}.\r\n         * @param {JXG.Line} el Reference to a line object, that has to be drawn.\r\n         * @see Line\r\n         * @see JXG.Line\r\n         * @see JXG.AbstractRenderer#updateLine\r\n         */\r\n        drawLine: function (el) {\r\n            el.rendNode = this.appendChildPrim(\r\n                this.createPrim(\"line\", el.id),\r\n                el.evalVisProp('layer')\r\n            );\r\n            this.appendNodesToElement(el, 'lines');\r\n            this.updateLine(el);\r\n        },\r\n\r\n        /**\r\n         * Updates visual appearance of the renderer element assigned to the given {@link JXG.Line}.\r\n         * @param {JXG.Line} el Reference to the {@link JXG.Line} object that has to be updated.\r\n         * @see Line\r\n         * @see JXG.Line\r\n         * @see JXG.AbstractRenderer#drawLine\r\n         */\r\n        updateLine: function (el) {\r\n            this._updateVisual(el);\r\n            this.updatePathWithArrowHeads(el); // Calls the renderer primitive\r\n            this.setLineCap(el);\r\n        },\r\n\r\n        /* ********* Curve related stuff *********** */\r\n\r\n        /**\r\n         * Draws a {@link JXG.Curve} on the {@link JXG.Board}.\r\n         * @param {JXG.Curve} el Reference to a graph object, that has to be plotted.\r\n         * @see Curve\r\n         * @see JXG.Curve\r\n         * @see JXG.AbstractRenderer#updateCurve\r\n         */\r\n        drawCurve: function (el) {\r\n            el.rendNode = this.appendChildPrim(\r\n                this.createPrim(\"path\", el.id),\r\n                el.evalVisProp('layer')\r\n            );\r\n            this.appendNodesToElement(el, 'path');\r\n            this.updateCurve(el);\r\n        },\r\n\r\n        /**\r\n         * Updates visual appearance of the renderer element assigned to the given {@link JXG.Curve}.\r\n         * @param {JXG.Curve} el Reference to a {@link JXG.Curve} object, that has to be updated.\r\n         * @see Curve\r\n         * @see JXG.Curve\r\n         * @see JXG.AbstractRenderer#drawCurve\r\n         */\r\n        updateCurve: function (el) {\r\n            this._updateVisual(el);\r\n            this.updatePathWithArrowHeads(el); // Calls the renderer primitive\r\n            this.setLineCap(el);\r\n        },\r\n\r\n        /* ********* Arrow heads and related stuff *********** */\r\n\r\n        /**\r\n         * Handles arrow heads of a line or curve element and calls the renderer primitive.\r\n         *\r\n         * @param {JXG.GeometryElement} el Reference to a line or curve object that has to be drawn.\r\n         * @param {Boolean} doHighlight\r\n         *\r\n         * @private\r\n         * @see Line\r\n         * @see JXG.Line\r\n         * @see Curve\r\n         * @see JXG.Curve\r\n         * @see JXG.AbstractRenderer#updateLine\r\n         * @see JXG.AbstractRenderer#updateCurve\r\n         * @see JXG.AbstractRenderer#makeArrows\r\n         * @see JXG.AbstractRenderer#getArrowHeadData\r\n         */\r\n        updatePathWithArrowHeads: function (el, doHighlight) {\r\n            var hl = doHighlight ? 'highlight' : '',\r\n                w,\r\n                arrowData;\r\n\r\n            if (doHighlight && el.evalVisProp('highlightstrokewidth')) {\r\n                w = Math.max(\r\n                    el.evalVisProp('highlightstrokewidth'),\r\n                    el.evalVisProp('strokewidth')\r\n                );\r\n            } else {\r\n                w = el.evalVisProp('strokewidth');\r\n            }\r\n\r\n            // Get information if there are arrow heads and how large they are.\r\n            arrowData = this.getArrowHeadData(el, w, hl);\r\n\r\n            // Create the SVG nodes if necessary\r\n            this.makeArrows(el, arrowData);\r\n\r\n            // Draw the paths with arrow heads\r\n            if (el.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                this.updateLineWithEndings(el, arrowData);\r\n            } else if (el.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n                this.updatePath(el);\r\n            }\r\n\r\n            this.setArrowSize(el, arrowData);\r\n        },\r\n\r\n        /**\r\n         * This method determines some data about the line endings of this element.\r\n         * If there are arrow heads, the offset is determined so that no parts of the line stroke\r\n         * lap over the arrow head.\r\n         * <p>\r\n         * The returned object also contains the types of the arrow heads.\r\n         *\r\n         * @param {JXG.GeometryElement} el JSXGraph line or curve element\r\n         * @param {Number} strokewidth strokewidth of the element\r\n         * @param {String} hl Ither 'highlight' or empty string\r\n         * @returns {Object} object containing the data\r\n         *\r\n         * @private\r\n         */\r\n        getArrowHeadData: function (el, strokewidth, hl) {\r\n            var minlen = Mat.eps,\r\n                typeFirst,\r\n                typeLast,\r\n                offFirst = 0,\r\n                offLast = 0,\r\n                sizeFirst = 0,\r\n                sizeLast = 0,\r\n                ev_fa = el.evalVisProp('firstarrow'),\r\n                ev_la = el.evalVisProp('lastarrow'),\r\n                off,\r\n                size;\r\n\r\n            /*\r\n               Handle arrow heads.\r\n\r\n               The default arrow head is an isosceles triangle with base length 10 units and height 10 units.\r\n               These 10 units are scaled to strokeWidth * arrowSize pixels.\r\n            */\r\n            if (ev_fa || ev_la) {\r\n                if (Type.exists(ev_fa.type)) {\r\n                    typeFirst = el.eval(ev_fa.type);\r\n                } else {\r\n                    if (el.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                        typeFirst = 1;\r\n                    } else {\r\n                        typeFirst = 7;\r\n                    }\r\n                }\r\n                if (Type.exists(ev_la.type)) {\r\n                    typeLast = el.eval(ev_la.type);\r\n                } else {\r\n                    if (el.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                        typeLast = 1;\r\n                    } else {\r\n                        typeLast = 7;\r\n                    }\r\n                }\r\n\r\n                if (ev_fa) {\r\n                    size = 6;\r\n                    if (Type.exists(ev_fa.size)) {\r\n                        size = el.eval(ev_fa.size);\r\n                    }\r\n                    if (hl !== \"\" && Type.exists(ev_fa[hl + \"size\"])) {\r\n                        size = el.eval(ev_fa[hl + \"size\"]);\r\n                    }\r\n\r\n                    off = strokewidth * size;\r\n                    if (typeFirst === 2) {\r\n                        off *= 0.5;\r\n                        minlen += strokewidth * size;\r\n                    } else if (typeFirst === 3) {\r\n                        off = (strokewidth * size) / 3;\r\n                        minlen += strokewidth;\r\n                    } else if (typeFirst === 4 || typeFirst === 5 || typeFirst === 6) {\r\n                        off = (strokewidth * size) / 1.5;\r\n                        minlen += strokewidth * size;\r\n                    } else if (typeFirst === 7) {\r\n                        off = 0;\r\n                        size = 10;\r\n                        minlen += strokewidth;\r\n                    } else {\r\n                        minlen += strokewidth * size;\r\n                    }\r\n                    offFirst += off;\r\n                    sizeFirst = size;\r\n                }\r\n\r\n                if (ev_la) {\r\n                    size = 6;\r\n                    if (Type.exists(ev_la.size)) {\r\n                        size = el.eval(ev_la.size);\r\n                    }\r\n                    if (hl !== \"\" && Type.exists(ev_la[hl + \"size\"])) {\r\n                        size = el.eval(ev_la[hl + \"size\"]);\r\n                    }\r\n                    off = strokewidth * size;\r\n                    if (typeLast === 2) {\r\n                        off *= 0.5;\r\n                        minlen += strokewidth * size;\r\n                    } else if (typeLast === 3) {\r\n                        off = (strokewidth * size) / 3;\r\n                        minlen += strokewidth;\r\n                    } else if (typeLast === 4 || typeLast === 5 || typeLast === 6) {\r\n                        off = (strokewidth * size) / 1.5;\r\n                        minlen += strokewidth * size;\r\n                    } else if (typeLast === 7) {\r\n                        off = 0;\r\n                        size = 10;\r\n                        minlen += strokewidth;\r\n                    } else {\r\n                        minlen += strokewidth * size;\r\n                    }\r\n                    offLast += off;\r\n                    sizeLast = size;\r\n                }\r\n            }\r\n            el.visPropCalc.typeFirst = typeFirst;\r\n            el.visPropCalc.typeLast = typeLast;\r\n\r\n            return {\r\n                evFirst: ev_fa,\r\n                evLast: ev_la,\r\n                typeFirst: typeFirst,\r\n                typeLast: typeLast,\r\n                offFirst: offFirst,\r\n                offLast: offLast,\r\n                sizeFirst: sizeFirst,\r\n                sizeLast: sizeLast,\r\n                showFirst: 1, // Show arrow head. 0 if the distance is too small\r\n                showLast: 1, // Show arrow head. 0 if the distance is too small\r\n                minLen: minlen,\r\n                strokeWidth: strokewidth\r\n            };\r\n        },\r\n\r\n        /**\r\n         * Corrects the line length if there are arrow heads, such that\r\n         * the arrow ends exactly at the intended position.\r\n         * Calls the renderer method to draw the line.\r\n         *\r\n         * @param {JXG.Line} el Reference to a line object, that has to be drawn\r\n         * @param {Object} arrowData Data concerning possible arrow heads\r\n         *\r\n         * @returns {JXG.AbstractRenderer} Reference to the renderer\r\n         *\r\n         * @private\r\n         * @see Line\r\n         * @see JXG.Line\r\n         * @see JXG.AbstractRenderer#updateLine\r\n         * @see JXG.AbstractRenderer#getPositionArrowHead\r\n         *\r\n         */\r\n        updateLineWithEndings: function (el, arrowData) {\r\n            var c1,\r\n                c2,\r\n                // useTotalLength = true,\r\n                margin = null;\r\n\r\n            c1 = new Coords(Const.COORDS_BY_USER, el.point1.coords.usrCoords, el.board);\r\n            c2 = new Coords(Const.COORDS_BY_USER, el.point2.coords.usrCoords, el.board);\r\n            margin = el.evalVisProp('margin');\r\n            Geometry.calcStraight(el, c1, c2, margin);\r\n\r\n            this.handleTouchpoints(el, c1, c2, arrowData);\r\n            this.getPositionArrowHead(el, c1, c2, arrowData);\r\n\r\n            this.updateLinePrim(\r\n                el.rendNode,\r\n                c1.scrCoords[1],\r\n                c1.scrCoords[2],\r\n                c2.scrCoords[1],\r\n                c2.scrCoords[2],\r\n                el.board\r\n            );\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         *\r\n         * Calls the renderer method to draw a curve.\r\n         *\r\n         * @param {JXG.GeometryElement} el Reference to a line object, that has to be drawn.\r\n         * @returns {JXG.AbstractRenderer} Reference to the renderer\r\n         *\r\n         * @private\r\n         * @see Curve\r\n         * @see JXG.Curve\r\n         * @see JXG.AbstractRenderer#updateCurve\r\n         *\r\n         */\r\n        updatePath: function (el) {\r\n            if (el.evalVisProp('handdrawing')) {\r\n                this.updatePathPrim(el.rendNode, this.updatePathStringBezierPrim(el), el.board);\r\n            } else {\r\n                this.updatePathPrim(el.rendNode, this.updatePathStringPrim(el), el.board);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Shorten the length of a line element such that the arrow head touches\r\n         * the start or end point and such that the arrow head ends exactly\r\n         * at the start / end position of the line.\r\n         * <p>\r\n         * The Coords objects c1 and c2 are changed in place. In object a, the Boolean properties\r\n         * 'showFirst' and 'showLast' are set.\r\n         *\r\n         * @param  {JXG.Line} el Reference to the line object that gets arrow heads.\r\n         * @param  {JXG.Coords} c1  Coords of the first point of the line (after {@link JXG.Math.Geometry#calcStraight}).\r\n         * @param  {JXG.Coords} c2  Coords of the second point of the line (after {@link JXG.Math.Geometry#calcStraight}).\r\n         * @param  {Object}  a Object { evFirst: Boolean, evLast: Boolean} containing information about arrow heads.\r\n         * @see JXG.AbstractRenderer#getArrowHeadData\r\n         *\r\n         */\r\n        getPositionArrowHead: function (el, c1, c2, a) {\r\n            var d, d1x, d1y, d2x, d2y;\r\n\r\n            //    Handle arrow heads.\r\n\r\n            //    The default arrow head (type==1) is an isosceles triangle with base length 10 units and height 10 units.\r\n            //    These 10 units are scaled to strokeWidth * arrowSize pixels.\r\n            if (a.evFirst || a.evLast) {\r\n                // Correct the position of the arrow heads\r\n                d1x = d1y = d2x = d2y = 0.0;\r\n                d = c1.distance(Const.COORDS_BY_SCREEN, c2);\r\n\r\n                if (a.evFirst && el.board.renderer.type !== 'vml') {\r\n                    if (d >= a.minLen) {\r\n                        d1x = ((c2.scrCoords[1] - c1.scrCoords[1]) * a.offFirst) / d;\r\n                        d1y = ((c2.scrCoords[2] - c1.scrCoords[2]) * a.offFirst) / d;\r\n                    } else {\r\n                        a.showFirst = 0;\r\n                    }\r\n                }\r\n\r\n                if (a.evLast && el.board.renderer.type !== 'vml') {\r\n                    if (d >= a.minLen) {\r\n                        d2x = ((c2.scrCoords[1] - c1.scrCoords[1]) * a.offLast) / d;\r\n                        d2y = ((c2.scrCoords[2] - c1.scrCoords[2]) * a.offLast) / d;\r\n                    } else {\r\n                        a.showLast = 0;\r\n                    }\r\n                }\r\n                c1.setCoordinates(\r\n                    Const.COORDS_BY_SCREEN,\r\n                    [c1.scrCoords[1] + d1x, c1.scrCoords[2] + d1y],\r\n                    false,\r\n                    true\r\n                );\r\n                c2.setCoordinates(\r\n                    Const.COORDS_BY_SCREEN,\r\n                    [c2.scrCoords[1] - d2x, c2.scrCoords[2] - d2y],\r\n                    false,\r\n                    true\r\n                );\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Handle touchlastpoint / touchfirstpoint\r\n         *\r\n         * @param {JXG.GeometryElement} el\r\n         * @param {JXG.Coords} c1 Coordinates of the start of the line. The coordinates are changed in place.\r\n         * @param {JXG.Coords} c2 Coordinates of the end of the line. The coordinates are changed in place.\r\n         * @param {Object} a\r\n         * @see JXG.AbstractRenderer#getArrowHeadData\r\n         */\r\n        handleTouchpoints: function (el, c1, c2, a) {\r\n            var s1, s2, d, d1x, d1y, d2x, d2y;\r\n\r\n            if (a.evFirst || a.evLast) {\r\n                d = d1x = d1y = d2x = d2y = 0.0;\r\n\r\n                s1 = el.point1.evalVisProp('size') +\r\n                    el.point1.evalVisProp('strokewidth');\r\n\r\n                s2 = el.point2.evalVisProp('size') +\r\n                    el.point2.evalVisProp('strokewidth');\r\n\r\n                // Handle touchlastpoint /touchfirstpoint\r\n                if (a.evFirst && el.evalVisProp('touchfirstpoint') &&\r\n                        el.point1.evalVisProp('visible')) {\r\n                    d = c1.distance(Const.COORDS_BY_SCREEN, c2);\r\n                    //if (d > s) {\r\n                    d1x = ((c2.scrCoords[1] - c1.scrCoords[1]) * s1) / d;\r\n                    d1y = ((c2.scrCoords[2] - c1.scrCoords[2]) * s1) / d;\r\n                    //}\r\n                }\r\n                if (a.evLast && el.evalVisProp('touchlastpoint') &&\r\n                        el.point2.evalVisProp('visible')) {\r\n                    d = c1.distance(Const.COORDS_BY_SCREEN, c2);\r\n                    //if (d > s) {\r\n                    d2x = ((c2.scrCoords[1] - c1.scrCoords[1]) * s2) / d;\r\n                    d2y = ((c2.scrCoords[2] - c1.scrCoords[2]) * s2) / d;\r\n                    //}\r\n                }\r\n                c1.setCoordinates(\r\n                    Const.COORDS_BY_SCREEN,\r\n                    [c1.scrCoords[1] + d1x, c1.scrCoords[2] + d1y],\r\n                    false,\r\n                    true\r\n                );\r\n                c2.setCoordinates(\r\n                    Const.COORDS_BY_SCREEN,\r\n                    [c2.scrCoords[1] - d2x, c2.scrCoords[2] - d2y],\r\n                    false,\r\n                    true\r\n                );\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the arrow head size.\r\n         *\r\n         * @param {JXG.GeometryElement} el Reference to a line or curve object that has to be drawn.\r\n         * @param {Object} arrowData Data concerning possible arrow heads\r\n         * @returns {JXG.AbstractRenderer} Reference to the renderer\r\n         *\r\n         * @private\r\n         * @see Line\r\n         * @see JXG.Line\r\n         * @see Curve\r\n         * @see JXG.Curve\r\n         * @see JXG.AbstractRenderer#updatePathWithArrowHeads\r\n         * @see JXG.AbstractRenderer#getArrowHeadData\r\n         */\r\n        setArrowSize: function (el, a) {\r\n            if (a.evFirst) {\r\n                this._setArrowWidth(\r\n                    el.rendNodeTriangleStart,\r\n                    a.showFirst * a.strokeWidth,\r\n                    el.rendNode,\r\n                    a.sizeFirst\r\n                );\r\n            }\r\n            if (a.evLast) {\r\n                this._setArrowWidth(\r\n                    el.rendNodeTriangleEnd,\r\n                    a.showLast * a.strokeWidth,\r\n                    el.rendNode,\r\n                    a.sizeLast\r\n                );\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Update the line endings (linecap) of a straight line from its attribute\r\n         * 'linecap'.\r\n         * Possible values for the attribute 'linecap' are: 'butt', 'round', 'square'.\r\n         * The default value is 'butt'. Not available for VML renderer.\r\n         *\r\n         * @param {JXG.Line} element A arbitrary line.\r\n         * @see Line\r\n         * @see JXG.Line\r\n         * @see JXG.AbstractRenderer#updateLine\r\n         */\r\n        setLineCap: function (el) { /* stub */ },\r\n\r\n        /* ********* Ticks related stuff *********** */\r\n\r\n        /**\r\n         * Creates a rendering node for ticks added to a line.\r\n         * @param {JXG.Line} el A arbitrary line.\r\n         * @see Line\r\n         * @see Ticks\r\n         * @see JXG.Line\r\n         * @see JXG.Ticks\r\n         * @see JXG.AbstractRenderer#updateTicks\r\n         */\r\n        drawTicks: function (el) {\r\n            el.rendNode = this.appendChildPrim(\r\n                this.createPrim(\"path\", el.id),\r\n                el.evalVisProp('layer')\r\n            );\r\n            this.appendNodesToElement(el, 'path');\r\n        },\r\n\r\n        /**\r\n         * Update {@link Ticks} on a {@link JXG.Line}. This method is only a stub and has to be implemented\r\n         * in any descendant renderer class.\r\n         * @param {JXG.Ticks} el Reference of a ticks object that has to be updated.\r\n         * @see Line\r\n         * @see Ticks\r\n         * @see JXG.Line\r\n         * @see JXG.Ticks\r\n         * @see JXG.AbstractRenderer#drawTicks\r\n         */\r\n        updateTicks: function (el) { /* stub */ },\r\n\r\n        /* ********* Circle related stuff *********** */\r\n\r\n        /**\r\n         * Draws a {@link JXG.Circle}\r\n         * @param {JXG.Circle} el Reference to a {@link JXG.Circle} object that has to be drawn.\r\n         * @see Circle\r\n         * @see JXG.Circle\r\n         * @see JXG.AbstractRenderer#updateEllipse\r\n         */\r\n        drawEllipse: function (el) {\r\n            el.rendNode = this.appendChildPrim(\r\n                this.createPrim(\"ellipse\", el.id),\r\n                el.evalVisProp('layer')\r\n            );\r\n            this.appendNodesToElement(el, 'ellipse');\r\n            this.updateEllipse(el);\r\n        },\r\n\r\n        /**\r\n         * Updates visual appearance of a given {@link JXG.Circle} on the {@link JXG.Board}.\r\n         * @param {JXG.Circle} el Reference to a {@link JXG.Circle} object, that has to be updated.\r\n         * @see Circle\r\n         * @see JXG.Circle\r\n         * @see JXG.AbstractRenderer#drawEllipse\r\n         */\r\n        updateEllipse: function (el) {\r\n            this._updateVisual(el);\r\n\r\n            var radius = el.Radius();\r\n\r\n            if (\r\n                /*radius > 0.0 &&*/\r\n                Math.abs(el.center.coords.usrCoords[0]) > Mat.eps &&\r\n                !isNaN(radius + el.center.coords.scrCoords[1] + el.center.coords.scrCoords[2]) &&\r\n                radius * el.board.unitX < 2000000\r\n            ) {\r\n                this.updateEllipsePrim(\r\n                    el.rendNode,\r\n                    el.center.coords.scrCoords[1],\r\n                    el.center.coords.scrCoords[2],\r\n                    radius * el.board.unitX,\r\n                    radius * el.board.unitY\r\n                );\r\n            }\r\n            this.setLineCap(el);\r\n        },\r\n\r\n        /* ********* Polygon related stuff *********** */\r\n\r\n        /**\r\n         * Draws a {@link JXG.Polygon} on the {@link JXG.Board}.\r\n         * @param {JXG.Polygon} el Reference to a Polygon object, that is to be drawn.\r\n         * @see Polygon\r\n         * @see JXG.Polygon\r\n         * @see JXG.AbstractRenderer#updatePolygon\r\n         */\r\n        drawPolygon: function (el) {\r\n            el.rendNode = this.appendChildPrim(\r\n                this.createPrim(\"polygon\", el.id),\r\n                el.evalVisProp('layer')\r\n            );\r\n            this.appendNodesToElement(el, 'polygon');\r\n            this.updatePolygon(el);\r\n        },\r\n\r\n        /**\r\n         * Updates properties of a {@link JXG.Polygon}'s rendering node.\r\n         * @param {JXG.Polygon} el Reference to a {@link JXG.Polygon} object, that has to be updated.\r\n         * @see Polygon\r\n         * @see JXG.Polygon\r\n         * @see JXG.AbstractRenderer#drawPolygon\r\n         */\r\n        updatePolygon: function (el) {\r\n            // Here originally strokecolor wasn't updated but strokewidth was.\r\n            // But if there's no strokecolor i don't see why we should update strokewidth.\r\n            this._updateVisual(el, { stroke: true, dash: true });\r\n            this.updatePolygonPrim(el.rendNode, el);\r\n        },\r\n\r\n        /* ********* Text related stuff *********** */\r\n\r\n        /**\r\n         * Shows a small copyright notice in the top left corner of the board.\r\n         * @param {String} str The copyright notice itself\r\n         * @param {Number} fontsize Size of the font the copyright notice is written in\r\n         * @see JXG.AbstractRenderer#displayLogo\r\n         * @see Text#fontSize\r\n         */\r\n        displayCopyright: function (str, fontsize) { /* stub */ },\r\n\r\n        /**\r\n         * Shows a small JSXGraph logo in the top left corner of the board.\r\n         * @param {String} str The data-URL of the logo\r\n         * @param {Number} fontsize Size of the font the copyright notice is written in\r\n         * @see JXG.AbstractRenderer#displayCopyright\r\n         * @see Text#fontSize\r\n         */\r\n        displayLogo: function (str, fontsize) { /* stub */ },\r\n\r\n        /**\r\n         * An internal text is a {@link JXG.Text} element which is drawn using only\r\n         * the given renderer but no HTML. This method is only a stub, the drawing\r\n         * is done in the special renderers.\r\n         * @param {JXG.Text} el Reference to a {@link JXG.Text} object\r\n         * @see Text\r\n         * @see JXG.Text\r\n         * @see JXG.AbstractRenderer#updateInternalText\r\n         * @see JXG.AbstractRenderer#drawText\r\n         * @see JXG.AbstractRenderer#updateText\r\n         * @see JXG.AbstractRenderer#updateTextStyle\r\n         */\r\n        drawInternalText: function (el) { /* stub */ },\r\n\r\n        /**\r\n         * Updates visual properties of an already existing {@link JXG.Text} element.\r\n         * @param {JXG.Text} el Reference to an {@link JXG.Text} object, that has to be updated.\r\n         * @see Text\r\n         * @see JXG.Text\r\n         * @see JXG.AbstractRenderer#drawInternalText\r\n         * @see JXG.AbstractRenderer#drawText\r\n         * @see JXG.AbstractRenderer#updateText\r\n         * @see JXG.AbstractRenderer#updateTextStyle\r\n         */\r\n        updateInternalText: function (el) { /* stub */ },\r\n\r\n        /**\r\n         * Displays a {@link JXG.Text} on the {@link JXG.Board} by putting a HTML div over it.\r\n         * @param {JXG.Text} el Reference to an {@link JXG.Text} object, that has to be displayed\r\n         * @see Text\r\n         * @see JXG.Text\r\n         * @see JXG.AbstractRenderer#drawInternalText\r\n         * @see JXG.AbstractRenderer#updateText\r\n         * @see JXG.AbstractRenderer#updateInternalText\r\n         * @see JXG.AbstractRenderer#updateTextStyle\r\n         */\r\n        drawText: function (el) {\r\n            var node, z, level, ev_visible;\r\n\r\n            if (\r\n                el.evalVisProp('display') === \"html\" &&\r\n                Env.isBrowser &&\r\n                this.type !== \"no\"\r\n            ) {\r\n                node = this.container.ownerDocument.createElement('div');\r\n                //node = this.container.ownerDocument.createElementNS('http://www.w3.org/1999/xhtml', 'div'); //\r\n                node.style.position = 'absolute';\r\n                node.className = el.evalVisProp('cssclass');\r\n\r\n                level = el.evalVisProp('layer');\r\n                if (!Type.exists(level)) {\r\n                    // trace nodes have level not set\r\n                    level = 0;\r\n                }\r\n\r\n                if (this.container.style.zIndex === \"\") {\r\n                    z = 0;\r\n                } else {\r\n                    z = parseInt(this.container.style.zIndex, 10);\r\n                }\r\n\r\n                node.style.zIndex = z + level;\r\n                this.container.appendChild(node);\r\n\r\n                node.setAttribute(\"id\", this.container.id + \"_\" + el.id);\r\n            } else {\r\n                node = this.drawInternalText(el);\r\n            }\r\n\r\n            el.rendNode = node;\r\n            el.htmlStr = \"\";\r\n\r\n            // Set el.visPropCalc.visible\r\n            if (el.visProp.islabel && Type.exists(el.visProp.anchor)) {\r\n                ev_visible = el.visProp.anchor.evalVisProp('visible');\r\n                el.prepareUpdate().updateVisibility(ev_visible);\r\n            } else {\r\n                el.prepareUpdate().updateVisibility();\r\n            }\r\n            this.updateText(el);\r\n        },\r\n\r\n        /**\r\n         * Updates visual properties of an already existing {@link JXG.Text} element.\r\n         * @param {JXG.Text} el Reference to an {@link JXG.Text} object, that has to be updated.\r\n         * @see Text\r\n         * @see JXG.Text\r\n         * @see JXG.AbstractRenderer#drawText\r\n         * @see JXG.AbstractRenderer#drawInternalText\r\n         * @see JXG.AbstractRenderer#updateInternalText\r\n         * @see JXG.AbstractRenderer#updateTextStyle\r\n         */\r\n        updateText: function (el) {\r\n            var content = el.plaintext,\r\n                v, c,\r\n                parentNode, node,\r\n                // scale, vshift,\r\n                // id, wrap_id,\r\n                ax, ay, angle, co, si,\r\n                to_h, to_v;\r\n\r\n            if (el.visPropCalc.visible) {\r\n                this.updateTextStyle(el, false);\r\n\r\n                if (el.evalVisProp('display') === \"html\" && this.type !== 'no') {\r\n                    // Set the position\r\n                    if (!isNaN(el.coords.scrCoords[1] + el.coords.scrCoords[2])) {\r\n                        // Horizontal\r\n                        c = el.coords.scrCoords[1];\r\n                        // webkit seems to fail for extremely large values for c.\r\n                        c = Math.abs(c) < 1000000 ? c : 1000000;\r\n                        ax = el.getAnchorX();\r\n\r\n                        if (ax === 'right') {\r\n                            // v = Math.floor(el.board.canvasWidth - c);\r\n                            v = el.board.canvasWidth - c;\r\n                            to_h = 'right';\r\n                        } else if (ax === 'middle') {\r\n                            // v = Math.floor(c - 0.5 * el.size[0]);\r\n                            v = c - 0.5 * el.size[0];\r\n                            to_h = 'center';\r\n                        } else {\r\n                            // 'left'\r\n                            // v = Math.floor(c);\r\n                            v = c;\r\n                            to_h = 'left';\r\n                        }\r\n\r\n                        // This may be useful for foreignObj.\r\n                        //if (window.devicePixelRatio !== undefined) {\r\n                        //v *= window.devicePixelRatio;\r\n                        //}\r\n\r\n                        if (el.visPropOld.left !== ax + v) {\r\n                            if (ax === 'right') {\r\n                                el.rendNode.style.right = v + 'px';\r\n                                el.rendNode.style.left = 'auto';\r\n                            } else {\r\n                                el.rendNode.style.left = v + 'px';\r\n                                el.rendNode.style.right = 'auto';\r\n                            }\r\n                            el.visPropOld.left = ax + v;\r\n                        }\r\n\r\n                        // Vertical\r\n                        c = el.coords.scrCoords[2] + this.vOffsetText;\r\n                        c = Math.abs(c) < 1000000 ? c : 1000000;\r\n                        ay = el.getAnchorY();\r\n\r\n                        if (ay === 'bottom') {\r\n                            // v = Math.floor(el.board.canvasHeight - c);\r\n                            v = el.board.canvasHeight - c;\r\n                            to_v = 'bottom';\r\n                        } else if (ay === 'middle') {\r\n                            // v = Math.floor(c - 0.5 * el.size[1]);\r\n                            v = c - 0.5 * el.size[1];\r\n                            to_v = 'center';\r\n                        } else {\r\n                            // top\r\n                            // v = Math.floor(c);\r\n                            v = c;\r\n                            to_v = 'top';\r\n                        }\r\n\r\n                        // This may be useful for foreignObj.\r\n                        //if (window.devicePixelRatio !== undefined) {\r\n                        //v *= window.devicePixelRatio;\r\n                        //}\r\n\r\n                        if (el.visPropOld.top !== ay + v) {\r\n                            if (ay === 'bottom') {\r\n                                el.rendNode.style.top = 'auto';\r\n                                el.rendNode.style.bottom = v + 'px';\r\n                            } else {\r\n                                el.rendNode.style.bottom = 'auto';\r\n                                el.rendNode.style.top = v + 'px';\r\n                            }\r\n                            el.visPropOld.top = ay + v;\r\n                        }\r\n                    }\r\n\r\n                    // Set the content\r\n                    if (el.htmlStr !== content) {\r\n                        try {\r\n                            if (el.type === Type.OBJECT_TYPE_BUTTON) {\r\n                                el.rendNodeButton.innerHTML = content;\r\n                            } else if (\r\n                                el.type === Type.OBJECT_TYPE_CHECKBOX ||\r\n                                el.type === Type.OBJECT_TYPE_INPUT\r\n                            ) {\r\n                                el.rendNodeLabel.innerHTML = content;\r\n                            } else {\r\n                                el.rendNode.innerHTML = content;\r\n                            }\r\n                        } catch (e) {\r\n                            // Setting innerHTML sometimes fails in IE8.\r\n                            // A workaround is to take the node off the DOM, assign innerHTML,\r\n                            // then append back.\r\n                            // Works for text elements as they are absolutely positioned.\r\n                            parentNode = el.rendNode.parentNode;\r\n                            el.rendNode.parentNode.removeChild(el.rendNode);\r\n                            el.rendNode.innerHTML = content;\r\n                            parentNode.appendChild(el.rendNode);\r\n                        }\r\n                        el.htmlStr = content;\r\n\r\n                        if (el.evalVisProp('usemathjax')) {\r\n                            // Typesetting directly might not work because MathJax was not loaded completely\r\n                            try {\r\n                                if (MathJax.typeset) {\r\n                                    // Version 3\r\n                                    MathJax.typeset([el.rendNode]);\r\n                                } else {\r\n                                    // Version 2\r\n                                    MathJax.Hub.Queue([\"Typeset\", MathJax.Hub, el.rendNode]);\r\n                                }\r\n\r\n                                // Obsolete:\r\n                                // // Restore the transformation necessary for fullscreen mode\r\n                                // // MathJax removes it when handling dynamic content\r\n                                // id = el.board.container;\r\n                                // wrap_id = \"fullscreenwrap_\" + id;\r\n                                // if (document.getElementById(wrap_id)) {\r\n                                //     scale = el.board.containerObj._cssFullscreenStore.scale;\r\n                                //     vshift = el.board.containerObj._cssFullscreenStore.vshift;\r\n                                //     Env.scaleJSXGraphDiv(\r\n                                //         \"#\" + wrap_id,\r\n                                //         \"#\" + id,\r\n                                //         scale,\r\n                                //         vshift\r\n                                //     );\r\n                                // }\r\n                            } catch (e) {\r\n                                JXG.debug(\"MathJax (not yet) loaded\");\r\n                            }\r\n                        } else if (el.evalVisProp('usekatex')) {\r\n                            try {\r\n                                // Checkboxes et. al. do not possess rendNodeLabel during the first update.\r\n                                // In this case node will be undefined and not rendered by KaTeX.\r\n                                if (el.rendNode.innerHTML.indexOf('<span') === 0 &&\r\n                                    el.rendNode.innerHTML.indexOf('<label') > 0 &&\r\n                                    (\r\n                                        el.rendNode.innerHTML.indexOf('<checkbox') > 0 ||\r\n                                        el.rendNode.innerHTML.indexOf('<input') > 0\r\n                                    )\r\n                                 ) {\r\n                                    node = el.rendNodeLabel;\r\n                                } else if (el.rendNode.innerHTML.indexOf('<button') === 0) {\r\n                                    node = el.rendNodeButton;\r\n                                } else {\r\n                                    node = el.rendNode;\r\n                                }\r\n\r\n                                if (node) {\r\n                                    /* eslint-disable no-undef */\r\n                                    katex.render(content, node, {\r\n                                        macros: el.evalVisProp('katexmacros'),\r\n                                        throwOnError: false\r\n                                    });\r\n                                    /* eslint-enable no-undef */\r\n                                }\r\n                            } catch (e) {\r\n                                JXG.debug(\"KaTeX not loaded (yet)\");\r\n                            }\r\n                        } else if (el.evalVisProp('useasciimathml')) {\r\n                            // This is not a constructor.\r\n                            // See http://asciimath.org/ for more information\r\n                            // about AsciiMathML and the project's source code.\r\n                            try {\r\n                                AMprocessNode(el.rendNode, false);\r\n                            } catch (e) {\r\n                                JXG.debug(\"AsciiMathML not loaded (yet)\");\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    angle = el.evalVisProp('rotate');\r\n                    if (angle !== 0) {\r\n                        // Don't forget to convert to rad\r\n                        angle *= (Math.PI / 180);\r\n                        co = Math.cos(angle);\r\n                        si = Math.sin(angle);\r\n\r\n                        el.rendNode.style['transform'] = 'matrix(' +\r\n                                [co, -1 * si, si, co, 0, 0].join(',') +\r\n                            ')';\r\n                        el.rendNode.style['transform-origin'] = to_h + ' ' + to_v;\r\n                    }\r\n                    this.transformRect(el, el.transformations);\r\n                } else {\r\n                    this.updateInternalText(el);\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Converts string containing CSS properties into\r\n         * array with key-value pair objects.\r\n         *\r\n         * @example\r\n         * \"color:blue; background-color:yellow\" is converted to\r\n         * [{'color': 'blue'}, {'backgroundColor': 'yellow'}]\r\n         *\r\n         * @param  {String} cssString String containing CSS properties\r\n         * @return {Array}           Array of CSS key-value pairs\r\n         */\r\n        _css2js: function (cssString) {\r\n            var pairs = [],\r\n                i,\r\n                len,\r\n                key,\r\n                val,\r\n                s,\r\n                list = Type.trim(cssString).replace(/;$/, \"\").split(\";\");\r\n\r\n            len = list.length;\r\n            for (i = 0; i < len; ++i) {\r\n                if (Type.trim(list[i]) !== \"\") {\r\n                    s = list[i].split(\":\");\r\n                    key = Type.trim(\r\n                        s[0].replace(/-([a-z])/gi, function (match, char) {\r\n                            return char.toUpperCase();\r\n                        })\r\n                    );\r\n                    val = Type.trim(s[1]);\r\n                    pairs.push({ key: key, val: val });\r\n                }\r\n            }\r\n            return pairs;\r\n        },\r\n\r\n        /**\r\n         * Updates font-size, color and opacity properties and CSS style properties of a {@link JXG.Text} node.\r\n         * This function is also called by highlight() and nohighlight().\r\n         * @param {JXG.Text} el Reference to the {@link JXG.Text} object, that has to be updated.\r\n         * @param {Boolean} doHighlight\r\n         * @see Text\r\n         * @see JXG.Text\r\n         * @see JXG.AbstractRenderer#drawText\r\n         * @see JXG.AbstractRenderer#drawInternalText\r\n         * @see JXG.AbstractRenderer#updateText\r\n         * @see JXG.AbstractRenderer#updateInternalText\r\n         * @see JXG.AbstractRenderer#updateInternalTextStyle\r\n         */\r\n        updateTextStyle: function (el, doHighlight) {\r\n            var fs,\r\n                so, sc,\r\n                css,\r\n                node,\r\n                display = Env.isBrowser ? el.visProp.display : \"internal\",\r\n                nodeList = [\"rendNode\", \"rendNodeTag\", \"rendNodeLabel\"],\r\n                lenN = nodeList.length,\r\n                fontUnit = el.evalVisProp('fontunit'),\r\n                cssList,\r\n                prop,\r\n                style,\r\n                cssString,\r\n                styleList = [\"cssdefaultstyle\", \"cssstyle\"],\r\n                lenS = styleList.length;\r\n\r\n            if (doHighlight) {\r\n                sc = el.evalVisProp('highlightstrokecolor');\r\n                so = el.evalVisProp('highlightstrokeopacity');\r\n                css = el.evalVisProp('highlightcssclass');\r\n            } else {\r\n                sc = el.evalVisProp('strokecolor');\r\n                so = el.evalVisProp('strokeopacity');\r\n                css = el.evalVisProp('cssclass');\r\n            }\r\n\r\n            // This part is executed for all text elements except internal texts in canvas.\r\n            // HTML-texts or internal texts in SVG or VML.\r\n            //            HTML    internal\r\n            //  SVG        +         +\r\n            //  VML        +         +\r\n            //  canvas     +         -\r\n            //  no         -         -\r\n            if (this.type !== \"no\" && (display === \"html\" || this.type !== 'canvas')) {\r\n                for (style = 0; style < lenS; style++) {\r\n                    // First set cssString to\r\n                    // ev.cssdefaultstyle of ev.highlightcssdefaultstyle,\r\n                    // then to\r\n                    // ev.cssstyle of ev.highlightcssstyle\r\n                    cssString = el.evalVisProp(\r\n                        (doHighlight ? 'highlight' : '') + styleList[style]\r\n                    );\r\n                    // Set the CSS style properties - without deleting other properties\r\n                    for (node = 0; node < lenN; node++) {\r\n                        if (Type.exists(el[nodeList[node]])) {\r\n                            if (cssString !== \"\" && el.visPropOld[styleList[style] + '_' + node] !== cssString) {\r\n                                cssList = this._css2js(cssString);\r\n                                for (prop in cssList) {\r\n                                    if (cssList.hasOwnProperty(prop)) {\r\n                                        el[nodeList[node]].style[cssList[prop].key] = cssList[prop].val;\r\n                                    }\r\n                                }\r\n                                el.visPropOld[styleList[style] + '_' + node] = cssString;\r\n                            }\r\n                        }\r\n                        // el.visPropOld[styleList[style]] = cssString;\r\n                    }\r\n                }\r\n\r\n                fs = el.evalVisProp('fontsize');\r\n                if (el.visPropOld.fontsize !== fs) {\r\n                    el.needsSizeUpdate = true;\r\n                    try {\r\n                        for (node = 0; node < lenN; node++) {\r\n                            if (Type.exists(el[nodeList[node]])) {\r\n                                el[nodeList[node]].style.fontSize = fs + fontUnit;\r\n                            }\r\n                        }\r\n                    } catch (e) {\r\n                        // IE needs special treatment.\r\n                        for (node = 0; node < lenN; node++) {\r\n                            if (Type.exists(el[nodeList[node]])) {\r\n                                el[nodeList[node]].style.fontSize = fs;\r\n                            }\r\n                        }\r\n                    }\r\n                    el.visPropOld.fontsize = fs;\r\n                }\r\n            }\r\n\r\n            this.setTabindex(el);\r\n\r\n            this.setObjectTransition(el);\r\n            if (display === \"html\" && this.type !== 'no') {\r\n                // Set new CSS class\r\n                if (el.visPropOld.cssclass !== css) {\r\n                    el.rendNode.className = css;\r\n                    el.visPropOld.cssclass = css;\r\n                    el.needsSizeUpdate = true;\r\n                }\r\n                this.setObjectStrokeColor(el, sc, so);\r\n            } else {\r\n                this.updateInternalTextStyle(el, sc, so);\r\n            }\r\n\r\n            if (el.evalVisProp('aria.enabled')) {\r\n                this.setARIA(el);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set color and opacity of internal texts.\r\n         * This method is used for Canvas and VML.\r\n         * SVG needs its own version.\r\n         * @private\r\n         * @see JXG.AbstractRenderer#updateTextStyle\r\n         * @see JXG.SVGRenderer#updateInternalTextStyle\r\n         */\r\n        updateInternalTextStyle: function (el, strokeColor, strokeOpacity) {\r\n            this.setObjectStrokeColor(el, strokeColor, strokeOpacity);\r\n        },\r\n\r\n        /* ********* Image related stuff *********** */\r\n\r\n        /**\r\n         * Draws an {@link JXG.Image} on a board; This is just a template that has to be implemented by special\r\n         * renderers.\r\n         * @param {JXG.Image} el Reference to the image object that is to be drawn\r\n         * @see Image\r\n         * @see JXG.Image\r\n         * @see JXG.AbstractRenderer#updateImage\r\n         */\r\n        drawImage: function (el) { /* stub */ },\r\n\r\n        /**\r\n         * Updates the properties of an {@link JXG.Image} element.\r\n         * @param {JXG.Image} el Reference to an {@link JXG.Image} object, that has to be updated.\r\n         * @see Image\r\n         * @see JXG.Image\r\n         * @see JXG.AbstractRenderer#drawImage\r\n         */\r\n        updateImage: function (el) {\r\n            this.updateRectPrim(\r\n                el.rendNode,\r\n                el.coords.scrCoords[1],\r\n                el.coords.scrCoords[2] - el.size[1],\r\n                el.size[0],\r\n                el.size[1]\r\n            );\r\n\r\n            this.updateImageURL(el);\r\n            this.transformRect(el, el.transformations);\r\n            this._updateVisual(el, { stroke: true, dash: true }, true);\r\n        },\r\n\r\n        /**\r\n         * Multiplication of transformations without updating. That means, at that point it is expected that the\r\n         * matrices contain numbers only. First, the origin in user coords is translated to <tt>(0,0)</tt> in screen\r\n         * coords. Then, the stretch factors are divided out. After the transformations in user coords, the stretch\r\n         * factors are multiplied in again, and the origin in user coords is translated back to its position. This\r\n         * method does not have to be implemented in a new renderer.\r\n         * @param {JXG.GeometryElement} el A JSXGraph element. We only need its board property.\r\n         * @param {Array} transformations An array of JXG.Transformations.\r\n         * @returns {Array} A matrix represented by a two dimensional array of numbers.\r\n         * @see JXG.AbstractRenderer#transformRect\r\n         */\r\n        joinTransforms: function (el, transformations) {\r\n            var i,\r\n                ox = el.board.origin.scrCoords[1],\r\n                oy = el.board.origin.scrCoords[2],\r\n                ux = el.board.unitX,\r\n                uy = el.board.unitY,\r\n\r\n                len = transformations.length,\r\n                // Translate to 0,0 in screen coords and then scale\r\n                m = [\r\n                    [1, 0, 0],\r\n                    [-ox / ux, 1 / ux, 0],\r\n                    [oy / uy, 0, -1 / uy]\r\n                ];\r\n\r\n            for (i = 0; i < len; i++) {\r\n                m = Mat.matMatMult(transformations[i].matrix, m);\r\n            }\r\n            // Scale back and then translate back\r\n            m = Mat.matMatMult(\r\n                [\r\n                    [1, 0, 0],\r\n                    [ox, ux, 0],\r\n                    [oy, 0, -uy]\r\n                ],\r\n                m\r\n            );\r\n            return m;\r\n        },\r\n\r\n        /**\r\n         * Applies transformations on images and text elements. This method has to implemented in\r\n         * all descendant classes where text and image transformations are to be supported.\r\n         * <p>\r\n         * Only affine transformation are supported, no proper projective transformations. This means, the\r\n         * respective entries of the transformation matrix are simply ignored.\r\n         *\r\n         * @param {JXG.Image|JXG.Text} el A {@link JXG.Image} or {@link JXG.Text} object.\r\n         * @param {Array} transformations An array of {@link JXG.Transformation} objects. This is usually the\r\n         * transformations property of the given element <tt>el</tt>.\r\n         */\r\n        transformRect: function (el, transformations) { /* stub */ },\r\n\r\n        /**\r\n         * If the URL of the image is provided by a function the URL has to be updated during updateImage()\r\n         * @param {JXG.Image} el Reference to an image object.\r\n         * @see JXG.AbstractRenderer#updateImage\r\n         */\r\n        updateImageURL: function (el) { /* stub */ },\r\n\r\n        /**\r\n         * Updates CSS style properties of a {@link JXG.Image} node.\r\n         * In SVGRenderer opacity is the only available style element.\r\n         * This function is called by highlight() and nohighlight().\r\n         * This function works for VML.\r\n         * It does not work for Canvas.\r\n         * SVGRenderer overwrites this method.\r\n         * @param {JXG.Text} el Reference to the {@link JXG.Image} object, that has to be updated.\r\n         * @param {Boolean} doHighlight\r\n         * @see Image\r\n         * @see JXG.Image\r\n         * @see JXG.AbstractRenderer#highlight\r\n         * @see JXG.AbstractRenderer#noHighlight\r\n         */\r\n        updateImageStyle: function (el, doHighlight) {\r\n            el.rendNode.className = el.evalVisProp(\r\n                doHighlight ? 'highlightcssclass' : 'cssclass'\r\n            );\r\n        },\r\n\r\n        drawForeignObject: function (el) { /* stub */ },\r\n\r\n        updateForeignObject: function (el) {\r\n            /* stub */\r\n        },\r\n\r\n        /* ********* Render primitive objects *********** */\r\n\r\n        /**\r\n         * Appends a node to a specific layer level. This is just an abstract method and has to be implemented\r\n         * in all renderers that want to use the <tt>createPrim</tt> model to draw.\r\n         * @param {Node} node A DOM tree node.\r\n         * @param {Number} level The layer the node is attached to. This is the index of the layer in\r\n         * {@link JXG.SVGRenderer#layer} or the <tt>z-index</tt> style property of the node in VMLRenderer.\r\n         */\r\n        appendChildPrim: function (node, level) { /* stub */ },\r\n\r\n        /**\r\n         * Stores the rendering nodes. This is an abstract method which has to be implemented in all renderers that use\r\n         * the <tt>createPrim</tt> method.\r\n         * @param {JXG.GeometryElement} el A JSXGraph element.\r\n         * @param {String} type The XML node name. Only used in VMLRenderer.\r\n         */\r\n        appendNodesToElement: function (el, type) { /* stub */ },\r\n\r\n        /**\r\n         * Creates a node of a given type with a given id.\r\n         * @param {String} type The type of the node to create.\r\n         * @param {String} id Set the id attribute to this.\r\n         * @returns {Node} Reference to the created node.\r\n         */\r\n        createPrim: function (type, id) { /* stub */ return null; },\r\n\r\n        /**\r\n         * Removes an element node. Just a stub.\r\n         * @param {Node} node The node to remove.\r\n         */\r\n        remove: function (node) { /* stub */ },\r\n\r\n        /**\r\n         * Can be used to create the nodes to display arrows. This is an abstract method which has to be implemented\r\n         * in any descendant renderer.\r\n         * @param {JXG.GeometryElement} el The element the arrows are to be attached to.\r\n         * @param {Object} arrowData Data concerning possible arrow heads\r\n         *\r\n         */\r\n        makeArrows: function (el, arrowData) { /* stub */ },\r\n\r\n        /**\r\n         * Updates width of an arrow DOM node. Used in\r\n         * @param {Node} node The arrow node.\r\n         * @param {Number} width\r\n         * @param {Node} parentNode Used in IE only\r\n         */\r\n        _setArrowWidth: function (node, width, parentNode) { /* stub */ },\r\n\r\n        /**\r\n         * Updates an ellipse node primitive. This is an abstract method which has to be implemented in all renderers\r\n         * that use the <tt>createPrim</tt> method.\r\n         * @param {Node} node Reference to the node.\r\n         * @param {Number} x Centre X coordinate\r\n         * @param {Number} y Centre Y coordinate\r\n         * @param {Number} rx The x-axis radius.\r\n         * @param {Number} ry The y-axis radius.\r\n         */\r\n        updateEllipsePrim: function (node, x, y, rx, ry) { /* stub */ },\r\n\r\n        /**\r\n         * Refreshes a line node. This is an abstract method which has to be implemented in all renderers that use\r\n         * the <tt>createPrim</tt> method.\r\n         * @param {Node} node The node to be refreshed.\r\n         * @param {Number} p1x The first point's x coordinate.\r\n         * @param {Number} p1y The first point's y coordinate.\r\n         * @param {Number} p2x The second point's x coordinate.\r\n         * @param {Number} p2y The second point's y coordinate.\r\n         * @param {JXG.Board} board\r\n         */\r\n        updateLinePrim: function (node, p1x, p1y, p2x, p2y, board) { /* stub */ },\r\n\r\n        /**\r\n         * Updates a path element. This is an abstract method which has to be implemented in all renderers that use\r\n         * the <tt>createPrim</tt> method.\r\n         * @param {Node} node The path node.\r\n         * @param {String} pathString A string formatted like e.g. <em>'M 1,2 L 3,1 L5,5'</em>. The format of the string\r\n         * depends on the rendering engine.\r\n         * @param {JXG.Board} board Reference to the element's board.\r\n         */\r\n        updatePathPrim: function (node, pathString, board) { /* stub */ },\r\n\r\n        /**\r\n         * Builds a path data string to draw a point with a face other than <em>rect</em> and <em>circle</em>. Since\r\n         * the format of such a string usually depends on the renderer this method\r\n         * is only an abstract method. Therefore, it has to be implemented in the descendant renderer itself unless\r\n         * the renderer does not use the createPrim interface but the draw* interfaces to paint.\r\n         * @param {JXG.Point} el The point element\r\n         * @param {Number} size A positive number describing the size. Usually the half of the width and height of\r\n         * the drawn point.\r\n         * @param {String} type A string describing the point's face. This method only accepts the shortcut version of\r\n         * each possible face: <tt>x, +, |, -, [], <>, <<>>,^, v, >, < </tt>\r\n         */\r\n        updatePathStringPoint: function (el, size, type) { /* stub */ },\r\n\r\n        /**\r\n         * Builds a path data string from a {@link JXG.Curve} element. Since the path data strings heavily depend on the\r\n         * underlying rendering technique this method is just a stub. Although such a path string is of no use for the\r\n         * CanvasRenderer, this method is used there to draw a path directly.\r\n         * @param {JXG.GeometryElement} el\r\n         */\r\n        updatePathStringPrim: function (el) { /* stub */ },\r\n\r\n        /**\r\n         * Builds a path data string from a {@link JXG.Curve} element such that the curve looks like hand drawn. Since\r\n         * the path data strings heavily depend on the underlying rendering technique this method is just a stub.\r\n         * Although such a path string is of no use for the CanvasRenderer, this method is used there to draw a path\r\n         * directly.\r\n         * @param  {JXG.GeometryElement} el\r\n         */\r\n        updatePathStringBezierPrim: function (el) { /* stub */ },\r\n\r\n        /**\r\n         * Update a polygon primitive.\r\n         * @param {Node} node\r\n         * @param {JXG.Polygon} el A JSXGraph element of type {@link JXG.Polygon}\r\n         */\r\n        updatePolygonPrim: function (node, el) { /* stub */ },\r\n\r\n        /**\r\n         * Update a rectangle primitive. This is used only for points with face of type 'rect'.\r\n         * @param {Node} node The node yearning to be updated.\r\n         * @param {Number} x x coordinate of the top left vertex.\r\n         * @param {Number} y y coordinate of the top left vertex.\r\n         * @param {Number} w Width of the rectangle.\r\n         * @param {Number} h The rectangle's height.\r\n         */\r\n        updateRectPrim: function (node, x, y, w, h) { /* stub */ },\r\n\r\n        /* ********* Set attributes *********** */\r\n\r\n        /**\r\n         * Shows or hides an element on the canvas; Only a stub, requires implementation in the derived renderer.\r\n         * @param {JXG.GeometryElement} el Reference to the object that has to appear.\r\n         * @param {Boolean} value true to show the element, false to hide the element.\r\n         */\r\n        display: function (el, value) {\r\n            if (el) {\r\n                el.visPropOld.visible = value;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Hides an element on the canvas; Only a stub, requires implementation in the derived renderer.\r\n         *\r\n         * Please use JXG.AbstractRenderer#display instead\r\n         * @param {JXG.GeometryElement} el Reference to the geometry element that has to disappear.\r\n         * @see JXG.AbstractRenderer#show\r\n         * @deprecated\r\n         */\r\n        hide: function (el) { /* stub */ },\r\n\r\n        /**\r\n         * Highlights an object, i.e. changes the current colors of the object to its highlighting colors\r\n         * and highlighting strokewidth.\r\n         * @param {JXG.GeometryElement} el Reference of the object that will be highlighted.\r\n         * @param {Boolean} [suppressHighlightStrokeWidth=undefined] If undefined or false, highlighting also changes strokeWidth. This might not be\r\n         * the cases for polygon borders. Thus, if a polygon is highlighted, its polygon borders change strokeWidth only if the polygon attribute\r\n         * highlightByStrokeWidth == true.\r\n         * @returns {JXG.AbstractRenderer} Reference to the renderer\r\n         * @see JXG.AbstractRenderer#updateTextStyle\r\n         */\r\n        highlight: function (el, suppressHighlightStrokeWidth) {\r\n            var i, do_hl, sw;\r\n\r\n            this.setObjectTransition(el);\r\n            if (!el.visProp.draft) {\r\n                if (el.type === Const.OBJECT_TYPE_POLYGON) {\r\n                    this.setObjectFillColor(el, el.evalVisProp('highlightfillcolor'), el.evalVisProp('highlightfillopacity'));\r\n                    do_hl = el.evalVisProp('highlightbystrokewidth');\r\n                    for (i = 0; i < el.borders.length; i++) {\r\n                        this.highlight(el.borders[i], !do_hl);\r\n                    }\r\n                } else {\r\n                    if (el.elementClass === Const.OBJECT_CLASS_TEXT) {\r\n                        this.updateTextStyle(el, true);\r\n                    } else if (el.type === Const.OBJECT_TYPE_IMAGE) {\r\n                        this.updateImageStyle(el, true);\r\n                        this.setObjectFillColor(\r\n                            el,\r\n                            el.evalVisProp('highlightfillcolor'),\r\n                            el.evalVisProp('highlightfillopacity')\r\n                        );\r\n                    } else {\r\n                        this.setObjectStrokeColor(\r\n                            el,\r\n                            el.evalVisProp('highlightstrokecolor'),\r\n                            el.evalVisProp('highlightstrokeopacity')\r\n                        );\r\n                        this.setObjectFillColor(\r\n                            el,\r\n                            el.evalVisProp('highlightfillcolor'),\r\n                            el.evalVisProp('highlightfillopacity')\r\n                        );\r\n                    }\r\n                }\r\n\r\n                // Highlight strokeWidth is suppressed if\r\n                // parameter suppressHighlightStrokeWidth is false or undefined.\r\n                // suppressHighlightStrokeWidth is false if polygon attribute\r\n                // highlightbystrokewidth is true.\r\n                if (!suppressHighlightStrokeWidth && el.evalVisProp('highlightstrokewidth')) {\r\n                    sw = Math.max(\r\n                        el.evalVisProp('highlightstrokewidth'),\r\n                        el.evalVisProp('strokewidth')\r\n                    );\r\n                    this.setObjectStrokeWidth(el, sw);\r\n                    if (\r\n                        el.elementClass === Const.OBJECT_CLASS_LINE ||\r\n                        el.elementClass === Const.OBJECT_CLASS_CURVE\r\n                    ) {\r\n                        this.updatePathWithArrowHeads(el, true);\r\n                    }\r\n                }\r\n            }\r\n            this.setCssClass(el, el.evalVisProp('highlightcssclass'));\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Uses the normal colors of an object, i.e. the opposite of {@link JXG.AbstractRenderer#highlight}.\r\n         * @param {JXG.GeometryElement} el Reference of the object that will get its normal colors.\r\n         * @returns {JXG.AbstractRenderer} Reference to the renderer\r\n         * @see JXG.AbstractRenderer#updateTextStyle\r\n         */\r\n        noHighlight: function (el) {\r\n            var i, sw;\r\n\r\n            this.setObjectTransition(el);\r\n            if (!el.evalVisProp('draft')) {\r\n                if (el.type === Const.OBJECT_TYPE_POLYGON) {\r\n                    this.setObjectFillColor(el, el.evalVisProp('fillcolor'), el.evalVisProp('fillopacity'));\r\n                    for (i = 0; i < el.borders.length; i++) {\r\n                        this.noHighlight(el.borders[i]);\r\n                    }\r\n                } else {\r\n                    if (el.elementClass === Const.OBJECT_CLASS_TEXT) {\r\n                        this.updateTextStyle(el, false);\r\n                    } else if (el.type === Const.OBJECT_TYPE_IMAGE) {\r\n                        this.updateImageStyle(el, false);\r\n                        this.setObjectFillColor(el, el.evalVisProp('fillcolor'), el.evalVisProp('fillopacity'));\r\n                    } else {\r\n                        this.setObjectStrokeColor(el, el.evalVisProp('strokecolor'), el.evalVisProp('strokeopacity'));\r\n                        this.setObjectFillColor(el, el.evalVisProp('fillcolor'), el.evalVisProp('fillopacity'));\r\n                    }\r\n                }\r\n\r\n                sw = el.evalVisProp('strokewidth');\r\n                this.setObjectStrokeWidth(el, sw);\r\n                if (\r\n                    el.elementClass === Const.OBJECT_CLASS_LINE ||\r\n                    el.elementClass === Const.OBJECT_CLASS_CURVE\r\n                ) {\r\n                    this.updatePathWithArrowHeads(el, false);\r\n                }\r\n            }\r\n            this.setCssClass(el, el.evalVisProp('cssclass'));\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Puts an object from draft mode back into normal mode.\r\n         * @param {JXG.GeometryElement} el Reference of the object that no longer is in draft mode.\r\n         */\r\n        removeDraft: function (el) {\r\n            this.setObjectTransition(el);\r\n            if (el.type === Const.OBJECT_TYPE_POLYGON) {\r\n                this.setObjectFillColor(el, el.evalVisProp('fillcolor'), el.evalVisProp('fillopacity'));\r\n            } else {\r\n                if (el.type === Const.OBJECT_CLASS_POINT) {\r\n                    this.setObjectFillColor(el, el.evalVisProp('fillcolor'), el.evalVisProp('fillopacity'));\r\n                }\r\n                this.setObjectStrokeColor(el, el.evalVisProp('strokecolor'), el.evalVisProp('strokeopacity'));\r\n                this.setObjectStrokeWidth(el, el.evalVisProp('strokewidth'));\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Set ARIA related properties of an element. The attribute \"aria\" of an element contains at least the\r\n         * properties \"enabled\", \"label\", and \"live\". Additionally, all available properties from\r\n         * {@link https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA} may be set.\r\n         * <p>\r\n         * In JSXGraph, the available properties are used without the leading 'aria-'.\r\n         * For example, the value of the JSXGraph attribute 'aria.label' will be set to the\r\n         * HTML attribute 'aria-label'.\r\n         *\r\n         * @param {JXG.GeometryElement} el Reference of the object that wants new\r\n         *        ARIA attributes.\r\n         */\r\n        setARIA: function(el) { /* stub */ },\r\n\r\n        /**\r\n         * Sets the buffering as recommended by SVGWG. Until now only Opera supports this and will be ignored by other\r\n         * browsers. Although this feature is only supported by SVG we have this method in {@link JXG.AbstractRenderer}\r\n         * because it is called from outside the renderer.\r\n         * @param {Node} node The SVG DOM Node which buffering type to update.\r\n         * @param {String} type Either 'auto', 'dynamic', or 'static'. For an explanation see\r\n         *   {@link https://www.w3.org/TR/SVGTiny12/painting.html#BufferedRenderingProperty}.\r\n         */\r\n        setBuffering: function (node, type) { /* stub */ },\r\n\r\n        /**\r\n         * Sets CSS classes for elements (relevant for SVG only).\r\n         *\r\n         * @param {JXG.GeometryElement} el Reference of the object that wants a\r\n         *         new set of CSS classes.\r\n         * @param {String} cssClass String containing a space separated list of CSS classes.\r\n         */\r\n        setCssClass: function (el, cssClass) { /* stub */ },\r\n\r\n        /**\r\n         * Sets an element's dash style.\r\n         * @param {JXG.GeometryElement} el An JSXGraph element.\r\n         */\r\n        setDashStyle: function (el) { /* stub */ },\r\n\r\n        /**\r\n         * Puts an object into draft mode, i.e. it's visual appearance will be changed. For GEONE<sub>x</sub>T backwards\r\n         * compatibility.\r\n         * @param {JXG.GeometryElement} el Reference of the object that is in draft mode.\r\n         */\r\n        setDraft: function (el) {\r\n            if (!el.evalVisProp('draft')) {\r\n                return;\r\n            }\r\n            var draftColor = el.board.options.elements.draft.color,\r\n                draftOpacity = el.board.options.elements.draft.opacity;\r\n\r\n                this.setObjectTransition(el);\r\n            if (el.type === Const.OBJECT_TYPE_POLYGON) {\r\n                this.setObjectFillColor(el, draftColor, draftOpacity);\r\n            } else {\r\n                if (el.elementClass === Const.OBJECT_CLASS_POINT) {\r\n                    this.setObjectFillColor(el, draftColor, draftOpacity);\r\n                } else {\r\n                    this.setObjectFillColor(el, \"none\", 0);\r\n                }\r\n                this.setObjectStrokeColor(el, draftColor, draftOpacity);\r\n                this.setObjectStrokeWidth(el, el.board.options.elements.draft.strokeWidth);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Sets up nodes for rendering a gradient fill.\r\n         * @param {JXG.GeometryElement}  el Reference of the object which gets the gradient\r\n         */\r\n        setGradient: function (el) { /* stub */ },\r\n\r\n        /**\r\n         * Move element into new layer. This is trivial for canvas, but needs more effort in SVG.\r\n         * Does not work dynamically, i.e. if level is a function.\r\n         *\r\n         * @param {JXG.GeometryElement} el Element which is put into different layer\r\n         * @param {Number} value Layer number\r\n         * @private\r\n         */\r\n        setLayer: function (el, level) { /* stub */ },\r\n\r\n        /**\r\n         * Sets an objects fill color.\r\n         * @param {JXG.GeometryElement} el Reference of the object that wants a new fill color.\r\n         * @param {String} color Color in a HTML/CSS compatible format. If you don't want any fill color at all, choose\r\n         * 'none'.\r\n         * @param {Number} opacity Opacity of the fill color. Must be between 0 and 1.\r\n         */\r\n        setObjectFillColor: function (el, color, opacity) { /* stub */ },\r\n\r\n        /**\r\n         * Changes an objects stroke color to the given color.\r\n         * @param {JXG.GeometryElement} el Reference of the {@link JXG.GeometryElement} that gets a new stroke\r\n         * color.\r\n         * @param {String} color Color value in a HTML compatible format, e.g. <strong>#00ff00</strong> or\r\n         * <strong>green</strong> for green.\r\n         * @param {Number} opacity Opacity of the fill color. Must be between 0 and 1.\r\n         */\r\n        setObjectStrokeColor: function (el, color, opacity) { /* stub */ },\r\n\r\n        /**\r\n         * Sets an element's stroke width.\r\n         * @param {JXG.GeometryElement} el Reference to the geometry element.\r\n         * @param {Number} width The new stroke width to be assigned to the element.\r\n         */\r\n        setObjectStrokeWidth: function (el, width) { /* stub */ },\r\n\r\n        /**\r\n         * Sets the transition duration (in milliseconds) for fill color and stroke\r\n         * color and opacity.\r\n         * @param {JXG.GeometryElement} el Reference of the object that wants a\r\n         *         new transition duration.\r\n         * @param {Number} duration (Optional) duration in milliseconds. If not given,\r\n         *        element.visProp.transitionDuration is taken. This is the default.\r\n         */\r\n        setObjectTransition: function (el, duration) { /* stub */ },\r\n\r\n        /**\r\n         * Sets a node's attribute.\r\n         * @param {Node} node The node that is to be updated.\r\n         * @param {String} key Name of the attribute.\r\n         * @param {String} val New value for the attribute.\r\n         */\r\n        setPropertyPrim: function (node, key, val) { /* stub */ },\r\n\r\n        /**\r\n         * Sets the shadow properties to a geometry element. This method is only a stub, it is implemented in the actual\r\n         * renderers.\r\n         * @param {JXG.GeometryElement} el Reference to a geometry object, that should get a shadow\r\n         */\r\n        setShadow: function (el) { /* stub */ },\r\n\r\n        /**\r\n         * Set the attribute `tabindex` to the attribute `tabindex` of an element.\r\n         * This is only relevant for the SVG renderer.\r\n         *\r\n         * @param {JXG.GeometryElement} el\r\n         */\r\n        setTabindex: function (el) { /* stub */ },\r\n\r\n        /**\r\n         * Shows a hidden element on the canvas; Only a stub, requires implementation in the derived renderer.\r\n         *\r\n         * Please use JXG.AbstractRenderer#display instead\r\n         * @param {JXG.GeometryElement} el Reference to the object that has to appear.\r\n         * @see JXG.AbstractRenderer#hide\r\n         * @deprecated\r\n         */\r\n        show: function (el) { /* stub */ },\r\n\r\n        /**\r\n         * Updates the gradient fill.\r\n         * @param {JXG.GeometryElement} el An JSXGraph element with an area that can be filled.\r\n         */\r\n        updateGradient: function (el) { /* stub */ },\r\n\r\n        /* ********* Renderer control *********** */\r\n\r\n        /**\r\n         * Stop redraw. This method is called before every update, so a non-vector-graphics based renderer can use this\r\n         * method to delete the contents of the drawing panel. This is an abstract method every descendant renderer\r\n         * should implement, if appropriate.\r\n         * @see JXG.AbstractRenderer#unsuspendRedraw\r\n         */\r\n        suspendRedraw: function () { /* stub */ },\r\n\r\n        /**\r\n         * Restart redraw. This method is called after updating all the rendering node attributes.\r\n         * @see JXG.AbstractRenderer#suspendRedraw\r\n         */\r\n        unsuspendRedraw: function () { /* stub */ },\r\n\r\n        /**\r\n         * The tiny zoom bar shown on the bottom of a board (if board attribute \"showNavigation\" is true).\r\n         * It is a div element and gets the CSS class \"JXG_navigation\" and the id {board id}_navigationbar.\r\n         * <p>\r\n         * The buttons get the CSS class \"JXG_navigation_button\" and the id {board_id}_name where name is\r\n         * one of [top, down, left, right, out, 100, in, fullscreen, screenshot, reload, cleartraces].\r\n         * <p>\r\n         * The symbols for zoom, navigation and reload are hard-coded.\r\n         *\r\n         * @param {JXG.Board} board Reference to a JSXGraph board.\r\n         * @param {Object} attr Attributes of the navigation bar\r\n         * @private\r\n         */\r\n        drawNavigationBar: function (board, attr) {\r\n            var doc,\r\n                node,\r\n                cancelbubble = function (e) {\r\n                    if (!e) {\r\n                        e = window.event;\r\n                    }\r\n\r\n                    if (e.stopPropagation) {\r\n                        // Non IE<=8\r\n                        e.stopPropagation();\r\n                    } else {\r\n                        e.cancelBubble = true;\r\n                    }\r\n                },\r\n                createButton = function (label, handler, board_id, type) {\r\n                    var button;\r\n\r\n                    board_id = board_id || \"\";\r\n\r\n                    button = doc.createElement('span');\r\n                    button.innerHTML = label; // button.appendChild(doc.createTextNode(label));\r\n\r\n                    // Style settings are superseded by adding the CSS class below\r\n                    button.style.paddingLeft = '7px';\r\n                    button.style.paddingRight = '7px';\r\n\r\n                    if (button.classList !== undefined) {\r\n                        // classList not available in IE 9\r\n                        button.classList.add(\"JXG_navigation_button\");\r\n                        button.classList.add(\"JXG_navigation_button_\" + type);\r\n                    }\r\n                    // button.setAttribute('tabindex', 0);\r\n\r\n                    button.setAttribute(\"id\", board_id + '_navigation_' + type);\r\n                    button.setAttribute(\"aria-hidden\", 'true');   // navigation buttons should never appear in screen reader\r\n\r\n                    node.appendChild(button);\r\n\r\n                    Env.addEvent(\r\n                        button,\r\n                        \"click\",\r\n                        function (e) {\r\n                            Type.bind(handler, board)();\r\n                            return false;\r\n                        },\r\n                        board\r\n                    );\r\n                    // prevent the click from bubbling down to the board\r\n                    Env.addEvent(button, \"pointerup\", cancelbubble, board);\r\n                    Env.addEvent(button, \"pointerdown\", cancelbubble, board);\r\n                    Env.addEvent(button, \"pointerleave\", cancelbubble, board);\r\n                    Env.addEvent(button, \"mouseup\", cancelbubble, board);\r\n                    Env.addEvent(button, \"mousedown\", cancelbubble, board);\r\n                    Env.addEvent(button, \"touchend\", cancelbubble, board);\r\n                    Env.addEvent(button, \"touchstart\", cancelbubble, board);\r\n                };\r\n\r\n            if (Env.isBrowser && this.type !== 'no') {\r\n                doc = board.containerObj.ownerDocument;\r\n                node = doc.createElement('div');\r\n\r\n                node.setAttribute(\"id\", board.container + \"_navigationbar\");\r\n\r\n                // Style settings are superseded by adding the CSS class below\r\n                node.style.color = attr.strokecolor;\r\n                node.style.backgroundColor = attr.fillcolor;\r\n                node.style.padding = attr.padding;\r\n                node.style.position = attr.position;\r\n                node.style.fontSize = attr.fontsize;\r\n                node.style.cursor = attr.cursor;\r\n                node.style.zIndex = attr.zindex;\r\n                board.containerObj.appendChild(node);\r\n                node.style.right = attr.right;\r\n                node.style.bottom = attr.bottom;\r\n\r\n                if (node.classList !== undefined) {\r\n                    // classList not available in IE 9\r\n                    node.classList.add(\"JXG_navigation\");\r\n                }\r\n                // For XHTML we need unicode instead of HTML entities\r\n\r\n                if (board.attr.showfullscreen) {\r\n                    createButton(\r\n                        board.attr.fullscreen.symbol,\r\n                        function () {\r\n                            board.toFullscreen(board.attr.fullscreen.id);\r\n                        },\r\n                        board.container, \"fullscreen\"\r\n                    );\r\n                }\r\n\r\n                if (board.attr.showscreenshot) {\r\n                    createButton(\r\n                        board.attr.screenshot.symbol,\r\n                        function () {\r\n                            window.setTimeout(function () {\r\n                                board.renderer.screenshot(board, \"\", false);\r\n                            }, 330);\r\n                        },\r\n                        board.container, \"screenshot\"\r\n                    );\r\n                }\r\n\r\n                if (board.attr.showreload) {\r\n                    // full reload circle: \\u27F2\r\n                    // the board.reload() method does not exist during the creation\r\n                    // of this button. That's why this anonymous function wrapper is required.\r\n                    createButton(\r\n                        \"\\u21BB\",\r\n                        function () {\r\n                            board.reload();\r\n                        },\r\n                        board.container, \"reload\"\r\n                    );\r\n                }\r\n\r\n                if (board.attr.showcleartraces) {\r\n                    // clear traces symbol (otimes): \\u27F2\r\n                    createButton(\"\\u2297\",\r\n                        function () {\r\n                            board.clearTraces();\r\n                        },\r\n                        board.container, \"cleartraces\"\r\n                    );\r\n                }\r\n\r\n                if (board.attr.shownavigation) {\r\n                    if (board.attr.showzoom) {\r\n                        createButton(\"\\u2013\", board.zoomOut, board.container, 'out');\r\n                        createButton(\"o\", board.zoom100, board.container, '100');\r\n                        createButton(\"+\", board.zoomIn, board.container, 'in');\r\n                    }\r\n                    createButton(\"\\u2190\", board.clickLeftArrow, board.container, 'left');\r\n                    createButton(\"\\u2193\", board.clickUpArrow, board.container, 'down'); // Down arrow\r\n                    createButton(\"\\u2191\", board.clickDownArrow, board.container, 'up'); // Up arrow\r\n                    createButton(\"\\u2192\", board.clickRightArrow, board.container, 'right');\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Wrapper for getElementById for maybe other renderers which elements are not directly accessible by DOM\r\n         * methods like document.getElementById().\r\n         * @param {String} id Unique identifier for element.\r\n         * @returns {Object} Reference to a JavaScript object. In case of SVG/VMLRenderer it's a reference to a SVG/VML node.\r\n         */\r\n        getElementById: function (id) {\r\n            var str;\r\n            if (Type.exists(this.container)) {\r\n                // Use querySelector over getElementById for compatibility with both 'regular' document\r\n                // and ShadowDOM fragments.\r\n                str = this.container.id + '_' + id;\r\n                // Mask special symbols like '/' and '\\' in id\r\n                if (Type.exists(CSS) && Type.exists(CSS.escape)) {\r\n                    str = CSS.escape(str);\r\n                }\r\n                return this.container.querySelector('#' + str);\r\n            }\r\n            return \"\";\r\n        },\r\n\r\n        /**\r\n         * Remove an element and provide a function that inserts it into its original position. This method\r\n         * is taken from this article {@link https://developers.google.com/speed/articles/javascript-dom}.\r\n         * @author KeeKim Heng, Google Web Developer\r\n         * @param {Element} el The element to be temporarily removed\r\n         * @returns {Function} A function that inserts the element into its original position\r\n         */\r\n        removeToInsertLater: function (el) {\r\n            var parentNode = el.parentNode,\r\n                nextSibling = el.nextSibling;\r\n\r\n            if (parentNode === null) {\r\n                return;\r\n            }\r\n            parentNode.removeChild(el);\r\n\r\n            return function () {\r\n                if (nextSibling) {\r\n                    parentNode.insertBefore(el, nextSibling);\r\n                } else {\r\n                    parentNode.appendChild(el);\r\n                }\r\n            };\r\n        },\r\n\r\n        /**\r\n         * Resizes the rendering element\r\n         * @param {Number} w New width\r\n         * @param {Number} h New height\r\n         */\r\n        resize: function (w, h) { /* stub */ },\r\n\r\n        /**\r\n         * Create crosshair elements (Fadenkreuz) for presentations.\r\n         * @param {Number} n Number of crosshairs.\r\n         */\r\n        createTouchpoints: function (n) { /* stub */ },\r\n\r\n        /**\r\n         * Show a specific crosshair.\r\n         * @param {Number} i Number of the crosshair to show\r\n         */\r\n        showTouchpoint: function (i) { /* stub */ },\r\n\r\n        /**\r\n         * Hide a specific crosshair.\r\n         * @param {Number} i Number of the crosshair to show\r\n         */\r\n        hideTouchpoint: function (i) { /* stub */ },\r\n\r\n        /**\r\n         * Move a specific crosshair.\r\n         * @param {Number} i Number of the crosshair to show\r\n         * @param {Array} pos New positon in screen coordinates\r\n         */\r\n        updateTouchpoint: function (i, pos) { /* stub */ },\r\n\r\n        /* ********* Dump related stuff *********** */\r\n\r\n        /**\r\n         * Convert SVG construction to base64 encoded SVG data URL.\r\n         * Only available on SVGRenderer.\r\n         *\r\n         * @see JXG.SVGRenderer#dumpToDataURI\r\n         */\r\n        dumpToDataURI: function (_ignoreTexts) { /* stub */ },\r\n\r\n        /**\r\n         * Convert SVG construction to canvas.\r\n         * Only available on SVGRenderer.\r\n         *\r\n         * @see JXG.SVGRenderer#dumpToCanvas\r\n         */\r\n        dumpToCanvas: function (canvasId, w, h, _ignoreTexts) { /* stub */ },\r\n\r\n        /**\r\n         * Display SVG image in html img-tag which enables\r\n         * easy download for the user.\r\n         *\r\n         * See JXG.SVGRenderer#screenshot\r\n         */\r\n        screenshot: function (board) { /* stub */ }\r\n\r\n    }\r\n);\r\n\r\nexport default JXG.AbstractRenderer;\r\n","/*global JXG: true, define: true, escape: true, unescape: true*/\r\n/*jslint nomen: true, plusplus: true, bitwise: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\n\r\n// constants\r\nvar UTF8_ACCEPT = 0,\r\n    // UTF8_REJECT = 12,\r\n    UTF8D = [\r\n        // The first part of the table maps bytes to character classes that\r\n        // to reduce the size of the transition table and create bitmasks.\r\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\r\n        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9,\r\n        9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,\r\n        7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2,\r\n        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 10, 3, 3, 3, 3, 3, 3, 3,\r\n        3, 3, 3, 3, 3, 4, 3, 3, 11, 6, 6, 6, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,\r\n\r\n        // The second part is a transition table that maps a combination\r\n        // of a state of the automaton and a character class to a state.\r\n        0, 12, 24, 36, 60, 96, 84, 12, 12, 12, 48, 72, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,\r\n        12, 12, 12, 0, 12, 12, 12, 12, 12, 0, 12, 0, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12,\r\n        24, 12, 12, 12, 12, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12, 24, 12, 12, 12, 12, 12,\r\n        12, 12, 24, 12, 12, 12, 12, 12, 12, 12, 12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12,\r\n        12, 12, 36, 12, 36, 12, 12, 12, 36, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12\r\n    ];\r\n\r\n// Util namespace\r\nJXG.Util = JXG.Util || {};\r\n\r\n/**\r\n * UTF8 encoding routines\r\n * @namespace\r\n */\r\nJXG.Util.UTF8 = {\r\n    /**\r\n     * Encode a string to utf-8.\r\n     * @param {String} string\r\n     * @returns {String} utf8 encoded string\r\n     */\r\n    encode: function (string) {\r\n        var n,\r\n            c,\r\n            utftext = \"\",\r\n            len = string.length;\r\n\r\n        string = string.replace(/\\r\\n/g, \"\\n\");\r\n\r\n        // See\r\n        // http://ecmanaut.blogspot.ca/2006/07/encoding-decoding-utf8-in-javascript.html\r\n        if (typeof unescape === \"function\" && typeof encodeURIComponent === 'function') {\r\n            return unescape(encodeURIComponent(string));\r\n        }\r\n\r\n        for (n = 0; n < len; n++) {\r\n            c = string.charCodeAt(n);\r\n\r\n            if (c < 128) {\r\n                utftext += String.fromCharCode(c);\r\n            } else if (c > 127 && c < 2048) {\r\n                utftext += String.fromCharCode((c >> 6) | 192);\r\n                utftext += String.fromCharCode((c & 63) | 128);\r\n            } else {\r\n                utftext += String.fromCharCode((c >> 12) | 224);\r\n                utftext += String.fromCharCode(((c >> 6) & 63) | 128);\r\n                utftext += String.fromCharCode((c & 63) | 128);\r\n            }\r\n        }\r\n\r\n        return utftext;\r\n    },\r\n\r\n    /**\r\n     * Decode a string from utf-8.\r\n     * @param {String} utftext to decode\r\n     * @returns {String} utf8 decoded string\r\n     */\r\n    decode: function (utftext) {\r\n        /*\r\n                 The following code is a translation from C99 to JavaScript.\r\n\r\n                 The original C99 code can be found at\r\n                    https://bjoern.hoehrmann.de/utf-8/decoder/dfa/\r\n\r\n                 Original copyright note:\r\n\r\n                 Copyright (c) 2008-2009 Bjoern Hoehrmann <bjoern@hoehrmann.de>\r\n\r\n                 License: MIT License (see LICENSE.MIT)\r\n            */\r\n\r\n        var i,\r\n            charCode,\r\n            type,\r\n            j = 0,\r\n            codepoint = 0,\r\n            state = UTF8_ACCEPT,\r\n            chars = [],\r\n            len = utftext.length,\r\n            results = [];\r\n\r\n        for (i = 0; i < len; i++) {\r\n            charCode = utftext.charCodeAt(i);\r\n            type = UTF8D[charCode];\r\n\r\n            if (state !== UTF8_ACCEPT) {\r\n                codepoint = (charCode & 0x3f) | (codepoint << 6);\r\n            } else {\r\n                codepoint = (0xff >> type) & charCode;\r\n            }\r\n\r\n            state = UTF8D[256 + state + type];\r\n\r\n            if (state === UTF8_ACCEPT) {\r\n                if (codepoint > 0xffff) {\r\n                    chars.push(0xd7c0 + (codepoint >> 10), 0xdc00 + (codepoint & 0x3ff));\r\n                } else {\r\n                    chars.push(codepoint);\r\n                }\r\n\r\n                j++;\r\n\r\n                if (j % 10000 === 0) {\r\n                    results.push(String.fromCharCode.apply(null, chars));\r\n                    chars = [];\r\n                }\r\n            }\r\n        }\r\n        results.push(String.fromCharCode.apply(null, chars));\r\n        return results.join(\"\");\r\n    },\r\n\r\n    /**\r\n     * Extends the standard charCodeAt() method of the String class to find the ASCII char code of\r\n     * a character at a given position in a UTF8 encoded string.\r\n     * @param {String} str\r\n     * @param {Number} i position of the character\r\n     * @returns {Number}\r\n     */\r\n    asciiCharCodeAt: function (str, i) {\r\n        var c = str.charCodeAt(i);\r\n\r\n        if (c > 255) {\r\n            switch (c) {\r\n                case 8364:\r\n                    c = 128;\r\n                    break;\r\n                case 8218:\r\n                    c = 130;\r\n                    break;\r\n                case 402:\r\n                    c = 131;\r\n                    break;\r\n                case 8222:\r\n                    c = 132;\r\n                    break;\r\n                case 8230:\r\n                    c = 133;\r\n                    break;\r\n                case 8224:\r\n                    c = 134;\r\n                    break;\r\n                case 8225:\r\n                    c = 135;\r\n                    break;\r\n                case 710:\r\n                    c = 136;\r\n                    break;\r\n                case 8240:\r\n                    c = 137;\r\n                    break;\r\n                case 352:\r\n                    c = 138;\r\n                    break;\r\n                case 8249:\r\n                    c = 139;\r\n                    break;\r\n                case 338:\r\n                    c = 140;\r\n                    break;\r\n                case 381:\r\n                    c = 142;\r\n                    break;\r\n                case 8216:\r\n                    c = 145;\r\n                    break;\r\n                case 8217:\r\n                    c = 146;\r\n                    break;\r\n                case 8220:\r\n                    c = 147;\r\n                    break;\r\n                case 8221:\r\n                    c = 148;\r\n                    break;\r\n                case 8226:\r\n                    c = 149;\r\n                    break;\r\n                case 8211:\r\n                    c = 150;\r\n                    break;\r\n                case 8212:\r\n                    c = 151;\r\n                    break;\r\n                case 732:\r\n                    c = 152;\r\n                    break;\r\n                case 8482:\r\n                    c = 153;\r\n                    break;\r\n                case 353:\r\n                    c = 154;\r\n                    break;\r\n                case 8250:\r\n                    c = 155;\r\n                    break;\r\n                case 339:\r\n                    c = 156;\r\n                    break;\r\n                case 382:\r\n                    c = 158;\r\n                    break;\r\n                case 376:\r\n                    c = 159;\r\n                    break;\r\n                default:\r\n                    break;\r\n            }\r\n        }\r\n        return c;\r\n    }\r\n};\r\n\r\nexport default JXG.Util.UTF8;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true, bitwise: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Encoding from \"./encoding.js\";\r\n\r\nvar alphabet = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\",\r\n    pad = \"=\";\r\n\r\n// Util namespace\r\nJXG.Util = JXG.Util || {};\r\n\r\n/**\r\n * Base64 routines\r\n * @namespace\r\n */\r\nJXG.Util.Base64 = {\r\n    // Local helper functions\r\n    /**\r\n     * Extracts one byte from a string and ensures the result is less than or equal to 255.\r\n     * @param {String} s\r\n     * @param {Number} i\r\n     * @returns {Number} <= 255\r\n     * @private\r\n     */\r\n    _getByte: function(s, i) {\r\n        return s.charCodeAt(i) & 0xff;\r\n    },\r\n\r\n    /**\r\n     * Determines the index of a base64 character in the base64 alphabet.\r\n     * @param {String} s\r\n     * @param {Number} i\r\n     * @returns {Number}\r\n     * @throws {Error} If the character can not be found in the alphabet.\r\n     * @private\r\n     */\r\n    _getIndex: function(s, i) {\r\n        return alphabet.indexOf(s.charAt(i));\r\n    },\r\n\r\n    /**\r\n     * Encode the given string.\r\n     * @param {String} input\r\n     * @returns {string} base64 encoded version of the input string.\r\n     */\r\n    encode: function (input) {\r\n        var i,\r\n            bin,\r\n            len,\r\n            padLen,\r\n            encInput,\r\n            buffer = [];\r\n\r\n        encInput = Encoding.encode(input);\r\n        len = encInput.length;\r\n        padLen = len % 3;\r\n\r\n        for (i = 0; i < len - padLen; i += 3) {\r\n            bin =\r\n                (this._getByte(encInput, i) << 16) |\r\n                (this._getByte(encInput, i + 1) << 8) |\r\n                this._getByte(encInput, i + 2);\r\n            buffer.push(\r\n                alphabet.charAt(bin >> 18),\r\n                alphabet.charAt((bin >> 12) & 63),\r\n                alphabet.charAt((bin >> 6) & 63),\r\n                alphabet.charAt(bin & 63)\r\n            );\r\n        }\r\n\r\n        switch (padLen) {\r\n            case 1:\r\n                bin = this._getByte(encInput, len - 1);\r\n                buffer.push(\r\n                    alphabet.charAt(bin >> 2),\r\n                    alphabet.charAt((bin << 4) & 63),\r\n                    pad,\r\n                    pad\r\n                );\r\n                break;\r\n            case 2:\r\n                bin = (this._getByte(encInput, len - 2) << 8) | this._getByte(encInput, len - 1);\r\n                buffer.push(\r\n                    alphabet.charAt(bin >> 10),\r\n                    alphabet.charAt((bin >> 4) & 63),\r\n                    alphabet.charAt((bin << 2) & 63),\r\n                    pad\r\n                );\r\n                break;\r\n        }\r\n\r\n        return buffer.join(\"\");\r\n    },\r\n\r\n    /**\r\n     * Decode from Base64\r\n     * @param {String} input Base64 encoded data\r\n     * @param {Boolean} utf8 In case this parameter is true {@link JXG.Util.UTF8.decode} will be applied to\r\n     * the result of the base64 decoder.\r\n     * @throws {Error} If the string has the wrong length.\r\n     * @returns {String}\r\n     */\r\n    decode: function (input, utf8) {\r\n        var encInput,\r\n            i,\r\n            len,\r\n            padLen,\r\n            bin,\r\n            output,\r\n            result = [],\r\n            buffer = [];\r\n\r\n        // deactivate regexp linting. Our regex is secure, because we replace everything with ''\r\n        /*jslint regexp:true*/\r\n        encInput = input.replace(/[^A-Za-z0-9+/=]/g, \"\");\r\n        /*jslint regexp:false*/\r\n\r\n        len = encInput.length;\r\n\r\n        if (len % 4 !== 0) {\r\n            throw new Error(\r\n                \"JSXGraph/utils/base64: Can't decode string (invalid input length).\"\r\n            );\r\n        }\r\n\r\n        if (encInput.charAt(len - 1) === pad) {\r\n            padLen = 1;\r\n\r\n            if (encInput.charAt(len - 2) === pad) {\r\n                padLen = 2;\r\n            }\r\n\r\n            // omit the last four bytes (taken care of after the for loop)\r\n            len -= 4;\r\n        }\r\n\r\n        for (i = 0; i < len; i += 4) {\r\n            bin =\r\n                (this._getIndex(encInput, i) << 18) |\r\n                (this._getIndex(encInput, i + 1) << 12) |\r\n                (this._getIndex(encInput, i + 2) << 6) |\r\n                this._getIndex(encInput, i + 3);\r\n            buffer.push(bin >> 16, (bin >> 8) & 255, bin & 255);\r\n\r\n            // flush the buffer, if it gets too big fromCharCode will crash\r\n            if (i % 10000 === 0) {\r\n                result.push(String.fromCharCode.apply(null, buffer));\r\n                buffer = [];\r\n            }\r\n        }\r\n\r\n        switch (padLen) {\r\n            case 1:\r\n                bin =\r\n                    (this._getIndex(encInput, len) << 12) |\r\n                    (this._getIndex(encInput, len + 1) << 6) |\r\n                    this._getIndex(encInput, len + 2);\r\n                buffer.push(bin >> 10, (bin >> 2) & 255);\r\n                break;\r\n\r\n            case 2:\r\n                bin = (this._getIndex(encInput, i) << 6) | this._getIndex(encInput, i + 1);\r\n                buffer.push(bin >> 4);\r\n                break;\r\n        }\r\n\r\n        result.push(String.fromCharCode.apply(null, buffer));\r\n        output = result.join(\"\");\r\n\r\n        if (utf8) {\r\n            output = Encoding.decode(output);\r\n        }\r\n\r\n        return output;\r\n    },\r\n\r\n    /**\r\n     * Decode the base64 input data as an array\r\n     * @param {string} input\r\n     * @returns {Array}\r\n     */\r\n    decodeAsArray: function (input) {\r\n        var i,\r\n            dec = this.decode(input),\r\n            ar = [],\r\n            len = dec.length;\r\n\r\n        for (i = 0; i < len; i++) {\r\n            ar[i] = dec.charCodeAt(i);\r\n        }\r\n\r\n        return ar;\r\n    }\r\n};\r\n\r\nexport default JXG.Util.Base64;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG:true, define: true, ActiveXObject:true, jxgBinFileReader:true, DOMParser:true, XMLHttpRequest:true, document:true, navigator:true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Env from \"../utils/env.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Encoding from \"../utils/encoding.js\";\r\nimport Base64 from \"../utils/base64.js\";\r\n\r\n/**\r\n * The FileReader object bundles the file input capabilities of JSXGraph.\r\n */\r\nJXG.FileReader = {\r\n    /**\r\n     *\r\n     * @param {String} url\r\n     * @param {JXG.Board} board\r\n     * @param {String} format\r\n     * @param {Boolean} async\r\n     * @param {Function} callback\r\n     *\r\n     * @private\r\n     */\r\n    handleRemoteFile: function (url, board, format, async, encoding, callback) {\r\n        var request = false;\r\n\r\n        try {\r\n            request = new XMLHttpRequest();\r\n            if (format.toLowerCase() === 'raw') {\r\n                request.overrideMimeType(\"text/plain; charset=\" + encoding);\r\n            } else {\r\n                request.overrideMimeType(\"text/xml; charset=\" + encoding);\r\n            }\r\n        } catch (e) {\r\n            try {\r\n                request = new ActiveXObject('Msxml2.XMLHTTP');\r\n            } catch (ex) {\r\n                try {\r\n                    request = new ActiveXObject('Microsoft.XMLHTTP');\r\n                } catch (exc) {\r\n                    request = false;\r\n                }\r\n            }\r\n        }\r\n        if (!request) {\r\n            JXG.debug(\"AJAX not activated!\");\r\n            return;\r\n        }\r\n\r\n        request.open(\"GET\", url, async);\r\n        if (format.toLowerCase() === 'raw') {\r\n            this.cbp = function () {\r\n                var req = request;\r\n                if (req.readyState === 4) {\r\n                    board(req.responseText);\r\n                }\r\n            };\r\n        } else {\r\n            this.cbp = function () {\r\n                var req = request,\r\n                    text = \"\";\r\n\r\n                if (req.readyState === 4) {\r\n                    // Hack for ancient IEs:\r\n                    // We use the Visual Basic stuff from below.\r\n                    if (\r\n                        Type.exists(req.responseStream) &&\r\n                        // PK: zip, geogebra\r\n                        // 31: gzip, cinderella\r\n                        (req.responseText.slice(0, 2) === \"PK\" ||\r\n                            Encoding.asciiCharCodeAt(req.responseText.slice(0, 1), 0) === 31)\r\n                    ) {\r\n                        // After this, text contains the binary? zip-compressed string\r\n                        text = Base64.decode(jxgBinFileReader(req));\r\n                    } else {\r\n                        // This is for all browsers except ancient IEs.\r\n                        text = req.responseText;\r\n                        // console.log(text);\r\n                    }\r\n                    this.parseString(text, board, format, callback);\r\n                }\r\n            };\r\n        }\r\n\r\n        this.cb = Type.bind(this.cbp, this);\r\n        // Old style\r\n        request.onreadystatechange = this.cb;\r\n\r\n        try {\r\n            request.send(null);\r\n        } catch (ex2) {\r\n            throw new Error(\r\n                \"JSXGraph: A problem occurred while trying to read remote file '\" + url + \"'.\"\r\n            );\r\n        }\r\n    },\r\n\r\n    /**\r\n     *\r\n     * @param {Blob} url The Blob or File from which to read\r\n     * @param {JXG.Board} board\r\n     * @param {String} format\r\n     * @param {Boolean} async\r\n     * @param {Function} callback\r\n     *\r\n     * @private\r\n     */\r\n    handleLocalFile: function (url, board, format, async, encoding, callback) {\r\n        if (!Type.exists(async)) {\r\n            async = true;\r\n        }\r\n\r\n        if (format.toLowerCase() === 'raw') {\r\n            this.cbp = function (e) {\r\n                board(e.target.result);\r\n            };\r\n        } else {\r\n            this.cbp = function (e) {\r\n                var text = e.target.result;\r\n                //console.log(text);\r\n                this.parseString(text, board, format, callback);\r\n            };\r\n        }\r\n\r\n        this.cb = Type.bind(this.cbp, this);\r\n\r\n        var reader = new FileReader();\r\n        reader.onload = this.cb;\r\n        if (format.toLowerCase() === 'raw') {\r\n            reader.readAsText(url);\r\n        } else {\r\n            reader.readAsText(url, encoding);\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Opens a file using the given URL and passes the contents to {@link JXG.FileReader#parseString}\r\n     * @param {String} url\r\n     * @param {JXG.Board|function} board Either a board or in case <tt>format</tt> equals 'raw' this has to be a callback function.\r\n     * @param {String} format The expected file format. Possible values are <dl>\r\n     * <dt>raw</dt><dd>Raw text file. In this case <tt>board</tt> has to be a callback function.</dd>\r\n     * <dt>geonext</dt><dd>Geonext File <a href=\"https://www.geonext.de\">https://www.geonext.de</a></dd>\r\n     * <dt>intergeo</dt><dd>Intergeo file format <a href=\"https://www.i2geo.net\">https://www.i2geo.net</a></dd>\r\n     * <dt>tracenpoche</dt><dd>Tracenpoche construction <a href=\"https://tracenpoche.sesamath.net/\">https://tracenpoche.sesamath.net/</a></dd>\r\n     * <dt>graph</dt><dd>Graph file</dd>\r\n     * <dt>digraph</dt><dd>DiGraph file</dd>\r\n     * <dt>geogebra</dt><dd>Geogebra File <a href=\"https://www.geogebra.org\">https://www.geogebra.org</a></dd>\r\n     * <dl><dt>cdy or cinderella</dt><dd>Cinderella (<a href=\"https://www.cinderella.de/\">https://www.cinderella.de</a></dd>\r\n     * </dl>\r\n     * @param {Boolean} async Call ajax asynchonously.\r\n     * @param {function} callback A function that is run when the board is ready.\r\n     */\r\n    parseFileContent: function (url, board, format, async, encoding, callback) {\r\n        if (Type.isString(url) || FileReader === undefined) {\r\n            this.handleRemoteFile(url, board, format, async, encoding, callback);\r\n        } else {\r\n            this.handleLocalFile(url, board, format, async, encoding, callback);\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Parses a given string according to the file format given in format.\r\n     * @param {String} str Contents of the file.\r\n     * @param {JXG.Board} board The board the construction in the file should be loaded in.\r\n     * @param {String} format Possible values are <dl>\r\n     * <dt>raw</dt><dd>Raw text file. In this case <tt>board</tt> has to be a callback function.</dd>\r\n     * <dt>geonext</dt><dd>Geonext File <a href=\"https://www.geonext.de\">https://www.geonext.de</a></dd>\r\n     * <dt>intergeo</dt><dd>Intergeo file format <a href=\"https://www.i2geo.net\">https://www.i2geo.net</a></dd>\r\n     * <dt>tracenpoche</dt><dd>Tracenpoche construction <a href=\"https://tracenpoche.sesamath.net/\">https://tracenpoche.sesamath.net/</a></dd>\r\n     * <dt>graph</dt><dd>Graph file</dd>\r\n     * <dt>digraph</dt><dd>DiGraph file</dd>\r\n     * <dt>geogebra</dt><dd>Geogebra File <a href=\"https://www.geogebra.org\">https://www.geogebra.org</a></dd>\r\n     * <dl><dt>cdy or cinderella</dt><dd>Cinderella (<a href=\"https://www.cinderella.de/\">https://www.cinderella.de</a></dd>\r\n     * </dl>\r\n     * @param {function} callback\r\n     */\r\n    parseString: function (str, board, format, callback) {\r\n        var Reader, read;\r\n\r\n        format = format.toLowerCase();\r\n        Reader = JXG.readers[format];\r\n\r\n        if (Type.exists(Reader)) {\r\n            read = new Reader(board, str);\r\n            read.read();\r\n        } else if (format === 'jessiecode') {\r\n        } else {\r\n            throw new Error(\"JSXGraph: There is no reader available for '\" + format + \"'.\");\r\n        }\r\n\r\n        if (Type.isFunction(callback)) {\r\n            callback(board);\r\n        }\r\n    }\r\n};\r\n\r\n// The following code is vbscript. This is a workaround to enable binary data downloads via AJAX in\r\n// Microsoft Internet Explorer.\r\n\r\n/*jslint evil:true, es5:true, white:true*/\r\n/*jshint multistr:true*/\r\nif (\r\n    !Env.isMetroApp() &&\r\n    Env.isBrowser &&\r\n    typeof navigator === \"object\" &&\r\n    /msie/i.test(navigator.userAgent) &&\r\n    !/opera/i.test(navigator.userAgent) &&\r\n    document &&\r\n    document.write\r\n) {\r\n    document.write(\r\n        '<script type=\"text/vbscript\">\\n\\\r\nFunction Base64Encode(inData)\\n\\\r\n  Const Base64 = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\"\\n\\\r\n  Dim cOut, sOut, I\\n\\\r\n  For I = 1 To LenB(inData) Step 3\\n\\\r\n    Dim nGroup, pOut, sGroup\\n\\\r\n    nGroup = &H10000 * AscB(MidB(inData, I, 1)) + _\\n\\\r\n      &H100 * MyASC(MidB(inData, I + 1, 1)) + MyASC(MidB(inData, I + 2, 1))\\n\\\r\n    nGroup = Oct(nGroup)\\n\\\r\n    nGroup = String(8 - Len(nGroup), \"0\") & nGroup\\n\\\r\n    pOut = Mid(Base64, CLng(\"&o\" & Mid(nGroup, 1, 2)) + 1, 1) + _\\n\\\r\n      Mid(Base64, CLng(\"&o\" & Mid(nGroup, 3, 2)) + 1, 1) + _\\n\\\r\n      Mid(Base64, CLng(\"&o\" & Mid(nGroup, 5, 2)) + 1, 1) + _\\n\\\r\n      Mid(Base64, CLng(\"&o\" & Mid(nGroup, 7, 2)) + 1, 1)\\n\\\r\n    sOut = sOut + pOut\\n\\\r\n  Next\\n\\\r\n  Select Case LenB(inData) Mod 3\\n\\\r\n    Case 1: \\'8 bit final\\n\\\r\n      sOut = Left(sOut, Len(sOut) - 2) + \"==\"\\n\\\r\n    Case 2: \\'16 bit final\\n\\\r\n      sOut = Left(sOut, Len(sOut) - 1) + \"=\"\\n\\\r\n  End Select\\n\\\r\n  Base64Encode = sOut\\n\\\r\nEnd Function\\n\\\r\n\\n\\\r\nFunction MyASC(OneChar)\\n\\\r\n  If OneChar = \"\" Then MyASC = 0 Else MyASC = AscB(OneChar)\\n\\\r\nEnd Function\\n\\\r\n\\n\\\r\nFunction jxgBinFileReader(xhr)\\n\\\r\n    Dim byteString\\n\\\r\n    Dim b64String\\n\\\r\n    Dim i\\n\\\r\n    byteString = xhr.responseBody\\n\\\r\n    ReDim byteArray(LenB(byteString))\\n\\\r\n    For i = 1 To LenB(byteString)\\n\\\r\n        byteArray(i-1) = AscB(MidB(byteString, i, 1))\\n\\\r\n    Next\\n\\\r\n    b64String = Base64Encode(byteString)\\n\\\r\n    jxgBinFileReader = b64String\\n\\\r\nEnd Function\\n\\\r\n</script>\\n'\r\n    );\r\n}\r\n\r\nexport default JXG.FileReader;\r\n","/*\r\n Copyright 2008-2025\r\n Matthias Ehmann,\r\n Michael Gerhaeuser,\r\n Carsten Miller,\r\n Bianca Valentin,\r\n Alfred Wassermann,\r\n Peter Wilfahrt\r\n\r\n This file is part of JSXGraph.\r\n\r\n JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n You can redistribute it and/or modify it under the terms of the\r\n\r\n * GNU Lesser General Public License as published by\r\n the Free Software Foundation, either version 3 of the License, or\r\n (at your option) any later version\r\n OR\r\n * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n JSXGraph is distributed in the hope that it will be useful,\r\n but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n GNU Lesser General Public License for more details.\r\n\r\n You should have received a copy of the GNU Lesser General Public License and\r\n the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * A composition is a simple container that manages none or more {@link JXG.GeometryElement}s.\r\n * @param {Object} elements A list of elements with a descriptive name for the element as the key and a reference\r\n * to the element as the value of every list entry. The name is used to access the element later on.\r\n * @example\r\n * var p1 = board.create('point', [1, 2]),\r\n *     p2 = board.create('point', [2, 3]),\r\n *     c = new JXG.Composition({\r\n *         start: p1,\r\n *         end: p2\r\n *     });\r\n *\r\n * // moves p1 to [3, 3]\r\n * c.start.moveTo([3, 3]);\r\n * @class JXG.Composition\r\n */\r\nJXG.Composition = function (elements) {\r\n    var e,\r\n        that = this,\r\n        genericMethods = [\r\n            /**\r\n             * Invokes setAttribute for every stored element with a setAttribute method and hands over the given arguments.\r\n             * See {@link JXG.GeometryElement#setAttribute} for further description, valid parameters and return values.\r\n             * @name setAttribute\r\n             * @memberOf JXG.Composition.prototype\r\n             * @function\r\n             */\r\n            \"setAttribute\",\r\n\r\n            /**\r\n             * Invokes setParents for every stored element with a setParents method and hands over the given arguments.\r\n             * See {@link JXG.GeometryElement#setParents} for further description, valid parameters and return values.\r\n             * @name setParents\r\n             * @memberOf JXG.Composition.prototype\r\n             * @function\r\n             */\r\n            \"setParents\",\r\n\r\n            /**\r\n             * Invokes prepareUpdate for every stored element with a prepareUpdate method and hands over the given arguments.\r\n             * See {@link JXG.GeometryElement#prepareUpdate} for further description, valid parameters and return values.\r\n             * @name prepareUpdate\r\n             * @memberOf JXG.Composition.prototype\r\n             * @function\r\n             */\r\n            \"prepareUpdate\",\r\n\r\n            /**\r\n             * Invokes updateRenderer for every stored element with a updateRenderer method and hands over the given arguments.\r\n             * See {@link JXG.GeometryElement#updateRenderer} for further description, valid parameters and return values.\r\n             * @name updateRenderer\r\n             * @memberOf JXG.Composition.prototype\r\n             * @function\r\n             */\r\n            \"updateRenderer\",\r\n\r\n            /**\r\n             * Invokes update for every stored element with a update method and hands over the given arguments.\r\n             * See {@link JXG.GeometryElement#update} for further description, valid parameters and return values.\r\n             * @name update\r\n             * @memberOf JXG.Composition.prototype\r\n             * @function\r\n             */\r\n            \"update\",\r\n\r\n            /**\r\n             * Invokes fullUpdate for every stored element with a fullUpdate method and hands over the given arguments.\r\n             * See {@link JXG.GeometryElement#fullUpdate} for further description, valid parameters and return values.\r\n             * @name fullUpdate\r\n             * @memberOf JXG.Composition.prototype\r\n             * @function\r\n             */\r\n            \"fullUpdate\",\r\n\r\n            /**\r\n             * Invokes highlight for every stored element with a highlight method and hands over the given arguments.\r\n             * See {@link JXG.GeometryElement#highlight} for further description, valid parameters and return values.\r\n             * @name highlight\r\n             * @memberOf JXG.Composition.prototype\r\n             * @function\r\n             */\r\n            \"highlight\",\r\n\r\n            /**\r\n             * Invokes noHighlight for every stored element with a noHighlight method and hands over the given arguments.\r\n             * See {@link JXG.GeometryElement#noHighlight} for further description, valid parameters and return values.\r\n             * @name noHighlight\r\n             * @memberOf JXG.Composition.prototype\r\n             * @function\r\n             */\r\n            \"noHighlight\"\r\n        ],\r\n        generateMethod = function (what) {\r\n            return function () {\r\n                var i;\r\n\r\n                for (i in that.elements) {\r\n                    if (that.elements.hasOwnProperty(i)) {\r\n                        if (Type.exists(that.elements[i][what])) {\r\n                            that.elements[i][what].apply(that.elements[i], arguments);\r\n                        }\r\n                    }\r\n                }\r\n                return that;\r\n            };\r\n        };\r\n\r\n    for (e = 0; e < genericMethods.length; e++) {\r\n        this[genericMethods[e]] = generateMethod(genericMethods[e]);\r\n    }\r\n\r\n    this.elements = {};\r\n    this.objects = this.elements;\r\n\r\n    this.elementsByName = {};\r\n    this.objectsList = [];\r\n\r\n    // unused, required for select()\r\n    this.groups = {};\r\n\r\n    this.methodMap = {\r\n        setAttribute: \"setAttribute\",\r\n        setProperty: \"setAttribute\",\r\n        setParents: \"setParents\",\r\n        add: \"add\",\r\n        remove: \"remove\",\r\n        select: \"select\"\r\n    };\r\n\r\n    for (e in elements) {\r\n        if (elements.hasOwnProperty(e)) {\r\n            this.add(e, elements[e]);\r\n        }\r\n    }\r\n\r\n    this.dump = true;\r\n    this.subs = {};\r\n};\r\n\r\nJXG.extend(\r\n    JXG.Composition.prototype,\r\n    /** @lends JXG.Composition.prototype */ {\r\n        /**\r\n         * Adds an element to the composition container.\r\n         * @param {String} what Descriptive name for the element, e.g. <em>startpoint</em> or <em>area</em>. This is used to\r\n         * access the element later on. There are some reserved names: <em>elements, add, remove, update, prepareUpdate,\r\n         * updateRenderer, highlight, noHighlight</em>, and all names that would form invalid object property names in\r\n         * JavaScript.\r\n         * @param {JXG.GeometryElement|JXG.Composition} element A reference to the element that is to be added. This can be\r\n         * another composition, too.\r\n         * @returns {Boolean} True, if the element was added successfully. Reasons why adding the element failed include\r\n         * using a reserved name and providing an invalid element.\r\n         */\r\n        add: function (what, element) {\r\n            if (!Type.exists(this[what]) && Type.exists(element)) {\r\n                if (Type.exists(element.id)) {\r\n                    this.elements[element.id] = element;\r\n                } else {\r\n                    this.elements[what] = element;\r\n                }\r\n\r\n                if (Type.exists(element.name)) {\r\n                    this.elementsByName[element.name] = element;\r\n                }\r\n\r\n                element.on(\"attribute:name\", this.nameListener, this);\r\n\r\n                this.objectsList.push(element);\r\n                this[what] = element;\r\n                this.methodMap[what] = element;\r\n\r\n                return true;\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Remove an element from the composition container.\r\n         * @param {String} what The name used to access the element.\r\n         * @returns {Boolean} True, if the element has been removed successfully.\r\n         */\r\n        remove: function (what) {\r\n            var found = false,\r\n                e;\r\n\r\n            for (e in this.elements) {\r\n                if (this.elements.hasOwnProperty(e)) {\r\n                    if (this.elements[e].id === this[what].id) {\r\n                        found = true;\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (found) {\r\n                delete this.elements[this[what].id];\r\n                delete this[what];\r\n            }\r\n\r\n            return found;\r\n        },\r\n\r\n        nameListener: function (oval, nval, el) {\r\n            delete this.elementsByName[oval];\r\n            this.elementsByName[nval] = el;\r\n        },\r\n\r\n        select: function (filter) {\r\n            // for now, hijack JXG.Board's select() method\r\n            if (Type.exists(JXG.Board)) {\r\n                return JXG.Board.prototype.select.call(this, filter);\r\n            }\r\n\r\n            return new JXG.Composition();\r\n        },\r\n\r\n        getParents: function () {\r\n            return this.parents;\r\n        },\r\n\r\n        getType: function () {\r\n            return this.elType;\r\n        },\r\n\r\n        getAttributes: function () {\r\n            var attr = {},\r\n                e;\r\n\r\n            for (e in this.subs) {\r\n                if (this.subs.hasOwnProperty(e)) {\r\n                    attr[e] = this.subs[e].visProp;\r\n                }\r\n            }\r\n\r\n            return this.attr;\r\n        }\r\n    }\r\n);\r\n\r\nexport default JXG.Composition;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, AMprocessNode: true, MathJax: true, window: true, document: true, init: true, translateASCIIMath: true, google: true*/\r\n\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview The JXG.Board class is defined in this file. JXG.Board controls all properties and methods\r\n * used to manage a geonext board like managing geometric elements, managing mouse and touch events, etc.\r\n */\r\n\r\nimport JXG from '../jxg.js';\r\nimport Const from './constants.js';\r\nimport Coords from './coords.js';\r\nimport Options from '../options.js';\r\nimport Numerics from '../math/numerics.js';\r\nimport Mat from '../math/math.js';\r\nimport Geometry from '../math/geometry.js';\r\nimport Complex from '../math/complex.js';\r\nimport Statistics from '../math/statistics.js';\r\nimport JessieCode from '../parser/jessiecode.js';\r\nimport Color from '../utils/color.js';\r\nimport Type from '../utils/type.js';\r\nimport EventEmitter from '../utils/event.js';\r\nimport Env from '../utils/env.js';\r\nimport Composition from './composition.js';\r\n\r\n/**\r\n * Constructs a new Board object.\r\n * @class JXG.Board controls all properties and methods used to manage a geonext board like managing geometric\r\n * elements, managing mouse and touch events, etc. You probably don't want to use this constructor directly.\r\n * Please use {@link JXG.JSXGraph.initBoard} to initialize a board.\r\n * @constructor\r\n * @param {String|Object} container The id of or reference to the HTML DOM element\r\n * the board is drawn in. This is usually a HTML div. If it is the reference to an HTML element and this element does not have an attribute \"id\",\r\n * this attribute \"id\" is set to a random value.\r\n * @param {JXG.AbstractRenderer} renderer The reference of a renderer.\r\n * @param {String} id Unique identifier for the board, may be an empty string or null or even undefined.\r\n * @param {JXG.Coords} origin The coordinates where the origin is placed, in user coordinates.\r\n * @param {Number} zoomX Zoom factor in x-axis direction\r\n * @param {Number} zoomY Zoom factor in y-axis direction\r\n * @param {Number} unitX Units in x-axis direction\r\n * @param {Number} unitY Units in y-axis direction\r\n * @param {Number} canvasWidth  The width of canvas\r\n * @param {Number} canvasHeight The height of canvas\r\n * @param {Object} attributes The attributes object given to {@link JXG.JSXGraph.initBoard}\r\n * @borrows JXG.EventEmitter#on as this.on\r\n * @borrows JXG.EventEmitter#off as this.off\r\n * @borrows JXG.EventEmitter#triggerEventHandlers as this.triggerEventHandlers\r\n * @borrows JXG.EventEmitter#eventHandlers as this.eventHandlers\r\n */\r\nJXG.Board = function (container, renderer, id,\r\n    origin, zoomX, zoomY, unitX, unitY,\r\n    canvasWidth, canvasHeight, attributes) {\r\n    /**\r\n     * Board is in no special mode, objects are highlighted on mouse over and objects may be\r\n     * clicked to start drag&drop.\r\n     * @type Number\r\n     * @constant\r\n     */\r\n    this.BOARD_MODE_NONE = 0x0000;\r\n\r\n    /**\r\n     * Board is in drag mode, objects aren't highlighted on mouse over and the object referenced in\r\n     * {@link JXG.Board#mouse} is updated on mouse movement.\r\n     * @type Number\r\n     * @constant\r\n     */\r\n    this.BOARD_MODE_DRAG = 0x0001;\r\n\r\n    /**\r\n     * In this mode a mouse move changes the origin's screen coordinates.\r\n     * @type Number\r\n     * @constant\r\n     */\r\n    this.BOARD_MODE_MOVE_ORIGIN = 0x0002;\r\n\r\n    /**\r\n     * Update is made with high quality, e.g. graphs are evaluated at much more points.\r\n     * @type Number\r\n     * @constant\r\n     * @see JXG.Board#updateQuality\r\n     */\r\n    this.BOARD_MODE_ZOOM = 0x0011;\r\n\r\n    /**\r\n     * Update is made with low quality, e.g. graphs are evaluated at a lesser amount of points.\r\n     * @type Number\r\n     * @constant\r\n     * @see JXG.Board#updateQuality\r\n     */\r\n    this.BOARD_QUALITY_LOW = 0x1;\r\n\r\n    /**\r\n     * Update is made with high quality, e.g. graphs are evaluated at much more points.\r\n     * @type Number\r\n     * @constant\r\n     * @see JXG.Board#updateQuality\r\n     */\r\n    this.BOARD_QUALITY_HIGH = 0x2;\r\n\r\n    /**\r\n     * Pointer to the document element containing the board.\r\n     * @type Object\r\n     */\r\n    if (Type.exists(attributes.document) && attributes.document !== false) {\r\n        this.document = attributes.document;\r\n    } else if (Env.isBrowser) {\r\n        this.document = document;\r\n    }\r\n\r\n    /**\r\n     * The html-id of the html element containing the board.\r\n     * @type String\r\n     */\r\n    this.container = ''; // container\r\n\r\n    /**\r\n     * ID of the board\r\n     * @type String\r\n     */\r\n    this.id = '';\r\n\r\n    /**\r\n     * Pointer to the html element containing the board.\r\n     * @type Object\r\n     */\r\n    this.containerObj = null; // (Env.isBrowser ? this.document.getElementById(this.container) : null);\r\n\r\n    // Set this.container and this.containerObj\r\n    if (Type.isString(container)) {\r\n        // Hosting div is given as string\r\n        this.container = container; // container\r\n        this.containerObj = (Env.isBrowser ? this.document.getElementById(this.container) : null);\r\n\r\n    } else if (Env.isBrowser) {\r\n\r\n        // Hosting div is given as object pointer\r\n        this.containerObj = container;\r\n        this.container = this.containerObj.getAttribute('id');\r\n        if (this.container === null) {\r\n            // Set random ID to this.container, but not to the DOM element\r\n\r\n            this.container = 'null' + parseInt(Math.random() * 16777216).toString();\r\n        }\r\n    }\r\n\r\n    if (Env.isBrowser && renderer.type !== 'no' && this.containerObj === null) {\r\n        throw new Error('\\nJSXGraph: HTML container element \"' + container + '\" not found.');\r\n    }\r\n\r\n    // TODO\r\n    // Why do we need this.id AND this.container?\r\n    // There was never a board attribute \"id\".\r\n    // The origin seems to be that in the geonext renderer we use a separate id, extracted from the GEONExT file.\r\n    if (Type.exists(id) && id !== '' && Env.isBrowser && !Type.exists(this.document.getElementById(id))) {\r\n        // If the given id is not valid, generate an unique id\r\n        this.id = id;\r\n    } else {\r\n        this.id = this.generateId();\r\n    }\r\n\r\n    /**\r\n     * A reference to this boards renderer.\r\n     * @type JXG.AbstractRenderer\r\n     * @name JXG.Board#renderer\r\n     * @private\r\n     * @ignore\r\n     */\r\n    this.renderer = renderer;\r\n\r\n    /**\r\n     * Grids keeps track of all grids attached to this board.\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.grids = [];\r\n\r\n    /**\r\n     * Copy of the default options\r\n     * @type JXG.Options\r\n     */\r\n    this.options = Type.deepCopy(Options);  // A possible theme is not yet merged in\r\n\r\n    /**\r\n     * Board attributes\r\n     * @type Object\r\n     */\r\n    this.attr = attributes;\r\n\r\n    if (this.attr.theme !== 'default' && Type.exists(JXG.themes[this.attr.theme])) {\r\n        Type.mergeAttr(this.options, JXG.themes[this.attr.theme], true);\r\n    }\r\n\r\n    /**\r\n     * Dimension of the board.\r\n     * @default 2\r\n     * @type Number\r\n     */\r\n    this.dimension = 2;\r\n    this.jc = new JessieCode();\r\n    this.jc.use(this);\r\n\r\n    /**\r\n     * Coordinates of the boards origin. This a object with the two properties\r\n     * usrCoords and scrCoords. usrCoords always equals [1, 0, 0] and scrCoords\r\n     * stores the boards origin in homogeneous screen coordinates.\r\n     * @type Object\r\n     * @private\r\n     */\r\n    this.origin = {};\r\n    this.origin.usrCoords = [1, 0, 0];\r\n    this.origin.scrCoords = [1, origin[0], origin[1]];\r\n\r\n    /**\r\n     * Zoom factor in X direction. It only stores the zoom factor to be able\r\n     * to get back to 100% in zoom100().\r\n     * @name JXG.Board.zoomX\r\n     * @type Number\r\n     * @private\r\n     * @ignore\r\n     */\r\n    this.zoomX = zoomX;\r\n\r\n    /**\r\n     * Zoom factor in Y direction. It only stores the zoom factor to be able\r\n     * to get back to 100% in zoom100().\r\n     * @name JXG.Board.zoomY\r\n     * @type Number\r\n     * @private\r\n     * @ignore\r\n     */\r\n    this.zoomY = zoomY;\r\n\r\n    /**\r\n     * The number of pixels which represent one unit in user-coordinates in x direction.\r\n     * @type Number\r\n     * @private\r\n     */\r\n    this.unitX = unitX * this.zoomX;\r\n\r\n    /**\r\n     * The number of pixels which represent one unit in user-coordinates in y direction.\r\n     * @type Number\r\n     * @private\r\n     */\r\n    this.unitY = unitY * this.zoomY;\r\n\r\n    /**\r\n     * Keep aspect ratio if bounding box is set and the width/height ratio differs from the\r\n     * width/height ratio of the canvas.\r\n     * @type Boolean\r\n     * @private\r\n     */\r\n    this.keepaspectratio = false;\r\n\r\n    /**\r\n     * Canvas width.\r\n     * @type Number\r\n     * @private\r\n     */\r\n    this.canvasWidth = canvasWidth;\r\n\r\n    /**\r\n     * Canvas Height\r\n     * @type Number\r\n     * @private\r\n     */\r\n    this.canvasHeight = canvasHeight;\r\n\r\n    EventEmitter.eventify(this);\r\n\r\n    this.hooks = [];\r\n\r\n    /**\r\n     * An array containing all other boards that are updated after this board has been updated.\r\n     * @type Array\r\n     * @see JXG.Board#addChild\r\n     * @see JXG.Board#removeChild\r\n     */\r\n    this.dependentBoards = [];\r\n\r\n    /**\r\n     * During the update process this is set to false to prevent an endless loop.\r\n     * @default false\r\n     * @type Boolean\r\n     */\r\n    this.inUpdate = false;\r\n\r\n    /**\r\n     * An associative array containing all geometric objects belonging to the board. Key is the id of the object and value is a reference to the object.\r\n     * @type Object\r\n     */\r\n    this.objects = {};\r\n\r\n    /**\r\n     * An array containing all geometric objects on the board in the order of construction.\r\n     * @type Array\r\n     */\r\n    this.objectsList = [];\r\n\r\n    /**\r\n     * An associative array containing all groups belonging to the board. Key is the id of the group and value is a reference to the object.\r\n     * @type Object\r\n     */\r\n    this.groups = {};\r\n\r\n    /**\r\n     * Stores all the objects that are currently running an animation.\r\n     * @type Object\r\n     */\r\n    this.animationObjects = {};\r\n\r\n    /**\r\n     * An associative array containing all highlighted elements belonging to the board.\r\n     * @type Object\r\n     */\r\n    this.highlightedObjects = {};\r\n\r\n    /**\r\n     * Number of objects ever created on this board. This includes every object, even invisible and deleted ones.\r\n     * @type Number\r\n     */\r\n    this.numObjects = 0;\r\n\r\n    /**\r\n     * An associative array / dictionary to store the objects of the board by name. The name of the object is the key and value is a reference to the object.\r\n     * @type Object\r\n     */\r\n    this.elementsByName = {};\r\n\r\n    /**\r\n     * The board mode the board is currently in. Possible values are\r\n     * <ul>\r\n     * <li>JXG.Board.BOARD_MODE_NONE</li>\r\n     * <li>JXG.Board.BOARD_MODE_DRAG</li>\r\n     * <li>JXG.Board.BOARD_MODE_MOVE_ORIGIN</li>\r\n     * </ul>\r\n     * @type Number\r\n     */\r\n    this.mode = this.BOARD_MODE_NONE;\r\n\r\n    /**\r\n     * The update quality of the board. In most cases this is set to {@link JXG.Board#BOARD_QUALITY_HIGH}.\r\n     * If {@link JXG.Board#mode} equals {@link JXG.Board#BOARD_MODE_DRAG} this is set to\r\n     * {@link JXG.Board#BOARD_QUALITY_LOW} to speed up the update process by e.g. reducing the number of\r\n     * evaluation points when plotting functions. Possible values are\r\n     * <ul>\r\n     * <li>BOARD_QUALITY_LOW</li>\r\n     * <li>BOARD_QUALITY_HIGH</li>\r\n     * </ul>\r\n     * @type Number\r\n     * @see JXG.Board#mode\r\n     */\r\n    this.updateQuality = this.BOARD_QUALITY_HIGH;\r\n\r\n    /**\r\n     * If true updates are skipped.\r\n     * @type Boolean\r\n     */\r\n    this.isSuspendedRedraw = false;\r\n\r\n    this.calculateSnapSizes();\r\n\r\n    /**\r\n     * The distance from the mouse to the dragged object in x direction when the user clicked the mouse button.\r\n     * @type Number\r\n     * @see JXG.Board#drag_dy\r\n     */\r\n    this.drag_dx = 0;\r\n\r\n    /**\r\n     * The distance from the mouse to the dragged object in y direction when the user clicked the mouse button.\r\n     * @type Number\r\n     * @see JXG.Board#drag_dx\r\n     */\r\n    this.drag_dy = 0;\r\n\r\n    /**\r\n     * The last position where a drag event has been fired.\r\n     * @type Array\r\n     * @see JXG.Board#moveObject\r\n     */\r\n    this.drag_position = [0, 0];\r\n\r\n    /**\r\n     * References to the object that is dragged with the mouse on the board.\r\n     * @type JXG.GeometryElement\r\n     * @see JXG.Board#touches\r\n     */\r\n    this.mouse = {};\r\n\r\n    /**\r\n     * Keeps track on touched elements, like {@link JXG.Board#mouse} does for mouse events.\r\n     * @type Array\r\n     * @see JXG.Board#mouse\r\n     */\r\n    this.touches = [];\r\n\r\n    /**\r\n     * A string containing the XML text of the construction.\r\n     * This is set in {@link JXG.FileReader.parseString}.\r\n     * Only useful if a construction is read from a GEONExT-, Intergeo-, Geogebra-, or Cinderella-File.\r\n     * @type String\r\n     */\r\n    this.xmlString = '';\r\n\r\n    /**\r\n     * Cached result of getCoordsTopLeftCorner for touch/mouseMove-Events to save some DOM operations.\r\n     * @type Array\r\n     */\r\n    this.cPos = [];\r\n\r\n    /**\r\n     * Contains the last time (epoch, msec) since the last touchMove event which was not thrown away or since\r\n     * touchStart because Android's Webkit browser fires too much of them.\r\n     * @type Number\r\n     */\r\n    this.touchMoveLast = 0;\r\n\r\n    /**\r\n     * Contains the pointerId of the last touchMove event which was not thrown away or since\r\n     * touchStart because Android's Webkit browser fires too much of them.\r\n     * @type Number\r\n     */\r\n    this.touchMoveLastId = Infinity;\r\n\r\n    /**\r\n     * Contains the last time (epoch, msec) since the last getCoordsTopLeftCorner call which was not thrown away.\r\n     * @type Number\r\n     */\r\n    this.positionAccessLast = 0;\r\n\r\n    /**\r\n     * Collects all elements that triggered a mouse down event.\r\n     * @type Array\r\n     */\r\n    this.downObjects = [];\r\n    this.clickObjects = {};\r\n\r\n    /**\r\n     * Collects all elements that have keyboard focus. Should be either one or no element.\r\n     * Elements are stored with their id.\r\n     * @type Array\r\n     */\r\n    this.focusObjects = [];\r\n\r\n    if (this.attr.showcopyright || this.attr.showlogo) {\r\n        this.renderer.displayLogo(Const.licenseLogo, parseInt(this.options.text.fontSize, 10), this);\r\n    }\r\n\r\n    if (this.attr.showcopyright) {\r\n        this.renderer.displayCopyright(Const.licenseText, parseInt(this.options.text.fontSize, 10));\r\n    }\r\n\r\n    /**\r\n     * Full updates are needed after zoom and axis translates. This saves some time during an update.\r\n     * @default false\r\n     * @type Boolean\r\n     */\r\n    this.needsFullUpdate = false;\r\n\r\n    /**\r\n     * If reducedUpdate is set to true then only the dragged element and few (e.g. 2) following\r\n     * elements are updated during mouse move. On mouse up the whole construction is\r\n     * updated. This enables us to be fast even on very slow devices.\r\n     * @type Boolean\r\n     * @default false\r\n     */\r\n    this.reducedUpdate = false;\r\n\r\n    /**\r\n     * The current color blindness deficiency is stored in this property. If color blindness is not emulated\r\n     * at the moment, it's value is 'none'.\r\n     */\r\n    this.currentCBDef = 'none';\r\n\r\n    /**\r\n     * If GEONExT constructions are displayed, then this property should be set to true.\r\n     * At the moment there should be no difference. But this may change.\r\n     * This is set in {@link JXG.GeonextReader.readGeonext}.\r\n     * @type Boolean\r\n     * @default false\r\n     * @see JXG.GeonextReader.readGeonext\r\n     */\r\n    this.geonextCompatibilityMode = false;\r\n\r\n    if (this.options.text.useASCIIMathML && translateASCIIMath) {\r\n        init();\r\n    } else {\r\n        this.options.text.useASCIIMathML = false;\r\n    }\r\n\r\n    /**\r\n     * A flag which tells if the board registers mouse events.\r\n     * @type Boolean\r\n     * @default false\r\n     */\r\n    this.hasMouseHandlers = false;\r\n\r\n    /**\r\n     * A flag which tells if the board registers touch events.\r\n     * @type Boolean\r\n     * @default false\r\n     */\r\n    this.hasTouchHandlers = false;\r\n\r\n    /**\r\n     * A flag which stores if the board registered pointer events.\r\n     * @type Boolean\r\n     * @default false\r\n     */\r\n    this.hasPointerHandlers = false;\r\n\r\n    /**\r\n     * A flag which stores if the board registered zoom events, i.e. mouse wheel scroll events.\r\n     * @type Boolean\r\n     * @default false\r\n     */\r\n    this.hasWheelHandlers = false;\r\n\r\n    /**\r\n     * A flag which tells if the board the JXG.Board#mouseUpListener is currently registered.\r\n     * @type Boolean\r\n     * @default false\r\n     */\r\n    this.hasMouseUp = false;\r\n\r\n    /**\r\n     * A flag which tells if the board the JXG.Board#touchEndListener is currently registered.\r\n     * @type Boolean\r\n     * @default false\r\n     */\r\n    this.hasTouchEnd = false;\r\n\r\n    /**\r\n     * A flag which tells us if the board has a pointerUp event registered at the moment.\r\n     * @type Boolean\r\n     * @default false\r\n     */\r\n    this.hasPointerUp = false;\r\n\r\n    /**\r\n     * Array containing the events related to resizing that have event listeners.\r\n     * @type Array\r\n     * @default []\r\n     */\r\n    this.resizeHandlers = [];\r\n\r\n    /**\r\n     * Offset for large coords elements like images\r\n     * @type Array\r\n     * @private\r\n     * @default [0, 0]\r\n     */\r\n    this._drag_offset = [0, 0];\r\n\r\n    /**\r\n     * Stores the input device used in the last down or move event.\r\n     * @type String\r\n     * @private\r\n     * @default 'mouse'\r\n     */\r\n    this._inputDevice = 'mouse';\r\n\r\n    /**\r\n     * Keeps a list of pointer devices which are currently touching the screen.\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this._board_touches = [];\r\n\r\n    /**\r\n     * A flag which tells us if the board is in the selecting mode\r\n     * @type Boolean\r\n     * @default false\r\n     */\r\n    this.selectingMode = false;\r\n\r\n    /**\r\n     * A flag which tells us if the user is selecting\r\n     * @type Boolean\r\n     * @default false\r\n     */\r\n    this.isSelecting = false;\r\n\r\n    /**\r\n     * A flag which tells us if the user is scrolling the viewport\r\n     * @type Boolean\r\n     * @private\r\n     * @default false\r\n     * @see JXG.Board#scrollListener\r\n     */\r\n    this._isScrolling = false;\r\n\r\n    /**\r\n     * A flag which tells us if a resize is in process\r\n     * @type Boolean\r\n     * @private\r\n     * @default false\r\n     * @see JXG.Board#resizeListener\r\n     */\r\n    this._isResizing = false;\r\n\r\n    /**\r\n     * A flag which tells us if the update is triggered by a change of the\r\n     * 3D view. In that case we only have to update the projection of\r\n     * the 3D elements and can avoid a full board update.\r\n     *\r\n     * @type Boolean\r\n     * @private\r\n     * @default false\r\n     */\r\n    this._change3DView = false;\r\n\r\n    /**\r\n     * A bounding box for the selection\r\n     * @type Array\r\n     * @default [ [0,0], [0,0] ]\r\n     */\r\n    this.selectingBox = [[0, 0], [0, 0]];\r\n\r\n    /**\r\n     * Array to log user activity.\r\n     * Entries are objects of the form '{type, id, start, end}' notifying\r\n     * the start time as well as the last time of a single event of type 'type'\r\n     * on a JSXGraph element of id 'id'.\r\n     * <p> 'start' and 'end' contain the amount of milliseconds elapsed between 1 January 1970 00:00:00 UTC\r\n     * and the time the event happened.\r\n     * <p>\r\n     * For the time being (i.e. v1.5.0) the only supported type is 'drag'.\r\n     * @type Array\r\n     */\r\n    this.userLog = [];\r\n\r\n    this.mathLib = Math;        // Math or JXG.Math.IntervalArithmetic\r\n    this.mathLibJXG = JXG.Math; // JXG.Math or JXG.Math.IntervalArithmetic\r\n\r\n    if (this.attr.registerevents === true) {\r\n        this.attr.registerevents = {\r\n            fullscreen: true,\r\n            keyboard: true,\r\n            pointer: true,\r\n            resize: true,\r\n            wheel: true\r\n        };\r\n    } else if (typeof this.attr.registerevents === 'object') {\r\n        if (!Type.exists(this.attr.registerevents.fullscreen)) {\r\n            this.attr.registerevents.fullscreen = true;\r\n        }\r\n        if (!Type.exists(this.attr.registerevents.keyboard)) {\r\n            this.attr.registerevents.keyboard = true;\r\n        }\r\n        if (!Type.exists(this.attr.registerevents.pointer)) {\r\n            this.attr.registerevents.pointer = true;\r\n        }\r\n        if (!Type.exists(this.attr.registerevents.resize)) {\r\n            this.attr.registerevents.resize = true;\r\n        }\r\n        if (!Type.exists(this.attr.registerevents.wheel)) {\r\n            this.attr.registerevents.wheel = true;\r\n        }\r\n    }\r\n    if (this.attr.registerevents !== false) {\r\n        if (this.attr.registerevents.fullscreen) {\r\n            this.addFullscreenEventHandlers();\r\n        }\r\n        if (this.attr.registerevents.keyboard) {\r\n            this.addKeyboardEventHandlers();\r\n        }\r\n        if (this.attr.registerevents.pointer) {\r\n            this.addEventHandlers();\r\n        }\r\n        if (this.attr.registerevents.resize) {\r\n            this.addResizeEventHandlers();\r\n        }\r\n        if (this.attr.registerevents.wheel) {\r\n            this.addWheelEventHandlers();\r\n        }\r\n    }\r\n\r\n    this.methodMap = {\r\n        update: 'update',\r\n        fullUpdate: 'fullUpdate',\r\n        on: 'on',\r\n        off: 'off',\r\n        trigger: 'trigger',\r\n        setAttribute: 'setAttribute',\r\n        setBoundingBox: 'setBoundingBox',\r\n        setView: 'setBoundingBox',\r\n        getBoundingBox: 'getBoundingBox',\r\n        BoundingBox: 'getBoundingBox',\r\n        getView: 'getBoundingBox',\r\n        View: 'getBoundingBox',\r\n        migratePoint: 'migratePoint',\r\n        colorblind: 'emulateColorblindness',\r\n        suspendUpdate: 'suspendUpdate',\r\n        unsuspendUpdate: 'unsuspendUpdate',\r\n        clearTraces: 'clearTraces',\r\n        left: 'clickLeftArrow',\r\n        right: 'clickRightArrow',\r\n        up: 'clickUpArrow',\r\n        down: 'clickDownArrow',\r\n        zoomIn: 'zoomIn',\r\n        zoomOut: 'zoomOut',\r\n        zoom100: 'zoom100',\r\n        zoomElements: 'zoomElements',\r\n        remove: 'removeObject',\r\n        removeObject: 'removeObject'\r\n    };\r\n};\r\n\r\nJXG.extend(\r\n    JXG.Board.prototype,\r\n    /** @lends JXG.Board.prototype */ {\r\n        /**\r\n         * Generates an unique name for the given object. The result depends on the objects type, if the\r\n         * object is a {@link JXG.Point}, capital characters are used, if it is of type {@link JXG.Line}\r\n         * only lower case characters are used. If object is of type {@link JXG.Polygon}, a bunch of lower\r\n         * case characters prefixed with P_ are used. If object is of type {@link JXG.Circle} the name is\r\n         * generated using lower case characters. prefixed with k_ is used. In any other case, lower case\r\n         * chars prefixed with s_ is used.\r\n         * @param {Object} object Reference of an JXG.GeometryElement that is to be named.\r\n         * @returns {String} Unique name for the object.\r\n         */\r\n        generateName: function (object) {\r\n            var possibleNames, i,\r\n                maxNameLength = this.attr.maxnamelength,\r\n                pre = '',\r\n                post = '',\r\n                indices = [],\r\n                name = '';\r\n\r\n            if (object.type === Const.OBJECT_TYPE_TICKS) {\r\n                return '';\r\n            }\r\n\r\n            if (Type.isPoint(object) || Type.isPoint3D(object)) {\r\n                // points have capital letters\r\n                possibleNames = [\r\n                    '', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'\r\n                ];\r\n            } else if (object.type === Const.OBJECT_TYPE_ANGLE) {\r\n                possibleNames = [\r\n                    '', '&alpha;', '&beta;', '&gamma;', '&delta;', '&epsilon;', '&zeta;', '&eta;', '&theta;', '&iota;', '&kappa;', '&lambda;',\r\n                    '&mu;', '&nu;', '&xi;', '&omicron;', '&pi;', '&rho;', '&sigma;', '&tau;', '&upsilon;', '&phi;', '&chi;', '&psi;', '&omega;'\r\n                ];\r\n            } else {\r\n                // all other elements get lowercase labels\r\n                possibleNames = [\r\n                    '', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'\r\n                ];\r\n            }\r\n\r\n            if (\r\n                !Type.isPoint(object) &&\r\n                !Type.isPoint3D(object) &&\r\n                object.elementClass !== Const.OBJECT_CLASS_LINE &&\r\n                object.type !== Const.OBJECT_TYPE_ANGLE\r\n            ) {\r\n                if (object.type === Const.OBJECT_TYPE_POLYGON) {\r\n                    pre = 'P_{';\r\n                } else if (object.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n                    pre = 'k_{';\r\n                } else if (object.elementClass === Const.OBJECT_CLASS_TEXT) {\r\n                    pre = 't_{';\r\n                } else {\r\n                    pre = 's_{';\r\n                }\r\n                post = '}';\r\n            }\r\n\r\n            for (i = 0; i < maxNameLength; i++) {\r\n                indices[i] = 0;\r\n            }\r\n\r\n            while (indices[maxNameLength - 1] < possibleNames.length) {\r\n                for (indices[0] = 1; indices[0] < possibleNames.length; indices[0]++) {\r\n                    name = pre;\r\n\r\n                    for (i = maxNameLength; i > 0; i--) {\r\n                        name += possibleNames[indices[i - 1]];\r\n                    }\r\n\r\n                    if (!Type.exists(this.elementsByName[name + post])) {\r\n                        return name + post;\r\n                    }\r\n                }\r\n                indices[0] = possibleNames.length;\r\n\r\n                for (i = 1; i < maxNameLength; i++) {\r\n                    if (indices[i - 1] === possibleNames.length) {\r\n                        indices[i - 1] = 1;\r\n                        indices[i] += 1;\r\n                    }\r\n                }\r\n            }\r\n\r\n            return '';\r\n        },\r\n\r\n        /**\r\n         * Generates unique id for a board. The result is randomly generated and prefixed with 'jxgBoard'.\r\n         * @returns {String} Unique id for a board.\r\n         */\r\n        generateId: function () {\r\n            var r = 1;\r\n\r\n            // as long as we don't have a unique id generate a new one\r\n            while (Type.exists(JXG.boards['jxgBoard' + r])) {\r\n                r = Math.round(Math.random() * 16777216);\r\n            }\r\n\r\n            return 'jxgBoard' + r;\r\n        },\r\n\r\n        /**\r\n         * Composes an id for an element. If the ID is empty ('' or null) a new ID is generated, depending on the\r\n         * object type. As a side effect {@link JXG.Board#numObjects}\r\n         * is updated.\r\n         * @param {Object} obj Reference of an geometry object that needs an id.\r\n         * @param {Number} type Type of the object.\r\n         * @returns {String} Unique id for an element.\r\n         */\r\n        setId: function (obj, type) {\r\n            var randomNumber,\r\n                num = this.numObjects,\r\n                elId = obj.id;\r\n\r\n            this.numObjects += 1;\r\n\r\n            // If no id is provided or id is empty string, a new one is chosen\r\n            if (elId === '' || !Type.exists(elId)) {\r\n                elId = this.id + type + num;\r\n                while (Type.exists(this.objects[elId])) {\r\n                    randomNumber = Math.round(Math.random() * 65535);\r\n                    elId = this.id + type + num + '-' + randomNumber;\r\n                }\r\n            }\r\n\r\n            obj.id = elId;\r\n            this.objects[elId] = obj;\r\n            obj._pos = this.objectsList.length;\r\n            this.objectsList[this.objectsList.length] = obj;\r\n\r\n            return elId;\r\n        },\r\n\r\n        /**\r\n         * After construction of the object the visibility is set\r\n         * and the label is constructed if necessary.\r\n         * @param {Object} obj The object to add.\r\n         */\r\n        finalizeAdding: function (obj) {\r\n            if (obj.evalVisProp('visible') === false) {\r\n                this.renderer.display(obj, false);\r\n            }\r\n        },\r\n\r\n        finalizeLabel: function (obj) {\r\n            if (\r\n                obj.hasLabel &&\r\n                !obj.label.evalVisProp('islabel') &&\r\n                obj.label.evalVisProp('visible') === false\r\n            ) {\r\n                this.renderer.display(obj.label, false);\r\n            }\r\n        },\r\n\r\n        /**********************************************************\r\n         *\r\n         * Event Handler helpers\r\n         *\r\n         **********************************************************/\r\n\r\n        /**\r\n         * Returns false if the event has been triggered faster than the maximum frame rate.\r\n         *\r\n         * @param {Event} evt Event object given by the browser (unused)\r\n         * @returns {Boolean} If the event has been triggered faster than the maximum frame rate, false is returned.\r\n         * @private\r\n         * @see JXG.Board#pointerMoveListener\r\n         * @see JXG.Board#touchMoveListener\r\n         * @see JXG.Board#mouseMoveListener\r\n         */\r\n        checkFrameRate: function (evt) {\r\n            var handleEvt = false,\r\n                time = new Date().getTime();\r\n\r\n            if (Type.exists(evt.pointerId) && this.touchMoveLastId !== evt.pointerId) {\r\n                handleEvt = true;\r\n                this.touchMoveLastId = evt.pointerId;\r\n            }\r\n            if (!handleEvt && (time - this.touchMoveLast) * this.attr.maxframerate >= 1000) {\r\n                handleEvt = true;\r\n            }\r\n            if (handleEvt) {\r\n                this.touchMoveLast = time;\r\n            }\r\n            return handleEvt;\r\n        },\r\n\r\n        /**\r\n         * Calculates mouse coordinates relative to the boards container.\r\n         * @returns {Array} Array of coordinates relative the boards container top left corner.\r\n         */\r\n        getCoordsTopLeftCorner: function () {\r\n            var cPos,\r\n                doc,\r\n                crect,\r\n                // In ownerDoc we need the 'real' document object.\r\n                // The first version is used in the case of shadowDOM,\r\n                // the second case in the 'normal' case.\r\n                ownerDoc = this.document.ownerDocument || this.document,\r\n                docElement = ownerDoc.documentElement || this.document.body.parentNode,\r\n                docBody = ownerDoc.body,\r\n                container = this.containerObj,\r\n                zoom,\r\n                o;\r\n\r\n            /**\r\n             * During drags and origin moves the container element is usually not changed.\r\n             * Check the position of the upper left corner at most every 1000 msecs\r\n             */\r\n            if (\r\n                this.cPos.length > 0 &&\r\n                (this.mode === this.BOARD_MODE_DRAG ||\r\n                    this.mode === this.BOARD_MODE_MOVE_ORIGIN ||\r\n                    new Date().getTime() - this.positionAccessLast < 1000)\r\n            ) {\r\n                return this.cPos;\r\n            }\r\n            this.positionAccessLast = new Date().getTime();\r\n\r\n            // Check if getBoundingClientRect exists. If so, use this as this covers *everything*\r\n            // even CSS3D transformations etc.\r\n            // Supported by all browsers but IE 6, 7.\r\n            if (container.getBoundingClientRect) {\r\n                crect = container.getBoundingClientRect();\r\n\r\n                zoom = 1.0;\r\n                // Recursively search for zoom style entries.\r\n                // This is necessary for reveal.js on webkit.\r\n                // It fails if the user does zooming\r\n                o = container;\r\n                while (o && Type.exists(o.parentNode)) {\r\n                    if (\r\n                        Type.exists(o.style) &&\r\n                        Type.exists(o.style.zoom) &&\r\n                        o.style.zoom !== ''\r\n                    ) {\r\n                        zoom *= parseFloat(o.style.zoom);\r\n                    }\r\n                    o = o.parentNode;\r\n                }\r\n                cPos = [crect.left * zoom, crect.top * zoom];\r\n\r\n                // add border width\r\n                cPos[0] += Env.getProp(container, 'border-left-width');\r\n                cPos[1] += Env.getProp(container, 'border-top-width');\r\n\r\n                // vml seems to ignore paddings\r\n                if (this.renderer.type !== 'vml') {\r\n                    // add padding\r\n                    cPos[0] += Env.getProp(container, 'padding-left');\r\n                    cPos[1] += Env.getProp(container, 'padding-top');\r\n                }\r\n\r\n                this.cPos = cPos.slice();\r\n                return this.cPos;\r\n            }\r\n\r\n            //\r\n            //  OLD CODE\r\n            //  IE 6-7 only:\r\n            //\r\n            cPos = Env.getOffset(container);\r\n            doc = this.document.documentElement.ownerDocument;\r\n\r\n            if (!this.containerObj.currentStyle && doc.defaultView) {\r\n                // Non IE\r\n                // this is for hacks like this one used in wordpress for the admin bar:\r\n                // html { margin-top: 28px }\r\n                // seems like it doesn't work in IE\r\n\r\n                cPos[0] += Env.getProp(docElement, 'margin-left');\r\n                cPos[1] += Env.getProp(docElement, 'margin-top');\r\n\r\n                cPos[0] += Env.getProp(docElement, 'border-left-width');\r\n                cPos[1] += Env.getProp(docElement, 'border-top-width');\r\n\r\n                cPos[0] += Env.getProp(docElement, 'padding-left');\r\n                cPos[1] += Env.getProp(docElement, 'padding-top');\r\n            }\r\n\r\n            if (docBody) {\r\n                cPos[0] += Env.getProp(docBody, 'left');\r\n                cPos[1] += Env.getProp(docBody, 'top');\r\n            }\r\n\r\n            // Google Translate offers widgets for web authors. These widgets apparently tamper with the clientX\r\n            // and clientY coordinates of the mouse events. The minified sources seem to be the only publicly\r\n            // available version so we're doing it the hacky way: Add a fixed offset.\r\n            // see https://groups.google.com/d/msg/google-translate-general/H2zj0TNjjpY/jw6irtPlCw8J\r\n            if (typeof google === 'object' && google.translate) {\r\n                cPos[0] += 10;\r\n                cPos[1] += 25;\r\n            }\r\n\r\n            // add border width\r\n            cPos[0] += Env.getProp(container, 'border-left-width');\r\n            cPos[1] += Env.getProp(container, 'border-top-width');\r\n\r\n            // vml seems to ignore paddings\r\n            if (this.renderer.type !== 'vml') {\r\n                // add padding\r\n                cPos[0] += Env.getProp(container, 'padding-left');\r\n                cPos[1] += Env.getProp(container, 'padding-top');\r\n            }\r\n\r\n            cPos[0] += this.attr.offsetx;\r\n            cPos[1] += this.attr.offsety;\r\n\r\n            this.cPos = cPos.slice();\r\n            return this.cPos;\r\n        },\r\n\r\n        /**\r\n         * This function divides the board into 9 sections and returns an array <tt>[u,v]</tt> which symbolizes the location of <tt>position</tt>.\r\n         * Optional a <tt>margin</tt> to the inner of the board is respected.<br>\r\n         *\r\n         * @name Board#getPointLoc\r\n         * @param {Array} position Array of requested position <tt>[x, y]</tt> or <tt>[w, x, y]</tt>.\r\n         * @param {Array|Number} [margin] Optional margin for the inner of the board: <tt>[top, right, bottom, left]</tt>. A single number <tt>m</tt> is interpreted as <tt>[m, m, m, m]</tt>.\r\n         * @returns {Array} [u,v] with the following meanings:\r\n         * <pre>\r\n         *     v    u > |   -1    |    0   |    1   |\r\n         * ------------------------------------------\r\n         *     1        | [-1,1]  |  [0,1] |  [1,1] |\r\n         * ------------------------------------------\r\n         *     0        | [-1,0]  |  Board |  [1,0] |\r\n         * ------------------------------------------\r\n         *    -1        | [-1,-1] | [0,-1] | [1,-1] |\r\n         * </pre>\r\n         * Positions inside the board (minus margin) return the value <tt>[0,0]</tt>.\r\n         *\r\n         * @example\r\n         *      var point1, point2, point3, point4, margin,\r\n         *             p1Location, p2Location, p3Location, p4Location,\r\n         *             helppoint1, helppoint2, helppoint3, helppoint4;\r\n         *\r\n         *      // margin to make the boundingBox virtually smaller\r\n         *      margin = [2,2,2,2];\r\n         *\r\n         *      // Points which are seen on screen\r\n         *      point1 = board.create('point', [0,0]);\r\n         *      point2 = board.create('point', [0,7]);\r\n         *      point3 = board.create('point', [7,7]);\r\n         *      point4 = board.create('point', [-7,-5]);\r\n         *\r\n         *      p1Location = board.getPointLoc(point1.coords.usrCoords, margin);\r\n         *      p2Location = board.getPointLoc(point2.coords.usrCoords, margin);\r\n         *      p3Location = board.getPointLoc(point3.coords.usrCoords, margin);\r\n         *      p4Location = board.getPointLoc(point4.coords.usrCoords, margin);\r\n         *\r\n         *      // Text seen on screen\r\n         *      board.create('text', [1,-1, \"getPointLoc(A): \" + \"[\" + p1Location + \"]\"])\r\n         *      board.create('text', [1,-2, \"getPointLoc(B): \" + \"[\" + p2Location + \"]\"])\r\n         *      board.create('text', [1,-3, \"getPointLoc(C): \" + \"[\" + p3Location + \"]\"])\r\n         *      board.create('text', [1,-4, \"getPointLoc(D): \" + \"[\" + p4Location + \"]\"])\r\n         *\r\n         *\r\n         *      // Helping points that are used to create the helping lines\r\n         *      helppoint1 = board.create('point', [(function (){\r\n         *          var bbx = board.getBoundingBox();\r\n         *          return [bbx[2] - 2, bbx[1] -2];\r\n         *      })], {\r\n         *          visible: false,\r\n         *      })\r\n         *\r\n         *      helppoint2 = board.create('point', [(function (){\r\n         *          var bbx = board.getBoundingBox();\r\n         *          return [bbx[0] + 2, bbx[1] -2];\r\n         *      })], {\r\n         *          visible: false,\r\n         *      })\r\n         *\r\n         *      helppoint3 = board.create('point', [(function (){\r\n         *          var bbx = board.getBoundingBox();\r\n         *          return [bbx[0]+ 2, bbx[3] + 2];\r\n         *      })],{\r\n         *          visible: false,\r\n         *      })\r\n         *\r\n         *      helppoint4 = board.create('point', [(function (){\r\n         *          var bbx = board.getBoundingBox();\r\n         *          return [bbx[2] -2, bbx[3] + 2];\r\n         *      })], {\r\n         *          visible: false,\r\n         *      })\r\n         *\r\n         *      // Helping lines to visualize the 9 sectors and the margin\r\n         *      board.create('line', [helppoint1, helppoint2]);\r\n         *      board.create('line', [helppoint2, helppoint3]);\r\n         *      board.create('line', [helppoint3, helppoint4]);\r\n         *      board.create('line', [helppoint4, helppoint1]);\r\n         *\r\n         * </pre><div id=\"JXG4b3efef5-839d-4fac-bad1-7a14c0a89c70\" class=\"jxgbox\" style=\"width: 500px; height: 500px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG4b3efef5-839d-4fac-bad1-7a14c0a89c70',\r\n         *             {boundingbox: [-8, 8, 8,-8], maxboundingbox: [-7.5,7.5,7.5,-7.5], axis: true, showcopyright: false, shownavigation: false, showZoom: false});\r\n         *     var point1, point2, point3, point4, margin,\r\n         *             p1Location, p2Location, p3Location, p4Location,\r\n         *             helppoint1, helppoint2, helppoint3, helppoint4;\r\n         *\r\n         *      // margin to make the boundingBox virtually smaller\r\n         *      margin = [2,2,2,2];\r\n         *\r\n         *      // Points which are seen on screen\r\n         *      point1 = board.create('point', [0,0]);\r\n         *      point2 = board.create('point', [0,7]);\r\n         *      point3 = board.create('point', [7,7]);\r\n         *      point4 = board.create('point', [-7,-5]);\r\n         *\r\n         *      p1Location = board.getPointLoc(point1.coords.usrCoords, margin);\r\n         *      p2Location = board.getPointLoc(point2.coords.usrCoords, margin);\r\n         *      p3Location = board.getPointLoc(point3.coords.usrCoords, margin);\r\n         *      p4Location = board.getPointLoc(point4.coords.usrCoords, margin);\r\n         *\r\n         *      // Text seen on screen\r\n         *      board.create('text', [1,-1, \"getPointLoc(A): \" + \"[\" + p1Location + \"]\"])\r\n         *      board.create('text', [1,-2, \"getPointLoc(B): \" + \"[\" + p2Location + \"]\"])\r\n         *      board.create('text', [1,-3, \"getPointLoc(C): \" + \"[\" + p3Location + \"]\"])\r\n         *      board.create('text', [1,-4, \"getPointLoc(D): \" + \"[\" + p4Location + \"]\"])\r\n         *\r\n         *\r\n         *      // Helping points that are used to create the helping lines\r\n         *      helppoint1 = board.create('point', [(function (){\r\n         *          var bbx = board.getBoundingBox();\r\n         *          return [bbx[2] - 2, bbx[1] -2];\r\n         *      })], {\r\n         *          visible: false,\r\n         *      })\r\n         *\r\n         *      helppoint2 = board.create('point', [(function (){\r\n         *          var bbx = board.getBoundingBox();\r\n         *          return [bbx[0] + 2, bbx[1] -2];\r\n         *      })], {\r\n         *          visible: false,\r\n         *      })\r\n         *\r\n         *      helppoint3 = board.create('point', [(function (){\r\n         *          var bbx = board.getBoundingBox();\r\n         *          return [bbx[0]+ 2, bbx[3] + 2];\r\n         *      })],{\r\n         *          visible: false,\r\n         *      })\r\n         *\r\n         *      helppoint4 = board.create('point', [(function (){\r\n         *          var bbx = board.getBoundingBox();\r\n         *          return [bbx[2] -2, bbx[3] + 2];\r\n         *      })], {\r\n         *          visible: false,\r\n         *      })\r\n         *\r\n         *      // Helping lines to visualize the 9 sectors and the margin\r\n         *      board.create('line', [helppoint1, helppoint2]);\r\n         *      board.create('line', [helppoint2, helppoint3]);\r\n         *      board.create('line', [helppoint3, helppoint4]);\r\n         *      board.create('line', [helppoint4, helppoint1]);\r\n         *  })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        getPointLoc: function (position, margin) {\r\n            var bbox, pos, res, marg;\r\n\r\n            bbox = this.getBoundingBox();\r\n            pos = position;\r\n            if (pos.length === 2) {\r\n                pos.unshift(undefined);\r\n            }\r\n            res = [0, 0];\r\n            marg = margin || 0;\r\n            if (Type.isNumber(marg)) {\r\n                marg = [marg, marg, marg, marg];\r\n            }\r\n\r\n            if (pos[1] > (bbox[2] - marg[1])) {\r\n                res[0] = 1;\r\n            }\r\n            if (pos[1] < (bbox[0] + marg[3])) {\r\n                res[0] = -1;\r\n            }\r\n\r\n            if (pos[2] > (bbox[1] - marg[0])) {\r\n                res[1] = 1;\r\n            }\r\n            if (pos[2] < (bbox[3] + marg[2])) {\r\n                res[1] = -1;\r\n            }\r\n\r\n            return res;\r\n        },\r\n\r\n        /**\r\n         * This function calculates where the origin is located (@link Board#getPointLoc).\r\n         * Optional a <tt>margin</tt> to the inner of the board is respected.<br>\r\n         *\r\n         * @name Board#getLocationOrigin\r\n         * @param {Array|Number} [margin] Optional margin for the inner of the board: <tt>[top, right, bottom, left]</tt>. A single number <tt>m</tt> is interpreted as <tt>[m, m, m, m]</tt>.\r\n         * @returns {Array} [u,v] which shows where the origin is located (@link Board#getPointLoc).\r\n         */\r\n        getLocationOrigin: function (margin) {\r\n            return this.getPointLoc([0, 0], margin);\r\n        },\r\n\r\n        /**\r\n         * Get the position of the pointing device in screen coordinates, relative to the upper left corner\r\n         * of the host tag.\r\n         * @param {Event} e Event object given by the browser.\r\n         * @param {Number} [i] Only use in case of touch events. This determines which finger to use and should not be set\r\n         * for mouseevents.\r\n         * @returns {Array} Contains the mouse coordinates in screen coordinates, ready for {@link JXG.Coords}\r\n         */\r\n        getMousePosition: function (e, i) {\r\n            var cPos = this.getCoordsTopLeftCorner(),\r\n                absPos,\r\n                v;\r\n\r\n            // Position of cursor using clientX/Y\r\n            absPos = Env.getPosition(e, i, this.document);\r\n\r\n            // Old:\r\n            // This seems to be obsolete anyhow:\r\n            // \"In case there has been no down event before.\"\r\n            // if (!Type.exists(this.cssTransMat)) {\r\n            // this.updateCSSTransforms();\r\n            // }\r\n            // New:\r\n            // We have to update the CSS transform matrix all the time,\r\n            // since libraries like ZIMJS do not notify JSXGraph about a change.\r\n            // In particular, sending a resize event event to JSXGraph\r\n            // would be necessary.\r\n            this.updateCSSTransforms();\r\n\r\n            // Position relative to the top left corner\r\n            v = [1, absPos[0] - cPos[0], absPos[1] - cPos[1]];\r\n            v = Mat.matVecMult(this.cssTransMat, v);\r\n            v[1] /= v[0];\r\n            v[2] /= v[0];\r\n            return [v[1], v[2]];\r\n\r\n            // Method without CSS transformation\r\n            /*\r\n             return [absPos[0] - cPos[0], absPos[1] - cPos[1]];\r\n             */\r\n        },\r\n\r\n        /**\r\n         * Initiate moving the origin. This is used in mouseDown and touchStart listeners.\r\n         * @param {Number} x Current mouse/touch coordinates\r\n         * @param {Number} y Current mouse/touch coordinates\r\n         */\r\n        initMoveOrigin: function (x, y) {\r\n            this.drag_dx = x - this.origin.scrCoords[1];\r\n            this.drag_dy = y - this.origin.scrCoords[2];\r\n\r\n            this.mode = this.BOARD_MODE_MOVE_ORIGIN;\r\n            this.updateQuality = this.BOARD_QUALITY_LOW;\r\n        },\r\n\r\n        /**\r\n         * Collects all elements below the current mouse pointer and fulfilling the following constraints:\r\n         * <ul>\r\n         * <li>isDraggable</li>\r\n         * <li>visible</li>\r\n         * <li>not fixed</li>\r\n         * <li>not frozen</li>\r\n         * </ul>\r\n         * @param {Number} x Current mouse/touch coordinates\r\n         * @param {Number} y current mouse/touch coordinates\r\n         * @param {Object} evt An event object\r\n         * @param {String} type What type of event? 'touch', 'mouse' or 'pen'.\r\n         * @returns {Array} A list of geometric elements.\r\n         */\r\n        initMoveObject: function (x, y, evt, type) {\r\n            var pEl,\r\n                el,\r\n                collect = [],\r\n                offset = [],\r\n                haspoint,\r\n                len = this.objectsList.length,\r\n                dragEl = { visProp: { layer: -10000 } };\r\n\r\n            // Store status of key presses for 3D movement\r\n            this._shiftKey = evt.shiftKey;\r\n            this._ctrlKey = evt.ctrlKey;\r\n\r\n            //for (el in this.objects) {\r\n            for (el = 0; el < len; el++) {\r\n                pEl = this.objectsList[el];\r\n                haspoint = pEl.hasPoint && pEl.hasPoint(x, y);\r\n\r\n                if (pEl.visPropCalc.visible && haspoint) {\r\n                    pEl.triggerEventHandlers([type + 'down', 'down'], [evt]);\r\n                    this.downObjects.push(pEl);\r\n                }\r\n\r\n                if (haspoint &&\r\n                    pEl.isDraggable &&\r\n                    pEl.visPropCalc.visible &&\r\n                    ((this.geonextCompatibilityMode &&\r\n                        (Type.isPoint(pEl) || pEl.elementClass === Const.OBJECT_CLASS_TEXT)) ||\r\n                        !this.geonextCompatibilityMode) &&\r\n                    !pEl.evalVisProp('fixed')\r\n                    /*(!pEl.visProp.frozen) &&*/\r\n                ) {\r\n                    // Elements in the highest layer get priority.\r\n                    if (\r\n                        pEl.visProp.layer > dragEl.visProp.layer ||\r\n                        (pEl.visProp.layer === dragEl.visProp.layer &&\r\n                            pEl.lastDragTime.getTime() >= dragEl.lastDragTime.getTime())\r\n                    ) {\r\n                        // If an element and its label have the focus\r\n                        // simultaneously, the element is taken.\r\n                        // This only works if we assume that every browser runs\r\n                        // through this.objects in the right order, i.e. an element A\r\n                        // added before element B turns up here before B does.\r\n                        if (\r\n                            !this.attr.ignorelabels ||\r\n                            !Type.exists(dragEl.label) ||\r\n                            pEl !== dragEl.label\r\n                        ) {\r\n                            dragEl = pEl;\r\n                            collect.push(dragEl);\r\n\r\n                            // Save offset for large coords elements.\r\n                            if (Type.exists(dragEl.coords)) {\r\n                                if (dragEl.elementClass === Const.OBJECT_CLASS_POINT ||\r\n                                    dragEl.relativeCoords    // Relative texts like labels\r\n                                ) {\r\n                                    offset.push(Statistics.subtract(dragEl.coords.scrCoords.slice(1), [x, y]));\r\n                                } else {\r\n                                   // Images and texts\r\n                                    offset.push(Statistics.subtract(dragEl.actualCoords.scrCoords.slice(1), [x, y]));\r\n                                }\r\n                            } else {\r\n                                offset.push([0, 0]);\r\n                            }\r\n\r\n                            // We can't drop out of this loop because of the event handling system\r\n                            //if (this.attr.takefirst) {\r\n                            //    return collect;\r\n                            //}\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (this.attr.drag.enabled && collect.length > 0) {\r\n                this.mode = this.BOARD_MODE_DRAG;\r\n            }\r\n\r\n            // A one-element array is returned.\r\n            if (this.attr.takefirst) {\r\n                collect.length = 1;\r\n                this._drag_offset = offset[0];\r\n            } else {\r\n                collect = collect.slice(-1);\r\n                this._drag_offset = offset[offset.length - 1];\r\n            }\r\n\r\n            if (!this._drag_offset) {\r\n                this._drag_offset = [0, 0];\r\n            }\r\n\r\n            // Move drag element to the top of the layer\r\n            if (this.renderer.type === 'svg' && Type.exists(collect[0]) &&\r\n                collect.length === 1 && Type.exists(collect[0].rendNode)\r\n            ) {\r\n                // Move object to top\r\n                if (collect[0].evalVisProp('dragtotopoflayer')) {\r\n                    collect[0].rendNode.parentNode.appendChild(collect[0].rendNode);\r\n                }\r\n                // Move object's label to top\r\n                if (collect[0].hasLabel &&\r\n                    collect[0].label.evalVisProp('display') === 'html' &&\r\n                    collect[0].label.evalVisProp('dragtotopoflayer')\r\n                ) {\r\n                    collect[0].label.rendNode.parentNode.appendChild(collect[0].label.rendNode);\r\n                }\r\n            }\r\n\r\n            // // Init rotation angle and scale factor for two finger movements\r\n            // this.previousRotation = 0.0;\r\n            // this.previousScale = 1.0;\r\n\r\n            if (collect.length >= 1) {\r\n                collect[0].highlight(true);\r\n                this.triggerEventHandlers(['mousehit', 'hit'], [evt, collect[0]]);\r\n            }\r\n\r\n            return collect;\r\n        },\r\n\r\n        /**\r\n         * Moves an object.\r\n         * @param {Number} x Coordinate\r\n         * @param {Number} y Coordinate\r\n         * @param {Object} o The touch object that is dragged: {JXG.Board#mouse} or {JXG.Board#touches}.\r\n         * @param {Object} evt The event object.\r\n         * @param {String} type Mouse or touch event?\r\n         */\r\n        moveObject: function (x, y, o, evt, type) {\r\n            var newPos = new Coords(\r\n                Const.COORDS_BY_SCREEN,\r\n                this.getScrCoordsOfMouse(x, y),\r\n                this\r\n            ),\r\n                drag,\r\n                dragScrCoords,\r\n                newDragScrCoords;\r\n\r\n            if (!(o && o.obj)) {\r\n                return;\r\n            }\r\n            drag = o.obj;\r\n\r\n            // Avoid updates for very small movements of coordsElements, see below\r\n            if (drag.coords) {\r\n                dragScrCoords = drag.coords.scrCoords.slice();\r\n            }\r\n\r\n            this.addLogEntry('drag', drag, newPos.usrCoords.slice(1));\r\n\r\n            // Store the position and add the correctionvector from the mouse\r\n            // position to the object's coords.\r\n            this.drag_position = [newPos.scrCoords[1], newPos.scrCoords[2]];\r\n            this.drag_position = Statistics.add(this.drag_position, this._drag_offset);\r\n\r\n            // Store status of key presses for 3D movement\r\n            this._shiftKey = evt.shiftKey;\r\n            this._ctrlKey = evt.ctrlKey;\r\n\r\n            //\r\n            // We have to distinguish between CoordsElements and other elements like lines.\r\n            // The latter need the difference between two move events.\r\n            if (Type.exists(drag.coords)) {\r\n                drag.setPositionDirectly(Const.COORDS_BY_SCREEN, this.drag_position, [x, y]);\r\n            } else {\r\n                this.displayInfobox(false);\r\n                // Hide infobox in case the user has touched an intersection point\r\n                // and drags the underlying line now.\r\n\r\n                if (!isNaN(o.targets[0].Xprev + o.targets[0].Yprev)) {\r\n                    drag.setPositionDirectly(\r\n                        Const.COORDS_BY_SCREEN,\r\n                        [newPos.scrCoords[1], newPos.scrCoords[2]],\r\n                        [o.targets[0].Xprev, o.targets[0].Yprev]\r\n                    );\r\n                }\r\n                // Remember the actual position for the next move event. Then we are able to\r\n                // compute the difference vector.\r\n                o.targets[0].Xprev = newPos.scrCoords[1];\r\n                o.targets[0].Yprev = newPos.scrCoords[2];\r\n            }\r\n            // This may be necessary for some gliders and labels\r\n            if (Type.exists(drag.coords)) {\r\n                drag.prepareUpdate().update(false).updateRenderer();\r\n                this.updateInfobox(drag);\r\n                drag.prepareUpdate().update(true).updateRenderer();\r\n            }\r\n\r\n            if (drag.coords) {\r\n                newDragScrCoords = drag.coords.scrCoords;\r\n            }\r\n            // No updates for very small movements of coordsElements\r\n            if (\r\n                !drag.coords ||\r\n                dragScrCoords[1] !== newDragScrCoords[1] ||\r\n                dragScrCoords[2] !== newDragScrCoords[2]\r\n            ) {\r\n                drag.triggerEventHandlers([type + 'drag', 'drag'], [evt]);\r\n                // Update all elements of the board\r\n                this.update(drag);\r\n            }\r\n            drag.highlight(true);\r\n            this.triggerEventHandlers(['mousehit', 'hit'], [evt, drag]);\r\n\r\n            drag.lastDragTime = new Date();\r\n        },\r\n\r\n        /**\r\n         * Moves elements in multitouch mode.\r\n         * @param {Array} p1 x,y coordinates of first touch\r\n         * @param {Array} p2 x,y coordinates of second touch\r\n         * @param {Object} o The touch object that is dragged: {JXG.Board#touches}.\r\n         * @param {Object} evt The event object that lead to this movement.\r\n         */\r\n        twoFingerMove: function (o, id, evt) {\r\n            var drag;\r\n\r\n            if (Type.exists(o) && Type.exists(o.obj)) {\r\n                drag = o.obj;\r\n            } else {\r\n                return;\r\n            }\r\n\r\n            if (\r\n                drag.elementClass === Const.OBJECT_CLASS_LINE ||\r\n                drag.type === Const.OBJECT_TYPE_POLYGON\r\n            ) {\r\n                this.twoFingerTouchObject(o.targets, drag, id);\r\n            } else if (drag.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n                this.twoFingerTouchCircle(o.targets, drag, id);\r\n            }\r\n\r\n            if (evt) {\r\n                drag.triggerEventHandlers(['touchdrag', 'drag'], [evt]);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Compute the transformation matrix to move an element according to the\r\n         * previous and actual positions of finger 1 and finger 2.\r\n         * See also https://math.stackexchange.com/questions/4010538/solve-for-2d-translation-rotation-and-scale-given-two-touch-point-movements\r\n         *\r\n         * @param {Object} finger1 Actual and previous position of finger 1\r\n         * @param {Object} finger1 Actual and previous position of finger 1\r\n         * @param {Boolean} scalable Flag if element may be scaled\r\n         * @param {Boolean} rotatable Flag if element may be rotated\r\n         * @returns {Array}\r\n         */\r\n        getTwoFingerTransform(finger1, finger2, scalable, rotatable) {\r\n            var crd,\r\n                x1, y1, x2, y2,\r\n                dx, dy,\r\n                xx1, yy1, xx2, yy2,\r\n                dxx, dyy,\r\n                C, S, LL, tx, ty, lbda;\r\n\r\n            crd = new Coords(Const.COORDS_BY_SCREEN, [finger1.Xprev, finger1.Yprev], this).usrCoords;\r\n            x1 = crd[1];\r\n            y1 = crd[2];\r\n            crd = new Coords(Const.COORDS_BY_SCREEN, [finger2.Xprev, finger2.Yprev], this).usrCoords;\r\n            x2 = crd[1];\r\n            y2 = crd[2];\r\n\r\n            crd = new Coords(Const.COORDS_BY_SCREEN, [finger1.X, finger1.Y], this).usrCoords;\r\n            xx1 = crd[1];\r\n            yy1 = crd[2];\r\n            crd = new Coords(Const.COORDS_BY_SCREEN, [finger2.X, finger2.Y], this).usrCoords;\r\n            xx2 = crd[1];\r\n            yy2 = crd[2];\r\n\r\n            dx = x2 - x1;\r\n            dy = y2 - y1;\r\n            dxx = xx2 - xx1;\r\n            dyy = yy2 - yy1;\r\n\r\n            LL = dx * dx + dy * dy;\r\n            C = (dxx * dx + dyy * dy) / LL;\r\n            S = (dyy * dx - dxx * dy) / LL;\r\n            if (!scalable) {\r\n                lbda = Mat.hypot(C, S);\r\n                C /= lbda;\r\n                S /= lbda;\r\n            }\r\n            if (!rotatable) {\r\n                S = 0;\r\n            }\r\n            tx = 0.5 * (xx1 + xx2 - C * (x1 + x2) + S * (y1 + y2));\r\n            ty = 0.5 * (yy1 + yy2 - S * (x1 + x2) - C * (y1 + y2));\r\n\r\n            return [1, 0, 0,\r\n                tx, C, -S,\r\n                ty, S, C];\r\n        },\r\n\r\n        /**\r\n         * Moves, rotates and scales a line or polygon with two fingers.\r\n         * <p>\r\n         * If one vertex of the polygon snaps to the grid or to points or is not draggable,\r\n         * two-finger-movement is cancelled.\r\n         *\r\n         * @param {Array} tar Array containing touch event objects: {JXG.Board#touches.targets}.\r\n         * @param {object} drag The object that is dragged:\r\n         * @param {Number} id pointerId of the event. In case of old touch event this is emulated.\r\n         */\r\n        twoFingerTouchObject: function (tar, drag, id) {\r\n            var t, T,\r\n                ar, i, len,\r\n                snap = false;\r\n\r\n            if (\r\n                Type.exists(tar[0]) &&\r\n                Type.exists(tar[1]) &&\r\n                !isNaN(tar[0].Xprev + tar[0].Yprev + tar[1].Xprev + tar[1].Yprev)\r\n            ) {\r\n\r\n                T = this.getTwoFingerTransform(\r\n                    tar[0], tar[1],\r\n                    drag.evalVisProp('scalable'),\r\n                    drag.evalVisProp('rotatable'));\r\n                t = this.create('transform', T, { type: 'generic' });\r\n                t.update();\r\n\r\n                if (drag.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                    ar = [];\r\n                    if (drag.point1.draggable()) {\r\n                        ar.push(drag.point1);\r\n                    }\r\n                    if (drag.point2.draggable()) {\r\n                        ar.push(drag.point2);\r\n                    }\r\n                    t.applyOnce(ar);\r\n                } else if (drag.type === Const.OBJECT_TYPE_POLYGON) {\r\n                    len = drag.vertices.length - 1;\r\n                    snap = drag.evalVisProp('snaptogrid') || drag.evalVisProp('snaptopoints');\r\n                    for (i = 0; i < len && !snap; ++i) {\r\n                        snap = snap || drag.vertices[i].evalVisProp('snaptogrid') || drag.vertices[i].evalVisProp('snaptopoints');\r\n                        snap = snap || (!drag.vertices[i].draggable());\r\n                    }\r\n                    if (!snap) {\r\n                        ar = [];\r\n                        for (i = 0; i < len; ++i) {\r\n                            if (drag.vertices[i].draggable()) {\r\n                                ar.push(drag.vertices[i]);\r\n                            }\r\n                        }\r\n                        t.applyOnce(ar);\r\n                    }\r\n                }\r\n\r\n                this.update();\r\n                drag.highlight(true);\r\n            }\r\n        },\r\n\r\n        /*\r\n         * Moves, rotates and scales a circle with two fingers.\r\n         * @param {Array} tar Array containing touch event objects: {JXG.Board#touches.targets}.\r\n         * @param {object} drag The object that is dragged:\r\n         * @param {Number} id pointerId of the event. In case of old touch event this is emulated.\r\n         */\r\n        twoFingerTouchCircle: function (tar, drag, id) {\r\n            var fixEl, moveEl, np, op, fix, d, alpha, t1, t2, t3, t4;\r\n\r\n            if (drag.method === 'pointCircle' || drag.method === 'pointLine') {\r\n                return;\r\n            }\r\n\r\n            if (\r\n                Type.exists(tar[0]) &&\r\n                Type.exists(tar[1]) &&\r\n                !isNaN(tar[0].Xprev + tar[0].Yprev + tar[1].Xprev + tar[1].Yprev)\r\n            ) {\r\n                if (id === tar[0].num) {\r\n                    fixEl = tar[1];\r\n                    moveEl = tar[0];\r\n                } else {\r\n                    fixEl = tar[0];\r\n                    moveEl = tar[1];\r\n                }\r\n\r\n                fix = new Coords(Const.COORDS_BY_SCREEN, [fixEl.Xprev, fixEl.Yprev], this)\r\n                    .usrCoords;\r\n                // Previous finger position\r\n                op = new Coords(Const.COORDS_BY_SCREEN, [moveEl.Xprev, moveEl.Yprev], this)\r\n                    .usrCoords;\r\n                // New finger position\r\n                np = new Coords(Const.COORDS_BY_SCREEN, [moveEl.X, moveEl.Y], this).usrCoords;\r\n\r\n                alpha = Geometry.rad(op.slice(1), fix.slice(1), np.slice(1));\r\n\r\n                // Rotate and scale by the movement of the second finger\r\n                t1 = this.create('transform', [-fix[1], -fix[2]], {\r\n                    type: 'translate'\r\n                });\r\n                t2 = this.create('transform', [alpha], { type: 'rotate' });\r\n                t1.melt(t2);\r\n                if (drag.evalVisProp('scalable')) {\r\n                    d = Geometry.distance(fix, np) / Geometry.distance(fix, op);\r\n                    t3 = this.create('transform', [d, d], { type: 'scale' });\r\n                    t1.melt(t3);\r\n                }\r\n                t4 = this.create('transform', [fix[1], fix[2]], {\r\n                    type: 'translate'\r\n                });\r\n                t1.melt(t4);\r\n\r\n                if (drag.center.draggable()) {\r\n                    t1.applyOnce([drag.center]);\r\n                }\r\n\r\n                if (drag.method === 'twoPoints') {\r\n                    if (drag.point2.draggable()) {\r\n                        t1.applyOnce([drag.point2]);\r\n                    }\r\n                } else if (drag.method === 'pointRadius') {\r\n                    if (Type.isNumber(drag.updateRadius.origin)) {\r\n                        drag.setRadius(drag.radius * d);\r\n                    }\r\n                }\r\n\r\n                this.update(drag.center);\r\n                drag.highlight(true);\r\n            }\r\n        },\r\n\r\n        highlightElements: function (x, y, evt, target) {\r\n            var el,\r\n                pEl,\r\n                pId,\r\n                overObjects = {},\r\n                len = this.objectsList.length;\r\n\r\n            // Elements  below the mouse pointer which are not highlighted yet will be highlighted.\r\n            for (el = 0; el < len; el++) {\r\n                pEl = this.objectsList[el];\r\n                pId = pEl.id;\r\n                if (\r\n                    Type.exists(pEl.hasPoint) &&\r\n                    pEl.visPropCalc.visible &&\r\n                    pEl.hasPoint(x, y)\r\n                ) {\r\n                    // this is required in any case because otherwise the box won't be shown until the point is dragged\r\n                    this.updateInfobox(pEl);\r\n\r\n                    if (!Type.exists(this.highlightedObjects[pId])) {\r\n                        // highlight only if not highlighted\r\n                        overObjects[pId] = pEl;\r\n                        pEl.highlight();\r\n                        // triggers board event.\r\n                        this.triggerEventHandlers(['mousehit', 'hit'], [evt, pEl, target]);\r\n                    }\r\n\r\n                    if (pEl.mouseover) {\r\n                        pEl.triggerEventHandlers(['mousemove', 'move'], [evt]);\r\n                    } else {\r\n                        pEl.triggerEventHandlers(['mouseover', 'over'], [evt]);\r\n                        pEl.mouseover = true;\r\n                    }\r\n                }\r\n            }\r\n\r\n            for (el = 0; el < len; el++) {\r\n                pEl = this.objectsList[el];\r\n                pId = pEl.id;\r\n                if (pEl.mouseover) {\r\n                    if (!overObjects[pId]) {\r\n                        pEl.triggerEventHandlers(['mouseout', 'out'], [evt]);\r\n                        pEl.mouseover = false;\r\n                    }\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Helper function which returns a reasonable starting point for the object being dragged.\r\n         * Formerly known as initXYstart().\r\n         * @private\r\n         * @param {JXG.GeometryElement} obj The object to be dragged\r\n         * @param {Array} targets Array of targets. It is changed by this function.\r\n         */\r\n        saveStartPos: function (obj, targets) {\r\n            var xy = [],\r\n                i,\r\n                len;\r\n\r\n            if (obj.type === Const.OBJECT_TYPE_TICKS) {\r\n                xy.push([1, NaN, NaN]);\r\n            } else if (obj.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                xy.push(obj.point1.coords.usrCoords);\r\n                xy.push(obj.point2.coords.usrCoords);\r\n            } else if (obj.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n                xy.push(obj.center.coords.usrCoords);\r\n                if (obj.method === 'twoPoints') {\r\n                    xy.push(obj.point2.coords.usrCoords);\r\n                }\r\n            } else if (obj.type === Const.OBJECT_TYPE_POLYGON) {\r\n                len = obj.vertices.length - 1;\r\n                for (i = 0; i < len; i++) {\r\n                    xy.push(obj.vertices[i].coords.usrCoords);\r\n                }\r\n            } else if (obj.type === Const.OBJECT_TYPE_SECTOR) {\r\n                xy.push(obj.point1.coords.usrCoords);\r\n                xy.push(obj.point2.coords.usrCoords);\r\n                xy.push(obj.point3.coords.usrCoords);\r\n            } else if (Type.isPoint(obj) || obj.type === Const.OBJECT_TYPE_GLIDER) {\r\n                xy.push(obj.coords.usrCoords);\r\n            } else if (obj.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n                // if (Type.exists(obj.parents)) {\r\n                //     len = obj.parents.length;\r\n                //     if (len > 0) {\r\n                //         for (i = 0; i < len; i++) {\r\n                //             xy.push(this.select(obj.parents[i]).coords.usrCoords);\r\n                //         }\r\n                //     } else\r\n                // }\r\n                if (obj.points.length > 0) {\r\n                    xy.push(obj.points[0].usrCoords);\r\n                }\r\n            } else {\r\n                try {\r\n                    xy.push(obj.coords.usrCoords);\r\n                } catch (e) {\r\n                    JXG.debug(\r\n                        'JSXGraph+ saveStartPos: obj.coords.usrCoords not available: ' + e\r\n                    );\r\n                }\r\n            }\r\n\r\n            len = xy.length;\r\n            for (i = 0; i < len; i++) {\r\n                targets.Zstart.push(xy[i][0]);\r\n                targets.Xstart.push(xy[i][1]);\r\n                targets.Ystart.push(xy[i][2]);\r\n            }\r\n        },\r\n\r\n        mouseOriginMoveStart: function (evt) {\r\n            var r, pos;\r\n\r\n            r = this._isRequiredKeyPressed(evt, 'pan');\r\n            if (r) {\r\n                pos = this.getMousePosition(evt);\r\n                this.initMoveOrigin(pos[0], pos[1]);\r\n            }\r\n\r\n            return r;\r\n        },\r\n\r\n        mouseOriginMove: function (evt) {\r\n            var r = this.mode === this.BOARD_MODE_MOVE_ORIGIN,\r\n                pos;\r\n\r\n            if (r) {\r\n                pos = this.getMousePosition(evt);\r\n                this.moveOrigin(pos[0], pos[1], true);\r\n            }\r\n\r\n            return r;\r\n        },\r\n\r\n        /**\r\n         * Start moving the origin with one finger.\r\n         * @private\r\n         * @param  {Object} evt Event from touchStartListener\r\n         * @return {Boolean}   returns if the origin is moved.\r\n         */\r\n        touchStartMoveOriginOneFinger: function (evt) {\r\n            var touches = evt['touches'],\r\n                conditions,\r\n                pos;\r\n\r\n            conditions =\r\n                this.attr.pan.enabled && !this.attr.pan.needtwofingers && touches.length === 1;\r\n\r\n            if (conditions) {\r\n                pos = this.getMousePosition(evt, 0);\r\n                this.initMoveOrigin(pos[0], pos[1]);\r\n            }\r\n\r\n            return conditions;\r\n        },\r\n\r\n        /**\r\n         * Move the origin with one finger\r\n         * @private\r\n         * @param  {Object} evt Event from touchMoveListener\r\n         * @return {Boolean}     returns if the origin is moved.\r\n         */\r\n        touchOriginMove: function (evt) {\r\n            var r = this.mode === this.BOARD_MODE_MOVE_ORIGIN,\r\n                pos;\r\n\r\n            if (r) {\r\n                pos = this.getMousePosition(evt, 0);\r\n                this.moveOrigin(pos[0], pos[1], true);\r\n            }\r\n\r\n            return r;\r\n        },\r\n\r\n        /**\r\n         * Stop moving the origin with one finger\r\n         * @return {null} null\r\n         * @private\r\n         */\r\n        originMoveEnd: function () {\r\n            this.updateQuality = this.BOARD_QUALITY_HIGH;\r\n            this.mode = this.BOARD_MODE_NONE;\r\n        },\r\n\r\n        /**********************************************************\r\n         *\r\n         * Event Handler\r\n         *\r\n         **********************************************************/\r\n\r\n        /**\r\n         * Suppresses the default event handling.\r\n         * Used for context menu.\r\n         *\r\n         * @param {Event} e\r\n         * @returns {Boolean} false\r\n         */\r\n        suppressDefault: function (e) {\r\n            if (Type.exists(e)) {\r\n                e.preventDefault();\r\n            }\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Add all possible event handlers to the board object\r\n         * that move objects, i.e. mouse, pointer and touch events.\r\n         */\r\n        addEventHandlers: function () {\r\n            if (Env.supportsPointerEvents()) {\r\n                this.addPointerEventHandlers();\r\n            } else {\r\n                this.addMouseEventHandlers();\r\n                this.addTouchEventHandlers();\r\n            }\r\n\r\n            if (this.containerObj !== null) {\r\n                // this.containerObj.oncontextmenu = this.suppressDefault;\r\n                Env.addEvent(this.containerObj, 'contextmenu', this.suppressDefault, this);\r\n            }\r\n\r\n            // This one produces errors on IE\r\n            // // Env.addEvent(this.containerObj, 'contextmenu', function (e) { e.preventDefault(); return false;}, this);\r\n            // This one works on IE, Firefox and Chromium with default configurations. On some Safari\r\n            // or Opera versions the user must explicitly allow the deactivation of the context menu.\r\n        },\r\n\r\n        /**\r\n         * Remove all event handlers from the board object\r\n         */\r\n        removeEventHandlers: function () {\r\n            if ((this.hasPointerHandlers || this.hasMouseHandlers || this.hasTouchHandlers) &&\r\n                this.containerObj !== null\r\n            ) {\r\n                Env.removeEvent(this.containerObj, 'contextmenu', this.suppressDefault, this);\r\n            }\r\n\r\n            this.removeMouseEventHandlers();\r\n            this.removeTouchEventHandlers();\r\n            this.removePointerEventHandlers();\r\n\r\n            this.removeFullscreenEventHandlers();\r\n            this.removeKeyboardEventHandlers();\r\n            this.removeResizeEventHandlers();\r\n\r\n            // if (Env.isBrowser) {\r\n            //     if (Type.exists(this.resizeObserver)) {\r\n            //         this.stopResizeObserver();\r\n            //     } else {\r\n            //         Env.removeEvent(window, 'resize', this.resizeListener, this);\r\n            //         this.stopIntersectionObserver();\r\n            //     }\r\n            //     Env.removeEvent(window, 'scroll', this.scrollListener, this);\r\n            // }\r\n        },\r\n\r\n        /**\r\n         * Add resize related event handlers\r\n         *\r\n         */\r\n        addResizeEventHandlers: function () {\r\n            // var that = this;\r\n\r\n            this.resizeHandlers = [];\r\n            if (Env.isBrowser) {\r\n                try {\r\n                    // Supported by all new browsers\r\n                    // resizeObserver: triggered if size of the JSXGraph div changes.\r\n                    this.startResizeObserver();\r\n                    this.resizeHandlers.push('resizeobserver');\r\n                } catch (err) {\r\n                    // Certain Safari and edge version do not support\r\n                    // resizeObserver, but intersectionObserver.\r\n                    // resize event: triggered if size of window changes\r\n                    Env.addEvent(window, 'resize', this.resizeListener, this);\r\n                    // intersectionObserver: triggered if JSXGraph becomes visible.\r\n                    this.startIntersectionObserver();\r\n                    this.resizeHandlers.push('resize');\r\n                }\r\n                // Scroll event: needs to be captured since on mobile devices\r\n                // sometimes a header bar is displayed / hidden, which triggers a\r\n                // resize event.\r\n                Env.addEvent(window, 'scroll', this.scrollListener, this);\r\n                this.resizeHandlers.push('scroll');\r\n\r\n                // On browser print:\r\n                // we need to call the listener when having @media: print.\r\n                try {\r\n                    // window.matchMedia('print').addEventListener('change', this.printListenerMatch.apply(this, arguments));\r\n                    window.matchMedia('print').addEventListener('change', this.printListenerMatch.bind(this));\r\n                    window.matchMedia('screen').addEventListener('change', this.printListenerMatch.bind(this));\r\n                    this.resizeHandlers.push('print');\r\n                } catch (err) {\r\n                    JXG.debug(\"Error adding printListener\", err);\r\n                }\r\n                // if (Type.isFunction(MediaQueryList.prototype.addEventListener)) {\r\n                //     window.matchMedia('print').addEventListener('change', function (mql) {\r\n                //         if (mql.matches) {\r\n                //             that.printListener();\r\n                //         }\r\n                //     });\r\n                // } else if (Type.isFunction(MediaQueryList.prototype.addListener)) { // addListener might be deprecated\r\n                //     window.matchMedia('print').addListener(function (mql, ev) {\r\n                //         if (mql.matches) {\r\n                //             that.printListener(ev);\r\n                //         }\r\n                //     });\r\n                // }\r\n\r\n                // When closing the print dialog we again have to resize.\r\n                // Env.addEvent(window, 'afterprint', this.printListener, this);\r\n                // this.resizeHandlers.push('afterprint');\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Remove resize related event handlers\r\n         *\r\n         */\r\n        removeResizeEventHandlers: function () {\r\n            var i, e;\r\n            if (this.resizeHandlers.length > 0 && Env.isBrowser) {\r\n                for (i = 0; i < this.resizeHandlers.length; i++) {\r\n                    e = this.resizeHandlers[i];\r\n                    switch (e) {\r\n                        case 'resizeobserver':\r\n                            if (Type.exists(this.resizeObserver)) {\r\n                                this.stopResizeObserver();\r\n                            }\r\n                            break;\r\n                        case 'resize':\r\n                            Env.removeEvent(window, 'resize', this.resizeListener, this);\r\n                            if (Type.exists(this.intersectionObserver)) {\r\n                                this.stopIntersectionObserver();\r\n                            }\r\n                            break;\r\n                        case 'scroll':\r\n                            Env.removeEvent(window, 'scroll', this.scrollListener, this);\r\n                            break;\r\n                        case 'print':\r\n                            window.matchMedia('print').removeEventListener('change', this.printListenerMatch.bind(this), false);\r\n                            window.matchMedia('screen').removeEventListener('change', this.printListenerMatch.bind(this), false);\r\n                            break;\r\n                        // case 'afterprint':\r\n                        //     Env.removeEvent(window, 'afterprint', this.printListener, this);\r\n                        //     break;\r\n                    }\r\n                }\r\n                this.resizeHandlers = [];\r\n            }\r\n        },\r\n\r\n\r\n        /**\r\n         * Registers pointer event handlers.\r\n         */\r\n        addPointerEventHandlers: function () {\r\n            if (!this.hasPointerHandlers && Env.isBrowser) {\r\n                var moveTarget = this.attr.movetarget || this.containerObj;\r\n\r\n                if (window.navigator.msPointerEnabled) {\r\n                    // IE10-\r\n                    Env.addEvent(this.containerObj, 'MSPointerDown', this.pointerDownListener, this);\r\n                    Env.addEvent(moveTarget, 'MSPointerMove', this.pointerMoveListener, this);\r\n                } else {\r\n                    Env.addEvent(this.containerObj, 'pointerdown', this.pointerDownListener, this);\r\n                    Env.addEvent(moveTarget, 'pointermove', this.pointerMoveListener, this);\r\n                    Env.addEvent(moveTarget, 'pointerleave', this.pointerLeaveListener, this);\r\n                    Env.addEvent(moveTarget, 'click', this.pointerClickListener, this);\r\n                    Env.addEvent(moveTarget, 'dblclick', this.pointerDblClickListener, this);\r\n                }\r\n\r\n                if (this.containerObj !== null) {\r\n                    // This is needed for capturing touch events.\r\n                    // It is in jsxgraph.css, for ms-touch-action...\r\n                    this.containerObj.style.touchAction = 'none';\r\n                    // this.containerObj.style.touchAction = 'auto';\r\n                }\r\n\r\n                this.hasPointerHandlers = true;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Registers mouse move, down and wheel event handlers.\r\n         */\r\n        addMouseEventHandlers: function () {\r\n            if (!this.hasMouseHandlers && Env.isBrowser) {\r\n                var moveTarget = this.attr.movetarget || this.containerObj;\r\n\r\n                Env.addEvent(this.containerObj, 'mousedown', this.mouseDownListener, this);\r\n                Env.addEvent(moveTarget, 'mousemove', this.mouseMoveListener, this);\r\n                Env.addEvent(moveTarget, 'click', this.mouseClickListener, this);\r\n                Env.addEvent(moveTarget, 'dblclick', this.mouseDblClickListener, this);\r\n\r\n                this.hasMouseHandlers = true;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Register touch start and move and gesture start and change event handlers.\r\n         * @param {Boolean} appleGestures If set to false the gesturestart and gesturechange event handlers\r\n         * will not be registered.\r\n         *\r\n         * Since iOS 13, touch events were abandoned in favour of pointer events\r\n         */\r\n        addTouchEventHandlers: function (appleGestures) {\r\n            if (!this.hasTouchHandlers && Env.isBrowser) {\r\n                var moveTarget = this.attr.movetarget || this.containerObj;\r\n\r\n                Env.addEvent(this.containerObj, 'touchstart', this.touchStartListener, this);\r\n                Env.addEvent(moveTarget, 'touchmove', this.touchMoveListener, this);\r\n\r\n                /*\r\n                if (!Type.exists(appleGestures) || appleGestures) {\r\n                    // Gesture listener are called in touchStart and touchMove.\r\n                    //Env.addEvent(this.containerObj, 'gesturestart', this.gestureStartListener, this);\r\n                    //Env.addEvent(this.containerObj, 'gesturechange', this.gestureChangeListener, this);\r\n                }\r\n                */\r\n\r\n                this.hasTouchHandlers = true;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Registers pointer event handlers.\r\n         */\r\n        addWheelEventHandlers: function () {\r\n            if (!this.hasWheelHandlers && Env.isBrowser) {\r\n                Env.addEvent(this.containerObj, 'mousewheel', this.mouseWheelListener, this);\r\n                Env.addEvent(this.containerObj, 'DOMMouseScroll', this.mouseWheelListener, this);\r\n                this.hasWheelHandlers = true;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Add fullscreen events which update the CSS transformation matrix to correct\r\n         * the mouse/touch/pointer positions in case of CSS transformations.\r\n         */\r\n        addFullscreenEventHandlers: function () {\r\n            var i,\r\n                // standard/Edge, firefox, chrome/safari, IE11\r\n                events = [\r\n                    'fullscreenchange',\r\n                    'mozfullscreenchange',\r\n                    'webkitfullscreenchange',\r\n                    'msfullscreenchange'\r\n                ],\r\n                le = events.length;\r\n\r\n            if (!this.hasFullscreenEventHandlers && Env.isBrowser) {\r\n                for (i = 0; i < le; i++) {\r\n                    Env.addEvent(this.document, events[i], this.fullscreenListener, this);\r\n                }\r\n                this.hasFullscreenEventHandlers = true;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Register keyboard event handlers.\r\n         */\r\n        addKeyboardEventHandlers: function () {\r\n            if (this.attr.keyboard.enabled && !this.hasKeyboardHandlers && Env.isBrowser) {\r\n                Env.addEvent(this.containerObj, 'keydown', this.keyDownListener, this);\r\n                Env.addEvent(this.containerObj, 'focusin', this.keyFocusInListener, this);\r\n                Env.addEvent(this.containerObj, 'focusout', this.keyFocusOutListener, this);\r\n                this.hasKeyboardHandlers = true;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Remove all registered touch event handlers.\r\n         */\r\n        removeKeyboardEventHandlers: function () {\r\n            if (this.hasKeyboardHandlers && Env.isBrowser) {\r\n                Env.removeEvent(this.containerObj, 'keydown', this.keyDownListener, this);\r\n                Env.removeEvent(this.containerObj, 'focusin', this.keyFocusInListener, this);\r\n                Env.removeEvent(this.containerObj, 'focusout', this.keyFocusOutListener, this);\r\n                this.hasKeyboardHandlers = false;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Remove all registered event handlers regarding fullscreen mode.\r\n         */\r\n        removeFullscreenEventHandlers: function () {\r\n            var i,\r\n                // standard/Edge, firefox, chrome/safari, IE11\r\n                events = [\r\n                    'fullscreenchange',\r\n                    'mozfullscreenchange',\r\n                    'webkitfullscreenchange',\r\n                    'msfullscreenchange'\r\n                ],\r\n                le = events.length;\r\n\r\n            if (this.hasFullscreenEventHandlers && Env.isBrowser) {\r\n                for (i = 0; i < le; i++) {\r\n                    Env.removeEvent(this.document, events[i], this.fullscreenListener, this);\r\n                }\r\n                this.hasFullscreenEventHandlers = false;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Remove MSPointer* Event handlers.\r\n         */\r\n        removePointerEventHandlers: function () {\r\n            if (this.hasPointerHandlers && Env.isBrowser) {\r\n                var moveTarget = this.attr.movetarget || this.containerObj;\r\n\r\n                if (window.navigator.msPointerEnabled) {\r\n                    // IE10-\r\n                    Env.removeEvent(this.containerObj, 'MSPointerDown', this.pointerDownListener, this);\r\n                    Env.removeEvent(moveTarget, 'MSPointerMove', this.pointerMoveListener, this);\r\n                } else {\r\n                    Env.removeEvent(this.containerObj, 'pointerdown', this.pointerDownListener, this);\r\n                    Env.removeEvent(moveTarget, 'pointermove', this.pointerMoveListener, this);\r\n                    Env.removeEvent(moveTarget, 'pointerleave', this.pointerLeaveListener, this);\r\n                    Env.removeEvent(moveTarget, 'click', this.pointerClickListener, this);\r\n                    Env.removeEvent(moveTarget, 'dblclick', this.pointerDblClickListener, this);\r\n                }\r\n\r\n                if (this.hasWheelHandlers) {\r\n                    Env.removeEvent(this.containerObj, 'mousewheel', this.mouseWheelListener, this);\r\n                    Env.removeEvent(this.containerObj, 'DOMMouseScroll', this.mouseWheelListener, this);\r\n                }\r\n\r\n                if (this.hasPointerUp) {\r\n                    if (window.navigator.msPointerEnabled) {\r\n                        // IE10-\r\n                        Env.removeEvent(this.document, 'MSPointerUp', this.pointerUpListener, this);\r\n                    } else {\r\n                        Env.removeEvent(this.document, 'pointerup', this.pointerUpListener, this);\r\n                        Env.removeEvent(this.document, 'pointercancel', this.pointerUpListener, this);\r\n                    }\r\n                    this.hasPointerUp = false;\r\n                }\r\n\r\n                this.hasPointerHandlers = false;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * De-register mouse event handlers.\r\n         */\r\n        removeMouseEventHandlers: function () {\r\n            if (this.hasMouseHandlers && Env.isBrowser) {\r\n                var moveTarget = this.attr.movetarget || this.containerObj;\r\n\r\n                Env.removeEvent(this.containerObj, 'mousedown', this.mouseDownListener, this);\r\n                Env.removeEvent(moveTarget, 'mousemove', this.mouseMoveListener, this);\r\n                Env.removeEvent(moveTarget, 'click', this.mouseClickListener, this);\r\n                Env.removeEvent(moveTarget, 'dblclick', this.mouseDblClickListener, this);\r\n\r\n                if (this.hasMouseUp) {\r\n                    Env.removeEvent(this.document, 'mouseup', this.mouseUpListener, this);\r\n                    this.hasMouseUp = false;\r\n                }\r\n\r\n                if (this.hasWheelHandlers) {\r\n                    Env.removeEvent(this.containerObj, 'mousewheel', this.mouseWheelListener, this);\r\n                    Env.removeEvent(\r\n                        this.containerObj,\r\n                        'DOMMouseScroll',\r\n                        this.mouseWheelListener,\r\n                        this\r\n                    );\r\n                }\r\n\r\n                this.hasMouseHandlers = false;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Remove all registered touch event handlers.\r\n         */\r\n        removeTouchEventHandlers: function () {\r\n            if (this.hasTouchHandlers && Env.isBrowser) {\r\n                var moveTarget = this.attr.movetarget || this.containerObj;\r\n\r\n                Env.removeEvent(this.containerObj, 'touchstart', this.touchStartListener, this);\r\n                Env.removeEvent(moveTarget, 'touchmove', this.touchMoveListener, this);\r\n\r\n                if (this.hasTouchEnd) {\r\n                    Env.removeEvent(this.document, 'touchend', this.touchEndListener, this);\r\n                    this.hasTouchEnd = false;\r\n                }\r\n\r\n                this.hasTouchHandlers = false;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Handler for click on left arrow in the navigation bar\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        clickLeftArrow: function () {\r\n            this.moveOrigin(\r\n                this.origin.scrCoords[1] + this.canvasWidth * 0.1,\r\n                this.origin.scrCoords[2]\r\n            );\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Handler for click on right arrow in the navigation bar\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        clickRightArrow: function () {\r\n            this.moveOrigin(\r\n                this.origin.scrCoords[1] - this.canvasWidth * 0.1,\r\n                this.origin.scrCoords[2]\r\n            );\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Handler for click on up arrow in the navigation bar\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        clickUpArrow: function () {\r\n            this.moveOrigin(\r\n                this.origin.scrCoords[1],\r\n                this.origin.scrCoords[2] - this.canvasHeight * 0.1\r\n            );\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Handler for click on down arrow in the navigation bar\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        clickDownArrow: function () {\r\n            this.moveOrigin(\r\n                this.origin.scrCoords[1],\r\n                this.origin.scrCoords[2] + this.canvasHeight * 0.1\r\n            );\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Triggered on iOS/Safari while the user inputs a gesture (e.g. pinch) and is used to zoom into the board.\r\n         * Works on iOS/Safari and Android.\r\n         * @param {Event} evt Browser event object\r\n         * @returns {Boolean}\r\n         */\r\n        gestureChangeListener: function (evt) {\r\n            var c,\r\n                dir1 = [],\r\n                dir2 = [],\r\n                angle,\r\n                mi = 10,\r\n                isPinch = false,\r\n                // Save zoomFactors\r\n                zx = this.attr.zoom.factorx,\r\n                zy = this.attr.zoom.factory,\r\n                factor, dist, theta, bound,\r\n                zoomCenter,\r\n                doZoom = false,\r\n                dx, dy, cx, cy;\r\n\r\n            if (this.mode !== this.BOARD_MODE_ZOOM) {\r\n                return true;\r\n            }\r\n            evt.preventDefault();\r\n\r\n            dist = Geometry.distance(\r\n                [evt.touches[0].clientX, evt.touches[0].clientY],\r\n                [evt.touches[1].clientX, evt.touches[1].clientY],\r\n                2\r\n            );\r\n\r\n            // Android pinch to zoom\r\n            // evt.scale was available in iOS touch events (pre iOS 13)\r\n            // evt.scale is undefined in Android\r\n            if (evt.scale === undefined) {\r\n                evt.scale = dist / this.prevDist;\r\n            }\r\n\r\n            if (!Type.exists(this.prevCoords)) {\r\n                return false;\r\n            }\r\n            // Compute the angle of the two finger directions\r\n            dir1 = [\r\n                evt.touches[0].clientX - this.prevCoords[0][0],\r\n                evt.touches[0].clientY - this.prevCoords[0][1]\r\n            ];\r\n            dir2 = [\r\n                evt.touches[1].clientX - this.prevCoords[1][0],\r\n                evt.touches[1].clientY - this.prevCoords[1][1]\r\n            ];\r\n\r\n            if (\r\n                dir1[0] * dir1[0] + dir1[1] * dir1[1] < mi * mi &&\r\n                dir2[0] * dir2[0] + dir2[1] * dir2[1] < mi * mi\r\n            ) {\r\n                return false;\r\n            }\r\n\r\n            angle = Geometry.rad(dir1, [0, 0], dir2);\r\n            if (\r\n                this.isPreviousGesture !== 'pan' &&\r\n                Math.abs(angle) > Math.PI * 0.2 &&\r\n                Math.abs(angle) < Math.PI * 1.8\r\n            ) {\r\n                isPinch = true;\r\n            }\r\n\r\n            if (this.isPreviousGesture !== 'pan' && !isPinch) {\r\n                if (Math.abs(evt.scale) < 0.77 || Math.abs(evt.scale) > 1.3) {\r\n                    isPinch = true;\r\n                }\r\n            }\r\n\r\n            factor = evt.scale / this.prevScale;\r\n            this.prevScale = evt.scale;\r\n            this.prevCoords = [\r\n                [evt.touches[0].clientX, evt.touches[0].clientY],\r\n                [evt.touches[1].clientX, evt.touches[1].clientY]\r\n            ];\r\n\r\n            c = new Coords(Const.COORDS_BY_SCREEN, this.getMousePosition(evt, 0), this);\r\n\r\n            if (this.attr.pan.enabled && this.attr.pan.needtwofingers && !isPinch) {\r\n                // Pan detected\r\n                this.isPreviousGesture = 'pan';\r\n                this.moveOrigin(c.scrCoords[1], c.scrCoords[2], true);\r\n\r\n            } else if (this.attr.zoom.enabled && Math.abs(factor - 1.0) < 0.5) {\r\n                doZoom = false;\r\n                zoomCenter = this.attr.zoom.center;\r\n                // Pinch detected\r\n                if (this.attr.zoom.pinchhorizontal || this.attr.zoom.pinchvertical) {\r\n                    dx = Math.abs(evt.touches[0].clientX - evt.touches[1].clientX);\r\n                    dy = Math.abs(evt.touches[0].clientY - evt.touches[1].clientY);\r\n                    theta = Math.abs(Math.atan2(dy, dx));\r\n                    bound = (Math.PI * this.attr.zoom.pinchsensitivity) / 90.0;\r\n                }\r\n\r\n                if (!this.keepaspectratio &&\r\n                    this.attr.zoom.pinchhorizontal &&\r\n                    theta < bound) {\r\n                    this.attr.zoom.factorx = factor;\r\n                    this.attr.zoom.factory = 1.0;\r\n                    cx = 0;\r\n                    cy = 0;\r\n                    doZoom = true;\r\n                } else if (!this.keepaspectratio &&\r\n                    this.attr.zoom.pinchvertical &&\r\n                    Math.abs(theta - Math.PI * 0.5) < bound\r\n                ) {\r\n                    this.attr.zoom.factorx = 1.0;\r\n                    this.attr.zoom.factory = factor;\r\n                    cx = 0;\r\n                    cy = 0;\r\n                    doZoom = true;\r\n                } else if (this.attr.zoom.pinch) {\r\n                    this.attr.zoom.factorx = factor;\r\n                    this.attr.zoom.factory = factor;\r\n                    cx = c.usrCoords[1];\r\n                    cy = c.usrCoords[2];\r\n                    doZoom = true;\r\n                }\r\n\r\n                if (doZoom) {\r\n                    if (zoomCenter === 'board') {\r\n                        this.zoomIn();\r\n                    } else { // including zoomCenter === 'auto'\r\n                        this.zoomIn(cx, cy);\r\n                    }\r\n\r\n                    // Restore zoomFactors\r\n                    this.attr.zoom.factorx = zx;\r\n                    this.attr.zoom.factory = zy;\r\n                }\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Called by iOS/Safari as soon as the user starts a gesture. Works natively on iOS/Safari,\r\n         * on Android we emulate it.\r\n         * @param {Event} evt\r\n         * @returns {Boolean}\r\n         */\r\n        gestureStartListener: function (evt) {\r\n            var pos;\r\n\r\n            evt.preventDefault();\r\n            this.prevScale = 1.0;\r\n            // Android pinch to zoom\r\n            this.prevDist = Geometry.distance(\r\n                [evt.touches[0].clientX, evt.touches[0].clientY],\r\n                [evt.touches[1].clientX, evt.touches[1].clientY],\r\n                2\r\n            );\r\n            this.prevCoords = [\r\n                [evt.touches[0].clientX, evt.touches[0].clientY],\r\n                [evt.touches[1].clientX, evt.touches[1].clientY]\r\n            ];\r\n            this.isPreviousGesture = 'none';\r\n\r\n            // If pinch-to-zoom is interpreted as panning\r\n            // we have to prepare move origin\r\n            pos = this.getMousePosition(evt, 0);\r\n            this.initMoveOrigin(pos[0], pos[1]);\r\n\r\n            this.mode = this.BOARD_MODE_ZOOM;\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Test if the required key combination is pressed for wheel zoom, move origin and\r\n         * selection\r\n         * @private\r\n         * @param  {Object}  evt    Mouse or pen event\r\n         * @param  {String}  action String containing the action: 'zoom', 'pan', 'selection'.\r\n         * Corresponds to the attribute subobject.\r\n         * @return {Boolean}        true or false.\r\n         */\r\n        _isRequiredKeyPressed: function (evt, action) {\r\n            var obj = this.attr[action];\r\n            if (!obj.enabled) {\r\n                return false;\r\n            }\r\n\r\n            if (\r\n                ((obj.needshift && evt.shiftKey) || (!obj.needshift && !evt.shiftKey)) &&\r\n                ((obj.needctrl && evt.ctrlKey) || (!obj.needctrl && !evt.ctrlKey))\r\n            ) {\r\n                return true;\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        /*\r\n         * Pointer events\r\n         */\r\n\r\n        /**\r\n         *\r\n         * Check if pointer event is already registered in {@link JXG.Board#_board_touches}.\r\n         *\r\n         * @param  {Object} evt Event object\r\n         * @return {Boolean} true if down event has already been sent.\r\n         * @private\r\n         */\r\n        _isPointerRegistered: function (evt) {\r\n            var i,\r\n                len = this._board_touches.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                if (this._board_touches[i].pointerId === evt.pointerId) {\r\n                    return true;\r\n                }\r\n            }\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         *\r\n         * Store the position of a pointer event.\r\n         * If not yet done, registers a pointer event in {@link JXG.Board#_board_touches}.\r\n         * Allows to follow the path of that finger on the screen.\r\n         * Only two simultaneous touches are supported.\r\n         *\r\n         * @param {Object} evt Event object\r\n         * @returns {JXG.Board} Reference to the board\r\n         * @private\r\n         */\r\n        _pointerStorePosition: function (evt) {\r\n            var i, found;\r\n\r\n            for (i = 0, found = false; i < this._board_touches.length; i++) {\r\n                if (this._board_touches[i].pointerId === evt.pointerId) {\r\n                    this._board_touches[i].clientX = evt.clientX;\r\n                    this._board_touches[i].clientY = evt.clientY;\r\n                    found = true;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            // Restrict the number of simultaneous touches to 2\r\n            if (!found && this._board_touches.length < 2) {\r\n                this._board_touches.push({\r\n                    pointerId: evt.pointerId,\r\n                    clientX: evt.clientX,\r\n                    clientY: evt.clientY\r\n                });\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Deregisters a pointer event in {@link JXG.Board#_board_touches}.\r\n         * It happens if a finger has been lifted from the screen.\r\n         *\r\n         * @param {Object} evt Event object\r\n         * @returns {JXG.Board} Reference to the board\r\n         * @private\r\n         */\r\n        _pointerRemoveTouches: function (evt) {\r\n            var i;\r\n            for (i = 0; i < this._board_touches.length; i++) {\r\n                if (this._board_touches[i].pointerId === evt.pointerId) {\r\n                    this._board_touches.splice(i, 1);\r\n                    break;\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Remove all registered fingers from {@link JXG.Board#_board_touches}.\r\n         * This might be necessary if too many fingers have been registered.\r\n         * @returns {JXG.Board} Reference to the board\r\n         * @private\r\n         */\r\n        _pointerClearTouches: function (pId) {\r\n            // var i;\r\n            // if (pId) {\r\n            //     for (i = 0; i < this._board_touches.length; i++) {\r\n            //         if (pId === this._board_touches[i].pointerId) {\r\n            //             this._board_touches.splice(i, i);\r\n            //             break;\r\n            //         }\r\n            //     }\r\n            // } else {\r\n            // }\r\n            if (this._board_touches.length > 0) {\r\n                this.dehighlightAll();\r\n            }\r\n            this.updateQuality = this.BOARD_QUALITY_HIGH;\r\n            this.mode = this.BOARD_MODE_NONE;\r\n            this._board_touches = [];\r\n            this.touches = [];\r\n        },\r\n\r\n        /**\r\n         * Determine which input device is used for this action.\r\n         * Possible devices are 'touch', 'pen' and 'mouse'.\r\n         * This affects the precision and certain events.\r\n         * In case of no browser, 'mouse' is used.\r\n         *\r\n         * @see JXG.Board#pointerDownListener\r\n         * @see JXG.Board#pointerMoveListener\r\n         * @see JXG.Board#initMoveObject\r\n         * @see JXG.Board#moveObject\r\n         *\r\n         * @param {Event} evt The browsers event object.\r\n         * @returns {String} 'mouse', 'pen', or 'touch'\r\n         * @private\r\n         */\r\n        _getPointerInputDevice: function (evt) {\r\n            if (Env.isBrowser) {\r\n                if (\r\n                    evt.pointerType === 'touch' || // New\r\n                    (window.navigator.msMaxTouchPoints && // Old\r\n                        window.navigator.msMaxTouchPoints > 1)\r\n                ) {\r\n                    return 'touch';\r\n                }\r\n                if (evt.pointerType === 'mouse') {\r\n                    return 'mouse';\r\n                }\r\n                if (evt.pointerType === 'pen') {\r\n                    return 'pen';\r\n                }\r\n            }\r\n            return 'mouse';\r\n        },\r\n\r\n        /**\r\n         * This method is called by the browser when a pointing device is pressed on the screen.\r\n         * @param {Event} evt The browsers event object.\r\n         * @param {Object} object If the object to be dragged is already known, it can be submitted via this parameter\r\n         * @param {Boolean} [allowDefaultEventHandling=false] If true event is not canceled, i.e. prevent call of evt.preventDefault()\r\n         * @returns {Boolean} false if the first finger event is sent twice, or not a browser, or in selection mode. Otherwise returns true.\r\n         */\r\n        pointerDownListener: function (evt, object, allowDefaultEventHandling) {\r\n            var i, j, k, pos,\r\n                elements, sel, target_obj,\r\n                type = 'mouse', // Used in case of no browser\r\n                found, target, ta;\r\n\r\n            // Fix for Firefox browser: When using a second finger, the\r\n            // touch event for the first finger is sent again.\r\n            if (!object && this._isPointerRegistered(evt)) {\r\n                return false;\r\n            }\r\n\r\n            if (Type.evaluate(this.attr.movetarget) === null &&\r\n                Type.exists(evt.target) && Type.exists(evt.target.releasePointerCapture)) {\r\n                evt.target.releasePointerCapture(evt.pointerId);\r\n            }\r\n\r\n            if (!object && evt.isPrimary) {\r\n                // First finger down. To be on the safe side this._board_touches is cleared.\r\n                // this._pointerClearTouches();\r\n            }\r\n\r\n            if (!this.hasPointerUp) {\r\n                if (window.navigator.msPointerEnabled) {\r\n                    // IE10-\r\n                    Env.addEvent(this.document, 'MSPointerUp', this.pointerUpListener, this);\r\n                } else {\r\n                    // 'pointercancel' is fired e.g. if the finger leaves the browser and drags down the system menu on Android\r\n                    Env.addEvent(this.document, 'pointerup', this.pointerUpListener, this);\r\n                    Env.addEvent(this.document, 'pointercancel', this.pointerUpListener, this);\r\n                }\r\n                this.hasPointerUp = true;\r\n            }\r\n\r\n            if (this.hasMouseHandlers) {\r\n                this.removeMouseEventHandlers();\r\n            }\r\n\r\n            if (this.hasTouchHandlers) {\r\n                this.removeTouchEventHandlers();\r\n            }\r\n\r\n            // Prevent accidental selection of text\r\n            if (this.document.selection && Type.isFunction(this.document.selection.empty)) {\r\n                this.document.selection.empty();\r\n            } else if (window.getSelection) {\r\n                sel = window.getSelection();\r\n                if (sel.removeAllRanges) {\r\n                    try {\r\n                        sel.removeAllRanges();\r\n                    } catch (e) { }\r\n                }\r\n            }\r\n\r\n            // Mouse, touch or pen device\r\n            this._inputDevice = this._getPointerInputDevice(evt);\r\n            type = this._inputDevice;\r\n            this.options.precision.hasPoint = this.options.precision[type];\r\n\r\n            // Handling of multi touch with pointer events should be easier than with touch events.\r\n            // Every pointer device has its own pointerId, e.g. the mouse\r\n            // always has id 1 or 0, fingers and pens get unique ids every time a pointerDown event is fired and they will\r\n            // keep this id until a pointerUp event is fired. What we have to do here is:\r\n            //  1. collect all elements under the current pointer\r\n            //  2. run through the touches control structure\r\n            //    a. look for the object collected in step 1.\r\n            //    b. if an object is found, check the number of pointers. If appropriate, add the pointer.\r\n            pos = this.getMousePosition(evt);\r\n\r\n            // Handle selection rectangle\r\n            this._testForSelection(evt);\r\n            if (this.selectingMode) {\r\n                this._startSelecting(pos);\r\n                this.triggerEventHandlers(\r\n                    ['touchstartselecting', 'pointerstartselecting', 'startselecting'],\r\n                    [evt]\r\n                );\r\n                return; // don't continue as a normal click\r\n            }\r\n\r\n            if (this.attr.drag.enabled && object) {\r\n                elements = [object];\r\n                this.mode = this.BOARD_MODE_DRAG;\r\n            } else {\r\n                elements = this.initMoveObject(pos[0], pos[1], evt, type);\r\n            }\r\n\r\n            target_obj = {\r\n                num: evt.pointerId,\r\n                X: pos[0],\r\n                Y: pos[1],\r\n                Xprev: NaN,\r\n                Yprev: NaN,\r\n                Xstart: [],\r\n                Ystart: [],\r\n                Zstart: []\r\n            };\r\n\r\n            // If no draggable object can be found, get out here immediately\r\n            if (elements.length > 0) {\r\n                // check touches structure\r\n                target = elements[elements.length - 1];\r\n                found = false;\r\n\r\n                // Reminder: this.touches is the list of elements which\r\n                // currently 'possess' a pointer (mouse, pen, finger)\r\n                for (i = 0; i < this.touches.length; i++) {\r\n                    // An element receives a further touch, i.e.\r\n                    // the target is already in our touches array, add the pointer to the existing touch\r\n                    if (this.touches[i].obj === target) {\r\n                        j = i;\r\n                        k = this.touches[i].targets.push(target_obj) - 1;\r\n                        found = true;\r\n                        break;\r\n                    }\r\n                }\r\n                if (!found) {\r\n                    // A new element has been touched.\r\n                    k = 0;\r\n                    j =\r\n                        this.touches.push({\r\n                            obj: target,\r\n                            targets: [target_obj]\r\n                        }) - 1;\r\n                }\r\n\r\n                this.dehighlightAll();\r\n                target.highlight(true);\r\n\r\n                this.saveStartPos(target, this.touches[j].targets[k]);\r\n\r\n                // Prevent accidental text selection\r\n                // this could get us new trouble: input fields, links and drop down boxes placed as text\r\n                // on the board don't work anymore.\r\n                if (evt && evt.preventDefault && !allowDefaultEventHandling) {\r\n                    // All browser supporting pointer events know preventDefault()\r\n                    evt.preventDefault();\r\n                }\r\n            }\r\n\r\n            if (this.touches.length > 0 && !allowDefaultEventHandling) {\r\n                evt.preventDefault();\r\n                evt.stopPropagation();\r\n            }\r\n\r\n            if (!Env.isBrowser) {\r\n                return false;\r\n            }\r\n            if (this._getPointerInputDevice(evt) !== 'touch') {\r\n                if (this.mode === this.BOARD_MODE_NONE) {\r\n                    this.mouseOriginMoveStart(evt);\r\n                }\r\n            } else {\r\n                this._pointerStorePosition(evt);\r\n                evt.touches = this._board_touches;\r\n\r\n                // Touch events on empty areas of the board are handled here, see also touchStartListener\r\n                // 1. case: one finger. If allowed, this triggers pan with one finger\r\n                if (\r\n                    evt.touches.length === 1 &&\r\n                    this.mode === this.BOARD_MODE_NONE &&\r\n                    this.touchStartMoveOriginOneFinger(evt)\r\n                ) {\r\n                    // Empty by purpose\r\n                } else if (\r\n                    evt.touches.length === 2 &&\r\n                    (this.mode === this.BOARD_MODE_NONE ||\r\n                        this.mode === this.BOARD_MODE_MOVE_ORIGIN)\r\n                ) {\r\n                    // 2. case: two fingers: pinch to zoom or pan with two fingers needed.\r\n                    // This happens when the second finger hits the device. First, the\r\n                    // 'one finger pan mode' has to be cancelled.\r\n                    if (this.mode === this.BOARD_MODE_MOVE_ORIGIN) {\r\n                        this.originMoveEnd();\r\n                    }\r\n\r\n                    this.gestureStartListener(evt);\r\n                }\r\n            }\r\n\r\n            // Allow browser scrolling\r\n            // For this: pan by one finger has to be disabled\r\n\r\n            ta = 'none';   // JSXGraph catches all user touch events\r\n            if (this.mode === this.BOARD_MODE_NONE &&\r\n                (Type.evaluate(this.attr.browserpan) === true || Type.evaluate(this.attr.browserpan.enabled) === true) &&\r\n                // One-finger pan has priority over browserPan\r\n                (Type.evaluate(this.attr.pan.enabled) === false || Type.evaluate(this.attr.pan.needtwofingers) === true)\r\n            ) {\r\n                // ta = 'pan-x pan-y';  // JSXGraph allows browser scrolling\r\n                ta = 'auto';  // JSXGraph allows browser scrolling\r\n            }\r\n            this.containerObj.style.touchAction = ta;\r\n\r\n            this.triggerEventHandlers(['touchstart', 'down', 'pointerdown', 'MSPointerDown'], [evt]);\r\n\r\n            return true;\r\n        },\r\n\r\n        /**\r\n         * Internal handling of click events for pointers and mouse.\r\n         *\r\n         * @param {Event} evt The browsers event object.\r\n         * @param {Array} evtArray list of event names\r\n         * @private\r\n         */\r\n        _handleClicks: function(evt, evtArray) {\r\n            var that = this,\r\n                el, delay, suppress;\r\n\r\n            if (this.selectingMode) {\r\n                evt.stopPropagation();\r\n                return;\r\n            }\r\n\r\n            delay = Type.evaluate(this.attr.clickdelay);\r\n            suppress = Type.evaluate(this.attr.dblclicksuppressclick);\r\n\r\n            if (suppress) {\r\n                // dblclick suppresses previous click events\r\n                this._preventSingleClick = false;\r\n\r\n                // Wait if there is a dblclick event.\r\n                // If not fire a click event\r\n                this._singleClickTimer = setTimeout(function() {\r\n                    if (!that._preventSingleClick) {\r\n                        // Fire click event and remove element from click list\r\n                        that.triggerEventHandlers(evtArray, [evt]);\r\n                        for (el in that.clickObjects) {\r\n                            if (that.clickObjects.hasOwnProperty(el)) {\r\n                                that.clickObjects[el].triggerEventHandlers(evtArray, [evt]);\r\n                                delete that.clickObjects[el];\r\n                            }\r\n                        }\r\n                    }\r\n                }, delay);\r\n            } else {\r\n                // dblclick is preceded by two click events\r\n\r\n                // Fire click events\r\n                that.triggerEventHandlers(evtArray, [evt]);\r\n                for (el in that.clickObjects) {\r\n                    if (that.clickObjects.hasOwnProperty(el)) {\r\n                        that.clickObjects[el].triggerEventHandlers(evtArray, [evt]);\r\n                    }\r\n                }\r\n\r\n                // Clear list of clicked elements with a delay\r\n                setTimeout(function() {\r\n                    for (el in that.clickObjects) {\r\n                        if (that.clickObjects.hasOwnProperty(el)) {\r\n                            delete that.clickObjects[el];\r\n                        }\r\n                    }\r\n                }, delay);\r\n            }\r\n            evt.stopPropagation();\r\n        },\r\n\r\n        /**\r\n         * Internal handling of dblclick events for pointers and mouse.\r\n         *\r\n         * @param {Event} evt The browsers event object.\r\n         * @param {Array} evtArray list of event names\r\n         * @private\r\n         */\r\n        _handleDblClicks: function(evt, evtArray) {\r\n            var el;\r\n\r\n            if (this.selectingMode) {\r\n                evt.stopPropagation();\r\n                return;\r\n            }\r\n\r\n            // Notify that a dblclick has happened\r\n            this._preventSingleClick = true;\r\n            clearTimeout(this._singleClickTimer);\r\n\r\n            // Fire dblclick event\r\n            this.triggerEventHandlers(evtArray, [evt]);\r\n            for (el in this.clickObjects) {\r\n                if (this.clickObjects.hasOwnProperty(el)) {\r\n                    this.clickObjects[el].triggerEventHandlers(evtArray, [evt]);\r\n                    delete this.clickObjects[el];\r\n                }\r\n            }\r\n\r\n            evt.stopPropagation();\r\n        },\r\n\r\n        /**\r\n         * This method is called by the browser when a pointer device clicks on the screen.\r\n         * @param {Event} evt The browsers event object.\r\n         */\r\n        pointerClickListener: function (evt) {\r\n            this._handleClicks(evt, ['click', 'pointerclick']);\r\n        },\r\n\r\n        /**\r\n         * This method is called by the browser when a pointer device double clicks on the screen.\r\n         * @param {Event} evt The browsers event object.\r\n         */\r\n        pointerDblClickListener: function (evt) {\r\n            this._handleDblClicks(evt, ['dblclick', 'pointerdblclick']);\r\n        },\r\n\r\n        /**\r\n         * This method is called by the browser when the mouse device clicks on the screen.\r\n         * @param {Event} evt The browsers event object.\r\n         */\r\n        mouseClickListener: function (evt) {\r\n            this._handleClicks(evt, ['click', 'mouseclick']);\r\n        },\r\n\r\n        /**\r\n         * This method is called by the browser when the mouse device double clicks on the screen.\r\n         * @param {Event} evt The browsers event object.\r\n         */\r\n        mouseDblClickListener: function (evt) {\r\n            this._handleDblClicks(evt, ['dblclick', 'mousedblclick']);\r\n        },\r\n\r\n        // /**\r\n        //  * Called if pointer leaves an HTML tag. It is called by the inner-most tag.\r\n        //  * That means, if a JSXGraph text, i.e. an HTML div, is placed close\r\n        //  * to the border of the board, this pointerout event will be ignored.\r\n        //  * @param  {Event} evt\r\n        //  * @return {Boolean}\r\n        //  */\r\n        // pointerOutListener: function (evt) {\r\n        //     if (evt.target === this.containerObj ||\r\n        //         (this.renderer.type === 'svg' && evt.target === this.renderer.foreignObjLayer)) {\r\n        //         this.pointerUpListener(evt);\r\n        //     }\r\n        //     return this.mode === this.BOARD_MODE_NONE;\r\n        // },\r\n\r\n        /**\r\n         * Called periodically by the browser while the user moves a pointing device across the screen.\r\n         * @param {Event} evt\r\n         * @returns {Boolean}\r\n         */\r\n        pointerMoveListener: function (evt) {\r\n            var i, j, pos, eps,\r\n                touchTargets,\r\n                type = 'mouse'; // in case of no browser\r\n\r\n            if (\r\n                this._getPointerInputDevice(evt) === 'touch' &&\r\n                !this._isPointerRegistered(evt)\r\n            ) {\r\n                // Test, if there was a previous down event of this _getPointerId\r\n                // (in case it is a touch event).\r\n                // Otherwise this move event is ignored. This is necessary e.g. for sketchometry.\r\n                return this.BOARD_MODE_NONE;\r\n            }\r\n\r\n            if (!this.checkFrameRate(evt)) {\r\n                return false;\r\n            }\r\n\r\n            if (this.mode !== this.BOARD_MODE_DRAG) {\r\n                this.dehighlightAll();\r\n                this.displayInfobox(false);\r\n            }\r\n\r\n            if (this.mode !== this.BOARD_MODE_NONE) {\r\n                evt.preventDefault();\r\n                evt.stopPropagation();\r\n            }\r\n\r\n            this.updateQuality = this.BOARD_QUALITY_LOW;\r\n            // Mouse, touch or pen device\r\n            this._inputDevice = this._getPointerInputDevice(evt);\r\n            type = this._inputDevice;\r\n            this.options.precision.hasPoint = this.options.precision[type];\r\n            eps = this.options.precision.hasPoint * 0.3333;\r\n\r\n            pos = this.getMousePosition(evt);\r\n            // Ignore pointer move event if too close at the border\r\n            // and setPointerCapture is off\r\n            if (Type.evaluate(this.attr.movetarget) === null &&\r\n                pos[0] <= eps || pos[1] <= eps ||\r\n                pos[0] >= this.canvasWidth - eps ||\r\n                pos[1] >= this.canvasHeight - eps\r\n            ) {\r\n                return this.mode === this.BOARD_MODE_NONE;\r\n            }\r\n\r\n            // selection\r\n            if (this.selectingMode) {\r\n                this._moveSelecting(pos);\r\n                this.triggerEventHandlers(\r\n                    ['touchmoveselecting', 'moveselecting', 'pointermoveselecting'],\r\n                    [evt, this.mode]\r\n                );\r\n            } else if (!this.mouseOriginMove(evt)) {\r\n                if (this.mode === this.BOARD_MODE_DRAG) {\r\n                    // Run through all jsxgraph elements which are touched by at least one finger.\r\n                    for (i = 0; i < this.touches.length; i++) {\r\n                        touchTargets = this.touches[i].targets;\r\n                        // Run through all touch events which have been started on this jsxgraph element.\r\n                        for (j = 0; j < touchTargets.length; j++) {\r\n                            if (touchTargets[j].num === evt.pointerId) {\r\n                                touchTargets[j].X = pos[0];\r\n                                touchTargets[j].Y = pos[1];\r\n\r\n                                if (touchTargets.length === 1) {\r\n                                    // Touch by one finger: this is possible for all elements that can be dragged\r\n                                    this.moveObject(pos[0], pos[1], this.touches[i], evt, type);\r\n                                } else if (touchTargets.length === 2) {\r\n                                    // Touch by two fingers: e.g. moving lines\r\n                                    this.twoFingerMove(this.touches[i], evt.pointerId, evt);\r\n\r\n                                    touchTargets[j].Xprev = pos[0];\r\n                                    touchTargets[j].Yprev = pos[1];\r\n                                }\r\n\r\n                                // There is only one pointer in the evt object, so there's no point in looking further\r\n                                break;\r\n                            }\r\n                        }\r\n                    }\r\n                } else {\r\n                    if (this._getPointerInputDevice(evt) === 'touch') {\r\n                        this._pointerStorePosition(evt);\r\n\r\n                        if (this._board_touches.length === 2) {\r\n                            evt.touches = this._board_touches;\r\n                            this.gestureChangeListener(evt);\r\n                        }\r\n                    }\r\n\r\n                    // Move event without dragging an element\r\n                    this.highlightElements(pos[0], pos[1], evt, -1);\r\n                }\r\n            }\r\n\r\n            // Hiding the infobox is commented out, since it prevents showing the infobox\r\n            // on IE 11+ on 'over'\r\n            //if (this.mode !== this.BOARD_MODE_DRAG) {\r\n            //this.displayInfobox(false);\r\n            //}\r\n            this.triggerEventHandlers(['pointermove', 'MSPointerMove', 'move'], [evt, this.mode]);\r\n            this.updateQuality = this.BOARD_QUALITY_HIGH;\r\n\r\n            return this.mode === this.BOARD_MODE_NONE;\r\n        },\r\n\r\n        /**\r\n         * Triggered as soon as the user stops touching the device with at least one finger.\r\n         *\r\n         * @param {Event} evt\r\n         * @returns {Boolean}\r\n         */\r\n        pointerUpListener: function (evt) {\r\n            var i, j, found, eh,\r\n                touchTargets,\r\n                updateNeeded = false;\r\n\r\n            this.triggerEventHandlers(['touchend', 'up', 'pointerup', 'MSPointerUp'], [evt]);\r\n            this.displayInfobox(false);\r\n\r\n            if (evt) {\r\n                for (i = 0; i < this.touches.length; i++) {\r\n                    touchTargets = this.touches[i].targets;\r\n                    for (j = 0; j < touchTargets.length; j++) {\r\n                        if (touchTargets[j].num === evt.pointerId) {\r\n                            touchTargets.splice(j, 1);\r\n                            if (touchTargets.length === 0) {\r\n                                this.touches.splice(i, 1);\r\n                            }\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            this.originMoveEnd();\r\n            this.update();\r\n\r\n            // selection\r\n            if (this.selectingMode) {\r\n                this._stopSelecting(evt);\r\n                this.triggerEventHandlers(\r\n                    ['touchstopselecting', 'pointerstopselecting', 'stopselecting'],\r\n                    [evt]\r\n                );\r\n                this.stopSelectionMode();\r\n            } else {\r\n                for (i = this.downObjects.length - 1; i > -1; i--) {\r\n                    found = false;\r\n                    for (j = 0; j < this.touches.length; j++) {\r\n                        if (this.touches[j].obj.id === this.downObjects[i].id) {\r\n                            found = true;\r\n                        }\r\n                    }\r\n                    if (!found) {\r\n                        this.downObjects[i].triggerEventHandlers(\r\n                            ['touchend', 'up', 'pointerup', 'MSPointerUp'],\r\n                            [evt]\r\n                        );\r\n                        if (!Type.exists(this.downObjects[i].coords)) {\r\n                            // snapTo methods have to be called e.g. for line elements here.\r\n                            // For coordsElements there might be a conflict with\r\n                            // attractors, see commit from 2022.04.08, 11:12:18.\r\n                            this.downObjects[i].snapToGrid();\r\n                            this.downObjects[i].snapToPoints();\r\n                            updateNeeded = true;\r\n                        }\r\n\r\n                        // Check if we have to keep the element for a click or dblclick event\r\n                        // Otherwise remove it from downObjects\r\n                        eh = this.downObjects[i].eventHandlers;\r\n                        if ((Type.exists(eh.click) && eh.click.length > 0) ||\r\n                            (Type.exists(eh.pointerclick) && eh.pointerclick.length > 0) ||\r\n                            (Type.exists(eh.dblclick) && eh.dblclick.length > 0) ||\r\n                            (Type.exists(eh.pointerdblclick) && eh.pointerdblclick.length > 0)\r\n                        ) {\r\n                            this.clickObjects[this.downObjects[i].id] = this.downObjects[i];\r\n                        }\r\n                        this.downObjects.splice(i, 1);\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (this.hasPointerUp) {\r\n                if (window.navigator.msPointerEnabled) {\r\n                    // IE10-\r\n                    Env.removeEvent(this.document, 'MSPointerUp', this.pointerUpListener, this);\r\n                } else {\r\n                    Env.removeEvent(this.document, 'pointerup', this.pointerUpListener, this);\r\n                    Env.removeEvent(\r\n                        this.document,\r\n                        'pointercancel',\r\n                        this.pointerUpListener,\r\n                        this\r\n                    );\r\n                }\r\n                this.hasPointerUp = false;\r\n            }\r\n\r\n            // After one finger leaves the screen the gesture is stopped.\r\n            this._pointerClearTouches(evt.pointerId);\r\n            if (this._getPointerInputDevice(evt) !== 'touch') {\r\n                this.dehighlightAll();\r\n            }\r\n\r\n            if (updateNeeded) {\r\n                this.update();\r\n            }\r\n\r\n            return true;\r\n        },\r\n\r\n        /**\r\n         * Triggered by the pointerleave event. This is needed in addition to\r\n         * {@link JXG.Board#pointerUpListener} in the situation that a pen is used\r\n         * and after an up event the pen leaves the hover range vertically. Here, it happens that\r\n         * after the pointerup event further pointermove events are fired and elements get highlighted.\r\n         * This highlighting has to be cancelled.\r\n         *\r\n         * @param {Event} evt\r\n         * @returns {Boolean}\r\n         */\r\n        pointerLeaveListener: function (evt) {\r\n            this.displayInfobox(false);\r\n            this.dehighlightAll();\r\n\r\n            return true;\r\n        },\r\n\r\n        /**\r\n         * Touch-Events\r\n         */\r\n\r\n        /**\r\n         * This method is called by the browser when a finger touches the surface of the touch-device.\r\n         * @param {Event} evt The browsers event object.\r\n         * @returns {Boolean} ...\r\n         */\r\n        touchStartListener: function (evt) {\r\n            var i, j, k,\r\n                pos, elements, obj,\r\n                eps = this.options.precision.touch,\r\n                evtTouches = evt['touches'],\r\n                found,\r\n                targets, target,\r\n                touchTargets;\r\n\r\n            if (!this.hasTouchEnd) {\r\n                Env.addEvent(this.document, 'touchend', this.touchEndListener, this);\r\n                this.hasTouchEnd = true;\r\n            }\r\n\r\n            // Do not remove mouseHandlers, since Chrome on win tablets sends mouseevents if used with pen.\r\n            //if (this.hasMouseHandlers) { this.removeMouseEventHandlers(); }\r\n\r\n            // prevent accidental selection of text\r\n            if (this.document.selection && Type.isFunction(this.document.selection.empty)) {\r\n                this.document.selection.empty();\r\n            } else if (window.getSelection) {\r\n                window.getSelection().removeAllRanges();\r\n            }\r\n\r\n            // multitouch\r\n            this._inputDevice = 'touch';\r\n            this.options.precision.hasPoint = this.options.precision.touch;\r\n\r\n            // This is the most critical part. first we should run through the existing touches and collect all targettouches that don't belong to our\r\n            // previous touches. once this is done we run through the existing touches again and watch out for free touches that can be attached to our existing\r\n            // touches, e.g. we translate (parallel translation) a line with one finger, now a second finger is over this line. this should change the operation to\r\n            // a rotational translation. or one finger moves a circle, a second finger can be attached to the circle: this now changes the operation from translation to\r\n            // stretching. as a last step we're going through the rest of the targettouches and initiate new move operations:\r\n            //  * points have higher priority over other elements.\r\n            //  * if we find a targettouch over an element that could be transformed with more than one finger, we search the rest of the targettouches, if they are over\r\n            //    this element and add them.\r\n            // ADDENDUM 11/10/11:\r\n            //  (1) run through the touches control object,\r\n            //  (2) try to find the targetTouches for every touch. on touchstart only new touches are added, hence we can find a targettouch\r\n            //      for every target in our touches objects\r\n            //  (3) if one of the targettouches was bound to a touches targets array, mark it\r\n            //  (4) run through the targettouches. if the targettouch is marked, continue. otherwise check for elements below the targettouch:\r\n            //      (a) if no element could be found: mark the target touches and continue\r\n            //      --- in the following cases, 'init' means:\r\n            //           (i) check if the element is already used in another touches element, if so, mark the targettouch and continue\r\n            //          (ii) if not, init a new touches element, add the targettouch to the touches property and mark it\r\n            //      (b) if the element is a point, init\r\n            //      (c) if the element is a line, init and try to find a second targettouch on that line. if a second one is found, add and mark it\r\n            //      (d) if the element is a circle, init and try to find TWO other targettouches on that circle. if only one is found, mark it and continue. otherwise\r\n            //          add both to the touches array and mark them.\r\n            for (i = 0; i < evtTouches.length; i++) {\r\n                evtTouches[i].jxg_isused = false;\r\n            }\r\n\r\n            for (i = 0; i < this.touches.length; i++) {\r\n                touchTargets = this.touches[i].targets;\r\n                for (j = 0; j < touchTargets.length; j++) {\r\n                    touchTargets[j].num = -1;\r\n                    eps = this.options.precision.touch;\r\n\r\n                    do {\r\n                        for (k = 0; k < evtTouches.length; k++) {\r\n                            // find the new targettouches\r\n                            if (\r\n                                Math.abs(\r\n                                    Math.pow(evtTouches[k].screenX - touchTargets[j].X, 2) +\r\n                                    Math.pow(evtTouches[k].screenY - touchTargets[j].Y, 2)\r\n                                ) <\r\n                                eps * eps\r\n                            ) {\r\n                                touchTargets[j].num = k;\r\n                                touchTargets[j].X = evtTouches[k].screenX;\r\n                                touchTargets[j].Y = evtTouches[k].screenY;\r\n                                evtTouches[k].jxg_isused = true;\r\n                                break;\r\n                            }\r\n                        }\r\n\r\n                        eps *= 2;\r\n                    } while (\r\n                        touchTargets[j].num === -1 &&\r\n                        eps < this.options.precision.touchMax\r\n                    );\r\n\r\n                    if (touchTargets[j].num === -1) {\r\n                        JXG.debug(\r\n                            \"i couldn't find a targettouches for target no \" +\r\n                            j +\r\n                            ' on ' +\r\n                            this.touches[i].obj.name +\r\n                            ' (' +\r\n                            this.touches[i].obj.id +\r\n                            '). Removed the target.'\r\n                        );\r\n                        JXG.debug(\r\n                            'eps = ' + eps + ', touchMax = ' + Options.precision.touchMax\r\n                        );\r\n                        touchTargets.splice(i, 1);\r\n                    }\r\n                }\r\n            }\r\n\r\n            // we just re-mapped the targettouches to our existing touches list.\r\n            // now we have to initialize some touches from additional targettouches\r\n            for (i = 0; i < evtTouches.length; i++) {\r\n                if (!evtTouches[i].jxg_isused) {\r\n                    pos = this.getMousePosition(evt, i);\r\n                    // selection\r\n                    // this._testForSelection(evt); // we do not have shift or ctrl keys yet.\r\n                    if (this.selectingMode) {\r\n                        this._startSelecting(pos);\r\n                        this.triggerEventHandlers(\r\n                            ['touchstartselecting', 'startselecting'],\r\n                            [evt]\r\n                        );\r\n                        evt.preventDefault();\r\n                        evt.stopPropagation();\r\n                        this.options.precision.hasPoint = this.options.precision.mouse;\r\n                        return this.touches.length > 0; // don't continue as a normal click\r\n                    }\r\n\r\n                    elements = this.initMoveObject(pos[0], pos[1], evt, 'touch');\r\n                    if (elements.length !== 0) {\r\n                        obj = elements[elements.length - 1];\r\n                        target = {\r\n                            num: i,\r\n                            X: evtTouches[i].screenX,\r\n                            Y: evtTouches[i].screenY,\r\n                            Xprev: NaN,\r\n                            Yprev: NaN,\r\n                            Xstart: [],\r\n                            Ystart: [],\r\n                            Zstart: []\r\n                        };\r\n\r\n                        if (\r\n                            Type.isPoint(obj) ||\r\n                            obj.elementClass === Const.OBJECT_CLASS_TEXT ||\r\n                            obj.type === Const.OBJECT_TYPE_TICKS ||\r\n                            obj.type === Const.OBJECT_TYPE_IMAGE\r\n                        ) {\r\n                            // It's a point, so it's single touch, so we just push it to our touches\r\n                            targets = [target];\r\n\r\n                            // For the UNDO/REDO of object moves\r\n                            this.saveStartPos(obj, targets[0]);\r\n\r\n                            this.touches.push({ obj: obj, targets: targets });\r\n                            obj.highlight(true);\r\n                        } else if (\r\n                            obj.elementClass === Const.OBJECT_CLASS_LINE ||\r\n                            obj.elementClass === Const.OBJECT_CLASS_CIRCLE ||\r\n                            obj.elementClass === Const.OBJECT_CLASS_CURVE ||\r\n                            obj.type === Const.OBJECT_TYPE_POLYGON\r\n                        ) {\r\n                            found = false;\r\n\r\n                            // first check if this geometric object is already captured in this.touches\r\n                            for (j = 0; j < this.touches.length; j++) {\r\n                                if (obj.id === this.touches[j].obj.id) {\r\n                                    found = true;\r\n                                    // only add it, if we don't have two targets in there already\r\n                                    if (this.touches[j].targets.length === 1) {\r\n                                        // For the UNDO/REDO of object moves\r\n                                        this.saveStartPos(obj, target);\r\n                                        this.touches[j].targets.push(target);\r\n                                    }\r\n\r\n                                    evtTouches[i].jxg_isused = true;\r\n                                }\r\n                            }\r\n\r\n                            // we couldn't find it in touches, so we just init a new touches\r\n                            // IF there is a second touch targetting this line, we will find it later on, and then add it to\r\n                            // the touches control object.\r\n                            if (!found) {\r\n                                targets = [target];\r\n\r\n                                // For the UNDO/REDO of object moves\r\n                                this.saveStartPos(obj, targets[0]);\r\n                                this.touches.push({ obj: obj, targets: targets });\r\n                                obj.highlight(true);\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    evtTouches[i].jxg_isused = true;\r\n                }\r\n            }\r\n\r\n            if (this.touches.length > 0) {\r\n                evt.preventDefault();\r\n                evt.stopPropagation();\r\n            }\r\n\r\n            // Touch events on empty areas of the board are handled here:\r\n            // 1. case: one finger. If allowed, this triggers pan with one finger\r\n            if (\r\n                evtTouches.length === 1 &&\r\n                this.mode === this.BOARD_MODE_NONE &&\r\n                this.touchStartMoveOriginOneFinger(evt)\r\n            ) {\r\n            } else if (\r\n                evtTouches.length === 2 &&\r\n                (this.mode === this.BOARD_MODE_NONE ||\r\n                    this.mode === this.BOARD_MODE_MOVE_ORIGIN)\r\n            ) {\r\n                // 2. case: two fingers: pinch to zoom or pan with two fingers needed.\r\n                // This happens when the second finger hits the device. First, the\r\n                // 'one finger pan mode' has to be cancelled.\r\n                if (this.mode === this.BOARD_MODE_MOVE_ORIGIN) {\r\n                    this.originMoveEnd();\r\n                }\r\n                this.gestureStartListener(evt);\r\n            }\r\n\r\n            this.options.precision.hasPoint = this.options.precision.mouse;\r\n            this.triggerEventHandlers(['touchstart', 'down'], [evt]);\r\n\r\n            return false;\r\n            //return this.touches.length > 0;\r\n        },\r\n\r\n        /**\r\n         * Called periodically by the browser while the user moves his fingers across the device.\r\n         * @param {Event} evt\r\n         * @returns {Boolean}\r\n         */\r\n        touchMoveListener: function (evt) {\r\n            var i,\r\n                pos1,\r\n                pos2,\r\n                touchTargets,\r\n                evtTouches = evt['touches'];\r\n\r\n            if (!this.checkFrameRate(evt)) {\r\n                return false;\r\n            }\r\n\r\n            if (this.mode !== this.BOARD_MODE_NONE) {\r\n                evt.preventDefault();\r\n                evt.stopPropagation();\r\n            }\r\n\r\n            if (this.mode !== this.BOARD_MODE_DRAG) {\r\n                this.dehighlightAll();\r\n                this.displayInfobox(false);\r\n            }\r\n\r\n            this._inputDevice = 'touch';\r\n            this.options.precision.hasPoint = this.options.precision.touch;\r\n            this.updateQuality = this.BOARD_QUALITY_LOW;\r\n\r\n            // selection\r\n            if (this.selectingMode) {\r\n                for (i = 0; i < evtTouches.length; i++) {\r\n                    if (!evtTouches[i].jxg_isused) {\r\n                        pos1 = this.getMousePosition(evt, i);\r\n                        this._moveSelecting(pos1);\r\n                        this.triggerEventHandlers(\r\n                            ['touchmoves', 'moveselecting'],\r\n                            [evt, this.mode]\r\n                        );\r\n                        break;\r\n                    }\r\n                }\r\n            } else {\r\n                if (!this.touchOriginMove(evt)) {\r\n                    if (this.mode === this.BOARD_MODE_DRAG) {\r\n                        // Runs over through all elements which are touched\r\n                        // by at least one finger.\r\n                        for (i = 0; i < this.touches.length; i++) {\r\n                            touchTargets = this.touches[i].targets;\r\n                            if (touchTargets.length === 1) {\r\n                                // Touch by one finger:  this is possible for all elements that can be dragged\r\n                                if (evtTouches[touchTargets[0].num]) {\r\n                                    pos1 = this.getMousePosition(evt, touchTargets[0].num);\r\n                                    if (\r\n                                        pos1[0] < 0 ||\r\n                                        pos1[0] > this.canvasWidth ||\r\n                                        pos1[1] < 0 ||\r\n                                        pos1[1] > this.canvasHeight\r\n                                    ) {\r\n                                        return;\r\n                                    }\r\n                                    touchTargets[0].X = pos1[0];\r\n                                    touchTargets[0].Y = pos1[1];\r\n                                    this.moveObject(\r\n                                        pos1[0],\r\n                                        pos1[1],\r\n                                        this.touches[i],\r\n                                        evt,\r\n                                        'touch'\r\n                                    );\r\n                                }\r\n                            } else if (\r\n                                touchTargets.length === 2 &&\r\n                                touchTargets[0].num > -1 &&\r\n                                touchTargets[1].num > -1\r\n                            ) {\r\n                                // Touch by two fingers: moving lines, ...\r\n                                if (\r\n                                    evtTouches[touchTargets[0].num] &&\r\n                                    evtTouches[touchTargets[1].num]\r\n                                ) {\r\n                                    // Get coordinates of the two touches\r\n                                    pos1 = this.getMousePosition(evt, touchTargets[0].num);\r\n                                    pos2 = this.getMousePosition(evt, touchTargets[1].num);\r\n                                    if (\r\n                                        pos1[0] < 0 ||\r\n                                        pos1[0] > this.canvasWidth ||\r\n                                        pos1[1] < 0 ||\r\n                                        pos1[1] > this.canvasHeight ||\r\n                                        pos2[0] < 0 ||\r\n                                        pos2[0] > this.canvasWidth ||\r\n                                        pos2[1] < 0 ||\r\n                                        pos2[1] > this.canvasHeight\r\n                                    ) {\r\n                                        return;\r\n                                    }\r\n\r\n                                    touchTargets[0].X = pos1[0];\r\n                                    touchTargets[0].Y = pos1[1];\r\n                                    touchTargets[1].X = pos2[0];\r\n                                    touchTargets[1].Y = pos2[1];\r\n\r\n                                    this.twoFingerMove(\r\n                                        this.touches[i],\r\n                                        touchTargets[0].num,\r\n                                        evt\r\n                                    );\r\n\r\n                                    touchTargets[0].Xprev = pos1[0];\r\n                                    touchTargets[0].Yprev = pos1[1];\r\n                                    touchTargets[1].Xprev = pos2[0];\r\n                                    touchTargets[1].Yprev = pos2[1];\r\n                                }\r\n                            }\r\n                        }\r\n                    } else {\r\n                        if (evtTouches.length === 2) {\r\n                            this.gestureChangeListener(evt);\r\n                        }\r\n                        // Move event without dragging an element\r\n                        pos1 = this.getMousePosition(evt, 0);\r\n                        this.highlightElements(pos1[0], pos1[1], evt, -1);\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (this.mode !== this.BOARD_MODE_DRAG) {\r\n                this.displayInfobox(false);\r\n            }\r\n\r\n            this.triggerEventHandlers(['touchmove', 'move'], [evt, this.mode]);\r\n            this.options.precision.hasPoint = this.options.precision.mouse;\r\n            this.updateQuality = this.BOARD_QUALITY_HIGH;\r\n\r\n            return this.mode === this.BOARD_MODE_NONE;\r\n        },\r\n\r\n        /**\r\n         * Triggered as soon as the user stops touching the device with at least one finger.\r\n         * @param {Event} evt\r\n         * @returns {Boolean}\r\n         */\r\n        touchEndListener: function (evt) {\r\n            var i,\r\n                j,\r\n                k,\r\n                eps = this.options.precision.touch,\r\n                tmpTouches = [],\r\n                found,\r\n                foundNumber,\r\n                evtTouches = evt && evt['touches'],\r\n                touchTargets,\r\n                updateNeeded = false;\r\n\r\n            this.triggerEventHandlers(['touchend', 'up'], [evt]);\r\n            this.displayInfobox(false);\r\n\r\n            // selection\r\n            if (this.selectingMode) {\r\n                this._stopSelecting(evt);\r\n                this.triggerEventHandlers(['touchstopselecting', 'stopselecting'], [evt]);\r\n                this.stopSelectionMode();\r\n            } else if (evtTouches && evtTouches.length > 0) {\r\n                for (i = 0; i < this.touches.length; i++) {\r\n                    tmpTouches[i] = this.touches[i];\r\n                }\r\n                this.touches.length = 0;\r\n\r\n                // try to convert the operation, e.g. if a lines is rotated and translated with two fingers and one finger is lifted,\r\n                // convert the operation to a simple one-finger-translation.\r\n                // ADDENDUM 11/10/11:\r\n                // see addendum to touchStartListener from 11/10/11\r\n                // (1) run through the tmptouches\r\n                // (2) check the touches.obj, if it is a\r\n                //     (a) point, try to find the targettouch, if found keep it and mark the targettouch, else drop the touch.\r\n                //     (b) line with\r\n                //          (i) one target: try to find it, if found keep it mark the targettouch, else drop the touch.\r\n                //         (ii) two targets: if none can be found, drop the touch. if one can be found, remove the other target. mark all found targettouches\r\n                //     (c) circle with [proceed like in line]\r\n\r\n                // init the targettouches marker\r\n                for (i = 0; i < evtTouches.length; i++) {\r\n                    evtTouches[i].jxg_isused = false;\r\n                }\r\n\r\n                for (i = 0; i < tmpTouches.length; i++) {\r\n                    // could all targets of the current this.touches.obj be assigned to targettouches?\r\n                    found = false;\r\n                    foundNumber = 0;\r\n                    touchTargets = tmpTouches[i].targets;\r\n\r\n                    for (j = 0; j < touchTargets.length; j++) {\r\n                        touchTargets[j].found = false;\r\n                        for (k = 0; k < evtTouches.length; k++) {\r\n                            if (\r\n                                Math.abs(\r\n                                    Math.pow(evtTouches[k].screenX - touchTargets[j].X, 2) +\r\n                                    Math.pow(evtTouches[k].screenY - touchTargets[j].Y, 2)\r\n                                ) <\r\n                                eps * eps\r\n                            ) {\r\n                                touchTargets[j].found = true;\r\n                                touchTargets[j].num = k;\r\n                                touchTargets[j].X = evtTouches[k].screenX;\r\n                                touchTargets[j].Y = evtTouches[k].screenY;\r\n                                foundNumber += 1;\r\n                                break;\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    if (Type.isPoint(tmpTouches[i].obj)) {\r\n                        found = touchTargets[0] && touchTargets[0].found;\r\n                    } else if (tmpTouches[i].obj.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                        found =\r\n                            (touchTargets[0] && touchTargets[0].found) ||\r\n                            (touchTargets[1] && touchTargets[1].found);\r\n                    } else if (tmpTouches[i].obj.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n                        found = foundNumber === 1 || foundNumber === 3;\r\n                    }\r\n\r\n                    // if we found this object to be still dragged by the user, add it back to this.touches\r\n                    if (found) {\r\n                        this.touches.push({\r\n                            obj: tmpTouches[i].obj,\r\n                            targets: []\r\n                        });\r\n\r\n                        for (j = 0; j < touchTargets.length; j++) {\r\n                            if (touchTargets[j].found) {\r\n                                this.touches[this.touches.length - 1].targets.push({\r\n                                    num: touchTargets[j].num,\r\n                                    X: touchTargets[j].screenX,\r\n                                    Y: touchTargets[j].screenY,\r\n                                    Xprev: NaN,\r\n                                    Yprev: NaN,\r\n                                    Xstart: touchTargets[j].Xstart,\r\n                                    Ystart: touchTargets[j].Ystart,\r\n                                    Zstart: touchTargets[j].Zstart\r\n                                });\r\n                            }\r\n                        }\r\n                    } else {\r\n                        tmpTouches[i].obj.noHighlight();\r\n                    }\r\n                }\r\n            } else {\r\n                this.touches.length = 0;\r\n            }\r\n\r\n            for (i = this.downObjects.length - 1; i > -1; i--) {\r\n                found = false;\r\n                for (j = 0; j < this.touches.length; j++) {\r\n                    if (this.touches[j].obj.id === this.downObjects[i].id) {\r\n                        found = true;\r\n                    }\r\n                }\r\n                if (!found) {\r\n                    this.downObjects[i].triggerEventHandlers(['touchup', 'up'], [evt]);\r\n                    if (!Type.exists(this.downObjects[i].coords)) {\r\n                        // snapTo methods have to be called e.g. for line elements here.\r\n                        // For coordsElements there might be a conflict with\r\n                        // attractors, see commit from 2022.04.08, 11:12:18.\r\n                        this.downObjects[i].snapToGrid();\r\n                        this.downObjects[i].snapToPoints();\r\n                        updateNeeded = true;\r\n                    }\r\n                    this.downObjects.splice(i, 1);\r\n                }\r\n            }\r\n\r\n            if (!evtTouches || evtTouches.length === 0) {\r\n                if (this.hasTouchEnd) {\r\n                    Env.removeEvent(this.document, 'touchend', this.touchEndListener, this);\r\n                    this.hasTouchEnd = false;\r\n                }\r\n\r\n                this.dehighlightAll();\r\n                this.updateQuality = this.BOARD_QUALITY_HIGH;\r\n\r\n                this.originMoveEnd();\r\n                if (updateNeeded) {\r\n                    this.update();\r\n                }\r\n            }\r\n\r\n            return true;\r\n        },\r\n\r\n        /**\r\n         * This method is called by the browser when the mouse button is clicked.\r\n         * @param {Event} evt The browsers event object.\r\n         * @returns {Boolean} True if no element is found under the current mouse pointer, false otherwise.\r\n         */\r\n        mouseDownListener: function (evt) {\r\n            var pos, elements, result;\r\n\r\n            // prevent accidental selection of text\r\n            if (this.document.selection && Type.isFunction(this.document.selection.empty)) {\r\n                this.document.selection.empty();\r\n            } else if (window.getSelection) {\r\n                window.getSelection().removeAllRanges();\r\n            }\r\n\r\n            if (!this.hasMouseUp) {\r\n                Env.addEvent(this.document, 'mouseup', this.mouseUpListener, this);\r\n                this.hasMouseUp = true;\r\n            } else {\r\n                // In case this.hasMouseUp==true, it may be that there was a\r\n                // mousedown event before which was not followed by an mouseup event.\r\n                // This seems to happen with interactive whiteboard pens sometimes.\r\n                return;\r\n            }\r\n\r\n            this._inputDevice = 'mouse';\r\n            this.options.precision.hasPoint = this.options.precision.mouse;\r\n            pos = this.getMousePosition(evt);\r\n\r\n            // selection\r\n            this._testForSelection(evt);\r\n            if (this.selectingMode) {\r\n                this._startSelecting(pos);\r\n                this.triggerEventHandlers(['mousestartselecting', 'startselecting'], [evt]);\r\n                return; // don't continue as a normal click\r\n            }\r\n\r\n            elements = this.initMoveObject(pos[0], pos[1], evt, 'mouse');\r\n\r\n            // if no draggable object can be found, get out here immediately\r\n            if (elements.length === 0) {\r\n                this.mode = this.BOARD_MODE_NONE;\r\n                result = true;\r\n            } else {\r\n                this.mouse = {\r\n                    obj: null,\r\n                    targets: [\r\n                        {\r\n                            X: pos[0],\r\n                            Y: pos[1],\r\n                            Xprev: NaN,\r\n                            Yprev: NaN\r\n                        }\r\n                    ]\r\n                };\r\n                this.mouse.obj = elements[elements.length - 1];\r\n\r\n                this.dehighlightAll();\r\n                this.mouse.obj.highlight(true);\r\n\r\n                this.mouse.targets[0].Xstart = [];\r\n                this.mouse.targets[0].Ystart = [];\r\n                this.mouse.targets[0].Zstart = [];\r\n\r\n                this.saveStartPos(this.mouse.obj, this.mouse.targets[0]);\r\n\r\n                // prevent accidental text selection\r\n                // this could get us new trouble: input fields, links and drop down boxes placed as text\r\n                // on the board don't work anymore.\r\n                if (evt && evt.preventDefault) {\r\n                    evt.preventDefault();\r\n                } else if (window.event) {\r\n                    window.event.returnValue = false;\r\n                }\r\n            }\r\n\r\n            if (this.mode === this.BOARD_MODE_NONE) {\r\n                result = this.mouseOriginMoveStart(evt);\r\n            }\r\n\r\n            this.triggerEventHandlers(['mousedown', 'down'], [evt]);\r\n\r\n            return result;\r\n        },\r\n\r\n        /**\r\n         * This method is called by the browser when the mouse is moved.\r\n         * @param {Event} evt The browsers event object.\r\n         */\r\n        mouseMoveListener: function (evt) {\r\n            var pos;\r\n\r\n            if (!this.checkFrameRate(evt)) {\r\n                return false;\r\n            }\r\n\r\n            pos = this.getMousePosition(evt);\r\n\r\n            this.updateQuality = this.BOARD_QUALITY_LOW;\r\n\r\n            if (this.mode !== this.BOARD_MODE_DRAG) {\r\n                this.dehighlightAll();\r\n                this.displayInfobox(false);\r\n            }\r\n\r\n            // we have to check for four cases:\r\n            //   * user moves origin\r\n            //   * user drags an object\r\n            //   * user just moves the mouse, here highlight all elements at\r\n            //     the current mouse position\r\n            //   * the user is selecting\r\n\r\n            // selection\r\n            if (this.selectingMode) {\r\n                this._moveSelecting(pos);\r\n                this.triggerEventHandlers(\r\n                    ['mousemoveselecting', 'moveselecting'],\r\n                    [evt, this.mode]\r\n                );\r\n            } else if (!this.mouseOriginMove(evt)) {\r\n                if (this.mode === this.BOARD_MODE_DRAG) {\r\n                    this.moveObject(pos[0], pos[1], this.mouse, evt, 'mouse');\r\n                } else {\r\n                    // BOARD_MODE_NONE\r\n                    // Move event without dragging an element\r\n                    this.highlightElements(pos[0], pos[1], evt, -1);\r\n                }\r\n                this.triggerEventHandlers(['mousemove', 'move'], [evt, this.mode]);\r\n            }\r\n            this.updateQuality = this.BOARD_QUALITY_HIGH;\r\n        },\r\n\r\n        /**\r\n         * This method is called by the browser when the mouse button is released.\r\n         * @param {Event} evt\r\n         */\r\n        mouseUpListener: function (evt) {\r\n            var i;\r\n\r\n            if (this.selectingMode === false) {\r\n                this.triggerEventHandlers(['mouseup', 'up'], [evt]);\r\n            }\r\n\r\n            // redraw with high precision\r\n            this.updateQuality = this.BOARD_QUALITY_HIGH;\r\n\r\n            if (this.mouse && this.mouse.obj) {\r\n                if (!Type.exists(this.mouse.obj.coords)) {\r\n                    // snapTo methods have to be called e.g. for line elements here.\r\n                    // For coordsElements there might be a conflict with\r\n                    // attractors, see commit from 2022.04.08, 11:12:18.\r\n                    // The parameter is needed for lines with snapToGrid enabled\r\n                    this.mouse.obj.snapToGrid(this.mouse.targets[0]);\r\n                    this.mouse.obj.snapToPoints();\r\n                }\r\n            }\r\n\r\n            this.originMoveEnd();\r\n            this.dehighlightAll();\r\n            this.update();\r\n\r\n            // selection\r\n            if (this.selectingMode) {\r\n                this._stopSelecting(evt);\r\n                this.triggerEventHandlers(['mousestopselecting', 'stopselecting'], [evt]);\r\n                this.stopSelectionMode();\r\n            } else {\r\n                for (i = 0; i < this.downObjects.length; i++) {\r\n                    this.downObjects[i].triggerEventHandlers(['mouseup', 'up'], [evt]);\r\n                }\r\n            }\r\n\r\n            this.downObjects.length = 0;\r\n\r\n            if (this.hasMouseUp) {\r\n                Env.removeEvent(this.document, 'mouseup', this.mouseUpListener, this);\r\n                this.hasMouseUp = false;\r\n            }\r\n\r\n            // release dragged mouse object\r\n            this.mouse = null;\r\n        },\r\n\r\n        /**\r\n         * Handler for mouse wheel events. Used to zoom in and out of the board.\r\n         * @param {Event} evt\r\n         * @returns {Boolean}\r\n         */\r\n        mouseWheelListener: function (evt) {\r\n            var wd, zoomCenter, pos;\r\n\r\n            if (!this.attr.zoom.enabled ||\r\n                !this.attr.zoom.wheel ||\r\n                !this._isRequiredKeyPressed(evt, 'zoom')) {\r\n\r\n                return true;\r\n            }\r\n\r\n            evt = evt || window.event;\r\n            wd = evt.detail ? -evt.detail : evt.wheelDelta / 40;\r\n            zoomCenter = this.attr.zoom.center;\r\n\r\n            if (zoomCenter === 'board') {\r\n                pos = [];\r\n            } else { // including zoomCenter === 'auto'\r\n                pos = new Coords(Const.COORDS_BY_SCREEN, this.getMousePosition(evt), this).usrCoords;\r\n            }\r\n\r\n            // pos == [] does not throw an error\r\n            if (wd > 0) {\r\n                this.zoomIn(pos[1], pos[2]);\r\n            } else {\r\n                this.zoomOut(pos[1], pos[2]);\r\n            }\r\n\r\n            this.triggerEventHandlers(['mousewheel'], [evt]);\r\n\r\n            evt.preventDefault();\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Allow moving of JSXGraph elements with arrow keys.\r\n         * The selection of the element is done with the tab key. For this,\r\n         * the attribute 'tabindex' of the element has to be set to some number (default=0).\r\n         * tabindex corresponds to the HTML and SVG attribute of the same name.\r\n         * <p>\r\n         * Panning of the construction is done with arrow keys\r\n         * if the pan key (shift or ctrl - depending on the board attributes) is pressed.\r\n         * <p>\r\n         * Zooming is triggered with the keys +, o, -, if\r\n         * the pan key (shift or ctrl - depending on the board attributes) is pressed.\r\n         * <p>\r\n         * Keyboard control (move, pan, and zoom) is disabled if an HTML element of type input or textarea has received focus.\r\n         *\r\n         * @param  {Event} evt The browser's event object\r\n         *\r\n         * @see JXG.Board#keyboard\r\n         * @see JXG.Board#keyFocusInListener\r\n         * @see JXG.Board#keyFocusOutListener\r\n         *\r\n         */\r\n        keyDownListener: function (evt) {\r\n            var id_node = evt.target.id,\r\n                id, el, res, doc,\r\n                sX = 0,\r\n                sY = 0,\r\n                // dx, dy are provided in screen units and\r\n                // are converted to user coordinates\r\n                dx = Type.evaluate(this.attr.keyboard.dx) / this.unitX,\r\n                dy = Type.evaluate(this.attr.keyboard.dy) / this.unitY,\r\n                // u = 100,\r\n                doZoom = false,\r\n                done = true,\r\n                dir,\r\n                actPos;\r\n\r\n            if (!this.attr.keyboard.enabled || id_node === '') {\r\n                return false;\r\n            }\r\n\r\n            // Tab key should be handled by the browser\r\n            if (evt.keyCode === 9) {\r\n                return false;\r\n            }\r\n\r\n            // dx = Math.round(dx * u) / u;\r\n            // dy = Math.round(dy * u) / u;\r\n\r\n            // An element of type input or textarea has focus, get out of here.\r\n            doc = this.containerObj.shadowRoot || document;\r\n            if (doc.activeElement) {\r\n                el = doc.activeElement;\r\n                if (el.tagName === 'INPUT' || el.tagName === 'textarea') {\r\n                    return false;\r\n                }\r\n            }\r\n\r\n            // Get the JSXGraph id from the id of the SVG node.\r\n            id = id_node.replace(this.containerObj.id + '_', '');\r\n            el = this.select(id);\r\n\r\n            if (Type.exists(el.coords)) {\r\n                actPos = el.coords.usrCoords.slice(1);\r\n            }\r\n\r\n            if (\r\n                (Type.evaluate(this.attr.keyboard.panshift) && evt.shiftKey) ||\r\n                (Type.evaluate(this.attr.keyboard.panctrl) && evt.ctrlKey)\r\n            ) {\r\n                // Pan key has been pressed\r\n\r\n                if (Type.evaluate(this.attr.zoom.enabled) === true) {\r\n                    doZoom = true;\r\n                }\r\n\r\n                // Arrow keys\r\n                if (evt.keyCode === 38) {\r\n                    // up\r\n                    this.clickUpArrow();\r\n                } else if (evt.keyCode === 40) {\r\n                    // down\r\n                    this.clickDownArrow();\r\n                } else if (evt.keyCode === 37) {\r\n                    // left\r\n                    this.clickLeftArrow();\r\n                } else if (evt.keyCode === 39) {\r\n                    // right\r\n                    this.clickRightArrow();\r\n\r\n                    // Zoom keys\r\n                } else if (doZoom && evt.keyCode === 171) {\r\n                    // +\r\n                    this.zoomIn();\r\n                } else if (doZoom && evt.keyCode === 173) {\r\n                    // -\r\n                    this.zoomOut();\r\n                } else if (doZoom && evt.keyCode === 79) {\r\n                    // o\r\n                    this.zoom100();\r\n                } else {\r\n                    done = false;\r\n                }\r\n            } else if (!evt.shiftKey && !evt.ctrlKey) {         // Move an element if neither shift or ctrl are pressed\r\n                // Adapt dx, dy to snapToGrid and attractToGrid.\r\n                // snapToGrid has priority.\r\n                if (Type.exists(el.visProp)) {\r\n                    if (\r\n                        Type.exists(el.visProp.snaptogrid) &&\r\n                        el.visProp.snaptogrid &&\r\n                        el.evalVisProp('snapsizex') &&\r\n                        el.evalVisProp('snapsizey')\r\n                    ) {\r\n                        // Adapt dx, dy such that snapToGrid is possible\r\n                        res = el.getSnapSizes();\r\n                        sX = res[0];\r\n                        sY = res[1];\r\n                        // If snaptogrid is true,\r\n                        // we can only jump from grid point to grid point.\r\n                        dx = sX;\r\n                        dy = sY;\r\n                    } else if (\r\n                        Type.exists(el.visProp.attracttogrid) &&\r\n                        el.visProp.attracttogrid &&\r\n                        el.evalVisProp('attractordistance') &&\r\n                        el.evalVisProp('attractorunit')\r\n                    ) {\r\n                        // Adapt dx, dy such that attractToGrid is possible\r\n                        sX = 1.1 * el.evalVisProp('attractordistance');\r\n                        sY = sX;\r\n\r\n                        if (el.evalVisProp('attractorunit') === 'screen') {\r\n                            sX /= this.unitX;\r\n                            sY /= this.unitX;\r\n                        }\r\n                        dx = Math.max(sX, dx);\r\n                        dy = Math.max(sY, dy);\r\n                    }\r\n                }\r\n\r\n                if (evt.keyCode === 38) {\r\n                    // up\r\n                    dir = [0, dy];\r\n                } else if (evt.keyCode === 40) {\r\n                    // down\r\n                    dir = [0, -dy];\r\n                } else if (evt.keyCode === 37) {\r\n                    // left\r\n                    dir = [-dx, 0];\r\n                } else if (evt.keyCode === 39) {\r\n                    // right\r\n                    dir = [dx, 0];\r\n                } else {\r\n                    done = false;\r\n                }\r\n\r\n                if (dir && el.isDraggable &&\r\n                    el.visPropCalc.visible &&\r\n                    ((this.geonextCompatibilityMode &&\r\n                        (Type.isPoint(el) ||\r\n                            el.elementClass === Const.OBJECT_CLASS_TEXT)\r\n                    ) || !this.geonextCompatibilityMode) &&\r\n                    !el.evalVisProp('fixed')\r\n                ) {\r\n                    this.mode = this.BOARD_MODE_DRAG;\r\n                    if (Type.exists(el.coords)) {\r\n                        dir[0] += actPos[0];\r\n                        dir[1] += actPos[1];\r\n                    }\r\n                    // For coordsElement setPosition has to call setPositionDirectly.\r\n                    // Otherwise the position is set by a translation.\r\n                    if (Type.exists(el.coords)) {\r\n                        el.setPosition(JXG.COORDS_BY_USER, dir);\r\n                        this.updateInfobox(el);\r\n                    } else {\r\n                        this.displayInfobox(false);\r\n                        el.setPositionDirectly(\r\n                            Const.COORDS_BY_USER,\r\n                            dir,\r\n                            [0, 0]\r\n                        );\r\n                    }\r\n\r\n                    this.triggerEventHandlers(['keymove', 'move'], [evt, this.mode]);\r\n                    el.triggerEventHandlers(['keydrag', 'drag'], [evt]);\r\n                    this.mode = this.BOARD_MODE_NONE;\r\n                }\r\n            }\r\n\r\n            this.update();\r\n\r\n            if (done && Type.exists(evt.preventDefault)) {\r\n                evt.preventDefault();\r\n            }\r\n            return done;\r\n        },\r\n\r\n        /**\r\n         * Event listener for SVG elements getting focus.\r\n         * This is needed for highlighting when using keyboard control.\r\n         * Only elements having the attribute 'tabindex' can receive focus.\r\n         *\r\n         * @see JXG.Board#keyFocusOutListener\r\n         * @see JXG.Board#keyDownListener\r\n         * @see JXG.Board#keyboard\r\n         *\r\n         * @param  {Event} evt The browser's event object\r\n         */\r\n        keyFocusInListener: function (evt) {\r\n            var id_node = evt.target.id,\r\n                id,\r\n                el;\r\n\r\n            if (!this.attr.keyboard.enabled || id_node === '') {\r\n                return false;\r\n            }\r\n\r\n            // Get JSXGraph id from node id\r\n            id = id_node.replace(this.containerObj.id + '_', '');\r\n            el = this.select(id);\r\n            if (Type.exists(el.highlight)) {\r\n                el.highlight(true);\r\n                this.focusObjects = [id];\r\n                el.triggerEventHandlers(['hit'], [evt]);\r\n            }\r\n            if (Type.exists(el.coords)) {\r\n                this.updateInfobox(el);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Event listener for SVG elements losing focus.\r\n         * This is needed for dehighlighting when using keyboard control.\r\n         * Only elements having the attribute 'tabindex' can receive focus.\r\n         *\r\n         * @see JXG.Board#keyFocusInListener\r\n         * @see JXG.Board#keyDownListener\r\n         * @see JXG.Board#keyboard\r\n         *\r\n         * @param  {Event} evt The browser's event object\r\n         */\r\n        keyFocusOutListener: function (evt) {\r\n            if (!this.attr.keyboard.enabled) {\r\n                return false;\r\n            }\r\n            this.focusObjects = []; // This has to be before displayInfobox(false)\r\n            this.dehighlightAll();\r\n            this.displayInfobox(false);\r\n        },\r\n\r\n        /**\r\n         * Update the width and height of the JSXGraph container div element.\r\n         * If width and height are not supplied, read actual values with offsetWidth/Height,\r\n         * and call board.resizeContainer() with this values.\r\n         * <p>\r\n         * If necessary, also call setBoundingBox().\r\n         * @param {Number} [width=this.containerObj.offsetWidth] Width of the container element\r\n         * @param {Number} [height=this.containerObj.offsetHeight] Height of the container element\r\n         * @returns {JXG.Board} Reference to the board\r\n         *\r\n         * @see JXG.Board#startResizeObserver\r\n         * @see JXG.Board#resizeListener\r\n         * @see JXG.Board#resizeContainer\r\n         * @see JXG.Board#setBoundingBox\r\n         *\r\n         */\r\n        updateContainerDims: function (width, height) {\r\n            var w = width,\r\n                h = height,\r\n                // bb,\r\n                css,\r\n                width_adjustment, height_adjustment;\r\n\r\n            if (width === undefined) {\r\n                // Get size of the board's container div\r\n                //\r\n                // offsetWidth/Height ignores CSS transforms,\r\n                // getBoundingClientRect includes CSS transforms\r\n                //\r\n                // bb = this.containerObj.getBoundingClientRect();\r\n                // w = bb.width;\r\n                // h = bb.height;\r\n                w = this.containerObj.offsetWidth;\r\n                h = this.containerObj.offsetHeight;\r\n            }\r\n\r\n            if (width === undefined && window && window.getComputedStyle) {\r\n                // Subtract the border size\r\n                css = window.getComputedStyle(this.containerObj, null);\r\n                width_adjustment = parseFloat(css.getPropertyValue('border-left-width')) + parseFloat(css.getPropertyValue('border-right-width'));\r\n                if (!isNaN(width_adjustment)) {\r\n                    w -= width_adjustment;\r\n                }\r\n                height_adjustment = parseFloat(css.getPropertyValue('border-top-width')) + parseFloat(css.getPropertyValue('border-bottom-width'));\r\n                if (!isNaN(height_adjustment)) {\r\n                    h -= height_adjustment;\r\n                }\r\n            }\r\n\r\n            // If div is invisible - do nothing\r\n            if (w <= 0 || h <= 0 || isNaN(w) || isNaN(h)) {\r\n                return this;\r\n            }\r\n\r\n            // If bounding box is not yet initialized, do it now.\r\n            if (isNaN(this.getBoundingBox()[0])) {\r\n                this.setBoundingBox(this.attr.boundingbox, this.keepaspectratio, 'keep');\r\n            }\r\n\r\n            // Do nothing if the dimension did not change since being visible\r\n            // the last time. Note that if the div had display:none in the mean time,\r\n            // we did not store this._prevDim.\r\n            if (Type.exists(this._prevDim) && this._prevDim.w === w && this._prevDim.h === h) {\r\n                return this;\r\n            }\r\n            // Set the size of the SVG or canvas element\r\n            this.resizeContainer(w, h, true);\r\n            this._prevDim = {\r\n                w: w,\r\n                h: h\r\n            };\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Start observer which reacts to size changes of the JSXGraph\r\n         * container div element. Calls updateContainerDims().\r\n         * If not available, an event listener for the window-resize event is started.\r\n         * On mobile devices also scrolling might trigger resizes.\r\n         * However, resize events triggered by scrolling events should be ignored.\r\n         * Therefore, also a scrollListener is started.\r\n         * Resize can be controlled with the board attribute resize.\r\n         *\r\n         * @see JXG.Board#updateContainerDims\r\n         * @see JXG.Board#resizeListener\r\n         * @see JXG.Board#scrollListener\r\n         * @see JXG.Board#resize\r\n         *\r\n         */\r\n        startResizeObserver: function () {\r\n            var that = this;\r\n\r\n            if (!Env.isBrowser || !this.attr.resize || !this.attr.resize.enabled) {\r\n                return;\r\n            }\r\n\r\n            this.resizeObserver = new ResizeObserver(function (entries) {\r\n                var bb;\r\n                if (!that._isResizing) {\r\n                    that._isResizing = true;\r\n                    bb = entries[0].contentRect;\r\n                    window.setTimeout(function () {\r\n                        try {\r\n                            that.updateContainerDims(bb.width, bb.height);\r\n                        } catch (e) {\r\n                            JXG.debug(e);   // Used to log errors during board.update()\r\n                            that.stopResizeObserver();\r\n                        } finally {\r\n                            that._isResizing = false;\r\n                        }\r\n                    }, that.attr.resize.throttle);\r\n                }\r\n            });\r\n            this.resizeObserver.observe(this.containerObj);\r\n        },\r\n\r\n        /**\r\n         * Stops the resize observer.\r\n         * @see JXG.Board#startResizeObserver\r\n         *\r\n         */\r\n        stopResizeObserver: function () {\r\n            if (!Env.isBrowser || !this.attr.resize || !this.attr.resize.enabled) {\r\n                return;\r\n            }\r\n\r\n            if (Type.exists(this.resizeObserver)) {\r\n                this.resizeObserver.unobserve(this.containerObj);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Fallback solutions if there is no resizeObserver available in the browser.\r\n         * Reacts to resize events of the window (only). Otherwise similar to\r\n         * startResizeObserver(). To handle changes of the visibility\r\n         * of the JSXGraph container element, additionally an intersection observer is used.\r\n         * which watches changes in the visibility of the JSXGraph container element.\r\n         * This is necessary e.g. for register tabs or dia shows.\r\n         *\r\n         * @see JXG.Board#startResizeObserver\r\n         * @see JXG.Board#startIntersectionObserver\r\n         */\r\n        resizeListener: function () {\r\n            var that = this;\r\n\r\n            if (!Env.isBrowser || !this.attr.resize || !this.attr.resize.enabled) {\r\n                return;\r\n            }\r\n            if (!this._isScrolling && !this._isResizing) {\r\n                this._isResizing = true;\r\n                window.setTimeout(function () {\r\n                    that.updateContainerDims();\r\n                    that._isResizing = false;\r\n                }, this.attr.resize.throttle);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Listener to watch for scroll events. Sets board._isScrolling = true\r\n         * @param  {Event} evt The browser's event object\r\n         *\r\n         * @see JXG.Board#startResizeObserver\r\n         * @see JXG.Board#resizeListener\r\n         *\r\n         */\r\n        scrollListener: function (evt) {\r\n            var that = this;\r\n\r\n            if (!Env.isBrowser) {\r\n                return;\r\n            }\r\n            if (!this._isScrolling) {\r\n                this._isScrolling = true;\r\n                window.setTimeout(function () {\r\n                    that._isScrolling = false;\r\n                }, 66);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Watch for changes of the visibility of the JSXGraph container element.\r\n         *\r\n         * @see JXG.Board#startResizeObserver\r\n         * @see JXG.Board#resizeListener\r\n         *\r\n         */\r\n        startIntersectionObserver: function () {\r\n            var that = this,\r\n                options = {\r\n                    root: null,\r\n                    rootMargin: '0px',\r\n                    threshold: 0.8\r\n                };\r\n\r\n            try {\r\n                this.intersectionObserver = new IntersectionObserver(function (entries) {\r\n                    // If bounding box is not yet initialized, do it now.\r\n                    if (isNaN(that.getBoundingBox()[0])) {\r\n                        that.updateContainerDims();\r\n                    }\r\n                }, options);\r\n                this.intersectionObserver.observe(that.containerObj);\r\n            } catch (err) {\r\n                JXG.debug('JSXGraph: IntersectionObserver not available in this browser.');\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Stop the intersection observer\r\n         *\r\n         * @see JXG.Board#startIntersectionObserver\r\n         *\r\n         */\r\n        stopIntersectionObserver: function () {\r\n            if (Type.exists(this.intersectionObserver)) {\r\n                this.intersectionObserver.unobserve(this.containerObj);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Update the container before and after printing.\r\n         * @param {Event} [evt]\r\n         */\r\n        printListener: function(evt) {\r\n            this.updateContainerDims();\r\n        },\r\n\r\n        /**\r\n         * Wrapper for printListener to be used in mediaQuery matches.\r\n         * @param {MediaQueryList} mql\r\n         */\r\n        printListenerMatch: function (mql) {\r\n            if (mql.matches) {\r\n                this.printListener();\r\n            }\r\n        },\r\n\r\n        /**********************************************************\r\n         *\r\n         * End of Event Handlers\r\n         *\r\n         **********************************************************/\r\n\r\n        /**\r\n         * Initialize the info box object which is used to display\r\n         * the coordinates of points near the mouse pointer,\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        initInfobox: function (attributes) {\r\n            var attr = Type.copyAttributes(attributes, this.options, 'infobox');\r\n\r\n            attr.id = this.id + '_infobox';\r\n\r\n            /**\r\n             * Infobox close to points in which the points' coordinates are displayed.\r\n             * This is simply a JXG.Text element. Access through board.infobox.\r\n             * Uses CSS class .JXGinfobox.\r\n             *\r\n             * @namespace\r\n             * @name JXG.Board.infobox\r\n             * @type JXG.Text\r\n             *\r\n             * @example\r\n             * const board = JXG.JSXGraph.initBoard(BOARDID, {\r\n             *     boundingbox: [-0.5, 0.5, 0.5, -0.5],\r\n             *     intl: {\r\n             *         enabled: false,\r\n             *         locale: 'de-DE'\r\n             *     },\r\n             *     keepaspectratio: true,\r\n             *     axis: true,\r\n             *     infobox: {\r\n             *         distanceY: 40,\r\n             *         intl: {\r\n             *             enabled: true,\r\n             *             options: {\r\n             *                 minimumFractionDigits: 1,\r\n             *                 maximumFractionDigits: 2\r\n             *             }\r\n             *         }\r\n             *     }\r\n             * });\r\n             * var p = board.create('point', [0.1, 0.1], {});\r\n             *\r\n             * </pre><div id=\"JXG822161af-fe77-4769-850f-cdf69935eab0\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n             * <script type=\"text/javascript\">\r\n             *     (function() {\r\n             *     const board = JXG.JSXGraph.initBoard('JXG822161af-fe77-4769-850f-cdf69935eab0', {\r\n             *         boundingbox: [-0.5, 0.5, 0.5, -0.5], showcopyright: false, shownavigation: false,\r\n             *         intl: {\r\n             *             enabled: false,\r\n             *             locale: 'de-DE'\r\n             *         },\r\n             *         keepaspectratio: true,\r\n             *         axis: true,\r\n             *         infobox: {\r\n             *             distanceY: 40,\r\n             *             intl: {\r\n             *                 enabled: true,\r\n             *                 options: {\r\n             *                     minimumFractionDigits: 1,\r\n             *                     maximumFractionDigits: 2\r\n             *                 }\r\n             *             }\r\n             *         }\r\n             *     });\r\n             *     var p = board.create('point', [0.1, 0.1], {});\r\n             *     })();\r\n             *\r\n             * </script><pre>\r\n             *\r\n             */\r\n            this.infobox = this.create('text', [0, 0, '0,0'], attr);\r\n            // this.infobox.needsUpdateSize = false;  // That is not true, but it speeds drawing up.\r\n            this.infobox.dump = false;\r\n\r\n            this.displayInfobox(false);\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Updates and displays a little info box to show coordinates of current selected points.\r\n         * @param {JXG.GeometryElement} el A GeometryElement\r\n         * @returns {JXG.Board} Reference to the board\r\n         * @see JXG.Board#displayInfobox\r\n         * @see JXG.Board#showInfobox\r\n         * @see Point#showInfobox\r\n         *\r\n         */\r\n        updateInfobox: function (el) {\r\n            var x, y, xc, yc,\r\n                vpinfoboxdigits,\r\n                distX, distY,\r\n                vpsi = el.evalVisProp('showinfobox');\r\n\r\n            if ((!Type.evaluate(this.attr.showinfobox) && vpsi === 'inherit') || !vpsi) {\r\n                return this;\r\n            }\r\n\r\n            if (Type.isPoint(el)) {\r\n                xc = el.coords.usrCoords[1];\r\n                yc = el.coords.usrCoords[2];\r\n                distX = this.infobox.evalVisProp('distancex');\r\n                distY = this.infobox.evalVisProp('distancey');\r\n\r\n                this.infobox.setCoords(\r\n                    xc + distX / this.unitX,\r\n                    yc + distY / this.unitY\r\n                );\r\n\r\n                vpinfoboxdigits = el.evalVisProp('infoboxdigits');\r\n                if (typeof el.infoboxText !== 'string') {\r\n                    if (vpinfoboxdigits === 'auto') {\r\n                        if (this.infobox.useLocale()) {\r\n                            x = this.infobox.formatNumberLocale(xc);\r\n                            y = this.infobox.formatNumberLocale(yc);\r\n                        } else {\r\n                            x = Type.autoDigits(xc);\r\n                            y = Type.autoDigits(yc);\r\n                        }\r\n                    } else if (Type.isNumber(vpinfoboxdigits)) {\r\n                        if (this.infobox.useLocale()) {\r\n                            x = this.infobox.formatNumberLocale(xc, vpinfoboxdigits);\r\n                            y = this.infobox.formatNumberLocale(yc, vpinfoboxdigits);\r\n                        } else {\r\n                            x = Type.toFixed(xc, vpinfoboxdigits);\r\n                            y = Type.toFixed(yc, vpinfoboxdigits);\r\n                        }\r\n\r\n                    } else {\r\n                        x = xc;\r\n                        y = yc;\r\n                    }\r\n\r\n                    this.highlightInfobox(x, y, el);\r\n                } else {\r\n                    this.highlightCustomInfobox(el.infoboxText, el);\r\n                }\r\n\r\n                this.displayInfobox(true);\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set infobox visible / invisible.\r\n         *\r\n         * It uses its property hiddenByParent to memorize its status.\r\n         * In this way, many DOM access can be avoided.\r\n         *\r\n         * @param  {Boolean} val true for visible, false for invisible\r\n         * @returns {JXG.Board} Reference to the board.\r\n         * @see JXG.Board#updateInfobox\r\n         *\r\n         */\r\n        displayInfobox: function (val) {\r\n            if (!val && this.focusObjects.length > 0 &&\r\n                this.select(this.focusObjects[0]).elementClass === Const.OBJECT_CLASS_POINT) {\r\n                // If an element has focus we do not hide its infobox\r\n                return this;\r\n            }\r\n            if (this.infobox.hiddenByParent === val) {\r\n                this.infobox.hiddenByParent = !val;\r\n                this.infobox.prepareUpdate().updateVisibility(val).updateRenderer();\r\n            }\r\n            return this;\r\n        },\r\n\r\n        // Alias for displayInfobox to be backwards compatible.\r\n        // The method showInfobox clashes with the board attribute showInfobox\r\n        showInfobox: function (val) {\r\n            return this.displayInfobox(val);\r\n        },\r\n\r\n        /**\r\n         * Changes the text of the info box to show the given coordinates.\r\n         * @param {String} x\r\n         * @param {String} y\r\n         * @param {JXG.GeometryElement} [el] The element the mouse is pointing at\r\n         * @returns {JXG.Board} Reference to the board.\r\n         */\r\n        highlightInfobox: function (x, y, el) {\r\n            this.highlightCustomInfobox('(' + x + ', ' + y + ')', el);\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Changes the text of the info box to what is provided via text.\r\n         * @param {String} text\r\n         * @param {JXG.GeometryElement} [el]\r\n         * @returns {JXG.Board} Reference to the board.\r\n         */\r\n        highlightCustomInfobox: function (text, el) {\r\n            this.infobox.setText(text);\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Remove highlighting of all elements.\r\n         * @returns {JXG.Board} Reference to the board.\r\n         */\r\n        dehighlightAll: function () {\r\n            var el,\r\n                pEl,\r\n                stillHighlighted = {},\r\n                needsDeHighlight = false;\r\n\r\n            for (el in this.highlightedObjects) {\r\n                if (this.highlightedObjects.hasOwnProperty(el)) {\r\n\r\n                    pEl = this.highlightedObjects[el];\r\n                    if (this.focusObjects.indexOf(el) < 0) { // Element does not have focus\r\n                        if (this.hasMouseHandlers || this.hasPointerHandlers) {\r\n                            pEl.noHighlight();\r\n                        }\r\n                        needsDeHighlight = true;\r\n                    } else {\r\n                        stillHighlighted[el] = pEl;\r\n                    }\r\n                    // In highlightedObjects should only be objects which fulfill all these conditions\r\n                    // And in case of complex elements, like a turtle based fractal, it should be faster to\r\n                    // just de-highlight the element instead of checking hasPoint...\r\n                    // if ((!Type.exists(pEl.hasPoint)) || !pEl.hasPoint(x, y) || !pEl.visPropCalc.visible)\r\n                }\r\n            }\r\n\r\n            this.highlightedObjects = stillHighlighted;\r\n\r\n            // We do not need to redraw during dehighlighting in CanvasRenderer\r\n            // because we are redrawing anyhow\r\n            //  -- We do need to redraw during dehighlighting. Otherwise objects won't be dehighlighted until\r\n            // another object is highlighted.\r\n            if (this.renderer.type === 'canvas' && needsDeHighlight) {\r\n                this.prepareUpdate();\r\n                this.renderer.suspendRedraw(this);\r\n                this.updateRenderer();\r\n                this.renderer.unsuspendRedraw();\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Returns the input parameters in an array. This method looks pointless and it really is, but it had a purpose\r\n         * once.\r\n         * @private\r\n         * @param {Number} x X coordinate in screen coordinates\r\n         * @param {Number} y Y coordinate in screen coordinates\r\n         * @returns {Array} Coordinates [x, y] of the mouse in screen coordinates.\r\n         * @see JXG.Board#getUsrCoordsOfMouse\r\n         */\r\n        getScrCoordsOfMouse: function (x, y) {\r\n            return [x, y];\r\n        },\r\n\r\n        /**\r\n         * This method calculates the user coords of the current mouse coordinates.\r\n         * @param {Event} evt Event object containing the mouse coordinates.\r\n         * @returns {Array} Coordinates [x, y] of the mouse in user coordinates.\r\n         * @example\r\n         * board.on('up', function (evt) {\r\n         *         var a = board.getUsrCoordsOfMouse(evt),\r\n         *             x = a[0],\r\n         *             y = a[1],\r\n         *             somePoint = board.create('point', [x,y], {name:'SomePoint',size:4});\r\n         *             // Shorter version:\r\n         *             //somePoint = board.create('point', a, {name:'SomePoint',size:4});\r\n         *         });\r\n         *\r\n         * </pre><div id='JXG48d5066b-16ba-4920-b8ea-a4f8eff6b746' class='jxgbox' style='width: 300px; height: 300px;'></div>\r\n         * <script type='text/javascript'>\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG48d5066b-16ba-4920-b8ea-a4f8eff6b746',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     board.on('up', function (evt) {\r\n         *             var a = board.getUsrCoordsOfMouse(evt),\r\n         *                 x = a[0],\r\n         *                 y = a[1],\r\n         *                 somePoint = board.create('point', [x,y], {name:'SomePoint',size:4});\r\n         *                 // Shorter version:\r\n         *                 //somePoint = board.create('point', a, {name:'SomePoint',size:4});\r\n         *             });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @see JXG.Board#getScrCoordsOfMouse\r\n         * @see JXG.Board#getAllUnderMouse\r\n         */\r\n        getUsrCoordsOfMouse: function (evt) {\r\n            var cPos = this.getCoordsTopLeftCorner(),\r\n                absPos = Env.getPosition(evt, null, this.document),\r\n                x = absPos[0] - cPos[0],\r\n                y = absPos[1] - cPos[1],\r\n                newCoords = new Coords(Const.COORDS_BY_SCREEN, [x, y], this);\r\n\r\n            return newCoords.usrCoords.slice(1);\r\n        },\r\n\r\n        /**\r\n         * Collects all elements under current mouse position plus current user coordinates of mouse cursor.\r\n         * @param {Event} evt Event object containing the mouse coordinates.\r\n         * @returns {Array} Array of elements at the current mouse position plus current user coordinates of mouse.\r\n         * @see JXG.Board#getUsrCoordsOfMouse\r\n         * @see JXG.Board#getAllObjectsUnderMouse\r\n         */\r\n        getAllUnderMouse: function (evt) {\r\n            var elList = this.getAllObjectsUnderMouse(evt);\r\n            elList.push(this.getUsrCoordsOfMouse(evt));\r\n\r\n            return elList;\r\n        },\r\n\r\n        /**\r\n         * Collects all elements under current mouse position.\r\n         * @param {Event} evt Event object containing the mouse coordinates.\r\n         * @returns {Array} Array of elements at the current mouse position.\r\n         * @see JXG.Board#getAllUnderMouse\r\n         */\r\n        getAllObjectsUnderMouse: function (evt) {\r\n            var cPos = this.getCoordsTopLeftCorner(),\r\n                absPos = Env.getPosition(evt, null, this.document),\r\n                dx = absPos[0] - cPos[0],\r\n                dy = absPos[1] - cPos[1],\r\n                elList = [],\r\n                el,\r\n                pEl,\r\n                len = this.objectsList.length;\r\n\r\n            for (el = 0; el < len; el++) {\r\n                pEl = this.objectsList[el];\r\n                if (pEl.visPropCalc.visible && pEl.hasPoint && pEl.hasPoint(dx, dy)) {\r\n                    elList[elList.length] = pEl;\r\n                }\r\n            }\r\n\r\n            return elList;\r\n        },\r\n\r\n        /**\r\n         * Update the coords object of all elements which possess this\r\n         * property. This is necessary after changing the viewport.\r\n         * @returns {JXG.Board} Reference to this board.\r\n         **/\r\n        updateCoords: function () {\r\n            var el, ob,\r\n                len = this.objectsList.length;\r\n\r\n            for (ob = 0; ob < len; ob++) {\r\n                el = this.objectsList[ob];\r\n\r\n                if (Type.exists(el.coords)) {\r\n                    if (el.evalVisProp('frozen') === true) {\r\n                        if (el.is3D) {\r\n                            el.element2D.coords.screen2usr();\r\n                        } else {\r\n                            el.coords.screen2usr();\r\n                        }\r\n                    } else {\r\n                        if (el.is3D) {\r\n                            el.element2D.coords.usr2screen();\r\n                        } else {\r\n                            el.coords.usr2screen();\r\n                            if (Type.exists(el.actualCoords)) {\r\n                                el.actualCoords.usr2screen();\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Moves the origin and initializes an update of all elements.\r\n         * @param {Number} x\r\n         * @param {Number} y\r\n         * @param {Boolean} [diff=false]\r\n         * @returns {JXG.Board} Reference to this board.\r\n         */\r\n        moveOrigin: function (x, y, diff) {\r\n            var ox, oy, ul, lr;\r\n            if (Type.exists(x) && Type.exists(y)) {\r\n                ox = this.origin.scrCoords[1];\r\n                oy = this.origin.scrCoords[2];\r\n\r\n                this.origin.scrCoords[1] = x;\r\n                this.origin.scrCoords[2] = y;\r\n\r\n                if (diff) {\r\n                    this.origin.scrCoords[1] -= this.drag_dx;\r\n                    this.origin.scrCoords[2] -= this.drag_dy;\r\n                }\r\n\r\n                ul = new Coords(Const.COORDS_BY_SCREEN, [0, 0], this).usrCoords;\r\n                lr = new Coords(\r\n                    Const.COORDS_BY_SCREEN,\r\n                    [this.canvasWidth, this.canvasHeight],\r\n                    this\r\n                ).usrCoords;\r\n                if (\r\n                    ul[1] < this.maxboundingbox[0] - Mat.eps ||\r\n                    ul[2] > this.maxboundingbox[1] + Mat.eps ||\r\n                    lr[1] > this.maxboundingbox[2] + Mat.eps ||\r\n                    lr[2] < this.maxboundingbox[3] - Mat.eps\r\n                ) {\r\n                    this.origin.scrCoords[1] = ox;\r\n                    this.origin.scrCoords[2] = oy;\r\n                }\r\n            }\r\n\r\n            this.updateCoords().clearTraces().fullUpdate();\r\n            this.triggerEventHandlers(['boundingbox']);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Add conditional updates to the elements.\r\n         * @param {String} str String containing conditional update in geonext syntax\r\n         */\r\n        addConditions: function (str) {\r\n            var term,\r\n                m,\r\n                left,\r\n                right,\r\n                name,\r\n                el,\r\n                property,\r\n                functions = [],\r\n                // plaintext = 'var el, x, y, c, rgbo;\\n',\r\n                i = str.indexOf('<data>'),\r\n                j = str.indexOf('<' + '/data>'),\r\n                xyFun = function (board, el, f, what) {\r\n                    return function () {\r\n                        var e, t;\r\n\r\n                        e = board.select(el.id);\r\n                        t = e.coords.usrCoords[what];\r\n\r\n                        if (what === 2) {\r\n                            e.setPositionDirectly(Const.COORDS_BY_USER, [f(), t]);\r\n                        } else {\r\n                            e.setPositionDirectly(Const.COORDS_BY_USER, [t, f()]);\r\n                        }\r\n                        e.prepareUpdate().update();\r\n                    };\r\n                },\r\n                visFun = function (board, el, f) {\r\n                    return function () {\r\n                        var e, v;\r\n\r\n                        e = board.select(el.id);\r\n                        v = f();\r\n\r\n                        e.setAttribute({ visible: v });\r\n                    };\r\n                },\r\n                colFun = function (board, el, f, what) {\r\n                    return function () {\r\n                        var e, v;\r\n\r\n                        e = board.select(el.id);\r\n                        v = f();\r\n\r\n                        if (what === 'strokewidth') {\r\n                            e.visProp.strokewidth = v;\r\n                        } else {\r\n                            v = Color.rgba2rgbo(v);\r\n                            e.visProp[what + 'color'] = v[0];\r\n                            e.visProp[what + 'opacity'] = v[1];\r\n                        }\r\n                    };\r\n                },\r\n                posFun = function (board, el, f) {\r\n                    return function () {\r\n                        var e = board.select(el.id);\r\n\r\n                        e.position = f();\r\n                    };\r\n                },\r\n                styleFun = function (board, el, f) {\r\n                    return function () {\r\n                        var e = board.select(el.id);\r\n\r\n                        e.setStyle(f());\r\n                    };\r\n                };\r\n\r\n            if (i < 0) {\r\n                return;\r\n            }\r\n\r\n            while (i >= 0) {\r\n                term = str.slice(i + 6, j); // throw away <data>\r\n                m = term.indexOf('=');\r\n                left = term.slice(0, m);\r\n                right = term.slice(m + 1);\r\n                m = left.indexOf('.');   // Resulting variable names must not contain dots, e.g. ' Steuern akt.'\r\n                name = left.slice(0, m); //.replace(/\\s+$/,''); // do NOT cut out name (with whitespace)\r\n                el = this.elementsByName[Type.unescapeHTML(name)];\r\n\r\n                property = left\r\n                    .slice(m + 1)\r\n                    .replace(/\\s+/g, '')\r\n                    .toLowerCase(); // remove whitespace in property\r\n                right = Type.createFunction(right, this, '', true);\r\n\r\n                // Debug\r\n                if (!Type.exists(this.elementsByName[name])) {\r\n                    JXG.debug('debug conditions: |' + name + '| undefined');\r\n                } else {\r\n                    // plaintext += 'el = this.objects[\\'' + el.id + '\\'];\\n';\r\n\r\n                    switch (property) {\r\n                        case 'x':\r\n                            functions.push(xyFun(this, el, right, 2));\r\n                            break;\r\n                        case 'y':\r\n                            functions.push(xyFun(this, el, right, 1));\r\n                            break;\r\n                        case 'visible':\r\n                            functions.push(visFun(this, el, right));\r\n                            break;\r\n                        case 'position':\r\n                            functions.push(posFun(this, el, right));\r\n                            break;\r\n                        case 'stroke':\r\n                            functions.push(colFun(this, el, right, 'stroke'));\r\n                            break;\r\n                        case 'style':\r\n                            functions.push(styleFun(this, el, right));\r\n                            break;\r\n                        case 'strokewidth':\r\n                            functions.push(colFun(this, el, right, 'strokewidth'));\r\n                            break;\r\n                        case 'fill':\r\n                            functions.push(colFun(this, el, right, 'fill'));\r\n                            break;\r\n                        case 'label':\r\n                            break;\r\n                        default:\r\n                            JXG.debug(\r\n                                'property \"' +\r\n                                property +\r\n                                '\" in conditions not yet implemented:' +\r\n                                right\r\n                            );\r\n                            break;\r\n                    }\r\n                }\r\n                str = str.slice(j + 7); // cut off '</data>'\r\n                i = str.indexOf('<data>');\r\n                j = str.indexOf('<' + '/data>');\r\n            }\r\n\r\n            this.updateConditions = function () {\r\n                var i;\r\n\r\n                for (i = 0; i < functions.length; i++) {\r\n                    functions[i]();\r\n                }\r\n\r\n                this.prepareUpdate().updateElements();\r\n                return true;\r\n            };\r\n            this.updateConditions();\r\n        },\r\n\r\n        /**\r\n         * Computes the commands in the conditions-section of the gxt file.\r\n         * It is evaluated after an update, before the unsuspendRedraw.\r\n         * The function is generated in\r\n         * @see JXG.Board#addConditions\r\n         * @private\r\n         */\r\n        updateConditions: function () {\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Calculates adequate snap sizes.\r\n         * @returns {JXG.Board} Reference to the board.\r\n         */\r\n        calculateSnapSizes: function () {\r\n            var p1, p2,\r\n                bbox = this.getBoundingBox(),\r\n                gridStep = Type.evaluate(this.options.grid.majorStep),\r\n                gridX = Type.evaluate(this.options.grid.gridX),\r\n                gridY = Type.evaluate(this.options.grid.gridY),\r\n                x, y;\r\n\r\n            if (!Type.isArray(gridStep)) {\r\n                gridStep = [gridStep, gridStep];\r\n            }\r\n            if (gridStep.length < 2) {\r\n                gridStep = [gridStep[0], gridStep[0]];\r\n            }\r\n            if (Type.exists(gridX)) {\r\n                gridStep[0] = gridX;\r\n            }\r\n            if (Type.exists(gridY)) {\r\n                gridStep[1] = gridY;\r\n            }\r\n\r\n            if (gridStep[0] === 'auto') {\r\n                gridStep[0] = 1;\r\n            } else {\r\n                gridStep[0] = Type.parseNumber(gridStep[0], Math.abs(bbox[1] - bbox[3]), 1 / this.unitX);\r\n            }\r\n            if (gridStep[1] === 'auto') {\r\n                gridStep[1] = 1;\r\n            } else {\r\n                gridStep[1] = Type.parseNumber(gridStep[1], Math.abs(bbox[0] - bbox[2]), 1 / this.unitY);\r\n            }\r\n\r\n            p1 = new Coords(Const.COORDS_BY_USER, [0, 0], this);\r\n            p2 = new Coords(\r\n                Const.COORDS_BY_USER,\r\n                [gridStep[0], gridStep[1]],\r\n                this\r\n            );\r\n            x = p1.scrCoords[1] - p2.scrCoords[1];\r\n            y = p1.scrCoords[2] - p2.scrCoords[2];\r\n\r\n            this.options.grid.snapSizeX = gridStep[0];\r\n            while (Math.abs(x) > 25) {\r\n                this.options.grid.snapSizeX *= 2;\r\n                x /= 2;\r\n            }\r\n\r\n            this.options.grid.snapSizeY = gridStep[1];\r\n            while (Math.abs(y) > 25) {\r\n                this.options.grid.snapSizeY *= 2;\r\n                y /= 2;\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Apply update on all objects with the new zoom-factors. Clears all traces.\r\n         * @returns {JXG.Board} Reference to the board.\r\n         */\r\n        applyZoom: function () {\r\n            this.updateCoords().calculateSnapSizes().clearTraces().fullUpdate();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Zooms into the board by the factors board.attr.zoom.factorX and board.attr.zoom.factorY and applies the zoom.\r\n         * The zoom operation is centered at x, y.\r\n         * @param {Number} [x]\r\n         * @param {Number} [y]\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        zoomIn: function (x, y) {\r\n            var bb = this.getBoundingBox(),\r\n                zX = Type.evaluate(this.attr.zoom.factorx),\r\n                zY =  Type.evaluate(this.attr.zoom.factory),\r\n                dX = (bb[2] - bb[0]) * (1.0 - 1.0 / zX),\r\n                dY = (bb[1] - bb[3]) * (1.0 - 1.0 / zY),\r\n                lr = 0.5,\r\n                tr = 0.5,\r\n                ma = Type.evaluate(this.attr.zoom.max),\r\n                mi =  Type.evaluate(this.attr.zoom.eps) || Type.evaluate(this.attr.zoom.min) || 0.001; // this.attr.zoom.eps is deprecated\r\n\r\n            if (\r\n                (this.zoomX > ma && zX > 1.0) ||\r\n                (this.zoomY > ma && zY > 1.0) ||\r\n                (this.zoomX < mi && zX < 1.0) || // zoomIn is used for all zooms on touch devices\r\n                (this.zoomY < mi && zY < 1.0)\r\n            ) {\r\n                return this;\r\n            }\r\n\r\n            if (Type.isNumber(x) && Type.isNumber(y)) {\r\n                lr = (x - bb[0]) / (bb[2] - bb[0]);\r\n                tr = (bb[1] - y) / (bb[1] - bb[3]);\r\n            }\r\n\r\n            this.setBoundingBox(\r\n                [\r\n                    bb[0] + dX * lr,\r\n                    bb[1] - dY * tr,\r\n                    bb[2] - dX * (1 - lr),\r\n                    bb[3] + dY * (1 - tr)\r\n                ],\r\n                this.keepaspectratio,\r\n                'update'\r\n            );\r\n            return this.applyZoom();\r\n        },\r\n\r\n        /**\r\n         * Zooms out of the board by the factors board.attr.zoom.factorX and board.attr.zoom.factorY and applies the zoom.\r\n         * The zoom operation is centered at x, y.\r\n         *\r\n         * @param {Number} [x]\r\n         * @param {Number} [y]\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        zoomOut: function (x, y) {\r\n            var bb = this.getBoundingBox(),\r\n                zX = Type.evaluate(this.attr.zoom.factorx),\r\n                zY = Type.evaluate(this.attr.zoom.factory),\r\n                dX = (bb[2] - bb[0]) * (1.0 - zX),\r\n                dY = (bb[1] - bb[3]) * (1.0 - zY),\r\n                lr = 0.5,\r\n                tr = 0.5,\r\n                mi = Type.evaluate(this.attr.zoom.eps) || Type.evaluate(this.attr.zoom.min) || 0.001; // this.attr.zoom.eps is deprecated\r\n\r\n            if (this.zoomX < mi || this.zoomY < mi) {\r\n                return this;\r\n            }\r\n\r\n            if (Type.isNumber(x) && Type.isNumber(y)) {\r\n                lr = (x - bb[0]) / (bb[2] - bb[0]);\r\n                tr = (bb[1] - y) / (bb[1] - bb[3]);\r\n            }\r\n\r\n            this.setBoundingBox(\r\n                [\r\n                    bb[0] + dX * lr,\r\n                    bb[1] - dY * tr,\r\n                    bb[2] - dX * (1 - lr),\r\n                    bb[3] + dY * (1 - tr)\r\n                ],\r\n                this.keepaspectratio,\r\n                'update'\r\n            );\r\n\r\n            return this.applyZoom();\r\n        },\r\n\r\n        /**\r\n         * Reset the zoom level to the original zoom level from initBoard();\r\n         * Additionally, if the board as been initialized with a boundingBox (which is the default),\r\n         * restore the viewport to the original viewport during initialization. Otherwise,\r\n         * (i.e. if the board as been initialized with unitX/Y and originX/Y),\r\n         * just set the zoom level to 100%.\r\n         *\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        zoom100: function () {\r\n            var bb, dX, dY;\r\n\r\n            if (Type.exists(this.attr.boundingbox)) {\r\n                this.setBoundingBox(this.attr.boundingbox, this.keepaspectratio, 'reset');\r\n            } else {\r\n                // Board has been set up with unitX/Y and originX/Y\r\n                bb = this.getBoundingBox();\r\n                dX = (bb[2] - bb[0]) * (1.0 - this.zoomX) * 0.5;\r\n                dY = (bb[1] - bb[3]) * (1.0 - this.zoomY) * 0.5;\r\n                this.setBoundingBox(\r\n                    [bb[0] + dX, bb[1] - dY, bb[2] - dX, bb[3] + dY],\r\n                    this.keepaspectratio,\r\n                    'reset'\r\n                );\r\n            }\r\n            return this.applyZoom();\r\n        },\r\n\r\n        /**\r\n         * Zooms the board so every visible point is shown. Keeps aspect ratio.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        zoomAllPoints: function () {\r\n            var el,\r\n                border,\r\n                borderX,\r\n                borderY,\r\n                pEl,\r\n                minX = 0,\r\n                maxX = 0,\r\n                minY = 0,\r\n                maxY = 0,\r\n                len = this.objectsList.length;\r\n\r\n            for (el = 0; el < len; el++) {\r\n                pEl = this.objectsList[el];\r\n\r\n                if (Type.isPoint(pEl) && pEl.visPropCalc.visible) {\r\n                    if (pEl.coords.usrCoords[1] < minX) {\r\n                        minX = pEl.coords.usrCoords[1];\r\n                    } else if (pEl.coords.usrCoords[1] > maxX) {\r\n                        maxX = pEl.coords.usrCoords[1];\r\n                    }\r\n                    if (pEl.coords.usrCoords[2] > maxY) {\r\n                        maxY = pEl.coords.usrCoords[2];\r\n                    } else if (pEl.coords.usrCoords[2] < minY) {\r\n                        minY = pEl.coords.usrCoords[2];\r\n                    }\r\n                }\r\n            }\r\n\r\n            border = 50;\r\n            borderX = border / this.unitX;\r\n            borderY = border / this.unitY;\r\n\r\n            this.setBoundingBox(\r\n                [minX - borderX, maxY + borderY, maxX + borderX, minY - borderY],\r\n                this.keepaspectratio,\r\n                'update'\r\n            );\r\n\r\n            return this.applyZoom();\r\n        },\r\n\r\n        /**\r\n         * Reset the bounding box and the zoom level to 100% such that a given set of elements is\r\n         * within the board's viewport.\r\n         * @param {Array} elements A set of elements given by id, reference, or name.\r\n         * @returns {JXG.Board} Reference to the board.\r\n         */\r\n        zoomElements: function (elements) {\r\n            var i, e,\r\n                box,\r\n                newBBox = [Infinity, -Infinity, -Infinity, Infinity],\r\n                cx, cy,\r\n                dx, dy,\r\n                d;\r\n\r\n            if (!Type.isArray(elements) || elements.length === 0) {\r\n                return this;\r\n            }\r\n\r\n            for (i = 0; i < elements.length; i++) {\r\n                e = this.select(elements[i]);\r\n\r\n                box = e.bounds();\r\n                if (Type.isArray(box)) {\r\n                    if (box[0] < newBBox[0]) {\r\n                        newBBox[0] = box[0];\r\n                    }\r\n                    if (box[1] > newBBox[1]) {\r\n                        newBBox[1] = box[1];\r\n                    }\r\n                    if (box[2] > newBBox[2]) {\r\n                        newBBox[2] = box[2];\r\n                    }\r\n                    if (box[3] < newBBox[3]) {\r\n                        newBBox[3] = box[3];\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (Type.isArray(newBBox)) {\r\n                cx = 0.5 * (newBBox[0] + newBBox[2]);\r\n                cy = 0.5 * (newBBox[1] + newBBox[3]);\r\n                dx = 1.5 * (newBBox[2] - newBBox[0]) * 0.5;\r\n                dy = 1.5 * (newBBox[1] - newBBox[3]) * 0.5;\r\n                d = Math.max(dx, dy);\r\n                this.setBoundingBox(\r\n                    [cx - d, cy + d, cx + d, cy - d],\r\n                    this.keepaspectratio,\r\n                    'update'\r\n                );\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Sets the zoom level to <tt>fX</tt> resp <tt>fY</tt>.\r\n         * @param {Number} fX\r\n         * @param {Number} fY\r\n         * @returns {JXG.Board} Reference to the board.\r\n         */\r\n        setZoom: function (fX, fY) {\r\n            var oX = this.attr.zoom.factorx,\r\n                oY = this.attr.zoom.factory;\r\n\r\n            this.attr.zoom.factorx = fX / this.zoomX;\r\n            this.attr.zoom.factory = fY / this.zoomY;\r\n\r\n            this.zoomIn();\r\n\r\n            this.attr.zoom.factorx = oX;\r\n            this.attr.zoom.factory = oY;\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Inner, recursive method of removeObject.\r\n         *\r\n         * @param {JXG.GeometryElement|Array} object The object to remove or array of objects to be removed.\r\n         * The element(s) is/are given by name, id or a reference.\r\n         * @param {Boolean} [saveMethod=false] If saveMethod=true, the algorithm runs through all elements\r\n         * and tests if the element to be deleted is a child element. If this is the case, it will be\r\n         * removed from the list of child elements. If saveMethod=false (default), the element\r\n         * is removed from the lists of child elements of all its ancestors.\r\n         * The latter should be much faster.\r\n         * @returns {JXG.Board} Reference to the board\r\n         * @private\r\n         */\r\n        _removeObj: function (object, saveMethod) {\r\n            var el, i;\r\n\r\n            if (Type.isArray(object)) {\r\n                for (i = 0; i < object.length; i++) {\r\n                    this._removeObj(object[i], saveMethod);\r\n                }\r\n\r\n                return this;\r\n            }\r\n\r\n            object = this.select(object);\r\n\r\n            // If the object which is about to be removed is unknown or a string, do nothing.\r\n            // it is a string if a string was given and could not be resolved to an element.\r\n            if (!Type.exists(object) || Type.isString(object)) {\r\n                return this;\r\n            }\r\n\r\n            try {\r\n                // remove all children.\r\n                for (el in object.childElements) {\r\n                    if (object.childElements.hasOwnProperty(el)) {\r\n                        object.childElements[el].board._removeObj(object.childElements[el]);\r\n                    }\r\n                }\r\n\r\n                // Remove all children in elements like turtle\r\n                for (el in object.objects) {\r\n                    if (object.objects.hasOwnProperty(el)) {\r\n                        object.objects[el].board._removeObj(object.objects[el]);\r\n                    }\r\n                }\r\n\r\n                // Remove the element from the childElement list and the descendant list of all elements.\r\n                if (saveMethod) {\r\n                    // Running through all objects has quadratic complexity if many objects are deleted.\r\n                    for (el in this.objects) {\r\n                        if (this.objects.hasOwnProperty(el)) {\r\n                            if (\r\n                                Type.exists(this.objects[el].childElements) &&\r\n                                Type.exists(\r\n                                    this.objects[el].childElements.hasOwnProperty(object.id)\r\n                                )\r\n                            ) {\r\n                                delete this.objects[el].childElements[object.id];\r\n                                delete this.objects[el].descendants[object.id];\r\n                            }\r\n                        }\r\n                    }\r\n                } else if (Type.exists(object.ancestors)) {\r\n                    // Running through the ancestors should be much more efficient.\r\n                    for (el in object.ancestors) {\r\n                        if (object.ancestors.hasOwnProperty(el)) {\r\n                            if (\r\n                                Type.exists(object.ancestors[el].childElements) &&\r\n                                Type.exists(\r\n                                    object.ancestors[el].childElements.hasOwnProperty(object.id)\r\n                                )\r\n                            ) {\r\n                                delete object.ancestors[el].childElements[object.id];\r\n                                delete object.ancestors[el].descendants[object.id];\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // remove the object itself from our control structures\r\n                if (object._pos > -1) {\r\n                    this.objectsList.splice(object._pos, 1);\r\n                    for (i = object._pos; i < this.objectsList.length; i++) {\r\n                        this.objectsList[i]._pos--;\r\n                    }\r\n                } else if (object.type !== Const.OBJECT_TYPE_TURTLE) {\r\n                    JXG.debug(\r\n                        'Board.removeObject: object ' + object.id + ' not found in list.'\r\n                    );\r\n                }\r\n\r\n                delete this.objects[object.id];\r\n                delete this.elementsByName[object.name];\r\n\r\n                if (object.visProp && object.evalVisProp('trace')) {\r\n                    object.clearTrace();\r\n                }\r\n\r\n                // the object deletion itself is handled by the object.\r\n                if (Type.exists(object.remove)) {\r\n                    object.remove();\r\n                }\r\n            } catch (e) {\r\n                JXG.debug(object.id + ': Could not be removed: ' + e);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Removes object from board and from the renderer object.\r\n         * <p>\r\n         * <b>Performance hints:</b> It is recommended to use the JSXGraph object's id.\r\n         * If many elements are removed, it is best to either\r\n         * <ul>\r\n         *   <li> remove the whole array if the elements are contained in an array instead\r\n         *    of looping through the array OR\r\n         *   <li> call <tt>board.suspendUpdate()</tt>\r\n         * before looping through the elements to be removed and call\r\n         * <tt>board.unsuspendUpdate()</tt> after the loop. Further, it is advisable to loop\r\n         * in reverse order, i.e. remove the object in reverse order of their creation time.\r\n         * </ul>\r\n         * @param {JXG.GeometryElement|Array} object The object to remove or array of objects to be removed.\r\n         * The element(s) is/are given by name, id or a reference.\r\n         * @param {Boolean} saveMethod If true, the algorithm runs through all elements\r\n         * and tests if the element to be deleted is a child element. If yes, it will be\r\n         * removed from the list of child elements. If false (default), the element\r\n         * is removed from the lists of child elements of all its ancestors.\r\n         * This should be much faster.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        removeObject: function (object, saveMethod) {\r\n            var i;\r\n\r\n            this.renderer.suspendRedraw(this);\r\n            if (Type.isArray(object)) {\r\n                for (i = 0; i < object.length; i++) {\r\n                    this._removeObj(object[i], saveMethod);\r\n                }\r\n            } else {\r\n                this._removeObj(object, saveMethod);\r\n            }\r\n            this.renderer.unsuspendRedraw();\r\n\r\n            this.update();\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Removes the ancestors of an object an the object itself from board and renderer.\r\n         * @param {JXG.GeometryElement} object The object to remove.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        removeAncestors: function (object) {\r\n            var anc;\r\n\r\n            for (anc in object.ancestors) {\r\n                if (object.ancestors.hasOwnProperty(anc)) {\r\n                    this.removeAncestors(object.ancestors[anc]);\r\n                }\r\n            }\r\n\r\n            this.removeObject(object);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Initialize some objects which are contained in every GEONExT construction by default,\r\n         * but are not contained in the gxt files.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        initGeonextBoard: function () {\r\n            var p1, p2, p3;\r\n\r\n            p1 = this.create('point', [0, 0], {\r\n                id: this.id + 'g00e0',\r\n                name: 'Ursprung',\r\n                withLabel: false,\r\n                visible: false,\r\n                fixed: true\r\n            });\r\n\r\n            p2 = this.create('point', [1, 0], {\r\n                id: this.id + 'gX0e0',\r\n                name: 'Punkt_1_0',\r\n                withLabel: false,\r\n                visible: false,\r\n                fixed: true\r\n            });\r\n\r\n            p3 = this.create('point', [0, 1], {\r\n                id: this.id + 'gY0e0',\r\n                name: 'Punkt_0_1',\r\n                withLabel: false,\r\n                visible: false,\r\n                fixed: true\r\n            });\r\n\r\n            this.create('line', [p1, p2], {\r\n                id: this.id + 'gXLe0',\r\n                name: 'X-Achse',\r\n                withLabel: false,\r\n                visible: false\r\n            });\r\n\r\n            this.create('line', [p1, p3], {\r\n                id: this.id + 'gYLe0',\r\n                name: 'Y-Achse',\r\n                withLabel: false,\r\n                visible: false\r\n            });\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Change the height and width of the board's container.\r\n         * After doing so, {@link JXG.JSXGraph.setBoundingBox} is called using\r\n         * the actual size of the bounding box and the actual value of keepaspectratio.\r\n         * If setBoundingbox() should not be called automatically,\r\n         * call resizeContainer with dontSetBoundingBox == true.\r\n         * @param {Number} canvasWidth New width of the container.\r\n         * @param {Number} canvasHeight New height of the container.\r\n         * @param {Boolean} [dontset=false] If true do not set the CSS width and height of the DOM element.\r\n         * @param {Boolean} [dontSetBoundingBox=false] If true do not call setBoundingBox(), but keep view centered around original visible center.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        resizeContainer: function (canvasWidth, canvasHeight, dontset, dontSetBoundingBox) {\r\n            var box,\r\n                oldWidth, oldHeight,\r\n                oX, oY;\r\n\r\n            oldWidth = this.canvasWidth;\r\n            oldHeight = this.canvasHeight;\r\n\r\n            if (!dontSetBoundingBox) {\r\n                box = this.getBoundingBox();    // This is the actual bounding box.\r\n            }\r\n\r\n            // this.canvasWidth = Math.max(parseFloat(canvasWidth), Mat.eps);\r\n            // this.canvasHeight = Math.max(parseFloat(canvasHeight), Mat.eps);\r\n            this.canvasWidth = parseFloat(canvasWidth);\r\n            this.canvasHeight = parseFloat(canvasHeight);\r\n\r\n            if (!dontset) {\r\n                this.containerObj.style.width = this.canvasWidth + 'px';\r\n                this.containerObj.style.height = this.canvasHeight + 'px';\r\n            }\r\n            this.renderer.resize(this.canvasWidth, this.canvasHeight);\r\n\r\n            if (!dontSetBoundingBox) {\r\n                this.setBoundingBox(box, this.keepaspectratio, 'keep');\r\n            } else {\r\n                oX = (this.canvasWidth - oldWidth) * 0.5;\r\n                oY = (this.canvasHeight - oldHeight) * 0.5;\r\n\r\n                this.moveOrigin(\r\n                    this.origin.scrCoords[1] + oX,\r\n                    this.origin.scrCoords[2] + oY\r\n                );\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Lists the dependencies graph in a new HTML-window.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        showDependencies: function () {\r\n            var el, t, c, f, i;\r\n\r\n            t = '<p>\\n';\r\n            for (el in this.objects) {\r\n                if (this.objects.hasOwnProperty(el)) {\r\n                    i = 0;\r\n                    for (c in this.objects[el].childElements) {\r\n                        if (this.objects[el].childElements.hasOwnProperty(c)) {\r\n                            i += 1;\r\n                        }\r\n                    }\r\n                    if (i >= 0) {\r\n                        t += '<strong>' + this.objects[el].id + ':<' + '/strong> ';\r\n                    }\r\n\r\n                    for (c in this.objects[el].childElements) {\r\n                        if (this.objects[el].childElements.hasOwnProperty(c)) {\r\n                            t +=\r\n                                this.objects[el].childElements[c].id +\r\n                                '(' +\r\n                                this.objects[el].childElements[c].name +\r\n                                ')' +\r\n                                ', ';\r\n                        }\r\n                    }\r\n                    t += '<p>\\n';\r\n                }\r\n            }\r\n            t += '<' + '/p>\\n';\r\n            f = window.open();\r\n            f.document.open();\r\n            f.document.write(t);\r\n            f.document.close();\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Lists the XML code of the construction in a new HTML-window.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        showXML: function () {\r\n            var f = window.open('');\r\n            f.document.open();\r\n            f.document.write('<pre>' + Type.escapeHTML(this.xmlString) + '<' + '/pre>');\r\n            f.document.close();\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Sets for all objects the needsUpdate flag to 'true'.\r\n         * @param{JXG.GeometryElement} [drag=undefined] Optional element that is dragged.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        prepareUpdate: function (drag) {\r\n            var el, i,\r\n                pEl,\r\n                len = this.objectsList.length;\r\n\r\n            /*\r\n            if (this.attr.updatetype === 'hierarchical') {\r\n                return this;\r\n            }\r\n            */\r\n\r\n            for (el = 0; el < len; el++) {\r\n                pEl = this.objectsList[el];\r\n                if (this._change3DView ||\r\n                    (Type.exists(drag) && drag.elType === 'view3d_slider')\r\n                ) {\r\n                    // The 3D view has changed. No elements are recomputed,\r\n                    // only 3D elements are projected to the new view.\r\n                    pEl.needsUpdate =\r\n                        pEl.visProp.element3d ||\r\n                        pEl.elType === 'view3d' ||\r\n                        pEl.elType === 'view3d_slider' ||\r\n                        this.needsFullUpdate;\r\n\r\n                    // Special case sphere3d in central projection:\r\n                    // We have to update the defining points of the ellipse\r\n                    if (pEl.visProp.element3d &&\r\n                        pEl.visProp.element3d.type === Const.OBJECT_TYPE_SPHERE3D\r\n                        ) {\r\n                        for (i = 0; i < pEl.parents.length; i++) {\r\n                            this.objects[pEl.parents[i]].needsUpdate = true;\r\n                        }\r\n                    }\r\n                } else {\r\n                    pEl.needsUpdate = pEl.needsRegularUpdate || this.needsFullUpdate;\r\n                }\r\n            }\r\n\r\n            for (el in this.groups) {\r\n                if (this.groups.hasOwnProperty(el)) {\r\n                    pEl = this.groups[el];\r\n                    pEl.needsUpdate = pEl.needsRegularUpdate || this.needsFullUpdate;\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Runs through all elements and calls their update() method.\r\n         * @param {JXG.GeometryElement} drag Element that caused the update.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        updateElements: function (drag) {\r\n            var el, pEl;\r\n            //var childId, i = 0;\r\n\r\n            drag = this.select(drag);\r\n\r\n            /*\r\n            if (Type.exists(drag)) {\r\n                for (el = 0; el < this.objectsList.length; el++) {\r\n                    pEl = this.objectsList[el];\r\n                    if (pEl.id === drag.id) {\r\n                        i = el;\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n            */\r\n            for (el = 0; el < this.objectsList.length; el++) {\r\n                pEl = this.objectsList[el];\r\n                if (this.needsFullUpdate && pEl.elementClass === Const.OBJECT_CLASS_TEXT) {\r\n                    pEl.updateSize();\r\n                }\r\n\r\n                // For updates of an element we distinguish if the dragged element is updated or\r\n                // other elements are updated.\r\n                // The difference lies in the treatment of gliders and points based on transformations.\r\n                pEl.update(!Type.exists(drag) || pEl.id !== drag.id).updateVisibility();\r\n            }\r\n\r\n            // update groups last\r\n            for (el in this.groups) {\r\n                if (this.groups.hasOwnProperty(el)) {\r\n                    this.groups[el].update(drag);\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Runs through all elements and calls their update() method.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        updateRenderer: function () {\r\n            var el,\r\n                len = this.objectsList.length,\r\n                autoPositionLabelList = [],\r\n                currentIndex, randomIndex;\r\n\r\n            if (!this.renderer) {\r\n                return;\r\n            }\r\n\r\n            /*\r\n            objs = this.objectsList.slice(0);\r\n            objs.sort(function (a, b) {\r\n                if (a.visProp.layer < b.visProp.layer) {\r\n                    return -1;\r\n                } else if (a.visProp.layer === b.visProp.layer) {\r\n                    return b.lastDragTime.getTime() - a.lastDragTime.getTime();\r\n                } else {\r\n                    return 1;\r\n                }\r\n            });\r\n            */\r\n\r\n            if (this.renderer.type === 'canvas') {\r\n                this.updateRendererCanvas();\r\n            } else {\r\n                for (el = 0; el < len; el++) {\r\n                    if (this.objectsList[el].visProp.islabel && this.objectsList[el].visProp.autoposition) {\r\n                        autoPositionLabelList.push(el);\r\n                    } else {\r\n                    this.objectsList[el].updateRenderer();\r\n                }\r\n            }\r\n\r\n                currentIndex = autoPositionLabelList.length;\r\n\r\n                // Randomize the order of the labels\r\n                while (currentIndex !== 0) {\r\n                    randomIndex = Math.floor(Math.random() * currentIndex);\r\n                    currentIndex--;\r\n                    [autoPositionLabelList[currentIndex], autoPositionLabelList[randomIndex]] = [autoPositionLabelList[randomIndex], autoPositionLabelList[currentIndex]];\r\n                }\r\n\r\n                for (el = 0; el < autoPositionLabelList.length; el++) {\r\n                    this.objectsList[autoPositionLabelList[el]].updateRenderer();\r\n                }\r\n                /*\r\n                for (el = autoPositionLabelList.length - 1; el >= 0; el--) {\r\n                    this.objectsList[autoPositionLabelList[el]].updateRenderer();\r\n                }\r\n                */\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Runs through all elements and calls their update() method.\r\n         * This is a special version for the CanvasRenderer.\r\n         * Here, we have to do our own layer handling.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        updateRendererCanvas: function () {\r\n            var el, pEl,\r\n                olen = this.objectsList.length,\r\n                // i, minim, lay,\r\n                // layers = this.options.layer,\r\n                // len = this.options.layer.numlayers,\r\n                // last = Number.NEGATIVE_INFINITY.toExponential,\r\n                depth_order_layers = [],\r\n                objects_sorted,\r\n                // Sort the elements for the canvas rendering according to\r\n                // their layer, _pos, depthOrder (with this priority)\r\n                // @private\r\n                _compareFn = function(a, b) {\r\n                    if (a.visProp.layer !== b.visProp.layer) {\r\n                        return a.visProp.layer - b.visProp.layer;\r\n                    }\r\n\r\n                    // The objects are in the same layer, but the layer is not depth ordered\r\n                    if (depth_order_layers.indexOf(a.visProp.layer) === -1) {\r\n                        return a._pos - b._pos;\r\n                    }\r\n\r\n                    // The objects are in the same layer and the layer is depth ordered\r\n                    // We have to sort 2D elements according to the zIndices of\r\n                    // their 3D parents.\r\n                    if (!a.visProp.element3d && !b.visProp.element3d) {\r\n                        return a._pos - b._pos;\r\n                    }\r\n\r\n                    if (a.visProp.element3d && !b.visProp.element3d) {\r\n                        return -1;\r\n                    }\r\n\r\n                    if (b.visProp.element3d && !a.visProp.element3d) {\r\n                        return 1;\r\n                    }\r\n\r\n                    return a.visProp.element3d.zIndex - b.visProp.element3d.zIndex;\r\n                };\r\n\r\n            // Only one view3d element is supported. Get the depth orderer layers and\r\n            // update the zIndices of the 3D elements.\r\n            for (el = 0; el < olen; el++) {\r\n                pEl = this.objectsList[el];\r\n                if (pEl.elType === 'view3d' && pEl.evalVisProp('depthorder.enabled')) {\r\n                    depth_order_layers = pEl.evalVisProp('depthorder.layers');\r\n                    pEl.updateRenderer();\r\n                    break;\r\n                }\r\n            }\r\n\r\n            objects_sorted = this.objectsList.toSorted(_compareFn);\r\n            olen = objects_sorted.length;\r\n            for (el = 0; el < olen; el++) {\r\n                objects_sorted[el].prepareUpdate().updateRenderer();\r\n            }\r\n\r\n            // for (i = 0; i < len; i++) {\r\n            //     minim = Number.POSITIVE_INFINITY;\r\n\r\n            //     for (lay in layers) {\r\n            //         if (layers.hasOwnProperty(lay)) {\r\n            //             if (layers[lay] > last && layers[lay] < minim) {\r\n            //                 minim = layers[lay];\r\n            //             }\r\n            //         }\r\n            //     }\r\n\r\n            //     for (el = 0; el < olen; el++) {\r\n            //         pEl = this.objectsList[el];\r\n            //         if (pEl.visProp.layer === minim) {\r\n            //             pEl.prepareUpdate().updateRenderer();\r\n            //         }\r\n            //     }\r\n            //     last = minim;\r\n            // }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Please use {@link JXG.Board.on} instead.\r\n         * @param {Function} hook A function to be called by the board after an update occurred.\r\n         * @param {String} [m='update'] When the hook is to be called. Possible values are <i>mouseup</i>, <i>mousedown</i> and <i>update</i>.\r\n         * @param {Object} [context=board] Determines the execution context the hook is called. This parameter is optional, default is the\r\n         * board object the hook is attached to.\r\n         * @returns {Number} Id of the hook, required to remove the hook from the board.\r\n         * @deprecated\r\n         */\r\n        addHook: function (hook, m, context) {\r\n            JXG.deprecated('Board.addHook()', 'Board.on()');\r\n            m = Type.def(m, 'update');\r\n\r\n            context = Type.def(context, this);\r\n\r\n            this.hooks.push([m, hook]);\r\n            this.on(m, hook, context);\r\n\r\n            return this.hooks.length - 1;\r\n        },\r\n\r\n        /**\r\n         * Alias of {@link JXG.Board.on}.\r\n         */\r\n        addEvent: JXG.shortcut(JXG.Board.prototype, 'on'),\r\n\r\n        /**\r\n         * Please use {@link JXG.Board.off} instead.\r\n         * @param {Number|function} id The number you got when you added the hook or a reference to the event handler.\r\n         * @returns {JXG.Board} Reference to the board\r\n         * @deprecated\r\n         */\r\n        removeHook: function (id) {\r\n            JXG.deprecated('Board.removeHook()', 'Board.off()');\r\n            if (this.hooks[id]) {\r\n                this.off(this.hooks[id][0], this.hooks[id][1]);\r\n                this.hooks[id] = null;\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Alias of {@link JXG.Board.off}.\r\n         */\r\n        removeEvent: JXG.shortcut(JXG.Board.prototype, 'off'),\r\n\r\n        /**\r\n         * Runs through all hooked functions and calls them.\r\n         * @returns {JXG.Board} Reference to the board\r\n         * @deprecated\r\n         */\r\n        updateHooks: function (m) {\r\n            var arg = Array.prototype.slice.call(arguments, 0);\r\n\r\n            JXG.deprecated('Board.updateHooks()', 'Board.triggerEventHandlers()');\r\n\r\n            arg[0] = Type.def(arg[0], 'update');\r\n            this.triggerEventHandlers([arg[0]], arguments);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Adds a dependent board to this board.\r\n         * @param {JXG.Board} board A reference to board which will be updated after an update of this board occurred.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        addChild: function (board) {\r\n            if (Type.exists(board) && Type.exists(board.containerObj)) {\r\n                this.dependentBoards.push(board);\r\n                this.update();\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Deletes a board from the list of dependent boards.\r\n         * @param {JXG.Board} board Reference to the board which will be removed.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        removeChild: function (board) {\r\n            var i;\r\n\r\n            for (i = this.dependentBoards.length - 1; i >= 0; i--) {\r\n                if (this.dependentBoards[i] === board) {\r\n                    this.dependentBoards.splice(i, 1);\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Runs through most elements and calls their update() method and update the conditions.\r\n         * @param {JXG.GeometryElement} [drag] Element that caused the update.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        update: function (drag) {\r\n            var i, len, b, insert, storeActiveEl;\r\n\r\n            if (this.inUpdate || this.isSuspendedUpdate) {\r\n                return this;\r\n            }\r\n            this.inUpdate = true;\r\n\r\n            if (\r\n                this.attr.minimizereflow === 'all' &&\r\n                this.containerObj &&\r\n                this.renderer.type !== 'vml'\r\n            ) {\r\n                storeActiveEl = this.document.activeElement; // Store focus element\r\n                insert = this.renderer.removeToInsertLater(this.containerObj);\r\n            }\r\n\r\n            if (this.attr.minimizereflow === 'svg' && this.renderer.type === 'svg') {\r\n                storeActiveEl = this.document.activeElement;\r\n                insert = this.renderer.removeToInsertLater(this.renderer.svgRoot);\r\n            }\r\n\r\n            this.prepareUpdate(drag).updateElements(drag).updateConditions();\r\n\r\n            this.renderer.suspendRedraw(this);\r\n            this.updateRenderer();\r\n            this.renderer.unsuspendRedraw();\r\n            this.triggerEventHandlers(['update'], []);\r\n\r\n            if (insert) {\r\n                insert();\r\n                storeActiveEl.focus(); // Restore focus element\r\n            }\r\n\r\n            // To resolve dependencies between boards\r\n            // for (var board in JXG.boards) {\r\n            len = this.dependentBoards.length;\r\n            for (i = 0; i < len; i++) {\r\n                b = this.dependentBoards[i];\r\n                if (Type.exists(b) && b !== this) {\r\n                    b.updateQuality = this.updateQuality;\r\n                    b.prepareUpdate().updateElements().updateConditions();\r\n                    b.renderer.suspendRedraw(this);\r\n                    b.updateRenderer();\r\n                    b.renderer.unsuspendRedraw();\r\n                    b.triggerEventHandlers(['update'], []);\r\n                }\r\n            }\r\n\r\n            this.inUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Runs through all elements and calls their update() method and update the conditions.\r\n         * This is necessary after zooming and changing the bounding box.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        fullUpdate: function () {\r\n            this.needsFullUpdate = true;\r\n            this.update();\r\n            this.needsFullUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Adds a grid to the board according to the settings given in board.options.\r\n         * @returns {JXG.Board} Reference to the board.\r\n         */\r\n        addGrid: function () {\r\n            this.create('grid', []);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Removes all grids assigned to this board. Warning: This method also removes all objects depending on one or\r\n         * more of the grids.\r\n         * @returns {JXG.Board} Reference to the board object.\r\n         */\r\n        removeGrids: function () {\r\n            var i;\r\n\r\n            for (i = 0; i < this.grids.length; i++) {\r\n                this.removeObject(this.grids[i]);\r\n            }\r\n\r\n            this.grids.length = 0;\r\n            this.update(); // required for canvas renderer\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Creates a new geometric element of type elementType.\r\n         * @param {String} elementType Type of the element to be constructed given as a string e.g. 'point' or 'circle'.\r\n         * @param {Array} parents Array of parent elements needed to construct the element e.g. coordinates for a point or two\r\n         * points to construct a line. This highly depends on the elementType that is constructed. See the corresponding JXG.create*\r\n         * methods for a list of possible parameters.\r\n         * @param {Object} [attributes] An object containing the attributes to be set. This also depends on the elementType.\r\n         * Common attributes are name, visible, strokeColor.\r\n         * @returns {Object} Reference to the created element. This is usually a GeometryElement, but can be an array containing\r\n         * two or more elements.\r\n         */\r\n        create: function (elementType, parents, attributes) {\r\n            var el, i;\r\n\r\n            elementType = elementType.toLowerCase();\r\n\r\n            if (!Type.exists(parents)) {\r\n                parents = [];\r\n            }\r\n\r\n            if (!Type.exists(attributes)) {\r\n                attributes = {};\r\n            }\r\n\r\n            for (i = 0; i < parents.length; i++) {\r\n                if (\r\n                    Type.isString(parents[i]) &&\r\n                    !(elementType === 'text' && i === 2) &&\r\n                    !(elementType === 'solidofrevolution3d' && i === 2) &&\r\n                    !(elementType === 'text3d' && (i === 2 || i === 4)) &&\r\n                    !(\r\n                        (elementType === 'input' ||\r\n                            elementType === 'checkbox' ||\r\n                            elementType === 'button') &&\r\n                        (i === 2 || i === 3)\r\n                    ) &&\r\n                    !(elementType === 'curve' /*&& i > 0*/) && // Allow curve plots with jessiecode, parents[0] is the\r\n                                                               // variable name\r\n                    !(elementType === 'functiongraph') && // Prevent problems with function terms like 'x', 'y'\r\n                    !(elementType === 'implicitcurve')\r\n                ) {\r\n                    if (i > 0 && parents[0].elType === 'view3d') {\r\n                        // 3D elements are based on 3D elements, only\r\n                        parents[i] = parents[0].select(parents[i]);\r\n                    } else {\r\n                        parents[i] = this.select(parents[i]);\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (Type.isFunction(JXG.elements[elementType])) {\r\n                el = JXG.elements[elementType](this, parents, attributes);\r\n            } else {\r\n                throw new Error('JSXGraph: create: Unknown element type given: ' + elementType);\r\n            }\r\n\r\n            if (!Type.exists(el)) {\r\n                JXG.debug('JSXGraph: create: failure creating ' + elementType);\r\n                return el;\r\n            }\r\n\r\n            if (el.prepareUpdate && el.update && el.updateRenderer) {\r\n                el.fullUpdate();\r\n            }\r\n            return el;\r\n        },\r\n\r\n        /**\r\n         * Deprecated name for {@link JXG.Board.create}.\r\n         * @deprecated\r\n         */\r\n        createElement: function () {\r\n            JXG.deprecated('Board.createElement()', 'Board.create()');\r\n            return this.create.apply(this, arguments);\r\n        },\r\n\r\n        /**\r\n         * Delete the elements drawn as part of a trace of an element.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        clearTraces: function () {\r\n            var el;\r\n\r\n            for (el = 0; el < this.objectsList.length; el++) {\r\n                this.objectsList[el].clearTrace();\r\n            }\r\n\r\n            this.numTraces = 0;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Stop updates of the board.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        suspendUpdate: function () {\r\n            if (!this.inUpdate) {\r\n                this.isSuspendedUpdate = true;\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Enable updates of the board.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        unsuspendUpdate: function () {\r\n            if (this.isSuspendedUpdate) {\r\n                this.isSuspendedUpdate = false;\r\n                this.fullUpdate();\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the bounding box of the board.\r\n         * @param {Array} bbox New bounding box [x1,y1,x2,y2]\r\n         * @param {Boolean} [keepaspectratio=false] If set to true, the aspect ratio will be 1:1, but\r\n         * the resulting viewport may be larger.\r\n         * @param {String} [setZoom='reset'] Reset, keep or update the zoom level of the board. 'reset'\r\n         * sets {@link JXG.Board#zoomX} and {@link JXG.Board#zoomY} to the start values (or 1.0).\r\n         * 'update' adapts these values accoring to the new bounding box and 'keep' does nothing.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        setBoundingBox: function (bbox, keepaspectratio, setZoom) {\r\n            var h, w, ux, uy,\r\n                offX = 0,\r\n                offY = 0,\r\n                zoom_ratio = 1,\r\n                ratio, dx, dy, prev_w, prev_h,\r\n                dim = Env.getDimensions(this.containerObj, this.document);\r\n\r\n            if (!Type.isArray(bbox)) {\r\n                return this;\r\n            }\r\n\r\n            if (\r\n                bbox[0] < this.maxboundingbox[0] - Mat.eps ||\r\n                bbox[1] > this.maxboundingbox[1] + Mat.eps ||\r\n                bbox[2] > this.maxboundingbox[2] + Mat.eps ||\r\n                bbox[3] < this.maxboundingbox[3] - Mat.eps\r\n            ) {\r\n                return this;\r\n            }\r\n\r\n            if (!Type.exists(setZoom)) {\r\n                setZoom = 'reset';\r\n            }\r\n\r\n            ux = this.unitX;\r\n            uy = this.unitY;\r\n            this.canvasWidth = parseFloat(dim.width);   // parseInt(dim.width, 10);\r\n            this.canvasHeight = parseFloat(dim.height); // parseInt(dim.height, 10);\r\n            w = this.canvasWidth;\r\n            h = this.canvasHeight;\r\n            if (keepaspectratio) {\r\n                if (this.keepaspectratio) {\r\n                    ratio = ux / uy;        // Keep this ratio if keepaspectratio was true\r\n                    if (isNaN(ratio)) {\r\n                        ratio = 1.0;\r\n                    }\r\n                } else {\r\n                    ratio = 1.0;\r\n                }\r\n                if (setZoom === 'keep') {\r\n                    zoom_ratio = this.zoomX / this.zoomY;\r\n                }\r\n                dx = bbox[2] - bbox[0];\r\n                dy = bbox[1] - bbox[3];\r\n                prev_w = ux * dx;\r\n                prev_h = uy * dy;\r\n                if (w >= h) {\r\n                    if (prev_w >= prev_h) {\r\n                        this.unitY = h / dy;\r\n                        this.unitX = this.unitY * ratio;\r\n                    } else {\r\n                        // Switch dominating interval\r\n                        this.unitY = h / Math.abs(dx) * Mat.sign(dy) / zoom_ratio;\r\n                        this.unitX = this.unitY * ratio;\r\n                    }\r\n                } else {\r\n                    if (prev_h > prev_w) {\r\n                        this.unitX = w / dx;\r\n                        this.unitY = this.unitX / ratio;\r\n                    } else {\r\n                        // Switch dominating interval\r\n                        this.unitX = w / Math.abs(dy) * Mat.sign(dx) * zoom_ratio;\r\n                        this.unitY = this.unitX / ratio;\r\n                    }\r\n                }\r\n                // Add the additional units in equal portions left and right\r\n                offX = (w / this.unitX - dx) * 0.5;\r\n                // Add the additional units in equal portions above and below\r\n                offY = (h / this.unitY - dy) * 0.5;\r\n                this.keepaspectratio = true;\r\n            } else {\r\n                this.unitX = w / (bbox[2] - bbox[0]);\r\n                this.unitY = h / (bbox[1] - bbox[3]);\r\n                this.keepaspectratio = false;\r\n            }\r\n\r\n            this.moveOrigin(-this.unitX * (bbox[0] - offX), this.unitY * (bbox[1] + offY));\r\n\r\n            if (setZoom === 'update') {\r\n                this.zoomX *= this.unitX / ux;\r\n                this.zoomY *= this.unitY / uy;\r\n            } else if (setZoom === 'reset') {\r\n                this.zoomX = Type.exists(this.attr.zoomx) ? this.attr.zoomx : 1.0;\r\n                this.zoomY = Type.exists(this.attr.zoomy) ? this.attr.zoomy : 1.0;\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Get the bounding box of the board.\r\n         * @returns {Array} bounding box [x1,y1,x2,y2] upper left corner, lower right corner\r\n         */\r\n        getBoundingBox: function () {\r\n            var ul = new Coords(Const.COORDS_BY_SCREEN, [0, 0], this).usrCoords,\r\n                lr = new Coords(\r\n                    Const.COORDS_BY_SCREEN,\r\n                    [this.canvasWidth, this.canvasHeight],\r\n                    this\r\n                ).usrCoords;\r\n            return [ul[1], ul[2], lr[1], lr[2]];\r\n        },\r\n\r\n        /**\r\n         * Sets the value of attribute <tt>key</tt> to <tt>value</tt>.\r\n         * @param {String} key The attribute's name.\r\n         * @param value The new value\r\n         * @private\r\n         */\r\n        _set: function (key, value) {\r\n            key = key.toLocaleLowerCase();\r\n\r\n            if (\r\n                value !== null &&\r\n                Type.isObject(value) &&\r\n                !Type.exists(value.id) &&\r\n                !Type.exists(value.name)\r\n            ) {\r\n                // value is of type {prop: val, prop: val,...}\r\n                // Convert these attributes to lowercase, too\r\n                // this.attr[key] = {};\r\n                // for (el in value) {\r\n                //     if (value.hasOwnProperty(el)) {\r\n                //         this.attr[key][el.toLocaleLowerCase()] = value[el];\r\n                //     }\r\n                // }\r\n                Type.mergeAttr(this.attr[key], value);\r\n            } else {\r\n                this.attr[key] = value;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Sets an arbitrary number of attributes. This method has one or more\r\n         * parameters of the following types:\r\n         * <ul>\r\n         * <li> object: {key1:value1,key2:value2,...}\r\n         * <li> string: 'key:value'\r\n         * <li> array: ['key', value]\r\n         * </ul>\r\n         * Some board attributes are immutable, like e.g. the renderer type.\r\n         *\r\n         * @param {Object} attributes An object with attributes.\r\n         * @returns {JXG.Board} Reference to the board\r\n         *\r\n         * @example\r\n         * const board = JXG.JSXGraph.initBoard('jxgbox', {\r\n         *     boundingbox: [-5, 5, 5, -5],\r\n         *     keepAspectRatio: false,\r\n         *     axis:true,\r\n         *     showFullscreen: true,\r\n         *     showScreenshot: true,\r\n         *     showCopyright: false\r\n         * });\r\n         *\r\n         * board.setAttribute({\r\n         *     animationDelay: 10,\r\n         *     boundingbox: [-10, 5, 10, -5],\r\n         *     defaultAxes: {\r\n         *         x: { strokeColor: 'blue', ticks: { strokeColor: 'blue'}}\r\n         *     },\r\n         *     description: 'test',\r\n         *     fullscreen: {\r\n         *         scale: 0.5\r\n         *     },\r\n         *     intl: {\r\n         *         enabled: true,\r\n         *         locale: 'de-DE'\r\n         *     }\r\n         * });\r\n         *\r\n         * board.setAttribute({\r\n         *     selection: {\r\n         *         enabled: true,\r\n         *         fillColor: 'blue'\r\n         *     },\r\n         *     showInfobox: false,\r\n         *     zoomX: 0.5,\r\n         *     zoomY: 2,\r\n         *     fullscreen: { symbol: 'x' },\r\n         *     screenshot: { symbol: 'y' },\r\n         *     showCopyright: true,\r\n         *     showFullscreen: false,\r\n         *     showScreenshot: false,\r\n         *     showZoom: false,\r\n         *     showNavigation: false\r\n         * });\r\n         * board.setAttribute('showCopyright:false');\r\n         *\r\n         * var p = board.create('point', [1, 1], {size: 10,\r\n         *     label: {\r\n         *         fontSize: 24,\r\n         *         highlightStrokeOpacity: 0.1,\r\n         *         offset: [5, 0]\r\n         *     }\r\n         * });\r\n         *\r\n         *\r\n         * </pre><div id=\"JXGea7b8e09-beac-4d95-9a0c-5fc1c761ffbc\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *     const board = JXG.JSXGraph.initBoard('JXGea7b8e09-beac-4d95-9a0c-5fc1c761ffbc', {\r\n         *         boundingbox: [-5, 5, 5, -5],\r\n         *         keepAspectRatio: false,\r\n         *         axis:true,\r\n         *         showFullscreen: true,\r\n         *         showScreenshot: true,\r\n         *         showCopyright: false\r\n         *     });\r\n         *\r\n         *     board.setAttribute({\r\n         *         animationDelay: 10,\r\n         *         boundingbox: [-10, 5, 10, -5],\r\n         *         defaultAxes: {\r\n         *             x: { strokeColor: 'blue', ticks: { strokeColor: 'blue'}}\r\n         *         },\r\n         *         description: 'test',\r\n         *         fullscreen: {\r\n         *             scale: 0.5\r\n         *         },\r\n         *         intl: {\r\n         *             enabled: true,\r\n         *             locale: 'de-DE'\r\n         *         }\r\n         *     });\r\n         *\r\n         *     board.setAttribute({\r\n         *         selection: {\r\n         *             enabled: true,\r\n         *             fillColor: 'blue'\r\n         *         },\r\n         *         showInfobox: false,\r\n         *         zoomX: 0.5,\r\n         *         zoomY: 2,\r\n         *         fullscreen: { symbol: 'x' },\r\n         *         screenshot: { symbol: 'y' },\r\n         *         showCopyright: true,\r\n         *         showFullscreen: false,\r\n         *         showScreenshot: false,\r\n         *         showZoom: false,\r\n         *         showNavigation: false\r\n         *     });\r\n         *\r\n         *     board.setAttribute('showCopyright:false');\r\n         *\r\n         *     var p = board.create('point', [1, 1], {size: 10,\r\n         *         label: {\r\n         *             fontSize: 24,\r\n         *             highlightStrokeOpacity: 0.1,\r\n         *             offset: [5, 0]\r\n         *         }\r\n         *     });\r\n         *\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         *\r\n         */\r\n        setAttribute: function (attr) {\r\n            var i, arg, pair,\r\n                key, value, oldvalue,// j, le,\r\n                node,\r\n                attributes = {};\r\n\r\n            // Normalize the user input\r\n            for (i = 0; i < arguments.length; i++) {\r\n                arg = arguments[i];\r\n                if (Type.isString(arg)) {\r\n                    // pairRaw is string of the form 'key:value'\r\n                    pair = arg.split(\":\");\r\n                    attributes[Type.trim(pair[0])] = Type.trim(pair[1]);\r\n                } else if (!Type.isArray(arg)) {\r\n                    // pairRaw consists of objects of the form {key1:value1,key2:value2,...}\r\n                    JXG.extend(attributes, arg);\r\n                } else {\r\n                    // pairRaw consists of array [key,value]\r\n                    attributes[arg[0]] = arg[1];\r\n                }\r\n            }\r\n\r\n            for (i in attributes) {\r\n                if (attributes.hasOwnProperty(i)) {\r\n                    key = i.replace(/\\s+/g, \"\").toLowerCase();\r\n                    value = attributes[i];\r\n                }\r\n                value = (value.toLowerCase && value.toLowerCase() === 'false')\r\n                    ? false\r\n                    : value;\r\n\r\n                oldvalue = this.attr[key];\r\n                if (oldvalue === value) {\r\n                    continue;\r\n                }\r\n                switch (key) {\r\n                    case 'axis':\r\n                        if (value === false) {\r\n                            if (Type.exists(this.defaultAxes)) {\r\n                                this.defaultAxes.x.setAttribute({ visible: false });\r\n                                this.defaultAxes.y.setAttribute({ visible: false });\r\n                            }\r\n                        } else {\r\n                            // TODO\r\n                        }\r\n                        break;\r\n                    case 'boundingbox':\r\n                        this.setBoundingBox(value, this.keepaspectratio);\r\n                        this._set(key, value);\r\n                        break;\r\n                    case 'defaultaxes':\r\n                        if (Type.exists(this.defaultAxes.x) && Type.exists(value.x)) {\r\n                            this.defaultAxes.x.setAttribute(value.x);\r\n                        }\r\n                        if (Type.exists(this.defaultAxes.y) && Type.exists(value.y)) {\r\n                            this.defaultAxes.y.setAttribute(value.y);\r\n                        }\r\n                        break;\r\n                    case 'title':\r\n                        this.document.getElementById(this.container + '_ARIAlabel')\r\n                            .innerText = value;\r\n                        this._set(key, value);\r\n                        break;\r\n                    case 'keepaspectratio':\r\n                        this._set(key, value);\r\n                        this.setBoundingBox(this.getBoundingBox(), value, 'keep');\r\n                        break;\r\n\r\n                    // /* eslint-disable no-fallthrough */\r\n                    case 'document':\r\n                    case 'maxboundingbox':\r\n                        this[key] = value;\r\n                        this._set(key, value);\r\n                        break;\r\n\r\n                    case 'zoomx':\r\n                    case 'zoomy':\r\n                        this[key] = value;\r\n                        this._set(key, value);\r\n                        this.setZoom(this.attr.zoomx, this.attr.zoomy);\r\n                        break;\r\n\r\n                    case 'registerevents':\r\n                    case 'renderer':\r\n                        // immutable, i.e. ignored\r\n                        break;\r\n\r\n                    case 'fullscreen':\r\n                    case 'screenshot':\r\n                        node = this.containerObj.ownerDocument.getElementById(\r\n                            this.container + '_navigation_' + key);\r\n                        if (node && Type.exists(value.symbol)) {\r\n                            node.innerText = Type.evaluate(value.symbol);\r\n                        }\r\n                        this._set(key, value);\r\n                        break;\r\n\r\n                    case 'selection':\r\n                        value.visible = false;\r\n                        value.withLines = false;\r\n                        value.vertices = { visible: false };\r\n                        this._set(key, value);\r\n                        break;\r\n\r\n                    case 'showcopyright':\r\n                        if (this.renderer.type === 'svg') {\r\n                            node = this.containerObj.ownerDocument.getElementById(\r\n                                this.renderer.uniqName('licenseText')\r\n                            );\r\n                            if (node) {\r\n                                node.style.display = ((Type.evaluate(value)) ? 'inline' : 'none');\r\n                            } else if (Type.evaluate(value)) {\r\n                                this.renderer.displayCopyright(Const.licenseText, parseInt(this.options.text.fontSize, 10));\r\n                            }\r\n                        }\r\n                        this._set(key, value);\r\n                        break;\r\n\r\n                    case 'showlogo':\r\n                        if (this.renderer.type === 'svg') {\r\n                            node = this.containerObj.ownerDocument.getElementById(\r\n                                this.renderer.uniqName('licenseLogo')\r\n                            );\r\n                            if (node) {\r\n                                node.style.display = ((Type.evaluate(value)) ? 'inline' : 'none');\r\n                            } else if (Type.evaluate(value)) {\r\n                                this.renderer.displayLogo(Const.licenseLogo, parseInt(this.options.text.fontSize, 10));\r\n                            }\r\n                        }\r\n                        this._set(key, value);\r\n                        break;\r\n\r\n                    default:\r\n                        if (Type.exists(this.attr[key])) {\r\n                            this._set(key, value);\r\n                        }\r\n                        break;\r\n                    // /* eslint-enable no-fallthrough */\r\n                }\r\n            }\r\n\r\n            // Redraw navbar to handle the remaining show* attributes\r\n            this.containerObj.ownerDocument.getElementById(\r\n                this.container + \"_navigationbar\"\r\n            ).remove();\r\n            this.renderer.drawNavigationBar(this, this.attr.navbar);\r\n\r\n            this.triggerEventHandlers([\"attribute\"], [attributes, this]);\r\n            this.fullUpdate();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Adds an animation. Animations are controlled by the boards, so the boards need to be aware of the\r\n         * animated elements. This function tells the board about new elements to animate.\r\n         * @param {JXG.GeometryElement} element The element which is to be animated.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        addAnimation: function (element) {\r\n            var that = this;\r\n\r\n            this.animationObjects[element.id] = element;\r\n\r\n            if (!this.animationIntervalCode) {\r\n                this.animationIntervalCode = window.setInterval(function () {\r\n                    that.animate();\r\n                }, element.board.attr.animationdelay);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Cancels all running animations.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        stopAllAnimation: function () {\r\n            var el;\r\n\r\n            for (el in this.animationObjects) {\r\n                if (\r\n                    this.animationObjects.hasOwnProperty(el) &&\r\n                    Type.exists(this.animationObjects[el])\r\n                ) {\r\n                    this.animationObjects[el] = null;\r\n                    delete this.animationObjects[el];\r\n                }\r\n            }\r\n\r\n            window.clearInterval(this.animationIntervalCode);\r\n            delete this.animationIntervalCode;\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * General purpose animation function. This currently only supports moving points from one place to another. This\r\n         * is faster than managing the animation per point, especially if there is more than one animated point at the same time.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        animate: function () {\r\n            var props,\r\n                el,\r\n                o,\r\n                newCoords,\r\n                r,\r\n                p,\r\n                c,\r\n                cbtmp,\r\n                count = 0,\r\n                obj = null;\r\n\r\n            for (el in this.animationObjects) {\r\n                if (\r\n                    this.animationObjects.hasOwnProperty(el) &&\r\n                    Type.exists(this.animationObjects[el])\r\n                ) {\r\n                    count += 1;\r\n                    o = this.animationObjects[el];\r\n\r\n                    if (o.animationPath) {\r\n                        if (Type.isFunction(o.animationPath)) {\r\n                            newCoords = o.animationPath(\r\n                                new Date().getTime() - o.animationStart\r\n                            );\r\n                        } else {\r\n                            newCoords = o.animationPath.pop();\r\n                        }\r\n\r\n                        if (\r\n                            !Type.exists(newCoords) ||\r\n                            (!Type.isArray(newCoords) && isNaN(newCoords))\r\n                        ) {\r\n                            delete o.animationPath;\r\n                        } else {\r\n                            o.setPositionDirectly(Const.COORDS_BY_USER, newCoords);\r\n                            o.fullUpdate();\r\n                            obj = o;\r\n                        }\r\n                    }\r\n                    if (o.animationData) {\r\n                        c = 0;\r\n\r\n                        for (r in o.animationData) {\r\n                            if (o.animationData.hasOwnProperty(r)) {\r\n                                p = o.animationData[r].pop();\r\n\r\n                                if (!Type.exists(p)) {\r\n                                    delete o.animationData[p];\r\n                                } else {\r\n                                    c += 1;\r\n                                    props = {};\r\n                                    props[r] = p;\r\n                                    o.setAttribute(props);\r\n                                }\r\n                            }\r\n                        }\r\n\r\n                        if (c === 0) {\r\n                            delete o.animationData;\r\n                        }\r\n                    }\r\n\r\n                    if (!Type.exists(o.animationData) && !Type.exists(o.animationPath)) {\r\n                        this.animationObjects[el] = null;\r\n                        delete this.animationObjects[el];\r\n\r\n                        if (Type.exists(o.animationCallback)) {\r\n                            cbtmp = o.animationCallback;\r\n                            o.animationCallback = null;\r\n                            cbtmp();\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (count === 0) {\r\n                window.clearInterval(this.animationIntervalCode);\r\n                delete this.animationIntervalCode;\r\n            } else {\r\n                this.update(obj);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Migrate the dependency properties of the point src\r\n         * to the point dest and delete the point src.\r\n         * For example, a circle around the point src\r\n         * receives the new center dest. The old center src\r\n         * will be deleted.\r\n         * @param {JXG.Point} src Original point which will be deleted\r\n         * @param {JXG.Point} dest New point with the dependencies of src.\r\n         * @param {Boolean} copyName Flag which decides if the name of the src element is copied to the\r\n         *  dest element.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        migratePoint: function (src, dest, copyName) {\r\n            var child,\r\n                childId,\r\n                prop,\r\n                found,\r\n                i,\r\n                srcLabelId,\r\n                srcHasLabel = false;\r\n\r\n            src = this.select(src);\r\n            dest = this.select(dest);\r\n\r\n            if (Type.exists(src.label)) {\r\n                srcLabelId = src.label.id;\r\n                srcHasLabel = true;\r\n                this.removeObject(src.label);\r\n            }\r\n\r\n            for (childId in src.childElements) {\r\n                if (src.childElements.hasOwnProperty(childId)) {\r\n                    child = src.childElements[childId];\r\n                    found = false;\r\n\r\n                    for (prop in child) {\r\n                        if (child.hasOwnProperty(prop)) {\r\n                            if (child[prop] === src) {\r\n                                child[prop] = dest;\r\n                                found = true;\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    if (found) {\r\n                        delete src.childElements[childId];\r\n                    }\r\n\r\n                    for (i = 0; i < child.parents.length; i++) {\r\n                        if (child.parents[i] === src.id) {\r\n                            child.parents[i] = dest.id;\r\n                        }\r\n                    }\r\n\r\n                    dest.addChild(child);\r\n                }\r\n            }\r\n\r\n            // The destination object should receive the name\r\n            // and the label of the originating (src) object\r\n            if (copyName) {\r\n                if (srcHasLabel) {\r\n                    delete dest.childElements[srcLabelId];\r\n                    delete dest.descendants[srcLabelId];\r\n                }\r\n\r\n                if (dest.label) {\r\n                    this.removeObject(dest.label);\r\n                }\r\n\r\n                delete this.elementsByName[dest.name];\r\n                dest.name = src.name;\r\n                if (srcHasLabel) {\r\n                    dest.createLabel();\r\n                }\r\n            }\r\n\r\n            this.removeObject(src);\r\n\r\n            if (Type.exists(dest.name) && dest.name !== '') {\r\n                this.elementsByName[dest.name] = dest;\r\n            }\r\n\r\n            this.fullUpdate();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Initializes color blindness simulation.\r\n         * @param {String} deficiency Describes the color blindness deficiency which is simulated. Accepted values are 'protanopia', 'deuteranopia', and 'tritanopia'.\r\n         * @returns {JXG.Board} Reference to the board\r\n         */\r\n        emulateColorblindness: function (deficiency) {\r\n            var e, o;\r\n\r\n            if (!Type.exists(deficiency)) {\r\n                deficiency = 'none';\r\n            }\r\n\r\n            if (this.currentCBDef === deficiency) {\r\n                return this;\r\n            }\r\n\r\n            for (e in this.objects) {\r\n                if (this.objects.hasOwnProperty(e)) {\r\n                    o = this.objects[e];\r\n\r\n                    if (deficiency !== 'none') {\r\n                        if (this.currentCBDef === 'none') {\r\n                            // this could be accomplished by JXG.extend, too. But do not use\r\n                            // JXG.deepCopy as this could result in an infinite loop because in\r\n                            // visProp there could be geometry elements which contain the board which\r\n                            // contains all objects which contain board etc.\r\n                            o.visPropOriginal = {\r\n                                strokecolor: o.visProp.strokecolor,\r\n                                fillcolor: o.visProp.fillcolor,\r\n                                highlightstrokecolor: o.visProp.highlightstrokecolor,\r\n                                highlightfillcolor: o.visProp.highlightfillcolor\r\n                            };\r\n                        }\r\n                        o.setAttribute({\r\n                            strokecolor: Color.rgb2cb(\r\n                                o.eval(o.visPropOriginal.strokecolor),\r\n                                deficiency\r\n                            ),\r\n                            fillcolor: Color.rgb2cb(\r\n                                o.eval(o.visPropOriginal.fillcolor),\r\n                                deficiency\r\n                            ),\r\n                            highlightstrokecolor: Color.rgb2cb(\r\n                                o.eval(o.visPropOriginal.highlightstrokecolor),\r\n                                deficiency\r\n                            ),\r\n                            highlightfillcolor: Color.rgb2cb(\r\n                                o.eval(o.visPropOriginal.highlightfillcolor),\r\n                                deficiency\r\n                            )\r\n                        });\r\n                    } else if (Type.exists(o.visPropOriginal)) {\r\n                        JXG.extend(o.visProp, o.visPropOriginal);\r\n                    }\r\n                }\r\n            }\r\n            this.currentCBDef = deficiency;\r\n            this.update();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Select a single or multiple elements at once.\r\n         * @param {String|Object|function} str The name, id or a reference to a JSXGraph element on this board. An object will\r\n         * be used as a filter to return multiple elements at once filtered by the properties of the object.\r\n         * @param {Boolean} onlyByIdOrName If true (default:false) elements are only filtered by their id, name or groupId.\r\n         * The advanced filters consisting of objects or functions are ignored.\r\n         * @returns {JXG.GeometryElement|JXG.Composition}\r\n         * @example\r\n         * // select the element with name A\r\n         * board.select('A');\r\n         *\r\n         * // select all elements with strokecolor set to 'red' (but not '#ff0000')\r\n         * board.select({\r\n         *   strokeColor: 'red'\r\n         * });\r\n         *\r\n         * // select all points on or below the x axis and make them black.\r\n         * board.select({\r\n         *   elementClass: JXG.OBJECT_CLASS_POINT,\r\n         *   Y: function (v) {\r\n         *     return v <= 0;\r\n         *   }\r\n         * }).setAttribute({color: 'black'});\r\n         *\r\n         * // select all elements\r\n         * board.select(function (el) {\r\n         *   return true;\r\n         * });\r\n         */\r\n        select: function (str, onlyByIdOrName) {\r\n            var flist,\r\n                olist,\r\n                i,\r\n                l,\r\n                s = str;\r\n\r\n            if (s === null) {\r\n                return s;\r\n            }\r\n\r\n            // It's a string, most likely an id or a name.\r\n            if (Type.isString(s) && s !== '') {\r\n                // Search by ID\r\n                if (Type.exists(this.objects[s])) {\r\n                    s = this.objects[s];\r\n                    // Search by name\r\n                } else if (Type.exists(this.elementsByName[s])) {\r\n                    s = this.elementsByName[s];\r\n                    // Search by group ID\r\n                } else if (Type.exists(this.groups[s])) {\r\n                    s = this.groups[s];\r\n                }\r\n\r\n                // It's a function or an object, but not an element\r\n            } else if (\r\n                !onlyByIdOrName &&\r\n                (Type.isFunction(s) || (Type.isObject(s) && !Type.isFunction(s.setAttribute)))\r\n            ) {\r\n                flist = Type.filterElements(this.objectsList, s);\r\n\r\n                olist = {};\r\n                l = flist.length;\r\n                for (i = 0; i < l; i++) {\r\n                    olist[flist[i].id] = flist[i];\r\n                }\r\n                s = new Composition(olist);\r\n\r\n                // It's an element which has been deleted (and still hangs around, e.g. in an attractor list\r\n            } else if (\r\n                Type.isObject(s) &&\r\n                Type.exists(s.id) &&\r\n                !Type.exists(this.objects[s.id])\r\n            ) {\r\n                s = null;\r\n            }\r\n\r\n            return s;\r\n        },\r\n\r\n        /**\r\n         * Checks if the given point is inside the boundingbox.\r\n         * @param {Number|JXG.Coords} x User coordinate or {@link JXG.Coords} object.\r\n         * @param {Number} [y] User coordinate. May be omitted in case <tt>x</tt> is a {@link JXG.Coords} object.\r\n         * @returns {Boolean}\r\n         */\r\n        hasPoint: function (x, y) {\r\n            var px = x,\r\n                py = y,\r\n                bbox = this.getBoundingBox();\r\n\r\n            if (Type.exists(x) && Type.isArray(x.usrCoords)) {\r\n                px = x.usrCoords[1];\r\n                py = x.usrCoords[2];\r\n            }\r\n\r\n            return !!(\r\n                Type.isNumber(px) &&\r\n                Type.isNumber(py) &&\r\n                bbox[0] < px &&\r\n                px < bbox[2] &&\r\n                bbox[1] > py &&\r\n                py > bbox[3]\r\n            );\r\n        },\r\n\r\n        /**\r\n         * Update CSS transformations of type scaling. It is used to correct the mouse position\r\n         * in {@link JXG.Board.getMousePosition}.\r\n         * The inverse transformation matrix is updated on each mouseDown and touchStart event.\r\n         *\r\n         * It is up to the user to call this method after an update of the CSS transformation\r\n         * in the DOM.\r\n         */\r\n        updateCSSTransforms: function () {\r\n            var obj = this.containerObj,\r\n                o = obj,\r\n                o2 = obj;\r\n\r\n            this.cssTransMat = Env.getCSSTransformMatrix(o);\r\n\r\n            // Newer variant of walking up the tree.\r\n            // We walk up all parent nodes and collect possible CSS transforms.\r\n            // Works also for ShadowDOM\r\n            if (Type.exists(o.getRootNode)) {\r\n                o = o.parentNode === o.getRootNode() ? o.parentNode.host : o.parentNode;\r\n                while (o) {\r\n                    this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);\r\n                    o = o.parentNode === o.getRootNode() ? o.parentNode.host : o.parentNode;\r\n                }\r\n                this.cssTransMat = Mat.inverse(this.cssTransMat);\r\n            } else {\r\n                /*\r\n                 * This is necessary for IE11\r\n                 */\r\n                o = o.offsetParent;\r\n                while (o) {\r\n                    this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);\r\n\r\n                    o2 = o2.parentNode;\r\n                    while (o2 !== o) {\r\n                        this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);\r\n                        o2 = o2.parentNode;\r\n                    }\r\n                    o = o.offsetParent;\r\n                }\r\n                this.cssTransMat = Mat.inverse(this.cssTransMat);\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Start selection mode. This function can either be triggered from outside or by\r\n         * a down event together with correct key pressing. The default keys are\r\n         * shift+ctrl. But this can be changed in the options.\r\n         *\r\n         * Starting from out side can be realized for example with a button like this:\r\n         * <pre>\r\n         * \t&lt;button onclick='board.startSelectionMode()'&gt;Start&lt;/button&gt;\r\n         * </pre>\r\n         * @example\r\n         * //\r\n         * // Set a new bounding box from the selection rectangle\r\n         * //\r\n         * var board = JXG.JSXGraph.initBoard('jxgbox', {\r\n         *         boundingBox:[-3,2,3,-2],\r\n         *         keepAspectRatio: false,\r\n         *         axis:true,\r\n         *         selection: {\r\n         *             enabled: true,\r\n         *             needShift: false,\r\n         *             needCtrl: true,\r\n         *             withLines: false,\r\n         *             vertices: {\r\n         *                 visible: false\r\n         *             },\r\n         *             fillColor: '#ffff00',\r\n         *         }\r\n         *      });\r\n         *\r\n         * var f = function f(x) { return Math.cos(x); },\r\n         *     curve = board.create('functiongraph', [f]);\r\n         *\r\n         * board.on('stopselecting', function(){\r\n         *     var box = board.stopSelectionMode(),\r\n         *\r\n         *         // bbox has the coordinates of the selection rectangle.\r\n         *         // Attention: box[i].usrCoords have the form [1, x, y], i.e.\r\n         *         // are homogeneous coordinates.\r\n         *         bbox = box[0].usrCoords.slice(1).concat(box[1].usrCoords.slice(1));\r\n         *\r\n         *         // Set a new bounding box\r\n         *         board.setBoundingBox(bbox, false);\r\n         *  });\r\n         *\r\n         *\r\n         * </pre><div class='jxgbox' id='JXG11eff3a6-8c50-11e5-b01d-901b0e1b8723' style='width: 300px; height: 300px;'></div>\r\n         * <script type='text/javascript'>\r\n         *     (function() {\r\n         *     //\r\n         *     // Set a new bounding box from the selection rectangle\r\n         *     //\r\n         *     var board = JXG.JSXGraph.initBoard('JXG11eff3a6-8c50-11e5-b01d-901b0e1b8723', {\r\n         *             boundingBox:[-3,2,3,-2],\r\n         *             keepAspectRatio: false,\r\n         *             axis:true,\r\n         *             selection: {\r\n         *                 enabled: true,\r\n         *                 needShift: false,\r\n         *                 needCtrl: true,\r\n         *                 withLines: false,\r\n         *                 vertices: {\r\n         *                     visible: false\r\n         *                 },\r\n         *                 fillColor: '#ffff00',\r\n         *             }\r\n         *        });\r\n         *\r\n         *     var f = function f(x) { return Math.cos(x); },\r\n         *         curve = board.create('functiongraph', [f]);\r\n         *\r\n         *     board.on('stopselecting', function(){\r\n         *         var box = board.stopSelectionMode(),\r\n         *\r\n         *             // bbox has the coordinates of the selection rectangle.\r\n         *             // Attention: box[i].usrCoords have the form [1, x, y], i.e.\r\n         *             // are homogeneous coordinates.\r\n         *             bbox = box[0].usrCoords.slice(1).concat(box[1].usrCoords.slice(1));\r\n         *\r\n         *             // Set a new bounding box\r\n         *             board.setBoundingBox(bbox, false);\r\n         *      });\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        startSelectionMode: function () {\r\n            this.selectingMode = true;\r\n            this.selectionPolygon.setAttribute({ visible: true });\r\n            this.selectingBox = [\r\n                [0, 0],\r\n                [0, 0]\r\n            ];\r\n            this._setSelectionPolygonFromBox();\r\n            this.selectionPolygon.fullUpdate();\r\n        },\r\n\r\n        /**\r\n         * Finalize the selection: disable selection mode and return the coordinates\r\n         * of the selection rectangle.\r\n         * @returns {Array} Coordinates of the selection rectangle. The array\r\n         * contains two {@link JXG.Coords} objects. One the upper left corner and\r\n         * the second for the lower right corner.\r\n         */\r\n        stopSelectionMode: function () {\r\n            this.selectingMode = false;\r\n            this.selectionPolygon.setAttribute({ visible: false });\r\n            return [\r\n                this.selectionPolygon.vertices[0].coords,\r\n                this.selectionPolygon.vertices[2].coords\r\n            ];\r\n        },\r\n\r\n        /**\r\n         * Start the selection of a region.\r\n         * @private\r\n         * @param  {Array} pos Screen coordiates of the upper left corner of the\r\n         * selection rectangle.\r\n         */\r\n        _startSelecting: function (pos) {\r\n            this.isSelecting = true;\r\n            this.selectingBox = [\r\n                [pos[0], pos[1]],\r\n                [pos[0], pos[1]]\r\n            ];\r\n            this._setSelectionPolygonFromBox();\r\n        },\r\n\r\n        /**\r\n         * Update the selection rectangle during a move event.\r\n         * @private\r\n         * @param  {Array} pos Screen coordiates of the move event\r\n         */\r\n        _moveSelecting: function (pos) {\r\n            if (this.isSelecting) {\r\n                this.selectingBox[1] = [pos[0], pos[1]];\r\n                this._setSelectionPolygonFromBox();\r\n                this.selectionPolygon.fullUpdate();\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Update the selection rectangle during an up event. Stop selection.\r\n         * @private\r\n         * @param  {Object} evt Event object\r\n         */\r\n        _stopSelecting: function (evt) {\r\n            var pos = this.getMousePosition(evt);\r\n\r\n            this.isSelecting = false;\r\n            this.selectingBox[1] = [pos[0], pos[1]];\r\n            this._setSelectionPolygonFromBox();\r\n        },\r\n\r\n        /**\r\n         * Update the Selection rectangle.\r\n         * @private\r\n         */\r\n        _setSelectionPolygonFromBox: function () {\r\n            var A = this.selectingBox[0],\r\n                B = this.selectingBox[1];\r\n\r\n            this.selectionPolygon.vertices[0].setPositionDirectly(JXG.COORDS_BY_SCREEN, [\r\n                A[0],\r\n                A[1]\r\n            ]);\r\n            this.selectionPolygon.vertices[1].setPositionDirectly(JXG.COORDS_BY_SCREEN, [\r\n                A[0],\r\n                B[1]\r\n            ]);\r\n            this.selectionPolygon.vertices[2].setPositionDirectly(JXG.COORDS_BY_SCREEN, [\r\n                B[0],\r\n                B[1]\r\n            ]);\r\n            this.selectionPolygon.vertices[3].setPositionDirectly(JXG.COORDS_BY_SCREEN, [\r\n                B[0],\r\n                A[1]\r\n            ]);\r\n        },\r\n\r\n        /**\r\n         * Test if a down event should start a selection. Test if the\r\n         * required keys are pressed. If yes, {@link JXG.Board.startSelectionMode} is called.\r\n         * @param  {Object} evt Event object\r\n         */\r\n        _testForSelection: function (evt) {\r\n            if (this._isRequiredKeyPressed(evt, 'selection')) {\r\n                if (!Type.exists(this.selectionPolygon)) {\r\n                    this._createSelectionPolygon(this.attr);\r\n                }\r\n                this.startSelectionMode();\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Create the internal selection polygon, which will be available as board.selectionPolygon.\r\n         * @private\r\n         * @param  {Object} attr board attributes, e.g. the subobject board.attr.\r\n         * @returns {Object} pointer to the board to enable chaining.\r\n         */\r\n        _createSelectionPolygon: function (attr) {\r\n            var selectionattr;\r\n\r\n            if (!Type.exists(this.selectionPolygon)) {\r\n                selectionattr = Type.copyAttributes(attr, Options, 'board', 'selection');\r\n                if (selectionattr.enabled === true) {\r\n                    this.selectionPolygon = this.create(\r\n                        'polygon',\r\n                        [\r\n                            [0, 0],\r\n                            [0, 0],\r\n                            [0, 0],\r\n                            [0, 0]\r\n                        ],\r\n                        selectionattr\r\n                    );\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /* **************************\r\n         *     EVENT DEFINITION\r\n         * for documentation purposes\r\n         * ************************** */\r\n\r\n        //region Event handler documentation\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the {@link JXG.Board#setAttribute} is called.\r\n         * @name JXG.Board#attribute\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__attribute: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user starts to touch or click the board.\r\n         * @name JXG.Board#down\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__down: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user starts to click on the board.\r\n         * @name JXG.Board#mousedown\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__mousedown: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user taps the pen on the board.\r\n         * @name JXG.Board#pendown\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__pendown: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user starts to click on the board with a\r\n         * device sending pointer events.\r\n         * @name JXG.Board#pointerdown\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__pointerdown: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user starts to touch the board.\r\n         * @name JXG.Board#touchstart\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__touchstart: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user stops to touch or click the board.\r\n         * @name JXG.Board#up\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__up: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user releases the mousebutton over the board.\r\n         * @name JXG.Board#mouseup\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__mouseup: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user releases the mousebutton over the board with a\r\n         * device sending pointer events.\r\n         * @name JXG.Board#pointerup\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__pointerup: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user stops touching the board.\r\n         * @name JXG.Board#touchend\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__touchend: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user clicks on the board.\r\n         * @name JXG.Board#click\r\n         * @see JXG.Board#clickDelay\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__click: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user double clicks on the board.\r\n         * This event works on desktop browser, but is undefined\r\n         * on mobile browsers.\r\n         * @name JXG.Board#dblclick\r\n         * @see JXG.Board#clickDelay\r\n         * @see JXG.Board#dblClickSuppressClick\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__dblclick: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user clicks on the board with a mouse device.\r\n         * @name JXG.Board#mouseclick\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__mouseclick: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user double clicks on the board with a mouse device.\r\n         * @name JXG.Board#mousedblclick\r\n         * @see JXG.Board#clickDelay\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__mousedblclick: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user clicks on the board with a pointer device.\r\n         * @name JXG.Board#pointerclick\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__pointerclick: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever the user double clicks on the board with a pointer device.\r\n         * This event works on desktop browser, but is undefined\r\n         * on mobile browsers.\r\n         * @name JXG.Board#pointerdblclick\r\n         * @see JXG.Board#clickDelay\r\n         * @param {Event} e The browser's event object.\r\n         */\r\n        __evt__pointerdblclick: function (e) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user is moving the finger or mouse pointer over the board.\r\n         * @name JXG.Board#move\r\n         * @param {Event} e The browser's event object.\r\n         * @param {Number} mode The mode the board currently is in\r\n         * @see JXG.Board#mode\r\n         */\r\n        __evt__move: function (e, mode) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user is moving the mouse over the board.\r\n         * @name JXG.Board#mousemove\r\n         * @param {Event} e The browser's event object.\r\n         * @param {Number} mode The mode the board currently is in\r\n         * @see JXG.Board#mode\r\n         */\r\n        __evt__mousemove: function (e, mode) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user is moving the pen over the board.\r\n         * @name JXG.Board#penmove\r\n         * @param {Event} e The browser's event object.\r\n         * @param {Number} mode The mode the board currently is in\r\n         * @see JXG.Board#mode\r\n         */\r\n        __evt__penmove: function (e, mode) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user is moving the mouse over the board with a\r\n         * device sending pointer events.\r\n         * @name JXG.Board#pointermove\r\n         * @param {Event} e The browser's event object.\r\n         * @param {Number} mode The mode the board currently is in\r\n         * @see JXG.Board#mode\r\n         */\r\n        __evt__pointermove: function (e, mode) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user is moving the finger over the board.\r\n         * @name JXG.Board#touchmove\r\n         * @param {Event} e The browser's event object.\r\n         * @param {Number} mode The mode the board currently is in\r\n         * @see JXG.Board#mode\r\n         */\r\n        __evt__touchmove: function (e, mode) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This event is fired whenever the user is moving an element over the board by\r\n         * pressing arrow keys on a keyboard.\r\n         * @name JXG.Board#keymove\r\n         * @param {Event} e The browser's event object.\r\n         * @param {Number} mode The mode the board currently is in\r\n         * @see JXG.Board#mode\r\n         */\r\n        __evt__keymove: function (e, mode) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever an element is highlighted this event is fired.\r\n         * @name JXG.Board#hit\r\n         * @param {Event} e The browser's event object.\r\n         * @param {JXG.GeometryElement} el The hit element.\r\n         * @param target\r\n         *\r\n         * @example\r\n         * var c = board.create('circle', [[1, 1], 2]);\r\n         * board.on('hit', function(evt, el) {\r\n         *     console.log('Hit element', el);\r\n         * });\r\n         *\r\n         * </pre><div id='JXG19eb31ac-88e6-11e8-bcb5-901b0e1b8723' class='jxgbox' style='width: 300px; height: 300px;'></div>\r\n         * <script type='text/javascript'>\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG19eb31ac-88e6-11e8-bcb5-901b0e1b8723',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var c = board.create('circle', [[1, 1], 2]);\r\n         *     board.on('hit', function(evt, el) {\r\n         *         console.log('Hit element', el);\r\n         *     });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         */\r\n        __evt__hit: function (e, el, target) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Whenever an element is highlighted this event is fired.\r\n         * @name JXG.Board#mousehit\r\n         * @see JXG.Board#hit\r\n         * @param {Event} e The browser's event object.\r\n         * @param {JXG.GeometryElement} el The hit element.\r\n         * @param target\r\n         */\r\n        __evt__mousehit: function (e, el, target) { },\r\n\r\n        /**\r\n         * @event\r\n         * @description This board is updated.\r\n         * @name JXG.Board#update\r\n         */\r\n        __evt__update: function () { },\r\n\r\n        /**\r\n         * @event\r\n         * @description The bounding box of the board has changed.\r\n         * @name JXG.Board#boundingbox\r\n         */\r\n        __evt__boundingbox: function () { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Select a region is started during a down event or by calling\r\n         * {@link JXG.Board.startSelectionMode}\r\n         * @name JXG.Board#startselecting\r\n         */\r\n        __evt__startselecting: function () { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Select a region is started during a down event\r\n         * from a device sending mouse events or by calling\r\n         * {@link JXG.Board.startSelectionMode}.\r\n         * @name JXG.Board#mousestartselecting\r\n         */\r\n        __evt__mousestartselecting: function () { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Select a region is started during a down event\r\n         * from a device sending pointer events or by calling\r\n         * {@link JXG.Board.startSelectionMode}.\r\n         * @name JXG.Board#pointerstartselecting\r\n         */\r\n        __evt__pointerstartselecting: function () { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Select a region is started during a down event\r\n         * from a device sending touch events or by calling\r\n         * {@link JXG.Board.startSelectionMode}.\r\n         * @name JXG.Board#touchstartselecting\r\n         */\r\n        __evt__touchstartselecting: function () { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Selection of a region is stopped during an up event.\r\n         * @name JXG.Board#stopselecting\r\n         */\r\n        __evt__stopselecting: function () { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Selection of a region is stopped during an up event\r\n         * from a device sending mouse events.\r\n         * @name JXG.Board#mousestopselecting\r\n         */\r\n        __evt__mousestopselecting: function () { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Selection of a region is stopped during an up event\r\n         * from a device sending pointer events.\r\n         * @name JXG.Board#pointerstopselecting\r\n         */\r\n        __evt__pointerstopselecting: function () { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Selection of a region is stopped during an up event\r\n         * from a device sending touch events.\r\n         * @name JXG.Board#touchstopselecting\r\n         */\r\n        __evt__touchstopselecting: function () { },\r\n\r\n        /**\r\n         * @event\r\n         * @description A move event while selecting of a region is active.\r\n         * @name JXG.Board#moveselecting\r\n         */\r\n        __evt__moveselecting: function () { },\r\n\r\n        /**\r\n         * @event\r\n         * @description A move event while selecting of a region is active\r\n         * from a device sending mouse events.\r\n         * @name JXG.Board#mousemoveselecting\r\n         */\r\n        __evt__mousemoveselecting: function () { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Select a region is started during a down event\r\n         * from a device sending mouse events.\r\n         * @name JXG.Board#pointermoveselecting\r\n         */\r\n        __evt__pointermoveselecting: function () { },\r\n\r\n        /**\r\n         * @event\r\n         * @description Select a region is started during a down event\r\n         * from a device sending touch events.\r\n         * @name JXG.Board#touchmoveselecting\r\n         */\r\n        __evt__touchmoveselecting: function () { },\r\n\r\n        /**\r\n         * @ignore\r\n         */\r\n        __evt: function () { },\r\n\r\n        //endregion\r\n\r\n        /**\r\n         * Expand the JSXGraph construction to fullscreen.\r\n         * In order to preserve the proportions of the JSXGraph element,\r\n         * a wrapper div is created which is set to fullscreen.\r\n         * This function is called when fullscreen mode is triggered\r\n         * <b>and</b> when it is closed.\r\n         * <p>\r\n         * The wrapping div has the CSS class 'jxgbox_wrap_private' which is\r\n         * defined in the file 'jsxgraph.css'\r\n         * <p>\r\n         * This feature is not available on iPhones (as of December 2021).\r\n         *\r\n         * @param {String} id (Optional) id of the div element which is brought to fullscreen.\r\n         * If not provided, this defaults to the JSXGraph div. However, it may be necessary for the aspect ratio trick\r\n         * which using padding-bottom/top and an out div element. Then, the id of the outer div has to be supplied.\r\n         *\r\n         * @return {JXG.Board} Reference to the board\r\n         *\r\n         * @example\r\n         * &lt;div id='jxgbox' class='jxgbox' style='width:500px; height:200px;'&gt;&lt;/div&gt;\r\n         * &lt;button onClick='board.toFullscreen()'&gt;Fullscreen&lt;/button&gt;\r\n         *\r\n         * &lt;script language='Javascript' type='text/javascript'&gt;\r\n         * var board = JXG.JSXGraph.initBoard('jxgbox', {axis:true, boundingbox:[-5,5,5,-5]});\r\n         * var p = board.create('point', [0, 1]);\r\n         * &lt;/script&gt;\r\n         *\r\n         * </pre><div id='JXGd5bab8b6-fd40-11e8-ab14-901b0e1b8723' class='jxgbox' style='width: 300px; height: 300px;'></div>\r\n         * <script type='text/javascript'>\r\n         *      var board_d5bab8b6;\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGd5bab8b6-fd40-11e8-ab14-901b0e1b8723',\r\n         *             {boundingbox:[-5,5,5,-5], axis: true, showcopyright: false, shownavigation: false});\r\n         *         var p = board.create('point', [0, 1]);\r\n         *         board_d5bab8b6 = board;\r\n         *     })();\r\n         * </script>\r\n         * <button onClick='board_d5bab8b6.toFullscreen()'>Fullscreen</button>\r\n         * <pre>\r\n         *\r\n         * @example\r\n         * &lt;div id='outer' style='max-width: 500px; margin: 0 auto;'&gt;\r\n         * &lt;div id='jxgbox' class='jxgbox' style='height: 0; padding-bottom: 100%'&gt;&lt;/div&gt;\r\n         * &lt;/div&gt;\r\n         * &lt;button onClick='board.toFullscreen('outer')'&gt;Fullscreen&lt;/button&gt;\r\n         *\r\n         * &lt;script language='Javascript' type='text/javascript'&gt;\r\n         * var board = JXG.JSXGraph.initBoard('jxgbox', {\r\n         *     axis:true,\r\n         *     boundingbox:[-5,5,5,-5],\r\n         *     fullscreen: { id: 'outer' },\r\n         *     showFullscreen: true\r\n         * });\r\n         * var p = board.create('point', [-2, 3], {});\r\n         * &lt;/script&gt;\r\n         *\r\n         * </pre><div id='JXG7103f6b_outer' style='max-width: 500px; margin: 0 auto;'>\r\n         * <div id='JXG7103f6be-6993-4ff8-8133-c78e50a8afac' class='jxgbox' style='height: 0; padding-bottom: 100%;'></div>\r\n         * </div>\r\n         * <button onClick='board_JXG7103f6be.toFullscreen('JXG7103f6b_outer')'>Fullscreen</button>\r\n         * <script type='text/javascript'>\r\n         *     var board_JXG7103f6be;\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG7103f6be-6993-4ff8-8133-c78e50a8afac',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, fullscreen: { id: 'JXG7103f6b_outer' }, showFullscreen: true,\r\n         *              showcopyright: false, shownavigation: false});\r\n         *     var p = board.create('point', [-2, 3], {});\r\n         *     board_JXG7103f6be = board;\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         *\r\n         */\r\n        toFullscreen: function (id) {\r\n            var wrap_id,\r\n                wrap_node,\r\n                inner_node,\r\n                dim,\r\n                doc = this.document,\r\n                fullscreenElement;\r\n\r\n            id = id || this.container;\r\n            this._fullscreen_inner_id = id;\r\n            inner_node = doc.getElementById(id);\r\n            wrap_id = 'fullscreenwrap_' + id;\r\n\r\n            if (!Type.exists(inner_node._cssFullscreenStore)) {\r\n                // Store the actual, absolute size of the div\r\n                // This is used in scaleJSXGraphDiv\r\n                dim = this.containerObj.getBoundingClientRect();\r\n                inner_node._cssFullscreenStore = {\r\n                    w: dim.width,\r\n                    h: dim.height\r\n                };\r\n            }\r\n\r\n            // Wrap a div around the JSXGraph div.\r\n            // It is removed when fullscreen mode is closed.\r\n            if (doc.getElementById(wrap_id)) {\r\n                wrap_node = doc.getElementById(wrap_id);\r\n            } else {\r\n                wrap_node = document.createElement('div');\r\n                wrap_node.classList.add('JXG_wrap_private');\r\n                wrap_node.setAttribute('id', wrap_id);\r\n                inner_node.parentNode.insertBefore(wrap_node, inner_node);\r\n                wrap_node.appendChild(inner_node);\r\n            }\r\n\r\n            // Trigger fullscreen mode\r\n            wrap_node.requestFullscreen =\r\n                wrap_node.requestFullscreen ||\r\n                wrap_node.webkitRequestFullscreen ||\r\n                wrap_node.mozRequestFullScreen ||\r\n                wrap_node.msRequestFullscreen;\r\n\r\n            if (doc.fullscreenElement !== undefined) {\r\n                fullscreenElement = doc.fullscreenElement;\r\n            } else if (doc.webkitFullscreenElement !== undefined) {\r\n                fullscreenElement = doc.webkitFullscreenElement;\r\n            } else {\r\n                fullscreenElement = doc.msFullscreenElement;\r\n            }\r\n\r\n            if (fullscreenElement === null) {\r\n                // Start fullscreen mode\r\n                if (wrap_node.requestFullscreen) {\r\n                    wrap_node.requestFullscreen();\r\n                    this.startFullscreenResizeObserver(wrap_node);\r\n                }\r\n            } else {\r\n                this.stopFullscreenResizeObserver(wrap_node);\r\n                if (Type.exists(document.exitFullscreen)) {\r\n                    document.exitFullscreen();\r\n                } else if (Type.exists(document.webkitExitFullscreen)) {\r\n                    document.webkitExitFullscreen();\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * If fullscreen mode is toggled, the possible CSS transformations\r\n         * which are applied to the JSXGraph canvas have to be reread.\r\n         * Otherwise the position of upper left corner is wrongly interpreted.\r\n         *\r\n         * @param  {Object} evt fullscreen event object (unused)\r\n         */\r\n        fullscreenListener: function (evt) {\r\n            var inner_id,\r\n                inner_node,\r\n                fullscreenElement,\r\n                doc = this.document;\r\n\r\n            inner_id = this._fullscreen_inner_id;\r\n            if (!Type.exists(inner_id)) {\r\n                return;\r\n            }\r\n\r\n            if (doc.fullscreenElement !== undefined) {\r\n                fullscreenElement = doc.fullscreenElement;\r\n            } else if (doc.webkitFullscreenElement !== undefined) {\r\n                fullscreenElement = doc.webkitFullscreenElement;\r\n            } else {\r\n                fullscreenElement = doc.msFullscreenElement;\r\n            }\r\n\r\n            inner_node = doc.getElementById(inner_id);\r\n            // If full screen mode is started we have to remove CSS margin around the JSXGraph div.\r\n            // Otherwise, the positioning of the fullscreen div will be false.\r\n            // When leaving the fullscreen mode, the margin is put back in.\r\n            if (fullscreenElement) {\r\n                // Just entered fullscreen mode\r\n\r\n                // Store the original data.\r\n                // Further, the CSS margin has to be removed when in fullscreen mode,\r\n                // and must be restored later.\r\n                //\r\n                // Obsolete:\r\n                // It is used in AbstractRenderer.updateText to restore the scaling matrix\r\n                // which is removed by MathJax.\r\n                inner_node._cssFullscreenStore.id = fullscreenElement.id;\r\n                inner_node._cssFullscreenStore.isFullscreen = true;\r\n                inner_node._cssFullscreenStore.margin = inner_node.style.margin;\r\n                inner_node._cssFullscreenStore.width = inner_node.style.width;\r\n                inner_node._cssFullscreenStore.height = inner_node.style.height;\r\n                inner_node._cssFullscreenStore.transform = inner_node.style.transform;\r\n                // Be sure to replace relative width / height units by absolute units\r\n                inner_node.style.width = inner_node._cssFullscreenStore.w + 'px';\r\n                inner_node.style.height = inner_node._cssFullscreenStore.h + 'px';\r\n                inner_node.style.margin = '';\r\n\r\n                // Do the shifting and scaling via CSS properties\r\n                // We do this after fullscreen mode has been established to get the correct size\r\n                // of the JSXGraph div.\r\n                Env.scaleJSXGraphDiv(fullscreenElement.id, inner_id, doc,\r\n                    Type.evaluate(this.attr.fullscreen.scale));\r\n\r\n                // Clear this.doc.fullscreenElement, because Safari doesn't to it and\r\n                // when leaving full screen mode it is still set.\r\n                fullscreenElement = null;\r\n            } else if (Type.exists(inner_node._cssFullscreenStore)) {\r\n                // Just left the fullscreen mode\r\n\r\n                inner_node._cssFullscreenStore.isFullscreen = false;\r\n                inner_node.style.margin = inner_node._cssFullscreenStore.margin;\r\n                inner_node.style.width = inner_node._cssFullscreenStore.width;\r\n                inner_node.style.height = inner_node._cssFullscreenStore.height;\r\n                inner_node.style.transform = inner_node._cssFullscreenStore.transform;\r\n                inner_node._cssFullscreenStore = null;\r\n\r\n                // Remove the wrapper div\r\n                inner_node.parentElement.replaceWith(inner_node);\r\n            }\r\n\r\n            this.updateCSSTransforms();\r\n        },\r\n\r\n        /**\r\n         * Start resize observer to handle\r\n         * orientation changes in fullscreen mode.\r\n         *\r\n         * @param {Object} node DOM object which is in fullscreen mode. It is the wrapper element\r\n         * around the JSXGraph div.\r\n         * @returns {JXG.Board} Reference to the board\r\n         * @private\r\n         * @see JXG.Board#toFullscreen\r\n         *\r\n         */\r\n        startFullscreenResizeObserver: function(node) {\r\n            var that = this;\r\n\r\n            if (!Env.isBrowser || !this.attr.resize || !this.attr.resize.enabled) {\r\n                return this;\r\n            }\r\n\r\n            this.resizeObserver = new ResizeObserver(function (entries) {\r\n                var inner_id,\r\n                    fullscreenElement,\r\n                    doc = that.document;\r\n\r\n                if (!that._isResizing) {\r\n                    that._isResizing = true;\r\n                    window.setTimeout(function () {\r\n                        try {\r\n                            inner_id = that._fullscreen_inner_id;\r\n                            if (doc.fullscreenElement !== undefined) {\r\n                                fullscreenElement = doc.fullscreenElement;\r\n                            } else if (doc.webkitFullscreenElement !== undefined) {\r\n                                fullscreenElement = doc.webkitFullscreenElement;\r\n                            } else {\r\n                                fullscreenElement = doc.msFullscreenElement;\r\n                            }\r\n                            if (fullscreenElement !== null) {\r\n                                Env.scaleJSXGraphDiv(fullscreenElement.id, inner_id, doc,\r\n                                    Type.evaluate(that.attr.fullscreen.scale));\r\n                            }\r\n                        } catch (err) {\r\n                            that.stopFullscreenResizeObserver(node);\r\n                        } finally {\r\n                            that._isResizing = false;\r\n                        }\r\n                    }, that.attr.resize.throttle);\r\n                }\r\n            });\r\n            this.resizeObserver.observe(node);\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Remove resize observer to handle orientation changes in fullscreen mode.\r\n         * @param {Object} node DOM object which is in fullscreen mode. It is the wrapper element\r\n         * around the JSXGraph div.\r\n         * @returns {JXG.Board} Reference to the board\r\n         * @private\r\n         * @see JXG.Board#toFullscreen\r\n         */\r\n        stopFullscreenResizeObserver: function(node) {\r\n            if (!Env.isBrowser || !this.attr.resize || !this.attr.resize.enabled) {\r\n                return this;\r\n            }\r\n\r\n            if (Type.exists(this.resizeObserver)) {\r\n                this.resizeObserver.unobserve(node);\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Add user activity to the array 'board.userLog'.\r\n         *\r\n         * @param {String} type Event type, e.g. 'drag'\r\n         * @param {Object} obj JSXGraph element object\r\n         *\r\n         * @see JXG.Board#userLog\r\n         * @return {JXG.Board} Reference to the board\r\n         */\r\n        addLogEntry: function (type, obj, pos) {\r\n            var t, id,\r\n                last = this.userLog.length - 1;\r\n\r\n            if (Type.exists(obj.elementClass)) {\r\n                id = obj.id;\r\n            }\r\n            if (Type.evaluate(this.attr.logging.enabled)) {\r\n                t = (new Date()).getTime();\r\n                if (last >= 0 &&\r\n                    this.userLog[last].type === type &&\r\n                    this.userLog[last].id === id &&\r\n                    // Distinguish consecutive drag events of\r\n                    // the same element\r\n                    t - this.userLog[last].end < 500) {\r\n\r\n                    this.userLog[last].end = t;\r\n                    this.userLog[last].endpos = pos;\r\n                } else {\r\n                    this.userLog.push({\r\n                        type: type,\r\n                        id: id,\r\n                        start: t,\r\n                        startpos: pos,\r\n                        end: t,\r\n                        endpos: pos,\r\n                        bbox: this.getBoundingBox(),\r\n                        canvas: [this.canvasWidth, this.canvasHeight],\r\n                        zoom: [this.zoomX, this.zoomY]\r\n                    });\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Function to animate a curve rolling on another curve.\r\n         * @param {Curve} c1 JSXGraph curve building the floor where c2 rolls\r\n         * @param {Curve} c2 JSXGraph curve which rolls on c1.\r\n         * @param {number} start_c1 The parameter t such that c1(t) touches c2. This is the start position of the\r\n         *                          rolling process\r\n         * @param {Number} stepsize Increase in t in each step for the curve c1\r\n         * @param {Number} direction\r\n         * @param {Number} time Delay time for setInterval()\r\n         * @param {Array} pointlist Array of points which are rolled in each step. This list should contain\r\n         *      all points which define c2 and gliders on c2.\r\n         *\r\n         * @example\r\n         *\r\n         * // Line which will be the floor to roll upon.\r\n         * var line = board.create('curve', [function (t) { return t;}, function (t){ return 1;}], {strokeWidth:6});\r\n         * // Center of the rolling circle\r\n         * var C = board.create('point',[0,2],{name:'C'});\r\n         * // Starting point of the rolling circle\r\n         * var P = board.create('point',[0,1],{name:'P', trace:true});\r\n         * // Circle defined as a curve. The circle 'starts' at P, i.e. circle(0) = P\r\n         * var circle = board.create('curve',[\r\n         *           function (t){var d = P.Dist(C),\r\n         *                           beta = JXG.Math.Geometry.rad([C.X()+1,C.Y()],C,P);\r\n         *                       t += beta;\r\n         *                       return C.X()+d*Math.cos(t);\r\n         *           },\r\n         *           function (t){var d = P.Dist(C),\r\n         *                           beta = JXG.Math.Geometry.rad([C.X()+1,C.Y()],C,P);\r\n         *                       t += beta;\r\n         *                       return C.Y()+d*Math.sin(t);\r\n         *           },\r\n         *           0,2*Math.PI],\r\n         *           {strokeWidth:6, strokeColor:'green'});\r\n         *\r\n         * // Point on circle\r\n         * var B = board.create('glider',[0,2,circle],{name:'B', color:'blue',trace:false});\r\n         * var roll = board.createRoulette(line, circle, 0, Math.PI/20, 1, 100, [C,P,B]);\r\n         * roll.start() // Start the rolling, to be stopped by roll.stop()\r\n         *\r\n         * </pre><div class='jxgbox' id='JXGe5e1b53c-a036-4a46-9e35-190d196beca5' style='width: 300px; height: 300px;'></div>\r\n         * <script type='text/javascript'>\r\n         * var brd = JXG.JSXGraph.initBoard('JXGe5e1b53c-a036-4a46-9e35-190d196beca5', {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright:false, shownavigation: false});\r\n         * // Line which will be the floor to roll upon.\r\n         * var line = brd.create('curve', [function (t) { return t;}, function (t){ return 1;}], {strokeWidth:6});\r\n         * // Center of the rolling circle\r\n         * var C = brd.create('point',[0,2],{name:'C'});\r\n         * // Starting point of the rolling circle\r\n         * var P = brd.create('point',[0,1],{name:'P', trace:true});\r\n         * // Circle defined as a curve. The circle 'starts' at P, i.e. circle(0) = P\r\n         * var circle = brd.create('curve',[\r\n         *           function (t){var d = P.Dist(C),\r\n         *                           beta = JXG.Math.Geometry.rad([C.X()+1,C.Y()],C,P);\r\n         *                       t += beta;\r\n         *                       return C.X()+d*Math.cos(t);\r\n         *           },\r\n         *           function (t){var d = P.Dist(C),\r\n         *                           beta = JXG.Math.Geometry.rad([C.X()+1,C.Y()],C,P);\r\n         *                       t += beta;\r\n         *                       return C.Y()+d*Math.sin(t);\r\n         *           },\r\n         *           0,2*Math.PI],\r\n         *           {strokeWidth:6, strokeColor:'green'});\r\n         *\r\n         * // Point on circle\r\n         * var B = brd.create('glider',[0,2,circle],{name:'B', color:'blue',trace:false});\r\n         * var roll = brd.createRoulette(line, circle, 0, Math.PI/20, 1, 100, [C,P,B]);\r\n         * roll.start() // Start the rolling, to be stopped by roll.stop()\r\n         * </script><pre>\r\n         */\r\n        createRoulette: function (c1, c2, start_c1, stepsize, direction, time, pointlist) {\r\n            var brd = this,\r\n                Roulette = function () {\r\n                    var alpha = 0,\r\n                        Tx = 0,\r\n                        Ty = 0,\r\n                        t1 = start_c1,\r\n                        t2 = Numerics.root(\r\n                            function (t) {\r\n                                var c1x = c1.X(t1),\r\n                                    c1y = c1.Y(t1),\r\n                                    c2x = c2.X(t),\r\n                                    c2y = c2.Y(t);\r\n\r\n                                return (c1x - c2x) * (c1x - c2x) + (c1y - c2y) * (c1y - c2y);\r\n                            },\r\n                            [0, Math.PI * 2]\r\n                        ),\r\n                        t1_new = 0.0,\r\n                        t2_new = 0.0,\r\n                        c1dist,\r\n                        rotation = brd.create(\r\n                            'transform',\r\n                            [\r\n                                function () {\r\n                                    return alpha;\r\n                                }\r\n                            ],\r\n                            { type: 'rotate' }\r\n                        ),\r\n                        rotationLocal = brd.create(\r\n                            'transform',\r\n                            [\r\n                                function () {\r\n                                    return alpha;\r\n                                },\r\n                                function () {\r\n                                    return c1.X(t1);\r\n                                },\r\n                                function () {\r\n                                    return c1.Y(t1);\r\n                                }\r\n                            ],\r\n                            { type: 'rotate' }\r\n                        ),\r\n                        translate = brd.create(\r\n                            'transform',\r\n                            [\r\n                                function () {\r\n                                    return Tx;\r\n                                },\r\n                                function () {\r\n                                    return Ty;\r\n                                }\r\n                            ],\r\n                            { type: 'translate' }\r\n                        ),\r\n                        // arc length via Simpson's rule.\r\n                        arclen = function (c, a, b) {\r\n                            var cpxa = Numerics.D(c.X)(a),\r\n                                cpya = Numerics.D(c.Y)(a),\r\n                                cpxb = Numerics.D(c.X)(b),\r\n                                cpyb = Numerics.D(c.Y)(b),\r\n                                cpxab = Numerics.D(c.X)((a + b) * 0.5),\r\n                                cpyab = Numerics.D(c.Y)((a + b) * 0.5),\r\n                                fa = Mat.hypot(cpxa, cpya),\r\n                                fb = Mat.hypot(cpxb, cpyb),\r\n                                fab = Mat.hypot(cpxab, cpyab);\r\n\r\n                            return ((fa + 4 * fab + fb) * (b - a)) / 6;\r\n                        },\r\n                        exactDist = function (t) {\r\n                            return c1dist - arclen(c2, t2, t);\r\n                        },\r\n                        beta = Math.PI / 18,\r\n                        beta9 = beta * 9,\r\n                        interval = null;\r\n\r\n                    this.rolling = function () {\r\n                        var h, g, hp, gp, z;\r\n\r\n                        t1_new = t1 + direction * stepsize;\r\n\r\n                        // arc length between c1(t1) and c1(t1_new)\r\n                        c1dist = arclen(c1, t1, t1_new);\r\n\r\n                        // find t2_new such that arc length between c2(t2) and c1(t2_new) equals c1dist.\r\n                        t2_new = Numerics.root(exactDist, t2);\r\n\r\n                        // c1(t) as complex number\r\n                        h = new Complex(c1.X(t1_new), c1.Y(t1_new));\r\n\r\n                        // c2(t) as complex number\r\n                        g = new Complex(c2.X(t2_new), c2.Y(t2_new));\r\n\r\n                        hp = new Complex(Numerics.D(c1.X)(t1_new), Numerics.D(c1.Y)(t1_new));\r\n                        gp = new Complex(Numerics.D(c2.X)(t2_new), Numerics.D(c2.Y)(t2_new));\r\n\r\n                        // z is angle between the tangents of c1 at t1_new, and c2 at t2_new\r\n                        z = Complex.C.div(hp, gp);\r\n\r\n                        alpha = Math.atan2(z.imaginary, z.real);\r\n                        // Normalizing the quotient\r\n                        z.div(Complex.C.abs(z));\r\n                        z.mult(g);\r\n                        Tx = h.real - z.real;\r\n\r\n                        // T = h(t1_new)-g(t2_new)*h'(t1_new)/g'(t2_new);\r\n                        Ty = h.imaginary - z.imaginary;\r\n\r\n                        // -(10-90) degrees: make corners roll smoothly\r\n                        if (alpha < -beta && alpha > -beta9) {\r\n                            alpha = -beta;\r\n                            rotationLocal.applyOnce(pointlist);\r\n                        } else if (alpha > beta && alpha < beta9) {\r\n                            alpha = beta;\r\n                            rotationLocal.applyOnce(pointlist);\r\n                        } else {\r\n                            rotation.applyOnce(pointlist);\r\n                            translate.applyOnce(pointlist);\r\n                            t1 = t1_new;\r\n                            t2 = t2_new;\r\n                        }\r\n                        brd.update();\r\n                    };\r\n\r\n                    this.start = function () {\r\n                        if (time > 0) {\r\n                            interval = window.setInterval(this.rolling, time);\r\n                        }\r\n                        return this;\r\n                    };\r\n\r\n                    this.stop = function () {\r\n                        window.clearInterval(interval);\r\n                        return this;\r\n                    };\r\n                    return this;\r\n                };\r\n            return new Roulette();\r\n        }\r\n    }\r\n);\r\n\r\nexport default JXG.Board;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, AMprocessNode: true, MathJax: true, document: true */\r\n/*jslint nomen: true, plusplus: true, newcap:true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Options from \"../options.js\";\r\nimport AbstractRenderer from \"./abstract.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Color from \"../utils/color.js\";\r\nimport Base64 from \"../utils/base64.js\";\r\nimport Numerics from \"../math/numerics.js\";\r\n\r\n/**\r\n * Uses SVG to implement the rendering methods defined in {@link JXG.AbstractRenderer}.\r\n * @class JXG.SVGRenderer\r\n * @augments JXG.AbstractRenderer\r\n * @param {Node} container Reference to a DOM node containing the board.\r\n * @param {Object} dim The dimensions of the board\r\n * @param {Number} dim.width\r\n * @param {Number} dim.height\r\n * @see JXG.AbstractRenderer\r\n */\r\nJXG.SVGRenderer = function (container, dim) {\r\n    var i;\r\n\r\n    // docstring in AbstractRenderer\r\n    this.type = 'svg';\r\n\r\n    this.isIE =\r\n        navigator.appVersion.indexOf('MSIE') !== -1 || navigator.userAgent.match(/Trident\\//);\r\n\r\n    /**\r\n     * SVG root node\r\n     * @type Node\r\n     */\r\n    this.svgRoot = null;\r\n\r\n    /**\r\n     * The SVG Namespace used in JSXGraph.\r\n     * @see http://www.w3.org/TR/SVG2/\r\n     * @type String\r\n     * @default http://www.w3.org/2000/svg\r\n     */\r\n    this.svgNamespace = \"http://www.w3.org/2000/svg\";\r\n\r\n    /**\r\n     * The xlink namespace. This is used for images.\r\n     * @see http://www.w3.org/TR/xlink/\r\n     * @type String\r\n     * @default http://www.w3.org/1999/xlink\r\n     */\r\n    this.xlinkNamespace = \"http://www.w3.org/1999/xlink\";\r\n\r\n    // container is documented in AbstractRenderer.\r\n    // Type node\r\n    this.container = container;\r\n\r\n    // prepare the div container and the svg root node for use with JSXGraph\r\n    this.container.style.MozUserSelect = 'none';\r\n    this.container.style.userSelect = 'none';\r\n\r\n    this.container.style.overflow = 'hidden';\r\n    if (this.container.style.position === \"\") {\r\n        this.container.style.position = 'relative';\r\n    }\r\n\r\n    this.svgRoot = this.container.ownerDocument.createElementNS(this.svgNamespace, 'svg');\r\n    this.svgRoot.style.overflow = 'hidden';\r\n    this.svgRoot.style.display = 'block';\r\n    this.resize(dim.width, dim.height);\r\n\r\n    //this.svgRoot.setAttributeNS(null, 'shape-rendering', 'crispEdge'); //'optimizeQuality'); //geometricPrecision');\r\n\r\n    this.container.appendChild(this.svgRoot);\r\n\r\n    /**\r\n     * The <tt>defs</tt> element is a container element to reference reusable SVG elements.\r\n     * @type Node\r\n     * @see https://www.w3.org/TR/SVG2/struct.html#DefsElement\r\n     */\r\n    this.defs = this.container.ownerDocument.createElementNS(this.svgNamespace, 'defs');\r\n    this.svgRoot.appendChild(this.defs);\r\n\r\n    /**\r\n     * Filters are used to apply shadows.\r\n     * @type Node\r\n     * @see https://www.w3.org/TR/SVG2/struct.html#DefsElement\r\n     */\r\n    /**\r\n     * Create an SVG shadow filter. If the object's RGB color is [r,g,b], it's opacity is op, and\r\n     * the parameter color is given as [r', g', b'] with opacity op'\r\n     * the shadow will have RGB color [blend*r + r', blend*g + g', blend*b + b'] and the opacity will be equal to op * op'.\r\n     * Further, blur and offset can be adjusted.\r\n     *\r\n     * The shadow color is [r*ble\r\n     * @param {String} id Node is of the filter.\r\n     * @param {Array|String} rgb RGB value for the blend color or the string 'none' for default values. Default 'black'.\r\n     * @param {Number} opacity Value between 0 and 1, default is 1.\r\n     * @param {Number} blend  Value between 0 and 1, default is 0.1.\r\n     * @param {Number} blur  Default: 3\r\n     * @param {Array} offset [dx, dy]. Default is [5,5].\r\n     * @returns DOM node to be added to this.defs.\r\n     * @private\r\n     */\r\n    this.createShadowFilter = function (id, rgb, opacity, blend, blur, offset) {\r\n        var filter = this.container.ownerDocument.createElementNS(this.svgNamespace, 'filter'),\r\n            feOffset, feColor, feGaussianBlur, feBlend,\r\n            mat;\r\n\r\n        filter.setAttributeNS(null, 'id', id);\r\n        filter.setAttributeNS(null, 'width', '300%');\r\n        filter.setAttributeNS(null, 'height', '300%');\r\n        filter.setAttributeNS(null, 'filterUnits', 'userSpaceOnUse');\r\n\r\n        feOffset = this.container.ownerDocument.createElementNS(this.svgNamespace, 'feOffset');\r\n        feOffset.setAttributeNS(null, 'in', 'SourceGraphic'); // b/w: SourceAlpha, Color: SourceGraphic\r\n        feOffset.setAttributeNS(null, 'result', 'offOut');\r\n        feOffset.setAttributeNS(null, 'dx', offset[0]);\r\n        feOffset.setAttributeNS(null, 'dy', offset[1]);\r\n        filter.appendChild(feOffset);\r\n\r\n        feColor = this.container.ownerDocument.createElementNS(this.svgNamespace, 'feColorMatrix');\r\n        feColor.setAttributeNS(null, 'in', 'offOut');\r\n        feColor.setAttributeNS(null, 'result', 'colorOut');\r\n        feColor.setAttributeNS(null, 'type', 'matrix');\r\n        // See https://developer.mozilla.org/en-US/docs/Web/SVG/Element/feColorMatrix\r\n        if (rgb === 'none' || !Type.isArray(rgb) || rgb.length < 3) {\r\n            feColor.setAttributeNS(null, 'values', '0.1 0 0 0 0  0 0.1 0 0 0  0 0 0.1 0 0  0 0 0 ' + opacity + ' 0');\r\n        } else {\r\n            rgb[0] /= 255;\r\n            rgb[1] /= 255;\r\n            rgb[2] /= 255;\r\n            mat = blend + ' 0 0 0 ' + rgb[0] +\r\n                '  0 ' + blend + ' 0 0 ' + rgb[1] +\r\n                '  0 0 ' + blend + ' 0 ' + rgb[2] +\r\n                '  0 0 0 ' + opacity + ' 0';\r\n            feColor.setAttributeNS(null, 'values', mat);\r\n        }\r\n        filter.appendChild(feColor);\r\n\r\n        feGaussianBlur = this.container.ownerDocument.createElementNS(this.svgNamespace, 'feGaussianBlur');\r\n        feGaussianBlur.setAttributeNS(null, 'in', 'colorOut');\r\n        feGaussianBlur.setAttributeNS(null, 'result', 'blurOut');\r\n        feGaussianBlur.setAttributeNS(null, 'stdDeviation', blur);\r\n        filter.appendChild(feGaussianBlur);\r\n\r\n        feBlend = this.container.ownerDocument.createElementNS(this.svgNamespace, 'feBlend');\r\n        feBlend.setAttributeNS(null, 'in', 'SourceGraphic');\r\n        feBlend.setAttributeNS(null, 'in2', 'blurOut');\r\n        feBlend.setAttributeNS(null, 'mode', 'normal');\r\n        filter.appendChild(feBlend);\r\n\r\n        return filter;\r\n    };\r\n\r\n    /**\r\n     * Create a \"unique\" string id from the arguments of the function.\r\n     * Concatenate all arguments by \"_\".\r\n     * \"Unique\" is achieved by simply prepending the container id.\r\n     * Do not escape the string.\r\n     *\r\n     * If the id is used in an \"url()\" call it must be eascaped.\r\n     *\r\n     * @params {String} one or strings which will be concatenated.\r\n     * @return {String}\r\n     * @private\r\n     */\r\n    this.uniqName = function () {\r\n        return this.container.id + '_' +\r\n            Array.prototype.slice.call(arguments).join('_');\r\n    };\r\n\r\n    /**\r\n     * Combine arguments to a string, joined by empty string.\r\n     * The container id needs to be escaped, as it may contain URI-unsafe characters\r\n     *\r\n     * @params {String} str variable number of strings\r\n     * @returns String\r\n     * @see JXG.SVGRenderer#toURL\r\n     * @private\r\n     * @example\r\n     * this.toStr('aaa', '_', 'bbb', 'TriangleEnd')\r\n     * // Output:\r\n     * // xxx_bbbTriangleEnd\r\n     */\r\n    this.toStr = function() {\r\n        // ES6 would be [...arguments].join()\r\n        var str = Array.prototype.slice.call(arguments).join('');\r\n        // Mask special symbols like '/' and '\\' in id\r\n        if (Type.exists(encodeURIComponent)) {\r\n            str = encodeURIComponent(str);\r\n        }\r\n        return str;\r\n    };\r\n\r\n    /**\r\n     * Combine arguments to an URL string of the form\r\n     * url(#...)\r\n     * Masks the container id. Calls {@link JXG.SVGRenderer#toStr}.\r\n     *\r\n     * @params {String} str variable number of strings\r\n     * @returns URL string\r\n     * @see JXG.SVGRenderer#toStr\r\n     * @private\r\n     * @example\r\n     * this.toURL('aaa', '_', 'bbb', 'TriangleEnd')\r\n     * // Output:\r\n     * // url(#xxx_bbbTriangleEnd)\r\n     */\r\n    this.toURL = function () {\r\n        return 'url(#' +\r\n            this.toStr.apply(this, arguments) + // Pass the arguments to toStr\r\n            ')';\r\n    };\r\n\r\n    /* Default shadow filter */\r\n    this.defs.appendChild(this.createShadowFilter(this.uniqName('f1'), 'none', 1, 0.1, 3, [5, 5]));\r\n\r\n    /**\r\n     * JSXGraph uses a layer system to sort the elements on the board. This puts certain types of elements in front\r\n     * of other types of elements. For the order used see {@link JXG.Options.layer}. The number of layers is documented\r\n     * there, too. The higher the number, the \"more on top\" are the elements on this layer.\r\n     * @type Array\r\n     */\r\n    this.layer = [];\r\n    for (i = 0; i < Options.layer.numlayers; i++) {\r\n        this.layer[i] = this.container.ownerDocument.createElementNS(this.svgNamespace, 'g');\r\n        this.svgRoot.appendChild(this.layer[i]);\r\n    }\r\n\r\n    try {\r\n        this.foreignObjLayer = this.container.ownerDocument.createElementNS(\r\n            this.svgNamespace,\r\n            \"foreignObject\"\r\n        );\r\n        this.foreignObjLayer.setAttribute(\"display\", 'none');\r\n        this.foreignObjLayer.setAttribute(\"x\", 0);\r\n        this.foreignObjLayer.setAttribute(\"y\", 0);\r\n        this.foreignObjLayer.setAttribute(\"width\", \"100%\");\r\n        this.foreignObjLayer.setAttribute(\"height\", \"100%\");\r\n        this.foreignObjLayer.setAttribute(\"id\", this.uniqName('foreignObj'));\r\n        this.svgRoot.appendChild(this.foreignObjLayer);\r\n        this.supportsForeignObject = true;\r\n    } catch (e) {\r\n        this.supportsForeignObject = false;\r\n    }\r\n};\r\n\r\nJXG.SVGRenderer.prototype = new AbstractRenderer();\r\n\r\nJXG.extend(\r\n    JXG.SVGRenderer.prototype,\r\n    /** @lends JXG.SVGRenderer.prototype */ {\r\n        /* ******************************** *\r\n         *  This renderer does not need to\r\n         *  override draw/update* methods\r\n         *  since it provides draw/update*Prim\r\n         *  methods except for some cases like\r\n         *  internal texts or images.\r\n         * ******************************** */\r\n\r\n        /* ********* Arrow head related stuff *********** */\r\n\r\n        /**\r\n         * Creates an arrow DOM node. Arrows are displayed in SVG with a <em>marker</em> tag.\r\n         * @private\r\n         * @param {JXG.GeometryElement} el A JSXGraph element, preferably one that can have an arrow attached.\r\n         * @param {String} [idAppendix=''] A string that is added to the node's id.\r\n         * @returns {Node} Reference to the node added to the DOM.\r\n         */\r\n        _createArrowHead: function (el, idAppendix, type) {\r\n            var node2,\r\n                node3,\r\n                id = el.id + \"Triangle\",\r\n                //type = null,\r\n                v,\r\n                h;\r\n\r\n            if (Type.exists(idAppendix)) {\r\n                id += idAppendix;\r\n            }\r\n            if (Type.exists(type)) {\r\n                id += type;\r\n            }\r\n            node2 = this.createPrim('marker', id);\r\n\r\n            // 'context-stroke': property is inherited from line or curve\r\n            if (JXG.isWebkitApple()) {\r\n                // 2025: Safari does not support 'context-stroke'\r\n                node2.setAttributeNS(null, 'fill', el.evalVisProp('strokecolor'));\r\n                node2.setAttributeNS(null, 'stroke', el.evalVisProp('strokecolor'));\r\n            } else {\r\n                node2.setAttributeNS(null, 'fill', 'context-stroke');\r\n                node2.setAttributeNS(null, 'stroke', 'context-stroke');\r\n            }\r\n\r\n            // node2.setAttributeNS(null, 'fill-opacity', 'context-stroke'); // Not available\r\n            // node2.setAttributeNS(null, 'stroke-opacity', 'context-stroke');\r\n            node2.setAttributeNS(null, 'stroke-width', 0); // this is the stroke-width of the arrow head.\r\n            // Should be zero to simplify the calculations\r\n\r\n            node2.setAttributeNS(null, 'orient', 'auto');\r\n            node2.setAttributeNS(null, 'markerUnits', 'strokeWidth'); // 'strokeWidth' 'userSpaceOnUse');\r\n\r\n            /*\r\n               Types 1, 2:\r\n               The arrow head is an isosceles triangle with base length 10 and height 10.\r\n\r\n               Type 3:\r\n               A rectangle\r\n\r\n               Types 4, 5, 6:\r\n               Defined by Bezier curves from mp_arrowheads.html\r\n\r\n               In any case but type 3 the arrow head is 10 units long,\r\n               type 3 is 10 units high.\r\n               These 10 units are scaled to strokeWidth * arrowSize pixels, see\r\n               this._setArrowWidth().\r\n\r\n               See also abstractRenderer.updateLine() where the line path is shortened accordingly.\r\n\r\n               Changes here are also necessary in setArrowWidth().\r\n\r\n               So far, lines with arrow heads are shortenend to avoid overlapping of\r\n               arrow head and line. This is not the case for curves, yet.\r\n               Therefore, the offset refX has to be adapted to the path type.\r\n            */\r\n            node3 = this.container.ownerDocument.createElementNS(this.svgNamespace, 'path');\r\n            h = 5;\r\n            if (idAppendix === 'Start') {\r\n                // First arrow\r\n                v = 0;\r\n                if (type === 2) {\r\n                    node3.setAttributeNS(null, \"d\", \"M 10,0 L 0,5 L 10,10 L 5,5 z\");\r\n                } else if (type === 3) {\r\n                    node3.setAttributeNS(null, \"d\", \"M 0,0 L 3.33,0 L 3.33,10 L 0,10 z\");\r\n                } else if (type === 4) {\r\n                    // insetRatio:0.8 tipAngle:45 wingCurve:15 tailCurve:0\r\n                    h = 3.31;\r\n                    node3.setAttributeNS(\r\n                        null,\r\n                        \"d\",\r\n                        \"M 0.00,3.31 C 3.53,3.84 7.13,4.50 10.00,6.63 C 9.33,5.52 8.67,4.42 8.00,3.31 C 8.67,2.21 9.33,1.10 10.00,0.00 C 7.13,2.13 3.53,2.79 0.00,3.31\"\r\n                    );\r\n                } else if (type === 5) {\r\n                    // insetRatio:0.9 tipAngle:40 wingCurve:5 tailCurve:15\r\n                    h = 3.28;\r\n                    node3.setAttributeNS(\r\n                        null,\r\n                        \"d\",\r\n                        \"M 0.00,3.28 C 3.39,4.19 6.81,5.07 10.00,6.55 C 9.38,5.56 9.00,4.44 9.00,3.28 C 9.00,2.11 9.38,0.99 10.00,0.00 C 6.81,1.49 3.39,2.37 0.00,3.28\"\r\n                    );\r\n                } else if (type === 6) {\r\n                    // insetRatio:0.9 tipAngle:35 wingCurve:5 tailCurve:0\r\n                    h = 2.84;\r\n                    node3.setAttributeNS(\r\n                        null,\r\n                        \"d\",\r\n                        \"M 0.00,2.84 C 3.39,3.59 6.79,4.35 10.00,5.68 C 9.67,4.73 9.33,3.78 9.00,2.84 C 9.33,1.89 9.67,0.95 10.00,0.00 C 6.79,1.33 3.39,2.09 0.00,2.84\"\r\n                    );\r\n                } else if (type === 7) {\r\n                    // insetRatio:0.9 tipAngle:60 wingCurve:30 tailCurve:0\r\n                    h = 5.2;\r\n                    node3.setAttributeNS(\r\n                        null,\r\n                        \"d\",\r\n                        \"M 0.00,5.20 C 4.04,5.20 7.99,6.92 10.00,10.39 M 10.00,0.00 C 7.99,3.47 4.04,5.20 0.00,5.20\"\r\n                    );\r\n                } else {\r\n                    // type == 1 or > 6\r\n                    node3.setAttributeNS(null, \"d\", \"M 10,0 L 0,5 L 10,10 z\");\r\n                }\r\n                if (\r\n                    // !Type.exists(el.rendNode.getTotalLength) &&\r\n                    el.elementClass === Const.OBJECT_CLASS_LINE\r\n                ) {\r\n                    if (type === 2) {\r\n                        v = 4.9;\r\n                    } else if (type === 3) {\r\n                        v = 3.3;\r\n                    } else if (type === 4 || type === 5 || type === 6) {\r\n                        v = 6.66;\r\n                    } else if (type === 7) {\r\n                        v = 0.0;\r\n                    } else {\r\n                        v = 10.0;\r\n                    }\r\n                }\r\n            } else {\r\n                // Last arrow\r\n                v = 10.0;\r\n                if (type === 2) {\r\n                    node3.setAttributeNS(null, \"d\", \"M 0,0 L 10,5 L 0,10 L 5,5 z\");\r\n                } else if (type === 3) {\r\n                    v = 3.3;\r\n                    node3.setAttributeNS(null, \"d\", \"M 0,0 L 3.33,0 L 3.33,10 L 0,10 z\");\r\n                } else if (type === 4) {\r\n                    // insetRatio:0.8 tipAngle:45 wingCurve:15 tailCurve:0\r\n                    h = 3.31;\r\n                    node3.setAttributeNS(\r\n                        null,\r\n                        \"d\",\r\n                        \"M 10.00,3.31 C 6.47,3.84 2.87,4.50 0.00,6.63 C 0.67,5.52 1.33,4.42 2.00,3.31 C 1.33,2.21 0.67,1.10 0.00,0.00 C 2.87,2.13 6.47,2.79 10.00,3.31\"\r\n                    );\r\n                } else if (type === 5) {\r\n                    // insetRatio:0.9 tipAngle:40 wingCurve:5 tailCurve:15\r\n                    h = 3.28;\r\n                    node3.setAttributeNS(\r\n                        null,\r\n                        \"d\",\r\n                        \"M 10.00,3.28 C 6.61,4.19 3.19,5.07 0.00,6.55 C 0.62,5.56 1.00,4.44 1.00,3.28 C 1.00,2.11 0.62,0.99 0.00,0.00 C 3.19,1.49 6.61,2.37 10.00,3.28\"\r\n                    );\r\n                } else if (type === 6) {\r\n                    // insetRatio:0.9 tipAngle:35 wingCurve:5 tailCurve:0\r\n                    h = 2.84;\r\n                    node3.setAttributeNS(\r\n                        null,\r\n                        \"d\",\r\n                        \"M 10.00,2.84 C 6.61,3.59 3.21,4.35 0.00,5.68 C 0.33,4.73 0.67,3.78 1.00,2.84 C 0.67,1.89 0.33,0.95 0.00,0.00 C 3.21,1.33 6.61,2.09 10.00,2.84\"\r\n                    );\r\n                } else if (type === 7) {\r\n                    // insetRatio:0.9 tipAngle:60 wingCurve:30 tailCurve:0\r\n                    h = 5.2;\r\n                    node3.setAttributeNS(\r\n                        null,\r\n                        \"d\",\r\n                        \"M 10.00,5.20 C 5.96,5.20 2.01,6.92 0.00,10.39 M 0.00,0.00 C 2.01,3.47 5.96,5.20 10.00,5.20\"\r\n                    );\r\n                } else {\r\n                    // type == 1 or > 6\r\n                    node3.setAttributeNS(null, \"d\", \"M 0,0 L 10,5 L 0,10 z\");\r\n                }\r\n                if (\r\n                    // !Type.exists(el.rendNode.getTotalLength) &&\r\n                    el.elementClass === Const.OBJECT_CLASS_LINE\r\n                ) {\r\n                    if (type === 2) {\r\n                        v = 5.1;\r\n                    } else if (type === 3) {\r\n                        v = 0.02;\r\n                    } else if (type === 4 || type === 5 || type === 6) {\r\n                        v = 3.33;\r\n                    } else if (type === 7) {\r\n                        v = 10.0;\r\n                    } else {\r\n                        v = 0.05;\r\n                    }\r\n                }\r\n            }\r\n            if (type === 7) {\r\n                node2.setAttributeNS(null, 'fill', 'none');\r\n                node2.setAttributeNS(null, 'stroke-width', 1); // this is the stroke-width of the arrow head.\r\n            }\r\n            node2.setAttributeNS(null, \"refY\", h);\r\n            node2.setAttributeNS(null, \"refX\", v);\r\n            // this.setPropertyPrim(node2, 'class', el.evalVisProp('cssclass'));\r\n\r\n            node2.appendChild(node3);\r\n            return node2;\r\n        },\r\n\r\n        /**\r\n         * Updates color of an arrow DOM node.\r\n         * @param {Node} node The arrow node.\r\n         * @param {String} color Color value in a HTML compatible format, e.g. <tt>#00ff00</tt> or <tt>green</tt> for green.\r\n         * @param {Number} opacity\r\n         * @param {JXG.GeometryElement} el The element the arrows are to be attached to\r\n         */\r\n        _setArrowColor: function (node, color, opacity, el, type) {\r\n            if (node) {\r\n                if (Type.isString(color)) {\r\n                    if (type !== 7) {\r\n                        this._setAttribute(function () {\r\n                            if (JXG.isWebkitApple()) {\r\n                                // 2025: Safari does not support 'context-stroke'\r\n                                node.setAttributeNS(null, 'fill', color);\r\n                            } else {\r\n                                node.setAttributeNS(null, 'fill', 'context-stroke');\r\n                            }\r\n                        }, el.visPropOld.fillcolor);\r\n                    } else {\r\n                        this._setAttribute(function () {\r\n                            node.setAttributeNS(null, 'fill', 'none');\r\n                            if (JXG.isWebkitApple()) {\r\n                                node.setAttributeNS(null, 'stroke', color);\r\n                            } else {\r\n                                node.setAttributeNS(null, 'stroke', 'context-stroke');\r\n                            }\r\n                        }, el.visPropOld.fillcolor);\r\n                    }\r\n                }\r\n\r\n                // if (this.isIE) {\r\n                    // Necessary, since Safari is the new IE (11.2024)\r\n                    el.rendNode.parentNode.insertBefore(el.rendNode, el.rendNode);\r\n                // }\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        _setArrowWidth: function (node, width, parentNode, size) {\r\n            var s, d;\r\n\r\n            if (node) {\r\n                // if (width === 0) {\r\n                //     // display:none does not work well in webkit\r\n                //     node.setAttributeNS(null, 'display', 'none');\r\n                // } else {\r\n                s = width;\r\n                d = s * size;\r\n                node.setAttributeNS(null, \"viewBox\", 0 + \" \" + 0 + \" \" + s * 10 + \" \" + s * 10);\r\n                node.setAttributeNS(null, \"markerHeight\", d);\r\n                node.setAttributeNS(null, \"markerWidth\", d);\r\n                node.setAttributeNS(null, \"display\", 'inherit');\r\n                // }\r\n\r\n                // if (this.isIE) {\r\n                    // Necessary, since Safari is the new IE (11.2024)\r\n                    parentNode.parentNode.insertBefore(parentNode, parentNode);\r\n                // }\r\n            }\r\n        },\r\n\r\n        /* ********* Line related stuff *********** */\r\n\r\n        // documented in AbstractRenderer\r\n        updateTicks: function (ticks) {\r\n            var i,\r\n                j,\r\n                c,\r\n                node,\r\n                x,\r\n                y,\r\n                tickStr = \"\",\r\n                len = ticks.ticks.length,\r\n                len2,\r\n                str,\r\n                isReal = true;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                c = ticks.ticks[i];\r\n                x = c[0];\r\n                y = c[1];\r\n\r\n                len2 = x.length;\r\n                str = \" M \" + x[0] + \" \" + y[0];\r\n                if (!Type.isNumber(x[0])) {\r\n                    isReal = false;\r\n                }\r\n                for (j = 1; isReal && j < len2; ++j) {\r\n                    if (Type.isNumber(x[j])) {\r\n                        str += \" L \" + x[j] + \" \" + y[j];\r\n                    } else {\r\n                        isReal = false;\r\n                    }\r\n                }\r\n                if (isReal) {\r\n                    tickStr += str;\r\n                }\r\n            }\r\n\r\n            node = ticks.rendNode;\r\n\r\n            if (!Type.exists(node)) {\r\n                node = this.createPrim(\"path\", ticks.id);\r\n                this.appendChildPrim(node, ticks.evalVisProp('layer'));\r\n                ticks.rendNode = node;\r\n            }\r\n\r\n            node.setAttributeNS(null, \"stroke\", ticks.evalVisProp('strokecolor'));\r\n            node.setAttributeNS(null, \"fill\", 'none');\r\n            // node.setAttributeNS(null, 'fill', ticks.evalVisProp('fillcolor'));\r\n            // node.setAttributeNS(null, 'fill-opacity', ticks.evalVisProp('fillopacity'));\r\n            node.setAttributeNS(null, 'stroke-opacity', ticks.evalVisProp('strokeopacity'));\r\n            node.setAttributeNS(null, \"stroke-width\", ticks.evalVisProp('strokewidth'));\r\n            this.updatePathPrim(node, tickStr, ticks.board);\r\n        },\r\n\r\n        /* ********* Text related stuff *********** */\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        displayCopyright: function (str, fontsize) {\r\n            var node, t,\r\n                x = 4 + 1.8 * fontsize,\r\n                y = 6 + fontsize,\r\n                alpha = 0.2;\r\n\r\n            node = this.createPrim(\"text\", 'licenseText');\r\n            node.setAttributeNS(null, 'x', x + 'px');\r\n            node.setAttributeNS(null, 'y', y + 'px');\r\n            node.setAttributeNS(null, 'style', 'font-family:Arial,Helvetica,sans-serif; font-size:' +\r\n                fontsize + 'px; opacity:' + alpha + ';');\r\n                // fill:#356AA0;\r\n            node.setAttributeNS(null, 'aria-hidden', 'true');\r\n\r\n            t = this.container.ownerDocument.createTextNode(str);\r\n            node.appendChild(t);\r\n            this.appendChildPrim(node, 0);\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        displayLogo: function (str, fontsize) {\r\n            var node,\r\n                s = 1.5 * fontsize,\r\n                alpha = 0.2;\r\n\r\n            node = this.createPrim(\"image\", 'licenseLogo');\r\n            node.setAttributeNS(null, 'x', '5px');\r\n            node.setAttributeNS(null, 'y', '5px');\r\n            node.setAttributeNS(null, 'width', s + 'px');\r\n            node.setAttributeNS(null, 'height', s + 'px');\r\n            node.setAttributeNS(null, \"preserveAspectRatio\", 'none');\r\n            node.setAttributeNS(null, 'style', 'opacity:' + alpha + ';');\r\n            node.setAttributeNS(null, 'aria-hidden', 'true');\r\n\r\n            node.setAttributeNS(this.xlinkNamespace, \"xlink:href\", str);\r\n            this.appendChildPrim(node, 0);\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        drawInternalText: function (el) {\r\n            var node = this.createPrim(\"text\", el.id);\r\n\r\n            //node.setAttributeNS(null, \"style\", \"alignment-baseline:middle\"); // Not yet supported by Firefox\r\n            // Preserve spaces\r\n            //node.setAttributeNS(\"http://www.w3.org/XML/1998/namespace\", \"space\", 'preserve');\r\n            node.style.whiteSpace = 'nowrap';\r\n\r\n            el.rendNodeText = this.container.ownerDocument.createTextNode(\"\");\r\n            node.appendChild(el.rendNodeText);\r\n            this.appendChildPrim(node, el.evalVisProp('layer'));\r\n\r\n            return node;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updateInternalText: function (el) {\r\n            var content = el.plaintext,\r\n                v, css,\r\n                ev_ax = el.getAnchorX(),\r\n                ev_ay = el.getAnchorY();\r\n\r\n            css = el.evalVisProp('cssclass');\r\n            if (el.rendNode.getAttributeNS(null, 'class') !== css) {\r\n                el.rendNode.setAttributeNS(null, \"class\", css);\r\n                el.needsSizeUpdate = true;\r\n            }\r\n\r\n            if (!isNaN(el.coords.scrCoords[1] + el.coords.scrCoords[2])) {\r\n                // Horizontal\r\n                v = el.coords.scrCoords[1];\r\n                if (el.visPropOld.left !== ev_ax + v) {\r\n                    el.rendNode.setAttributeNS(null, \"x\", v + 'px');\r\n\r\n                    if (ev_ax === 'left') {\r\n                        el.rendNode.setAttributeNS(null, \"text-anchor\", 'start');\r\n                    } else if (ev_ax === 'right') {\r\n                        el.rendNode.setAttributeNS(null, \"text-anchor\", 'end');\r\n                    } else if (ev_ax === 'middle') {\r\n                        el.rendNode.setAttributeNS(null, \"text-anchor\", 'middle');\r\n                    }\r\n                    el.visPropOld.left = ev_ax + v;\r\n                }\r\n\r\n                // Vertical\r\n                v = el.coords.scrCoords[2];\r\n                if (el.visPropOld.top !== ev_ay + v) {\r\n                    el.rendNode.setAttributeNS(null, \"y\", v + this.vOffsetText * 0.5 + 'px');\r\n\r\n                    // Not supported by IE, edge\r\n                    // el.rendNode.setAttributeNS(null, \"dy\", '0');\r\n                    // if (ev_ay === 'bottom') {\r\n                    //     el.rendNode.setAttributeNS(null, 'dominant-baseline', 'text-after-edge');\r\n                    // } else if (ev_ay === 'top') {\r\n                    //     el.rendNode.setAttributeNS(null, 'dominant-baseline', 'text-before-edge');\r\n                    // } else if (ev_ay === 'middle') {\r\n                    //     el.rendNode.setAttributeNS(null, 'dominant-baseline', 'middle');\r\n                    // }\r\n\r\n                    if (ev_ay === 'bottom') {\r\n                        el.rendNode.setAttributeNS(null, \"dy\", '0');\r\n                        el.rendNode.setAttributeNS(null, 'dominant-baseline', 'auto');\r\n                    } else if (ev_ay === 'top') {\r\n                        el.rendNode.setAttributeNS(null, \"dy\", '1.6ex');\r\n                        el.rendNode.setAttributeNS(null, 'dominant-baseline', 'auto');\r\n                    } else if (ev_ay === 'middle') {\r\n                        el.rendNode.setAttributeNS(null, \"dy\", '0.6ex');\r\n                        el.rendNode.setAttributeNS(null, 'dominant-baseline', 'auto');\r\n                    }\r\n                    el.visPropOld.top = ev_ay + v;\r\n                }\r\n            }\r\n            if (el.htmlStr !== content) {\r\n                el.rendNodeText.data = content;\r\n                el.htmlStr = content;\r\n            }\r\n            this.transformRect(el, el.transformations);\r\n        },\r\n\r\n        /**\r\n         * Set color and opacity of internal texts.\r\n         * @private\r\n         * @see JXG.AbstractRenderer#updateTextStyle\r\n         * @see JXG.AbstractRenderer#updateInternalTextStyle\r\n         */\r\n        updateInternalTextStyle: function (el, strokeColor, strokeOpacity, duration) {\r\n            this.setObjectFillColor(el, strokeColor, strokeOpacity);\r\n        },\r\n\r\n        /* ********* Image related stuff *********** */\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        drawImage: function (el) {\r\n            var node = this.createPrim(\"image\", el.id);\r\n\r\n            node.setAttributeNS(null, \"preserveAspectRatio\", 'none');\r\n            this.appendChildPrim(node, el.evalVisProp('layer'));\r\n            el.rendNode = node;\r\n\r\n            this.updateImage(el);\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        transformRect: function (el, t) {\r\n            var s, m, node,\r\n                str = \"\",\r\n                cx, cy,\r\n                len = t.length;\r\n\r\n            if (len > 0) {\r\n                node = el.rendNode;\r\n                m = this.joinTransforms(el, t);\r\n                s = [m[1][1], m[2][1], m[1][2], m[2][2], m[1][0], m[2][0]].join(\",\");\r\n                if (s.indexOf('NaN') === -1) {\r\n                    str += \" matrix(\" + s + \") \";\r\n                    if (el.elementClass === Const.OBJECT_CLASS_TEXT && el.visProp.display === 'html') {\r\n                        node.style.transform = str;\r\n                        cx = -el.coords.scrCoords[1];\r\n                        cy = -el.coords.scrCoords[2];\r\n                        switch (el.evalVisProp('anchorx')) {\r\n                            case 'right': cx += el.size[0]; break;\r\n                            case 'middle': cx += el.size[0] * 0.5; break;\r\n                        }\r\n                        switch (el.evalVisProp('anchory')) {\r\n                            case 'bottom': cy += el.size[1]; break;\r\n                            case 'middle': cy += el.size[1] * 0.5; break;\r\n                        }\r\n                        node.style['transform-origin'] = (cx) + 'px ' + (cy) + 'px';\r\n                    } else {\r\n                        // Images and texts with display:'internal'\r\n                        node.setAttributeNS(null, \"transform\", str);\r\n                    }\r\n                }\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updateImageURL: function (el) {\r\n            var url = el.eval(el.url);\r\n\r\n            if (el._src !== url) {\r\n                el.imgIsLoaded = false;\r\n                el.rendNode.setAttributeNS(this.xlinkNamespace, \"xlink:href\", url);\r\n                el._src = url;\r\n\r\n                return true;\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updateImageStyle: function (el, doHighlight) {\r\n            var css = el.evalVisProp(\r\n                doHighlight ? 'highlightcssclass' : 'cssclass'\r\n            );\r\n\r\n            el.rendNode.setAttributeNS(null, \"class\", css);\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        drawForeignObject: function (el) {\r\n            el.rendNode = this.appendChildPrim(\r\n                this.createPrim(\"foreignObject\", el.id),\r\n                el.evalVisProp('layer')\r\n            );\r\n\r\n            this.appendNodesToElement(el, 'foreignObject');\r\n            this.updateForeignObject(el);\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updateForeignObject: function (el) {\r\n            if (el._useUserSize) {\r\n                el.rendNode.style.overflow = 'hidden';\r\n            } else {\r\n                el.rendNode.style.overflow = 'visible';\r\n            }\r\n\r\n            this.updateRectPrim(\r\n                el.rendNode,\r\n                el.coords.scrCoords[1],\r\n                el.coords.scrCoords[2] - el.size[1],\r\n                el.size[0],\r\n                el.size[1]\r\n            );\r\n\r\n            if (el.evalVisProp('evaluateOnlyOnce') !== true || !el.renderedOnce) {\r\n                el.rendNode.innerHTML = el.content;\r\n                el.renderedOnce = true;\r\n            }\r\n            this._updateVisual(el, { stroke: true, dash: true }, true);\r\n        },\r\n\r\n        /* ********* Render primitive objects *********** */\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        appendChildPrim: function (node, level) {\r\n            if (!Type.exists(level)) {\r\n                // trace nodes have level not set\r\n                level = 0;\r\n            } else if (level >= Options.layer.numlayers) {\r\n                level = Options.layer.numlayers - 1;\r\n            }\r\n            this.layer[level].appendChild(node);\r\n\r\n            return node;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        createPrim: function (type, id) {\r\n            var node = this.container.ownerDocument.createElementNS(this.svgNamespace, type);\r\n            node.setAttributeNS(null, \"id\", this.uniqName(id));\r\n            node.style.position = 'absolute';\r\n            if (type === 'path') {\r\n                node.setAttributeNS(null, \"stroke-linecap\", 'round');\r\n                node.setAttributeNS(null, \"stroke-linejoin\", 'round');\r\n                node.setAttributeNS(null, \"fill-rule\", 'evenodd');\r\n            }\r\n\r\n            return node;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        remove: function (shape) {\r\n            if (Type.exists(shape) && Type.exists(shape.parentNode)) {\r\n                shape.parentNode.removeChild(shape);\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        setLayer: function (el, level) {\r\n            if (!Type.exists(level)) {\r\n                level = 0;\r\n            } else if (level >= Options.layer.numlayers) {\r\n                level = Options.layer.numlayers - 1;\r\n            }\r\n\r\n            this.layer[level].appendChild(el.rendNode);\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        makeArrows: function (el, a) {\r\n            var node2, str,\r\n                ev_fa = a.evFirst,\r\n                ev_la = a.evLast;\r\n\r\n            if (this.isIE && el.visPropCalc.visible && (ev_fa || ev_la)) {\r\n                // Necessary, since Safari is the new IE (11.2024)\r\n                el.rendNode.parentNode.insertBefore(el.rendNode, el.rendNode);\r\n                return;\r\n            }\r\n\r\n            // We can not compare against visPropOld if there is need for a new arrow head,\r\n            // since here visPropOld and ev_fa / ev_la already have the same value.\r\n            // This has been set in _updateVisual.\r\n            //\r\n            node2 = el.rendNodeTriangleStart;\r\n            if (ev_fa) {\r\n                str = this.toStr(this.container.id, '_', el.id, 'TriangleStart', a.typeFirst);\r\n\r\n                // If we try to set the same arrow head as is already set, we can bail out now\r\n                if (!Type.exists(node2) || node2.id !== str) {\r\n                    node2 = this.container.ownerDocument.getElementById(str);\r\n                    // Check if the marker already exists.\r\n                    // If not, create a new marker\r\n                    if (node2 === null) {\r\n                        node2 = this._createArrowHead(el, \"Start\", a.typeFirst);\r\n                        this.defs.appendChild(node2);\r\n                    }\r\n                    el.rendNodeTriangleStart = node2;\r\n                    el.rendNode.setAttributeNS(null, 'marker-start', this.toURL(str));\r\n                }\r\n            } else {\r\n                if (Type.exists(node2)) {\r\n                    this.remove(node2);\r\n                    el.rendNodeTriangleStart = null;\r\n                }\r\n                // el.rendNode.setAttributeNS(null, \"marker-start\", null);\r\n                el.rendNode.removeAttributeNS(null, 'marker-start');\r\n            }\r\n\r\n            node2 = el.rendNodeTriangleEnd;\r\n            if (ev_la) {\r\n                str = this.toStr(this.container.id, '_', el.id, 'TriangleEnd', a.typeLast);\r\n\r\n                // If we try to set the same arrow head as is already set, we can bail out now\r\n                if (!Type.exists(node2) || node2.id !== str) {\r\n                    node2 = this.container.ownerDocument.getElementById(str);\r\n                    // Check if the marker already exists.\r\n                    // If not, create a new marker\r\n                    if (node2 === null) {\r\n                        node2 = this._createArrowHead(el, \"End\", a.typeLast);\r\n                        this.defs.appendChild(node2);\r\n                    }\r\n                    el.rendNodeTriangleEnd = node2;\r\n                    el.rendNode.setAttributeNS(null, \"marker-end\", this.toURL(str));\r\n                }\r\n            } else {\r\n                if (Type.exists(node2)) {\r\n                    this.remove(node2);\r\n                    el.rendNodeTriangleEnd = null;\r\n                }\r\n                // el.rendNode.setAttributeNS(null, \"marker-end\", null);\r\n                el.rendNode.removeAttributeNS(null, \"marker-end\");\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updateEllipsePrim: function (node, x, y, rx, ry) {\r\n            var huge = 1000000;\r\n\r\n            huge = 200000; // IE\r\n            // webkit does not like huge values if the object is dashed\r\n            // iE doesn't like huge values above 216000\r\n            x = Math.abs(x) < huge ? x : (huge * x) / Math.abs(x);\r\n            y = Math.abs(y) < huge ? y : (huge * y) / Math.abs(y);\r\n            rx = Math.abs(rx) < huge ? rx : (huge * rx) / Math.abs(rx);\r\n            ry = Math.abs(ry) < huge ? ry : (huge * ry) / Math.abs(ry);\r\n\r\n            node.setAttributeNS(null, \"cx\", x);\r\n            node.setAttributeNS(null, \"cy\", y);\r\n            node.setAttributeNS(null, \"rx\", Math.abs(rx));\r\n            node.setAttributeNS(null, \"ry\", Math.abs(ry));\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updateLinePrim: function (node, p1x, p1y, p2x, p2y) {\r\n            var huge = 1000000;\r\n\r\n            huge = 200000; //IE\r\n            if (!isNaN(p1x + p1y + p2x + p2y)) {\r\n                // webkit does not like huge values if the object is dashed\r\n                // IE doesn't like huge values above 216000\r\n                p1x = Math.abs(p1x) < huge ? p1x : (huge * p1x) / Math.abs(p1x);\r\n                p1y = Math.abs(p1y) < huge ? p1y : (huge * p1y) / Math.abs(p1y);\r\n                p2x = Math.abs(p2x) < huge ? p2x : (huge * p2x) / Math.abs(p2x);\r\n                p2y = Math.abs(p2y) < huge ? p2y : (huge * p2y) / Math.abs(p2y);\r\n\r\n                node.setAttributeNS(null, \"x1\", p1x);\r\n                node.setAttributeNS(null, \"y1\", p1y);\r\n                node.setAttributeNS(null, \"x2\", p2x);\r\n                node.setAttributeNS(null, \"y2\", p2y);\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updatePathPrim: function (node, pointString) {\r\n            if (pointString === \"\") {\r\n                pointString = \"M 0 0\";\r\n            }\r\n            node.setAttributeNS(null, \"d\", pointString);\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updatePathStringPoint: function (el, size, type) {\r\n            var s = \"\",\r\n                scr = el.coords.scrCoords,\r\n                sqrt32 = size * Math.sqrt(3) * 0.5,\r\n                s05 = size * 0.5;\r\n\r\n            if (type === 'x') {\r\n                s =\r\n                    \" M \" +\r\n                    (scr[1] - size) +\r\n                    \" \" +\r\n                    (scr[2] - size) +\r\n                    \" L \" +\r\n                    (scr[1] + size) +\r\n                    \" \" +\r\n                    (scr[2] + size) +\r\n                    \" M \" +\r\n                    (scr[1] + size) +\r\n                    \" \" +\r\n                    (scr[2] - size) +\r\n                    \" L \" +\r\n                    (scr[1] - size) +\r\n                    \" \" +\r\n                    (scr[2] + size);\r\n            } else if (type === \"+\") {\r\n                s =\r\n                    \" M \" +\r\n                    (scr[1] - size) +\r\n                    \" \" +\r\n                    scr[2] +\r\n                    \" L \" +\r\n                    (scr[1] + size) +\r\n                    \" \" +\r\n                    scr[2] +\r\n                    \" M \" +\r\n                    scr[1] +\r\n                    \" \" +\r\n                    (scr[2] - size) +\r\n                    \" L \" +\r\n                    scr[1] +\r\n                    \" \" +\r\n                    (scr[2] + size);\r\n            } else if (type === \"|\") {\r\n                s =\r\n                    \" M \" +\r\n                    scr[1] +\r\n                    \" \" +\r\n                    (scr[2] - size) +\r\n                    \" L \" +\r\n                    scr[1] +\r\n                    \" \" +\r\n                    (scr[2] + size);\r\n            } else if (type === \"-\") {\r\n                s =\r\n                    \" M \" +\r\n                    (scr[1] - size) +\r\n                    \" \" +\r\n                    scr[2] +\r\n                    \" L \" +\r\n                    (scr[1] + size) +\r\n                    \" \" +\r\n                    scr[2];\r\n            } else if (type === \"<>\" || type === \"<<>>\") {\r\n                if (type === \"<<>>\") {\r\n                    size *= 1.41;\r\n                }\r\n                s =\r\n                    \" M \" +\r\n                    (scr[1] - size) +\r\n                    \" \" +\r\n                    scr[2] +\r\n                    \" L \" +\r\n                    scr[1] +\r\n                    \" \" +\r\n                    (scr[2] + size) +\r\n                    \" L \" +\r\n                    (scr[1] + size) +\r\n                    \" \" +\r\n                    scr[2] +\r\n                    \" L \" +\r\n                    scr[1] +\r\n                    \" \" +\r\n                    (scr[2] - size) +\r\n                    \" Z \";\r\n                } else if (type === \"^\") {\r\n                    s =\r\n                    \" M \" +\r\n                    scr[1] +\r\n                    \" \" +\r\n                    (scr[2] - size) +\r\n                    \" L \" +\r\n                    (scr[1] - sqrt32) +\r\n                    \" \" +\r\n                    (scr[2] + s05) +\r\n                    \" L \" +\r\n                    (scr[1] + sqrt32) +\r\n                    \" \" +\r\n                    (scr[2] + s05) +\r\n                    \" Z \"; // close path\r\n            } else if (type === 'v') {\r\n                s =\r\n                    \" M \" +\r\n                    scr[1] +\r\n                    \" \" +\r\n                    (scr[2] + size) +\r\n                    \" L \" +\r\n                    (scr[1] - sqrt32) +\r\n                    \" \" +\r\n                    (scr[2] - s05) +\r\n                    \" L \" +\r\n                    (scr[1] + sqrt32) +\r\n                    \" \" +\r\n                    (scr[2] - s05) +\r\n                    \" Z \";\r\n            } else if (type === \">\") {\r\n                s =\r\n                    \" M \" +\r\n                    (scr[1] + size) +\r\n                    \" \" +\r\n                    scr[2] +\r\n                    \" L \" +\r\n                    (scr[1] - s05) +\r\n                    \" \" +\r\n                    (scr[2] - sqrt32) +\r\n                    \" L \" +\r\n                    (scr[1] - s05) +\r\n                    \" \" +\r\n                    (scr[2] + sqrt32) +\r\n                    \" Z \";\r\n            } else if (type === \"<\") {\r\n                s =\r\n                    \" M \" +\r\n                    (scr[1] - size) +\r\n                    \" \" +\r\n                    scr[2] +\r\n                    \" L \" +\r\n                    (scr[1] + s05) +\r\n                    \" \" +\r\n                    (scr[2] - sqrt32) +\r\n                    \" L \" +\r\n                    (scr[1] + s05) +\r\n                    \" \" +\r\n                    (scr[2] + sqrt32) +\r\n                    \" Z \";\r\n            }\r\n            return s;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updatePathStringPrim: function (el) {\r\n            var i,\r\n                scr,\r\n                len,\r\n                symbm = \" M \",\r\n                symbl = \" L \",\r\n                symbc = \" C \",\r\n                nextSymb = symbm,\r\n                maxSize = 5000.0,\r\n                pStr = \"\";\r\n\r\n            if (el.numberPoints <= 0) {\r\n                return \"\";\r\n            }\r\n\r\n            len = Math.min(el.points.length, el.numberPoints);\r\n\r\n            if (el.bezierDegree === 1) {\r\n                for (i = 0; i < len; i++) {\r\n                    scr = el.points[i].scrCoords;\r\n                    if (isNaN(scr[1]) || isNaN(scr[2])) {\r\n                        // PenUp\r\n                        nextSymb = symbm;\r\n                    } else {\r\n                        // Chrome has problems with values being too far away.\r\n                        scr[1] = Math.max(Math.min(scr[1], maxSize), -maxSize);\r\n                        scr[2] = Math.max(Math.min(scr[2], maxSize), -maxSize);\r\n\r\n                        // Attention: first coordinate may be inaccurate if far way\r\n                        //pStr += [nextSymb, scr[1], ' ', scr[2]].join('');\r\n                        pStr += nextSymb + scr[1] + \" \" + scr[2]; // Seems to be faster now (webkit and firefox)\r\n                        nextSymb = symbl;\r\n                    }\r\n                }\r\n            } else if (el.bezierDegree === 3) {\r\n                i = 0;\r\n                while (i < len) {\r\n                    scr = el.points[i].scrCoords;\r\n                    if (isNaN(scr[1]) || isNaN(scr[2])) {\r\n                        // PenUp\r\n                        nextSymb = symbm;\r\n                    } else {\r\n                        pStr += nextSymb + scr[1] + \" \" + scr[2];\r\n                        if (nextSymb === symbc) {\r\n                            i += 1;\r\n                            scr = el.points[i].scrCoords;\r\n                            pStr += \" \" + scr[1] + \" \" + scr[2];\r\n                            i += 1;\r\n                            scr = el.points[i].scrCoords;\r\n                            pStr += \" \" + scr[1] + \" \" + scr[2];\r\n                        }\r\n                        nextSymb = symbc;\r\n                    }\r\n                    i += 1;\r\n                }\r\n            }\r\n            return pStr;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updatePathStringBezierPrim: function (el) {\r\n            var i, j, k,\r\n                scr,\r\n                lx, ly,\r\n                len,\r\n                symbm = \" M \",\r\n                symbl = \" C \",\r\n                nextSymb = symbm,\r\n                maxSize = 5000.0,\r\n                pStr = \"\",\r\n                f = el.evalVisProp('strokewidth'),\r\n                isNoPlot = el.evalVisProp('curvetype') !== 'plot';\r\n\r\n            if (el.numberPoints <= 0) {\r\n                return \"\";\r\n            }\r\n\r\n            if (isNoPlot && el.board.options.curve.RDPsmoothing) {\r\n                el.points = Numerics.RamerDouglasPeucker(el.points, 0.5);\r\n            }\r\n\r\n            len = Math.min(el.points.length, el.numberPoints);\r\n            for (j = 1; j < 3; j++) {\r\n                nextSymb = symbm;\r\n                for (i = 0; i < len; i++) {\r\n                    scr = el.points[i].scrCoords;\r\n\r\n                    if (isNaN(scr[1]) || isNaN(scr[2])) {\r\n                        // PenUp\r\n                        nextSymb = symbm;\r\n                    } else {\r\n                        // Chrome has problems with values being too far away.\r\n                        scr[1] = Math.max(Math.min(scr[1], maxSize), -maxSize);\r\n                        scr[2] = Math.max(Math.min(scr[2], maxSize), -maxSize);\r\n\r\n                        // Attention: first coordinate may be inaccurate if far way\r\n                        if (nextSymb === symbm) {\r\n                            //pStr += [nextSymb, scr[1], ' ', scr[2]].join('');\r\n                            pStr += nextSymb + scr[1] + \" \" + scr[2]; // Seems to be faster now (webkit and firefox)\r\n                        } else {\r\n                            k = 2 * j;\r\n                            pStr += [\r\n                                nextSymb,\r\n                                lx + (scr[1] - lx) * 0.333 + f * (k * Math.random() - j),\r\n                                \" \",\r\n                                ly + (scr[2] - ly) * 0.333 + f * (k * Math.random() - j),\r\n                                \" \",\r\n                                lx + (scr[1] - lx) * 0.666 + f * (k * Math.random() - j),\r\n                                \" \",\r\n                                ly + (scr[2] - ly) * 0.666 + f * (k * Math.random() - j),\r\n                                \" \",\r\n                                scr[1],\r\n                                \" \",\r\n                                scr[2]\r\n                            ].join(\"\");\r\n                        }\r\n\r\n                        nextSymb = symbl;\r\n                        lx = scr[1];\r\n                        ly = scr[2];\r\n                    }\r\n                }\r\n            }\r\n            return pStr;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updatePolygonPrim: function (node, el) {\r\n            var i,\r\n                pStr = \"\",\r\n                scrCoords,\r\n                len = el.vertices.length;\r\n\r\n            node.setAttributeNS(null, \"stroke\", 'none');\r\n            node.setAttributeNS(null, \"fill-rule\", 'evenodd');\r\n            if (el.elType === 'polygonalchain') {\r\n                len++;\r\n            }\r\n\r\n            for (i = 0; i < len - 1; i++) {\r\n                if (el.vertices[i].isReal) {\r\n                    scrCoords = el.vertices[i].coords.scrCoords;\r\n                    pStr = pStr + scrCoords[1] + \",\" + scrCoords[2];\r\n                } else {\r\n                    node.setAttributeNS(null, \"points\", \"\");\r\n                    return;\r\n                }\r\n\r\n                if (i < len - 2) {\r\n                    pStr += \" \";\r\n                }\r\n            }\r\n            if (pStr.indexOf('NaN') === -1) {\r\n                node.setAttributeNS(null, \"points\", pStr);\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updateRectPrim: function (node, x, y, w, h) {\r\n            node.setAttributeNS(null, \"x\", x);\r\n            node.setAttributeNS(null, \"y\", y);\r\n            node.setAttributeNS(null, \"width\", w);\r\n            node.setAttributeNS(null, \"height\", h);\r\n        },\r\n\r\n        /* ********* Set attributes *********** */\r\n\r\n        /**\r\n         * Call user-defined function to set visual attributes.\r\n         * If \"testAttribute\" is the empty string, the function\r\n         * is called immediately, otherwise it is called in a timeOut.\r\n         *\r\n         * This is necessary to realize smooth transitions but avoid transitions\r\n         * when first creating the objects.\r\n         *\r\n         * Usually, the string in testAttribute is the visPropOld attribute\r\n         * of the values which are set.\r\n         *\r\n         * @param {Function} setFunc       Some function which usually sets some attributes\r\n         * @param {String} testAttribute If this string is the empty string  the function is called immediately,\r\n         *                               otherwise it is called in a setImeout.\r\n         * @see JXG.SVGRenderer#setObjectFillColor\r\n         * @see JXG.SVGRenderer#setObjectStrokeColor\r\n         * @see JXG.SVGRenderer#_setArrowColor\r\n         * @private\r\n         */\r\n        _setAttribute: function (setFunc, testAttribute) {\r\n            if (testAttribute === \"\") {\r\n                setFunc();\r\n            } else {\r\n                window.setTimeout(setFunc, 1);\r\n            }\r\n        },\r\n\r\n        display: function (el, val) {\r\n            var node;\r\n\r\n            if (el && el.rendNode) {\r\n                el.visPropOld.visible = val;\r\n                node = el.rendNode;\r\n                if (val) {\r\n                    node.setAttributeNS(null, \"display\", 'inline');\r\n                    node.style.visibility = 'inherit';\r\n                } else {\r\n                    node.setAttributeNS(null, \"display\", 'none');\r\n                    node.style.visibility = 'hidden';\r\n                }\r\n            }\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        hide: function (el) {\r\n            JXG.deprecated(\"Board.renderer.hide()\", \"Board.renderer.display()\");\r\n            this.display(el, false);\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        setARIA: function(el) {\r\n            // This method is only called in abstractRenderer._updateVisual() if aria.enabled == true.\r\n            var key, k, v;\r\n\r\n            // this.setPropertyPrim(el.rendNode, 'aria-label', el.evalVisProp('aria.label'));\r\n            // this.setPropertyPrim(el.rendNode, 'aria-live', el.evalVisProp('aria.live'));\r\n            for (key in el.visProp.aria) {\r\n                if (el.visProp.aria.hasOwnProperty(key) && key !== 'enabled') {\r\n                    k = 'aria.' + key;\r\n                    v = el.evalVisProp('aria.' + key);\r\n                    if (el.visPropOld[k] !== v) {\r\n                        this.setPropertyPrim(el.rendNode, 'aria-' + key, v);\r\n                        el.visPropOld[k] = v;\r\n                    }\r\n                }\r\n            }\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        setBuffering: function (el, type) {\r\n            el.rendNode.setAttribute(\"buffered-rendering\", type);\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        setCssClass(el, cssClass) {\r\n\r\n            if (el.visPropOld.cssclass !== cssClass) {\r\n                this.setPropertyPrim(el.rendNode, 'class', cssClass);\r\n                el.visPropOld.cssclass = cssClass;\r\n            }\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        setDashStyle: function (el) {\r\n            var dashStyle = el.evalVisProp('dash'),\r\n                ds = el.evalVisProp('dashscale'),\r\n                sw = ds ? 0.5 * el.evalVisProp('strokewidth') : 1,\r\n                node = el.rendNode;\r\n\r\n            if (dashStyle > 0) {\r\n                node.setAttributeNS(null, \"stroke-dasharray\",\r\n                    // sw could distinguish highlighting or not.\r\n                    // But it seems to preferable to ignore this.\r\n                    this.dashArray[dashStyle - 1].map(function (x) { return x * sw; }).join(',')\r\n                );\r\n            } else {\r\n                if (node.hasAttributeNS(null, \"stroke-dasharray\")) {\r\n                    node.removeAttributeNS(null, \"stroke-dasharray\");\r\n                }\r\n            }\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        setGradient: function (el) {\r\n            var fillNode = el.rendNode,\r\n                node, node2, node3,\r\n                ev_g = el.evalVisProp('gradient');\r\n\r\n            if (ev_g === \"linear\" || ev_g === 'radial') {\r\n                node = this.createPrim(ev_g + \"Gradient\", el.id + \"_gradient\");\r\n                node2 = this.createPrim(\"stop\", el.id + \"_gradient1\");\r\n                node3 = this.createPrim(\"stop\", el.id + \"_gradient2\");\r\n                node.appendChild(node2);\r\n                node.appendChild(node3);\r\n                this.defs.appendChild(node);\r\n                fillNode.setAttributeNS(\r\n                    null,\r\n                    'style',\r\n                    // \"fill:url(#\" + this.container.id + \"_\" + el.id + \"_gradient)\"\r\n                    'fill:' + this.toURL(this.container.id + '_' + el.id + '_gradient')\r\n                );\r\n                el.gradNode1 = node2;\r\n                el.gradNode2 = node3;\r\n                el.gradNode = node;\r\n            } else {\r\n                fillNode.removeAttributeNS(null, 'style');\r\n            }\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        setLineCap: function (el) {\r\n            var capStyle = el.evalVisProp('linecap');\r\n\r\n            if (\r\n                capStyle === undefined ||\r\n                capStyle === \"\" ||\r\n                el.visPropOld.linecap === capStyle ||\r\n                !Type.exists(el.rendNode)\r\n            ) {\r\n                return;\r\n            }\r\n\r\n            this.setPropertyPrim(el.rendNode, \"stroke-linecap\", capStyle);\r\n            el.visPropOld.linecap = capStyle;\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        setObjectFillColor: function (el, color, opacity, rendNode) {\r\n            var node, c, rgbo, oo,\r\n                rgba = color,\r\n                o = opacity,\r\n                grad = el.evalVisProp('gradient');\r\n\r\n            o = o > 0 ? o : 0;\r\n\r\n            // TODO  save gradient and gradientangle\r\n            if (\r\n                el.visPropOld.fillcolor === rgba &&\r\n                el.visPropOld.fillopacity === o &&\r\n                grad === null\r\n            ) {\r\n                return;\r\n            }\r\n            if (Type.exists(rgba) && rgba !== false) {\r\n                if (rgba.length !== 9) {\r\n                    // RGB, not RGBA\r\n                    c = rgba;\r\n                    oo = o;\r\n                } else {\r\n                    // True RGBA, not RGB\r\n                    rgbo = Color.rgba2rgbo(rgba);\r\n                    c = rgbo[0];\r\n                    oo = o * rgbo[1];\r\n                }\r\n\r\n                if (rendNode === undefined) {\r\n                    node = el.rendNode;\r\n                } else {\r\n                    node = rendNode;\r\n                }\r\n\r\n                if (c !== \"none\" && c !== \"\" && c !== false) {\r\n                    this._setAttribute(function () {\r\n                        node.setAttributeNS(null, \"fill\", c);\r\n                    }, el.visPropOld.fillcolor);\r\n                }\r\n\r\n                if (el.type === JXG.OBJECT_TYPE_IMAGE) {\r\n                    this._setAttribute(function () {\r\n                        node.setAttributeNS(null, \"opacity\", oo);\r\n                    }, el.visPropOld.fillopacity);\r\n                    //node.style['opacity'] = oo;  // This would overwrite values set by CSS class.\r\n                } else {\r\n                    if (c === 'none') {\r\n                        // This is done only for non-images\r\n                        // because images have no fill color.\r\n                        oo = 0;\r\n                        // This is necessary if there is a foreignObject below.\r\n                        node.setAttributeNS(null, \"pointer-events\", 'visibleStroke');\r\n                    } else {\r\n                        // This is the default\r\n                        node.setAttributeNS(null, \"pointer-events\", 'visiblePainted');\r\n                    }\r\n                    this._setAttribute(function () {\r\n                        node.setAttributeNS(null, 'fill-opacity', oo);\r\n                    }, el.visPropOld.fillopacity);\r\n                }\r\n\r\n                if (grad === \"linear\" || grad === 'radial') {\r\n                    this.updateGradient(el);\r\n                }\r\n            }\r\n            el.visPropOld.fillcolor = rgba;\r\n            el.visPropOld.fillopacity = o;\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        setObjectStrokeColor: function (el, color, opacity) {\r\n            var rgba = color,\r\n                c, rgbo,\r\n                o = opacity,\r\n                oo, node;\r\n\r\n            o = o > 0 ? o : 0;\r\n\r\n            if (el.visPropOld.strokecolor === rgba && el.visPropOld.strokeopacity === o) {\r\n                return;\r\n            }\r\n\r\n            if (Type.exists(rgba) && rgba !== false) {\r\n                if (rgba.length !== 9) {\r\n                    // RGB, not RGBA\r\n                    c = rgba;\r\n                    oo = o;\r\n                } else {\r\n                    // True RGBA, not RGB\r\n                    rgbo = Color.rgba2rgbo(rgba);\r\n                    c = rgbo[0];\r\n                    oo = o * rgbo[1];\r\n                }\r\n\r\n                node = el.rendNode;\r\n\r\n                if (el.elementClass === Const.OBJECT_CLASS_TEXT) {\r\n                    if (el.evalVisProp('display') === 'html') {\r\n                        this._setAttribute(function () {\r\n                            node.style.color = c;\r\n                            node.style.opacity = oo;\r\n                        }, el.visPropOld.strokecolor);\r\n                    } else {\r\n                        this._setAttribute(function () {\r\n                            node.setAttributeNS(null, 'fill', c);\r\n                            node.setAttributeNS(null, 'fill-opacity', oo);\r\n                        }, el.visPropOld.strokecolor);\r\n                    }\r\n                } else {\r\n                    this._setAttribute(function () {\r\n                        node.setAttributeNS(null, \"stroke\", c);\r\n                        node.setAttributeNS(null, 'stroke-opacity', oo);\r\n                    }, el.visPropOld.strokecolor);\r\n                }\r\n\r\n                if (\r\n                    el.elementClass === Const.OBJECT_CLASS_CURVE ||\r\n                    el.elementClass === Const.OBJECT_CLASS_LINE\r\n                ) {\r\n                    if (el.evalVisProp('firstarrow')) {\r\n                        this._setArrowColor(\r\n                            el.rendNodeTriangleStart,\r\n                            c, oo, el,\r\n                            el.visPropCalc.typeFirst\r\n                        );\r\n                    }\r\n\r\n                    if (el.evalVisProp('lastarrow')) {\r\n                        this._setArrowColor(\r\n                            el.rendNodeTriangleEnd,\r\n                            c, oo, el,\r\n                            el.visPropCalc.typeLast\r\n                        );\r\n                    }\r\n                }\r\n            }\r\n\r\n            el.visPropOld.strokecolor = rgba;\r\n            el.visPropOld.strokeopacity = o;\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        setObjectStrokeWidth: function (el, width) {\r\n            var node,\r\n                w = width;\r\n\r\n            if (isNaN(w) || el.visPropOld.strokewidth === w) {\r\n                return;\r\n            }\r\n\r\n            node = el.rendNode;\r\n            this.setPropertyPrim(node, \"stroked\", 'true');\r\n            if (Type.exists(w)) {\r\n                this.setPropertyPrim(node, \"stroke-width\", w + 'px');\r\n\r\n                // if (el.elementClass === Const.OBJECT_CLASS_CURVE ||\r\n                // el.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                //     if (el.evalVisProp('firstarrow')) {\r\n                //         this._setArrowWidth(el.rendNodeTriangleStart, w, el.rendNode);\r\n                //     }\r\n                //\r\n                //     if (el.evalVisProp('lastarrow')) {\r\n                //         this._setArrowWidth(el.rendNodeTriangleEnd, w, el.rendNode);\r\n                //     }\r\n                // }\r\n            }\r\n            el.visPropOld.strokewidth = w;\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        setObjectTransition: function (el, duration) {\r\n            var node, props,\r\n                transitionArr = [],\r\n                transitionStr,\r\n                i,\r\n                len = 0,\r\n                nodes = [\"rendNode\", \"rendNodeTriangleStart\", \"rendNodeTriangleEnd\"];\r\n\r\n            if (duration === undefined) {\r\n                duration = el.evalVisProp('transitionduration');\r\n            }\r\n\r\n            props = el.evalVisProp('transitionproperties');\r\n            if (duration === el.visPropOld.transitionduration &&\r\n                props === el.visPropOld.transitionproperties) {\r\n                return;\r\n            }\r\n\r\n            // if (\r\n            //     el.elementClass === Const.OBJECT_CLASS_TEXT &&\r\n            //     el.evalVisProp('display') === \"html\"\r\n            // ) {\r\n            //     // transitionStr = \" color \" + duration + \"ms,\" +\r\n            //     //     \" opacity \" + duration + 'ms'\r\n            //     transitionStr = \" all \" + duration + \"ms ease\";\r\n            // } else {\r\n            //     transitionStr =\r\n            //         \" fill \" + duration + \"ms,\" +\r\n            //         \" fill-opacity \" + duration + \"ms,\" +\r\n            //         \" stroke \" + duration + \"ms,\" +\r\n            //         \" stroke-opacity \" + duration + \"ms,\" +\r\n            //         \" stroke-width \" + duration + \"ms,\" +\r\n            //         \" width \" + duration + \"ms,\" +\r\n            //         \" height \" + duration + \"ms,\" +\r\n            //         \" rx \" + duration + \"ms,\" +\r\n            //         \" ry \" + duration + 'ms'\r\n            // }\r\n\r\n            if (Type.exists(props)) {\r\n                len = props.length;\r\n            }\r\n            for (i = 0; i < len; i++) {\r\n                transitionArr.push(props[i] + ' ' + duration + 'ms');\r\n            }\r\n            transitionStr = transitionArr.join(', ');\r\n\r\n            len = nodes.length;\r\n            for (i = 0; i < len; ++i) {\r\n                if (el[nodes[i]]) {\r\n                    node = el[nodes[i]];\r\n                    node.style.transition = transitionStr;\r\n                }\r\n            }\r\n\r\n            el.visPropOld.transitionduration = duration;\r\n            el.visPropOld.transitionproperties = props;\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        setShadow: function (el) {\r\n            var ev_s = el.evalVisProp('shadow'),\r\n                ev_s_json, c, b, bl, o, op, id, node,\r\n                use_board_filter = true,\r\n                show = false;\r\n\r\n            ev_s_json = JSON.stringify(ev_s);\r\n            if (ev_s_json === el.visPropOld.shadow) {\r\n                return;\r\n            }\r\n\r\n            if (typeof ev_s === 'boolean') {\r\n                use_board_filter = true;\r\n                show = ev_s;\r\n                c = 'none';\r\n                b = 3;\r\n                bl = 0.1;\r\n                o = [5, 5];\r\n                op = 1;\r\n            } else {\r\n                if (el.evalVisProp('shadow.enabled')) {\r\n                    use_board_filter = false;\r\n                    show = true;\r\n                    c = JXG.rgbParser(el.evalVisProp('shadow.color'));\r\n                    b = el.evalVisProp('shadow.blur');\r\n                    bl = el.evalVisProp('shadow.blend');\r\n                    o = el.evalVisProp('shadow.offset');\r\n                    op = el.evalVisProp('shadow.opacity');\r\n                } else {\r\n                    show = false;\r\n                }\r\n            }\r\n\r\n            if (Type.exists(el.rendNode)) {\r\n                if (show) {\r\n                    if (use_board_filter) {\r\n                        el.rendNode.setAttributeNS(null, 'filter', this.toURL(this.container.id + '_' + 'f1'));\r\n                        // 'url(#' + this.container.id + '_' + 'f1)');\r\n                    } else {\r\n                        node = this.container.ownerDocument.getElementById(id);\r\n                        if (node) {\r\n                            this.defs.removeChild(node);\r\n                        }\r\n                        id = el.rendNode.id + '_' + 'f1';\r\n                        this.defs.appendChild(this.createShadowFilter(id, c, op, bl, b, o));\r\n                        el.rendNode.setAttributeNS(null, 'filter', this.toURL(id));\r\n                        // 'url(#' + id + ')');\r\n                    }\r\n                } else {\r\n                    el.rendNode.removeAttributeNS(null, 'filter');\r\n                }\r\n            }\r\n\r\n            el.visPropOld.shadow = ev_s_json;\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        setTabindex: function (el) {\r\n            var val;\r\n            if (el.board.attr.keyboard.enabled && Type.exists(el.rendNode)) {\r\n                val = el.evalVisProp('tabindex');\r\n                if (!el.visPropCalc.visible /* || el.evalVisProp('fixed') */) {\r\n                    val = null;\r\n                }\r\n                if (val !== el.visPropOld.tabindex) {\r\n                    el.rendNode.setAttribute(\"tabindex\", val);\r\n                    el.visPropOld.tabindex = val;\r\n                }\r\n            }\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        setPropertyPrim: function (node, key, val) {\r\n            if (key === 'stroked') {\r\n                return;\r\n            }\r\n            node.setAttributeNS(null, key, val);\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        show: function (el) {\r\n            JXG.deprecated(\"Board.renderer.show()\", \"Board.renderer.display()\");\r\n            this.display(el, true);\r\n            // var node;\r\n            //\r\n            // if (el && el.rendNode) {\r\n            //     node = el.rendNode;\r\n            //     node.setAttributeNS(null, 'display', 'inline');\r\n            //     node.style.visibility = 'inherit'\r\n            // }\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        updateGradient: function (el) {\r\n            var col,\r\n                op,\r\n                node2 = el.gradNode1,\r\n                node3 = el.gradNode2,\r\n                ev_g = el.evalVisProp('gradient');\r\n\r\n            if (!Type.exists(node2) || !Type.exists(node3)) {\r\n                return;\r\n            }\r\n\r\n            op = el.evalVisProp('fillopacity');\r\n            op = op > 0 ? op : 0;\r\n            col = el.evalVisProp('fillcolor');\r\n\r\n            node2.setAttributeNS(null, \"style\", \"stop-color:\" + col + \";stop-opacity:\" + op);\r\n            node3.setAttributeNS(\r\n                null,\r\n                \"style\",\r\n                \"stop-color:\" +\r\n                el.evalVisProp('gradientsecondcolor') +\r\n                \";stop-opacity:\" +\r\n                el.evalVisProp('gradientsecondopacity')\r\n            );\r\n            node2.setAttributeNS(\r\n                null,\r\n                \"offset\",\r\n                el.evalVisProp('gradientstartoffset') * 100 + \"%\"\r\n            );\r\n            node3.setAttributeNS(\r\n                null,\r\n                \"offset\",\r\n                el.evalVisProp('gradientendoffset') * 100 + \"%\"\r\n            );\r\n            if (ev_g === 'linear') {\r\n                this.updateGradientAngle(el.gradNode, el.evalVisProp('gradientangle'));\r\n            } else if (ev_g === 'radial') {\r\n                this.updateGradientCircle(\r\n                    el.gradNode,\r\n                    el.evalVisProp('gradientcx'),\r\n                    el.evalVisProp('gradientcy'),\r\n                    el.evalVisProp('gradientr'),\r\n                    el.evalVisProp('gradientfx'),\r\n                    el.evalVisProp('gradientfy'),\r\n                    el.evalVisProp('gradientfr')\r\n                );\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Set the gradient angle for linear color gradients.\r\n         *\r\n         * @private\r\n         * @param {SVGnode} node SVG gradient node of an arbitrary JSXGraph element.\r\n         * @param {Number} radians angle value in radians. 0 is horizontal from left to right, Pi/4 is vertical from top to bottom.\r\n         */\r\n        updateGradientAngle: function (node, radians) {\r\n            // Angles:\r\n            // 0: ->\r\n            // 90: down\r\n            // 180: <-\r\n            // 90: up\r\n            var f = 1.0,\r\n                co = Math.cos(radians),\r\n                si = Math.sin(radians);\r\n\r\n            if (Math.abs(co) > Math.abs(si)) {\r\n                f /= Math.abs(co);\r\n            } else {\r\n                f /= Math.abs(si);\r\n            }\r\n\r\n            if (co >= 0) {\r\n                node.setAttributeNS(null, \"x1\", 0);\r\n                node.setAttributeNS(null, \"x2\", co * f);\r\n            } else {\r\n                node.setAttributeNS(null, \"x1\", -co * f);\r\n                node.setAttributeNS(null, \"x2\", 0);\r\n            }\r\n            if (si >= 0) {\r\n                node.setAttributeNS(null, \"y1\", 0);\r\n                node.setAttributeNS(null, \"y2\", si * f);\r\n            } else {\r\n                node.setAttributeNS(null, \"y1\", -si * f);\r\n                node.setAttributeNS(null, \"y2\", 0);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Set circles for radial color gradients.\r\n         *\r\n         * @private\r\n         * @param {SVGnode} node SVG gradient node\r\n         * @param {Number} cx SVG value cx (value between 0 and 1)\r\n         * @param {Number} cy  SVG value cy (value between 0 and 1)\r\n         * @param {Number} r  SVG value r (value between 0 and 1)\r\n         * @param {Number} fx  SVG value fx (value between 0 and 1)\r\n         * @param {Number} fy  SVG value fy (value between 0 and 1)\r\n         * @param {Number} fr  SVG value fr (value between 0 and 1)\r\n         */\r\n        updateGradientCircle: function (node, cx, cy, r, fx, fy, fr) {\r\n            node.setAttributeNS(null, \"cx\", cx * 100 + \"%\"); // Center first color\r\n            node.setAttributeNS(null, \"cy\", cy * 100 + \"%\");\r\n            node.setAttributeNS(null, \"r\", r * 100 + \"%\");\r\n            node.setAttributeNS(null, \"fx\", fx * 100 + \"%\"); // Center second color / focal point\r\n            node.setAttributeNS(null, \"fy\", fy * 100 + \"%\");\r\n            node.setAttributeNS(null, \"fr\", fr * 100 + \"%\");\r\n        },\r\n\r\n        /* ********* Renderer control *********** */\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        suspendRedraw: function () {\r\n            // It seems to be important for the Linux version of firefox\r\n            this.suspendHandle = this.svgRoot.suspendRedraw(10000);\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        unsuspendRedraw: function () {\r\n            this.svgRoot.unsuspendRedraw(this.suspendHandle);\r\n            // this.svgRoot.unsuspendRedrawAll();\r\n            //this.svgRoot.forceRedraw();\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        resize: function (w, h) {\r\n            this.svgRoot.setAttribute(\"width\", parseFloat(w));\r\n            this.svgRoot.setAttribute(\"height\", parseFloat(h));\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        createTouchpoints: function (n) {\r\n            var i, na1, na2, node;\r\n            this.touchpoints = [];\r\n            for (i = 0; i < n; i++) {\r\n                na1 = \"touchpoint1_\" + i;\r\n                node = this.createPrim(\"path\", na1);\r\n                this.appendChildPrim(node, 19);\r\n                node.setAttributeNS(null, \"d\", \"M 0 0\");\r\n                this.touchpoints.push(node);\r\n\r\n                this.setPropertyPrim(node, \"stroked\", 'true');\r\n                this.setPropertyPrim(node, \"stroke-width\", '1px');\r\n                node.setAttributeNS(null, \"stroke\", \"#000000\");\r\n                node.setAttributeNS(null, 'stroke-opacity', 1.0);\r\n                node.setAttributeNS(null, \"display\", 'none');\r\n\r\n                na2 = \"touchpoint2_\" + i;\r\n                node = this.createPrim(\"ellipse\", na2);\r\n                this.appendChildPrim(node, 19);\r\n                this.updateEllipsePrim(node, 0, 0, 0, 0);\r\n                this.touchpoints.push(node);\r\n\r\n                this.setPropertyPrim(node, \"stroked\", 'true');\r\n                this.setPropertyPrim(node, \"stroke-width\", '1px');\r\n                node.setAttributeNS(null, \"stroke\", \"#000000\");\r\n                node.setAttributeNS(null, \"fill\", \"#ffffff\");\r\n                node.setAttributeNS(null, 'stroke-opacity', 1.0);\r\n                node.setAttributeNS(null, 'fill-opacity', 0.0);\r\n                node.setAttributeNS(null, \"display\", 'none');\r\n            }\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        showTouchpoint: function (i) {\r\n            if (this.touchpoints && i >= 0 && 2 * i < this.touchpoints.length) {\r\n                this.touchpoints[2 * i].setAttributeNS(null, \"display\", 'inline');\r\n                this.touchpoints[2 * i + 1].setAttributeNS(null, \"display\", 'inline');\r\n            }\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        hideTouchpoint: function (i) {\r\n            if (this.touchpoints && i >= 0 && 2 * i < this.touchpoints.length) {\r\n                this.touchpoints[2 * i].setAttributeNS(null, \"display\", 'none');\r\n                this.touchpoints[2 * i + 1].setAttributeNS(null, \"display\", 'none');\r\n            }\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        updateTouchpoint: function (i, pos) {\r\n            var x,\r\n                y,\r\n                d = 37;\r\n\r\n            if (this.touchpoints && i >= 0 && 2 * i < this.touchpoints.length) {\r\n                x = pos[0];\r\n                y = pos[1];\r\n\r\n                this.touchpoints[2 * i].setAttributeNS(\r\n                    null,\r\n                    \"d\",\r\n                    \"M \" +\r\n                    (x - d) +\r\n                    \" \" +\r\n                    y +\r\n                    \" \" +\r\n                    \"L \" +\r\n                    (x + d) +\r\n                    \" \" +\r\n                    y +\r\n                    \" \" +\r\n                    \"M \" +\r\n                    x +\r\n                    \" \" +\r\n                    (y - d) +\r\n                    \" \" +\r\n                    \"L \" +\r\n                    x +\r\n                    \" \" +\r\n                    (y + d)\r\n                );\r\n                this.updateEllipsePrim(this.touchpoints[2 * i + 1], pos[0], pos[1], 25, 25);\r\n            }\r\n        },\r\n\r\n        /* ********* Dump related stuff *********** */\r\n\r\n        /**\r\n         * Walk recursively through the DOM subtree of a node and collect all\r\n         * value attributes together with the id of that node.\r\n         * <b>Attention:</b> Only values of nodes having a valid id are taken.\r\n         * @param  {Node} node   root node of DOM subtree that will be searched recursively.\r\n         * @return {Array}      Array with entries of the form [id, value]\r\n         * @private\r\n         */\r\n        _getValuesOfDOMElements: function (node) {\r\n            var values = [];\r\n            if (node.nodeType === 1) {\r\n                node = node.firstChild;\r\n                while (node) {\r\n                    if (node.id !== undefined && node.value !== undefined) {\r\n                        values.push([node.id, node.value]);\r\n                    }\r\n                    Type.concat(values, this._getValuesOfDOMElements(node));\r\n                    node = node.nextSibling;\r\n                }\r\n            }\r\n            return values;\r\n        },\r\n\r\n        // _getDataUri: function (url, callback) {\r\n        //     var image = new Image();\r\n        //     image.onload = function () {\r\n        //         var canvas = document.createElement('canvas');\r\n        //         canvas.width = this.naturalWidth; // or 'width' if you want a special/scaled size\r\n        //         canvas.height = this.naturalHeight; // or 'height' if you want a special/scaled size\r\n        //         canvas.getContext('2d').drawImage(this, 0, 0);\r\n        //         callback(canvas.toDataURL(\"image/png\"));\r\n        //         canvas.remove();\r\n        //     };\r\n        //     image.src = url;\r\n        // },\r\n\r\n        _getImgDataURL: function (svgRoot) {\r\n            var images, len, canvas, ctx, ur, i;\r\n\r\n            images = svgRoot.getElementsByTagName('image');\r\n            len = images.length;\r\n            if (len > 0) {\r\n                canvas = document.createElement('canvas');\r\n                //img = new Image();\r\n                for (i = 0; i < len; i++) {\r\n                    images[i].setAttribute(\"crossorigin\", 'anonymous');\r\n                    //img.src = images[i].href;\r\n                    //img.onload = function() {\r\n                    // img.crossOrigin = 'anonymous'\r\n                    ctx = canvas.getContext('2d');\r\n                    canvas.width = images[i].getAttribute('width');\r\n                    canvas.height = images[i].getAttribute('height');\r\n                    try {\r\n                        ctx.drawImage(images[i], 0, 0, canvas.width, canvas.height);\r\n\r\n                        // If the image is not png, the format must be specified here\r\n                        ur = canvas.toDataURL();\r\n                        images[i].setAttribute(\"xlink:href\", ur);\r\n                    } catch (err) {\r\n                        console.log(\"CORS problem! Image can not be used\", err);\r\n                    }\r\n                }\r\n                //canvas.remove();\r\n            }\r\n            return true;\r\n        },\r\n\r\n        /**\r\n         * Return a data URI of the SVG code representing the construction.\r\n         * The SVG code of the construction is base64 encoded. The return string starts\r\n         * with \"data:image/svg+xml;base64,...\".\r\n         *\r\n         * @param {Boolean} ignoreTexts If true, the foreignObject tag is set to display=none.\r\n         * This is necessary for older versions of Safari. Default: false\r\n         * @returns {String}  data URI string\r\n         *\r\n         * @example\r\n         * var A = board.create('point', [2, 2]);\r\n         *\r\n         * var txt = board.renderer.dumpToDataURI(false);\r\n         * // txt consists of a string of the form\r\n         * // data:image/svg+xml;base64,PHN2Zy. base64 encoded SVG..+PC9zdmc+\r\n         * // Behind the comma, there is the base64 encoded SVG code\r\n         * // which is decoded with atob().\r\n         * // The call of decodeURIComponent(escape(...)) is necessary\r\n         * // to handle unicode strings correctly.\r\n         * var ar = txt.split(',');\r\n         * document.getElementById('output').value = decodeURIComponent(escape(atob(ar[1])));\r\n         *\r\n         * </pre><div id=\"JXG1bad4bec-6d08-4ce0-9b7f-d817e8dd762d\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <textarea id=\"output2023\" rows=\"5\" cols=\"50\"></textarea>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG1bad4bec-6d08-4ce0-9b7f-d817e8dd762d',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var A = board.create('point', [2, 2]);\r\n         *\r\n         *     var txt = board.renderer.dumpToDataURI(false);\r\n         *     // txt consists of a string of the form\r\n         *     // data:image/svg+xml;base64,PHN2Zy. base64 encoded SVG..+PC9zdmc+\r\n         *     // Behind the comma, there is the base64 encoded SVG code\r\n         *     // which is decoded with atob().\r\n         *     // The call of decodeURIComponent(escape(...)) is necessary\r\n         *     // to handle unicode strings correctly.\r\n         *     var ar = txt.split(',');\r\n         *     document.getElementById('output2023').value = decodeURIComponent(escape(atob(ar[1])));\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        dumpToDataURI: function (ignoreTexts) {\r\n            var svgRoot = this.svgRoot,\r\n                btoa = window.btoa || Base64.encode,\r\n                svg, i, len,\r\n                values = [];\r\n\r\n            // Move all HTML tags (beside the SVG root) of the container\r\n            // to the foreignObject element inside of the svgRoot node\r\n            // Problem:\r\n            // input values are not copied. This can be verified by looking at an innerHTML output\r\n            // of an input element. Therefore, we do it \"by hand\".\r\n            if (this.container.hasChildNodes() && Type.exists(this.foreignObjLayer)) {\r\n                if (!ignoreTexts) {\r\n                    this.foreignObjLayer.setAttribute(\"display\", 'inline');\r\n                }\r\n                while (svgRoot.nextSibling) {\r\n                    // Copy all value attributes\r\n                    Type.concat(values, this._getValuesOfDOMElements(svgRoot.nextSibling));\r\n                    this.foreignObjLayer.appendChild(svgRoot.nextSibling);\r\n                }\r\n            }\r\n\r\n            this._getImgDataURL(svgRoot);\r\n\r\n            // Convert the SVG graphic into a string containing SVG code\r\n            svgRoot.setAttribute(\"xmlns\", \"http://www.w3.org/2000/svg\");\r\n            svg = new XMLSerializer().serializeToString(svgRoot);\r\n\r\n            if (ignoreTexts !== true) {\r\n                // Handle SVG texts\r\n                // Insert all value attributes back into the svg string\r\n                len = values.length;\r\n                for (i = 0; i < len; i++) {\r\n                    svg = svg.replace(\r\n                        'id=\"' + values[i][0] + '\"',\r\n                        'id=\"' + values[i][0] + '\" value=\"' + values[i][1] + '\"'\r\n                    );\r\n                }\r\n            }\r\n\r\n            // if (false) {\r\n            //     // Debug: use example svg image\r\n            //     svg = '<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.0\" width=\"220\" height=\"220\"><rect width=\"66\" height=\"30\" x=\"21\" y=\"32\" stroke=\"#204a87\" stroke-width=\"2\" fill=\"none\" /></svg>';\r\n            // }\r\n\r\n            // In IE we have to remove the namespace again.\r\n            // Since 2024 we have to check if the namespace attribute appears twice in one tag, because\r\n            // there might by a svg inside of the svg, e.g. the screenshot icon.\r\n            if (this.isIE &&\r\n                (svg.match(/xmlns=\"http:\\/\\/www.w3.org\\/2000\\/svg\"\\s+xmlns=\"http:\\/\\/www.w3.org\\/2000\\/svg\"/g) || []).length > 1\r\n            ) {\r\n                svg = svg.replace(/xmlns=\"http:\\/\\/www.w3.org\\/2000\\/svg\"\\s+xmlns=\"http:\\/\\/www.w3.org\\/2000\\/svg\"/g, \"\");\r\n            }\r\n\r\n            // Safari fails if the svg string contains a \"&nbsp;\"\r\n            // Obsolete with Safari 12+\r\n            svg = svg.replace(/&nbsp;/g, \" \");\r\n            // Replacing &quot;s might be necessary for older Safari versions\r\n            // svg = svg.replace(/url\\(&quot;(.*)&quot;\\)/g, \"url($1)\"); // Bug: does not replace matching &quot;s\r\n            // svg = svg.replace(/&quot;/g, \"\");\r\n\r\n            // Move all HTML tags back from\r\n            // the foreignObject element to the container\r\n            if (Type.exists(this.foreignObjLayer) && this.foreignObjLayer.hasChildNodes()) {\r\n                // Restore all HTML elements\r\n                while (this.foreignObjLayer.firstChild) {\r\n                    this.container.appendChild(this.foreignObjLayer.firstChild);\r\n                }\r\n                this.foreignObjLayer.setAttribute(\"display\", 'none');\r\n            }\r\n\r\n            return \"data:image/svg+xml;base64,\" + btoa(unescape(encodeURIComponent(svg)));\r\n        },\r\n\r\n        /**\r\n         * Convert the SVG construction into an HTML canvas image.\r\n         * This works for all SVG supporting browsers. Implemented as Promise.\r\n         * <p>\r\n         * Might fail if any text element or foreign object element contains SVG. This\r\n         * is the case e.g. for the default fullscreen symbol.\r\n         * <p>\r\n         * For IE, it is realized as function.\r\n         * It works from version 9, with the exception that HTML texts\r\n         * are ignored on IE. The drawing is done with a delay of\r\n         * 200 ms. Otherwise there would be problems with IE.\r\n         *\r\n         * @param {String} canvasId Id of an HTML canvas element\r\n         * @param {Number} w Width in pixel of the dumped image, i.e. of the canvas tag.\r\n         * @param {Number} h Height in pixel of the dumped image, i.e. of the canvas tag.\r\n         * @param {Boolean} ignoreTexts If true, the foreignObject tag is taken out from the SVG root.\r\n         * This is necessary for older versions of Safari. Default: false\r\n         * @returns {Promise}  Promise object\r\n         *\r\n         * @example\r\n         * \tboard.renderer.dumpToCanvas('canvas').then(function() { console.log('done'); });\r\n         *\r\n         * @example\r\n         *  // IE 11 example:\r\n         * \tboard.renderer.dumpToCanvas('canvas');\r\n         * \tsetTimeout(function() { console.log('done'); }, 400);\r\n         */\r\n        dumpToCanvas: function (canvasId, w, h, ignoreTexts) {\r\n            var svg, tmpImg,\r\n                cv, ctx,\r\n                doc = this.container.ownerDocument;\r\n\r\n            // Prepare the canvas element\r\n            cv = doc.getElementById(canvasId);\r\n\r\n            // Clear the canvas\r\n            /* eslint-disable no-self-assign */\r\n            cv.width = cv.width;\r\n            /* eslint-enable no-self-assign */\r\n\r\n            ctx = cv.getContext('2d');\r\n            if (w !== undefined && h !== undefined) {\r\n                cv.style.width = parseFloat(w) + 'px';\r\n                cv.style.height = parseFloat(h) + 'px';\r\n                // Scale twice the CSS size to make the image crisp\r\n                // cv.setAttribute('width', 2 * parseFloat(wOrg));\r\n                // cv.setAttribute('height', 2 * parseFloat(hOrg));\r\n                // ctx.scale(2 * wOrg / w, 2 * hOrg / h);\r\n                cv.setAttribute(\"width\", parseFloat(w));\r\n                cv.setAttribute(\"height\", parseFloat(h));\r\n            }\r\n\r\n            // Display the SVG string as data-uri in an HTML img.\r\n            /**\r\n             * @type {Image}\r\n             * @ignore\r\n             * {ignore}\r\n             */\r\n            tmpImg = new Image();\r\n            svg = this.dumpToDataURI(ignoreTexts);\r\n            tmpImg.src = svg;\r\n\r\n            // Finally, draw the HTML img in the canvas.\r\n            if (!(\"Promise\" in window)) {\r\n                /**\r\n                 * @function\r\n                 * @ignore\r\n                 */\r\n                tmpImg.onload = function () {\r\n                    // IE needs a pause...\r\n                    // Seems to be broken\r\n                    window.setTimeout(function () {\r\n                        try {\r\n                            ctx.drawImage(tmpImg, 0, 0, w, h);\r\n                        } catch (err) {\r\n                            console.log(\"screenshots not longer supported on IE\");\r\n                        }\r\n                    }, 200);\r\n                };\r\n                return this;\r\n            }\r\n\r\n            return new Promise(function (resolve, reject) {\r\n                try {\r\n                    tmpImg.onload = function () {\r\n                        ctx.drawImage(tmpImg, 0, 0, w, h);\r\n                        resolve();\r\n                    };\r\n                } catch (e) {\r\n                    reject(e);\r\n                }\r\n            });\r\n        },\r\n\r\n        /**\r\n         * Display SVG image in html img-tag which enables\r\n         * easy download for the user.\r\n         *\r\n         * Support:\r\n         * <ul>\r\n         * <li> IE: No\r\n         * <li> Edge: full\r\n         * <li> Firefox: full\r\n         * <li> Chrome: full\r\n         * <li> Safari: full (No text support in versions prior to 12).\r\n         * </ul>\r\n         *\r\n         * @param {JXG.Board} board Link to the board.\r\n         * @param {String} imgId Optional id of an img object. If given and different from the empty string,\r\n         * the screenshot is copied to this img object. The width and height will be set to the values of the\r\n         * JSXGraph container.\r\n         * @param {Boolean} ignoreTexts If set to true, the foreignObject is taken out of the\r\n         *  SVGRoot and texts are not displayed. This is mandatory for Safari. Default: false\r\n         * @return {Object}       the svg renderer object\r\n         */\r\n        screenshot: function (board, imgId, ignoreTexts) {\r\n            var node,\r\n                doc = this.container.ownerDocument,\r\n                parent = this.container.parentNode,\r\n                // cPos,\r\n                // cssTxt,\r\n                canvas, id, img,\r\n                button, buttonText,\r\n                w, h,\r\n                bas = board.attr.screenshot,\r\n                navbar, navbarDisplay, insert,\r\n                newImg = false,\r\n                _copyCanvasToImg,\r\n                isDebug = false;\r\n\r\n            if (this.type === 'no') {\r\n                return this;\r\n            }\r\n\r\n            w = bas.scale * this.container.getBoundingClientRect().width;\r\n            h = bas.scale * this.container.getBoundingClientRect().height;\r\n\r\n            if (imgId === undefined || imgId === \"\") {\r\n                newImg = true;\r\n                img = new Image(); //doc.createElement('img');\r\n                img.style.width = w + 'px';\r\n                img.style.height = h + 'px';\r\n            } else {\r\n                newImg = false;\r\n                img = doc.getElementById(imgId);\r\n            }\r\n            // img.crossOrigin = 'anonymous';\r\n\r\n            // Create div which contains canvas element and close button\r\n            if (newImg) {\r\n                node = doc.createElement('div');\r\n                node.style.cssText = bas.css;\r\n                node.style.width = w + 'px';\r\n                node.style.height = h + 'px';\r\n                node.style.zIndex = this.container.style.zIndex + 120;\r\n\r\n                // Try to position the div exactly over the JSXGraph board\r\n                node.style.position = 'absolute';\r\n                node.style.top = this.container.offsetTop + 'px';\r\n                node.style.left = this.container.offsetLeft + 'px';\r\n            }\r\n\r\n            if (!isDebug) {\r\n                // Create canvas element and add it to the DOM\r\n                // It will be removed after the image has been stored.\r\n                canvas = doc.createElement('canvas');\r\n                id = Math.random().toString(36).slice(2, 7);\r\n                canvas.setAttribute(\"id\", id);\r\n                canvas.setAttribute(\"width\", w);\r\n                canvas.setAttribute(\"height\", h);\r\n                canvas.style.width = w + 'px';\r\n                canvas.style.height = w + 'px';\r\n                canvas.style.display = 'none';\r\n                parent.appendChild(canvas);\r\n            } else {\r\n                // Debug: use canvas element 'jxgbox_canvas' from jsxdev/dump.html\r\n                id = \"jxgbox_canvas\";\r\n                canvas = doc.getElementById(id);\r\n            }\r\n\r\n            if (newImg) {\r\n                // Create close button\r\n                button = doc.createElement('span');\r\n                buttonText = doc.createTextNode(\"\\u2716\");\r\n                button.style.cssText = bas.cssButton;\r\n                button.appendChild(buttonText);\r\n                button.onclick = function () {\r\n                    node.parentNode.removeChild(node);\r\n                };\r\n\r\n                // Add all nodes\r\n                node.appendChild(img);\r\n                node.appendChild(button);\r\n                parent.insertBefore(node, this.container.nextSibling);\r\n            }\r\n\r\n            // Hide navigation bar in board\r\n            navbar = doc.getElementById(this.uniqName('navigationbar'));\r\n            if (Type.exists(navbar)) {\r\n                navbarDisplay = navbar.style.display;\r\n                navbar.style.display = 'none';\r\n                insert = this.removeToInsertLater(navbar);\r\n            }\r\n\r\n            _copyCanvasToImg = function () {\r\n                // Show image in img tag\r\n                img.src = canvas.toDataURL(\"image/png\");\r\n\r\n                // Remove canvas node\r\n                if (!isDebug) {\r\n                    parent.removeChild(canvas);\r\n                }\r\n            };\r\n\r\n            // Create screenshot in image element\r\n            if (\"Promise\" in window) {\r\n                this.dumpToCanvas(id, w, h, ignoreTexts).then(_copyCanvasToImg);\r\n            } else {\r\n                // IE\r\n                this.dumpToCanvas(id, w, h, ignoreTexts);\r\n                window.setTimeout(_copyCanvasToImg, 200);\r\n            }\r\n\r\n            // Reinsert navigation bar in board\r\n            if (Type.exists(navbar)) {\r\n                navbar.style.display = navbarDisplay;\r\n                insert();\r\n            }\r\n\r\n            return this;\r\n        }\r\n    }\r\n);\r\n\r\nexport default JXG.SVGRenderer;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, AMprocessNode: true, MathJax: true, document: true */\r\n/*jslint nomen: true, plusplus: true, newcap:true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport AbstractRenderer from \"./abstract.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Color from \"../utils/color.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Numerics from \"../math/numerics.js\";\r\n\r\n/**\r\n * Uses VML to implement the rendering methods defined in {@link JXG.AbstractRenderer}.\r\n * VML was used in very old Internet Explorer versions upto IE 8.\r\n *\r\n *\r\n * @class JXG.VMLRenderer\r\n * @augments JXG.AbstractRenderer\r\n * @param {Node} container Reference to a DOM node containing the board.\r\n * @see JXG.AbstractRenderer\r\n * @deprecated\r\n */\r\nJXG.VMLRenderer = function (container) {\r\n    this.type = 'vml';\r\n\r\n    this.container = container;\r\n    this.container.style.overflow = 'hidden';\r\n    if (this.container.style.position === \"\") {\r\n        this.container.style.position = 'relative';\r\n    }\r\n    this.container.onselectstart = function () {\r\n        return false;\r\n    };\r\n\r\n    this.resolution = 10; // Paths are drawn with a resolution of this.resolution/pixel.\r\n\r\n    // Add VML includes and namespace\r\n    // Original: IE <=7\r\n    //container.ownerDocument.createStyleSheet().addRule(\"v\\\\:*\", \"behavior: url(#default#VML);\");\r\n    if (!Type.exists(JXG.vmlStylesheet)) {\r\n        container.ownerDocument.namespaces.add(\"jxgvml\", \"urn:schemas-microsoft-com:vml\");\r\n        JXG.vmlStylesheet = this.container.ownerDocument.createStyleSheet();\r\n        JXG.vmlStylesheet.addRule(\".jxgvml\", \"behavior:url(#default#VML)\");\r\n    }\r\n\r\n    try {\r\n        if (!container.ownerDocument.namespaces.jxgvml) {\r\n            container.ownerDocument.namespaces.add(\"jxgvml\", \"urn:schemas-microsoft-com:vml\");\r\n        }\r\n\r\n        this.createNode = function (tagName) {\r\n            return container.ownerDocument.createElement(\r\n                \"<jxgvml:\" + tagName + ' class=\"jxgvml\">'\r\n            );\r\n        };\r\n    } catch (e) {\r\n        this.createNode = function (tagName) {\r\n            return container.ownerDocument.createElement(\r\n                \"<\" + tagName + ' xmlns=\"urn:schemas-microsoft.com:vml\" class=\"jxgvml\">'\r\n            );\r\n        };\r\n    }\r\n\r\n    // dash styles\r\n    this.dashArray = [\r\n        \"Solid\",\r\n        \"1 1\",\r\n        \"ShortDash\",\r\n        \"Dash\",\r\n        \"LongDash\",\r\n        \"ShortDashDot\",\r\n        \"LongDashDot\"\r\n    ];\r\n};\r\n\r\nJXG.VMLRenderer.prototype = new AbstractRenderer();\r\n\r\nJXG.extend(\r\n    JXG.VMLRenderer.prototype,\r\n    /** @lends JXG.VMLRenderer.prototype */ {\r\n        /**\r\n         * Sets attribute <tt>key</tt> of node <tt>node</tt> to <tt>value</tt>.\r\n         * @param {Node} node A DOM node.\r\n         * @param {String} key Name of the attribute.\r\n         * @param {String} val New value of the attribute.\r\n         * @param {Boolean} [iFlag=false] If false, the attribute's name is case insensitive.\r\n         */\r\n        _setAttr: function (node, key, val, iFlag) {\r\n            try {\r\n                if (this.container.ownerDocument.documentMode === 8) {\r\n                    node[key] = val;\r\n                } else {\r\n                    node.setAttribute(key, val, iFlag);\r\n                }\r\n            } catch (e) {\r\n                JXG.debug(\"_setAttr:\" /*node.id*/ + \" \" + key + \" \" + val + \"<br>\\n\");\r\n            }\r\n        },\r\n\r\n        /* ******************************** *\r\n         *  This renderer does not need to\r\n         *  override draw/update* methods\r\n         *  since it provides draw/update*Prim\r\n         *  methods.\r\n         * ******************************** */\r\n\r\n        /* **************************\r\n         *    Lines\r\n         * **************************/\r\n\r\n        // documented in AbstractRenderer\r\n        updateTicks: function (ticks) {\r\n            var i,\r\n                len,\r\n                c,\r\n                x,\r\n                y,\r\n                r = this.resolution,\r\n                tickArr = [];\r\n\r\n            len = ticks.ticks.length;\r\n            for (i = 0; i < len; i++) {\r\n                c = ticks.ticks[i];\r\n                x = c[0];\r\n                y = c[1];\r\n\r\n                if (Type.isNumber(x[0]) && Type.isNumber(x[1])) {\r\n                    tickArr.push(\r\n                        \" m \" +\r\n                            Math.round(r * x[0]) +\r\n                            \", \" +\r\n                            Math.round(r * y[0]) +\r\n                            \" l \" +\r\n                            Math.round(r * x[1]) +\r\n                            \", \" +\r\n                            Math.round(r * y[1]) +\r\n                            \" \"\r\n                    );\r\n                }\r\n            }\r\n\r\n            if (!Type.exists(ticks.rendNode)) {\r\n                ticks.rendNode = this.createPrim(\"path\", ticks.id);\r\n                this.appendChildPrim(ticks.rendNode, ticks.evalVisProp('layer'));\r\n            }\r\n\r\n            this._setAttr(ticks.rendNode, \"stroked\", 'true');\r\n            this._setAttr(\r\n                ticks.rendNode,\r\n                \"strokecolor\",\r\n                ticks.evalVisProp('strokecolor'),\r\n                1\r\n            );\r\n            this._setAttr(\r\n                ticks.rendNode,\r\n                \"strokeweight\",\r\n                ticks.evalVisProp('strokewidth')\r\n            );\r\n            this._setAttr(\r\n                ticks.rendNodeStroke,\r\n                \"opacity\",\r\n                ticks.evalVisProp('strokeopacity') * 100 + \"%\"\r\n            );\r\n            this.updatePathPrim(ticks.rendNode, tickArr, ticks.board);\r\n        },\r\n\r\n        /* **************************\r\n         *    Text related stuff\r\n         * **************************/\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        displayCopyright: function (str, fontsize) {\r\n            var node, t;\r\n\r\n            node = this.createNode('textbox');\r\n            node.style.position = 'absolute';\r\n            this._setAttr(node, \"id\", this.container.id + \"_\" + 'licenseText');\r\n\r\n            node.style.left = 20;\r\n            node.style.top = 2;\r\n            node.style.fontSize = fontsize;\r\n            node.style.color = \"#356AA0\";\r\n            node.style.fontFamily = \"Arial,Helvetica,sans-serif\";\r\n            this._setAttr(node, \"opacity\", \"30%\");\r\n            node.style.filter =\r\n                \"progid:DXImageTransform.Microsoft.Matrix(M11='1.0', sizingMethod='auto expand', enabled = false) progid:DXImageTransform.Microsoft.Alpha(opacity = 30, enabled = true)\";\r\n\r\n            t = this.container.ownerDocument.createTextNode(str);\r\n            node.appendChild(t);\r\n            this.appendChildPrim(node, 0);\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        drawInternalText: function (el) {\r\n            var node;\r\n            node = this.createNode('textbox');\r\n            node.style.position = 'absolute';\r\n            el.rendNodeText = this.container.ownerDocument.createTextNode(\"\");\r\n            node.appendChild(el.rendNodeText);\r\n            this.appendChildPrim(node, 9);\r\n            node.style.filter =\r\n                \"progid:DXImageTransform.Microsoft.Matrix(M11='1.0', sizingMethod='auto expand', enabled = false) progid:DXImageTransform.Microsoft.Alpha(opacity = 100, enabled = false)\";\r\n\r\n            return node;\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        updateInternalText: function (el) {\r\n            var v,\r\n                content = el.plaintext,\r\n                m = this.joinTransforms(el, el.transformations),\r\n                offset = [0, 0],\r\n                maxX,\r\n                maxY,\r\n                minX,\r\n                minY,\r\n                i,\r\n                node = el.rendNode,\r\n                p = [],\r\n                ev_ax = el.getAnchorX(),\r\n                ev_ay = el.getAnchorY();\r\n\r\n            if (!isNaN(el.coords.scrCoords[1] + el.coords.scrCoords[2])) {\r\n                // Horizontal\r\n                if (ev_ax === 'right') {\r\n                    offset[0] = 1;\r\n                } else if (ev_ax === 'middle') {\r\n                    offset[0] = 0.5;\r\n                } // default (ev_ax === 'left') offset[0] = 0;\r\n\r\n                // Vertical\r\n                if (ev_ay === 'bottom') {\r\n                    offset[1] = 1;\r\n                } else if (ev_ay === 'middle') {\r\n                    offset[1] = 0.5;\r\n                } // default (ev_ay === 'top') offset[1] = 0;\r\n\r\n                // Compute maxX, maxY, minX, minY\r\n                p[0] = Mat.matVecMult(m, [\r\n                    1,\r\n                    el.coords.scrCoords[1] - offset[0] * el.size[0],\r\n                    el.coords.scrCoords[2] + (1 - offset[1]) * el.size[1] + this.vOffsetText\r\n                ]);\r\n                p[0][1] /= p[0][0];\r\n                p[0][2] /= p[0][0];\r\n                p[1] = Mat.matVecMult(m, [\r\n                    1,\r\n                    el.coords.scrCoords[1] + (1 - offset[0]) * el.size[0],\r\n                    el.coords.scrCoords[2] + (1 - offset[1]) * el.size[1] + this.vOffsetText\r\n                ]);\r\n                p[1][1] /= p[1][0];\r\n                p[1][2] /= p[1][0];\r\n                p[2] = Mat.matVecMult(m, [\r\n                    1,\r\n                    el.coords.scrCoords[1] + (1 - offset[0]) * el.size[0],\r\n                    el.coords.scrCoords[2] - offset[1] * el.size[1] + this.vOffsetText\r\n                ]);\r\n                p[2][1] /= p[2][0];\r\n                p[2][2] /= p[2][0];\r\n                p[3] = Mat.matVecMult(m, [\r\n                    1,\r\n                    el.coords.scrCoords[1] - offset[0] * el.size[0],\r\n                    el.coords.scrCoords[2] - offset[1] * el.size[1] + this.vOffsetText\r\n                ]);\r\n                p[3][1] /= p[3][0];\r\n                p[3][2] /= p[3][0];\r\n                maxX = p[0][1];\r\n                minX = p[0][1];\r\n                maxY = p[0][2];\r\n                minY = p[0][2];\r\n\r\n                for (i = 1; i < 4; i++) {\r\n                    maxX = Math.max(maxX, p[i][1]);\r\n                    minX = Math.min(minX, p[i][1]);\r\n                    maxY = Math.max(maxY, p[i][2]);\r\n                    minY = Math.min(minY, p[i][2]);\r\n                }\r\n\r\n                // Horizontal\r\n                v =\r\n                    offset[0] === 1\r\n                        ? Math.floor(el.board.canvasWidth - maxX)\r\n                        : Math.floor(minX);\r\n                if (el.visPropOld.left !== ev_ax + v) {\r\n                    if (offset[0] === 1) {\r\n                        el.rendNode.style.right = v + 'px';\r\n                        el.rendNode.style.left = 'auto';\r\n                    } else {\r\n                        el.rendNode.style.left = v + 'px';\r\n                        el.rendNode.style.right = 'auto';\r\n                    }\r\n                    el.visPropOld.left = ev_ax + v;\r\n                }\r\n\r\n                // Vertical\r\n                v =\r\n                    offset[1] === 1\r\n                        ? Math.floor(el.board.canvasHeight - maxY)\r\n                        : Math.floor(minY);\r\n                if (el.visPropOld.top !== ev_ay + v) {\r\n                    if (offset[1] === 1) {\r\n                        el.rendNode.style.bottom = v + 'px';\r\n                        el.rendNode.style.top = 'auto';\r\n                    } else {\r\n                        el.rendNode.style.top = v + 'px';\r\n                        el.rendNode.style.bottom = 'auto';\r\n                    }\r\n                    el.visPropOld.top = ev_ay + v;\r\n                }\r\n            }\r\n\r\n            if (el.htmlStr !== content) {\r\n                el.rendNodeText.data = content;\r\n                el.htmlStr = content;\r\n            }\r\n\r\n            //this.transformRect(el, el.transformations);\r\n            node.filters.item(0).M11 = m[1][1];\r\n            node.filters.item(0).M12 = m[1][2];\r\n            node.filters.item(0).M21 = m[2][1];\r\n            node.filters.item(0).M22 = m[2][2];\r\n            node.filters.item(0).enabled = true;\r\n        },\r\n\r\n        /* **************************\r\n         *    Image related stuff\r\n         * **************************/\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        drawImage: function (el) {\r\n            // IE 8: Bilder ueber data URIs werden bis 32kB unterstuetzt.\r\n            var node;\r\n\r\n            node = this.container.ownerDocument.createElement('img');\r\n            node.style.position = 'absolute';\r\n            this._setAttr(node, \"id\", this.container.id + \"_\" + el.id);\r\n\r\n            this.container.appendChild(node);\r\n            this.appendChildPrim(node, el.evalVisProp('layer'));\r\n\r\n            // Adding the rotation filter. This is always filter item 0:\r\n            // node.filters.item(0), see transformRect\r\n            // Also add the alpha filter. This is always filter item 1\r\n            // node.filters.item(1), see setObjectFillColor and setObjectSTrokeColor\r\n            //node.style.filter = node.style['-ms-filter'] = \"progid:DXImageTransform.Microsoft.Matrix(M11='1.0', sizingMethod='auto expand')\";\r\n            node.style.filter =\r\n                \"progid:DXImageTransform.Microsoft.Matrix(M11='1.0', sizingMethod='auto expand') progid:DXImageTransform.Microsoft.Alpha(opacity = 100, enabled = false)\";\r\n            el.rendNode = node;\r\n            this.updateImage(el);\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        transformRect: function (el, t) {\r\n            var m,\r\n                maxX,\r\n                maxY,\r\n                minX,\r\n                minY,\r\n                i,\r\n                node = el.rendNode,\r\n                p = [],\r\n                len = t.length;\r\n\r\n            if (len > 0) {\r\n                /*\r\n                nt = el.rendNode.style.filter.toString();\r\n                if (!nt.match(/DXImageTransform/)) {\r\n                    node.style.filter = \"progid:DXImageTransform.Microsoft.Matrix(M11='1.0', sizingMethod='auto expand') \" + nt;\r\n                }\r\n                */\r\n\r\n                m = this.joinTransforms(el, t);\r\n                p[0] = Mat.matVecMult(m, el.coords.scrCoords);\r\n                p[0][1] /= p[0][0];\r\n                p[0][2] /= p[0][0];\r\n                p[1] = Mat.matVecMult(m, [\r\n                    1,\r\n                    el.coords.scrCoords[1] + el.size[0],\r\n                    el.coords.scrCoords[2]\r\n                ]);\r\n                p[1][1] /= p[1][0];\r\n                p[1][2] /= p[1][0];\r\n                p[2] = Mat.matVecMult(m, [\r\n                    1,\r\n                    el.coords.scrCoords[1] + el.size[0],\r\n                    el.coords.scrCoords[2] - el.size[1]\r\n                ]);\r\n                p[2][1] /= p[2][0];\r\n                p[2][2] /= p[2][0];\r\n                p[3] = Mat.matVecMult(m, [\r\n                    1,\r\n                    el.coords.scrCoords[1],\r\n                    el.coords.scrCoords[2] - el.size[1]\r\n                ]);\r\n                p[3][1] /= p[3][0];\r\n                p[3][2] /= p[3][0];\r\n                maxX = p[0][1];\r\n                minX = p[0][1];\r\n                maxY = p[0][2];\r\n                minY = p[0][2];\r\n\r\n                for (i = 1; i < 4; i++) {\r\n                    maxX = Math.max(maxX, p[i][1]);\r\n                    minX = Math.min(minX, p[i][1]);\r\n                    maxY = Math.max(maxY, p[i][2]);\r\n                    minY = Math.min(minY, p[i][2]);\r\n                }\r\n                node.style.left = Math.floor(minX) + 'px';\r\n                node.style.top = Math.floor(minY) + 'px';\r\n\r\n                node.filters.item(0).M11 = m[1][1];\r\n                node.filters.item(0).M12 = m[1][2];\r\n                node.filters.item(0).M21 = m[2][1];\r\n                node.filters.item(0).M22 = m[2][2];\r\n                node.filters.item(0).enabled = true;\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updateImageURL: function (el) {\r\n            var url = el.eval(el.url);\r\n\r\n            this._setAttr(el.rendNode, \"src\", url);\r\n        },\r\n\r\n        /* **************************\r\n         * Render primitive objects\r\n         * **************************/\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        appendChildPrim: function (node, level) {\r\n            // For trace nodes\r\n            if (!Type.exists(level)) {\r\n                level = 0;\r\n            }\r\n\r\n            node.style.zIndex = level;\r\n            this.container.appendChild(node);\r\n\r\n            return node;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        appendNodesToElement: function (el, type) {\r\n            if (type === \"shape\" || type === \"path\" || type === 'polygon') {\r\n                el.rendNodePath = this.getElementById(el.id + \"_path\");\r\n            }\r\n            el.rendNodeFill = this.getElementById(el.id + \"_fill\");\r\n            el.rendNodeStroke = this.getElementById(el.id + \"_stroke\");\r\n            el.rendNodeShadow = this.getElementById(el.id + \"_shadow\");\r\n            el.rendNode = this.getElementById(el.id);\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        createPrim: function (type, id) {\r\n            var node,\r\n                pathNode,\r\n                fillNode = this.createNode('fill'),\r\n                strokeNode = this.createNode('stroke'),\r\n                shadowNode = this.createNode('shadow');\r\n\r\n            this._setAttr(fillNode, \"id\", this.container.id + \"_\" + id + \"_fill\");\r\n            this._setAttr(strokeNode, \"id\", this.container.id + \"_\" + id + \"_stroke\");\r\n            this._setAttr(shadowNode, \"id\", this.container.id + \"_\" + id + \"_shadow\");\r\n\r\n            if (type === \"circle\" || type === 'ellipse') {\r\n                node = this.createNode('oval');\r\n                node.appendChild(fillNode);\r\n                node.appendChild(strokeNode);\r\n                node.appendChild(shadowNode);\r\n            } else if (\r\n                type === \"polygon\" ||\r\n                type === \"path\" ||\r\n                type === \"shape\" ||\r\n                type === \"line\"\r\n            ) {\r\n                node = this.createNode('shape');\r\n                node.appendChild(fillNode);\r\n                node.appendChild(strokeNode);\r\n                node.appendChild(shadowNode);\r\n                pathNode = this.createNode('path');\r\n                this._setAttr(pathNode, \"id\", this.container.id + \"_\" + id + \"_path\");\r\n                node.appendChild(pathNode);\r\n            } else {\r\n                node = this.createNode(type);\r\n                node.appendChild(fillNode);\r\n                node.appendChild(strokeNode);\r\n                node.appendChild(shadowNode);\r\n            }\r\n\r\n            node.style.position = 'absolute';\r\n            node.style.left = '0px';\r\n            node.style.top = '0px';\r\n            this._setAttr(node, \"id\", this.container.id + \"_\" + id);\r\n\r\n            return node;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        remove: function (node) {\r\n            if (Type.exists(node)) {\r\n                node.removeNode(true);\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        makeArrows: function (el) {\r\n            var nodeStroke,\r\n                ev_fa = el.evalVisProp('firstarrow'),\r\n                ev_la = el.evalVisProp('lastarrow');\r\n\r\n            if (el.visPropOld.firstarrow === ev_fa && el.visPropOld.lastarrow === ev_la) {\r\n                return;\r\n            }\r\n\r\n            if (ev_fa) {\r\n                nodeStroke = el.rendNodeStroke;\r\n                this._setAttr(nodeStroke, \"startarrow\", 'block');\r\n                this._setAttr(nodeStroke, \"startarrowlength\", 'long');\r\n            } else {\r\n                nodeStroke = el.rendNodeStroke;\r\n                if (Type.exists(nodeStroke)) {\r\n                    this._setAttr(nodeStroke, \"startarrow\", 'none');\r\n                }\r\n            }\r\n\r\n            if (ev_la) {\r\n                nodeStroke = el.rendNodeStroke;\r\n                this._setAttr(nodeStroke, \"id\", this.container.id + \"_\" + el.id + 'stroke');\r\n                this._setAttr(nodeStroke, \"endarrow\", 'block');\r\n                this._setAttr(nodeStroke, \"endarrowlength\", 'long');\r\n            } else {\r\n                nodeStroke = el.rendNodeStroke;\r\n                if (Type.exists(nodeStroke)) {\r\n                    this._setAttr(nodeStroke, \"endarrow\", 'none');\r\n                }\r\n            }\r\n            el.visPropOld.firstarrow = ev_fa;\r\n            el.visPropOld.lastarrow = ev_la;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updateEllipsePrim: function (node, x, y, rx, ry) {\r\n            node.style.left = Math.floor(x - rx) + 'px';\r\n            node.style.top = Math.floor(y - ry) + 'px';\r\n            node.style.width = Math.floor(Math.abs(rx) * 2) + 'px';\r\n            node.style.height = Math.floor(Math.abs(ry) * 2) + 'px';\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updateLinePrim: function (node, p1x, p1y, p2x, p2y, board) {\r\n            var s,\r\n                r = this.resolution;\r\n\r\n            if (!isNaN(p1x + p1y + p2x + p2y)) {\r\n                s = [\r\n                    \"m \",\r\n                    Math.floor(r * p1x),\r\n                    \", \",\r\n                    Math.floor(r * p1y),\r\n                    \" l \",\r\n                    Math.floor(r * p2x),\r\n                    \", \",\r\n                    Math.floor(r * p2y)\r\n                ];\r\n                this.updatePathPrim(node, s, board);\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updatePathPrim: function (node, pointString, board) {\r\n            var x = board.canvasWidth,\r\n                y = board.canvasHeight;\r\n            if (pointString.length <= 0) {\r\n                pointString = [\"m 0,0\"];\r\n            }\r\n            node.style.width = x;\r\n            node.style.height = y;\r\n            this._setAttr(\r\n                node,\r\n                \"coordsize\",\r\n                [Math.floor(this.resolution * x), Math.floor(this.resolution * y)].join(\",\")\r\n            );\r\n            this._setAttr(node, \"path\", pointString.join(\"\"));\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updatePathStringPoint: function (el, size, type) {\r\n            var s = [],\r\n                mround = Math.round,\r\n                scr = el.coords.scrCoords,\r\n                sqrt32 = size * Math.sqrt(3) * 0.5,\r\n                s05 = size * 0.5,\r\n                r = this.resolution;\r\n\r\n            if (type === 'x') {\r\n                s.push(\r\n                    [\r\n                        \" m \",\r\n                        mround(r * (scr[1] - size)),\r\n                        \", \",\r\n                        mround(r * (scr[2] - size)),\r\n                        \" l \",\r\n                        mround(r * (scr[1] + size)),\r\n                        \", \",\r\n                        mround(r * (scr[2] + size)),\r\n                        \" m \",\r\n                        mround(r * (scr[1] + size)),\r\n                        \", \",\r\n                        mround(r * (scr[2] - size)),\r\n                        \" l \",\r\n                        mround(r * (scr[1] - size)),\r\n                        \", \",\r\n                        mround(r * (scr[2] + size))\r\n                    ].join(\"\")\r\n                );\r\n            } else if (type === \"+\") {\r\n                s.push(\r\n                    [\r\n                        \" m \",\r\n                        mround(r * (scr[1] - size)),\r\n                        \", \",\r\n                        mround(r * scr[2]),\r\n                        \" l \",\r\n                        mround(r * (scr[1] + size)),\r\n                        \", \",\r\n                        mround(r * scr[2]),\r\n                        \" m \",\r\n                        mround(r * scr[1]),\r\n                        \", \",\r\n                        mround(r * (scr[2] - size)),\r\n                        \" l \",\r\n                        mround(r * scr[1]),\r\n                        \", \",\r\n                        mround(r * (scr[2] + size))\r\n                    ].join(\"\")\r\n                );\r\n            } else if (type === \"<>\" || type === \"<<>>\") {\r\n                if (type === \"<<>>\") {\r\n                    size *= 1.41;\r\n                }\r\n                s.push(\r\n                    [\r\n                        \" m \",\r\n                        mround(r * (scr[1] - size)),\r\n                        \", \",\r\n                        mround(r * scr[2]),\r\n                        \" l \",\r\n                        mround(r * scr[1]),\r\n                        \", \",\r\n                        mround(r * (scr[2] + size)),\r\n                        \" l \",\r\n                        mround(r * (scr[1] + size)),\r\n                        \", \",\r\n                        mround(r * scr[2]),\r\n                        \" l \",\r\n                        mround(r * scr[1]),\r\n                        \", \",\r\n                        mround(r * (scr[2] - size)),\r\n                        \" x e \"\r\n                    ].join(\"\")\r\n                );\r\n            } else if (type === \"^\") {\r\n                s.push(\r\n                    [\r\n                        \" m \",\r\n                        mround(r * scr[1]),\r\n                        \", \",\r\n                        mround(r * (scr[2] - size)),\r\n                        \" l \",\r\n                        mround(r * (scr[1] - sqrt32)),\r\n                        \", \",\r\n                        mround(r * (scr[2] + s05)),\r\n                        \" l \",\r\n                        mround(r * (scr[1] + sqrt32)),\r\n                        \", \",\r\n                        mround(r * (scr[2] + s05)),\r\n                        \" x e \"\r\n                    ].join(\"\")\r\n                );\r\n            } else if (type === 'v') {\r\n                s.push(\r\n                    [\r\n                        \" m \",\r\n                        mround(r * scr[1]),\r\n                        \", \",\r\n                        mround(r * (scr[2] + size)),\r\n                        \" l \",\r\n                        mround(r * (scr[1] - sqrt32)),\r\n                        \", \",\r\n                        mround(r * (scr[2] - s05)),\r\n                        \" l \",\r\n                        mround(r * (scr[1] + sqrt32)),\r\n                        \", \",\r\n                        mround(r * (scr[2] - s05)),\r\n                        \" x e \"\r\n                    ].join(\"\")\r\n                );\r\n            } else if (type === \">\") {\r\n                s.push(\r\n                    [\r\n                        \" m \",\r\n                        mround(r * (scr[1] + size)),\r\n                        \", \",\r\n                        mround(r * scr[2]),\r\n                        \" l \",\r\n                        mround(r * (scr[1] - s05)),\r\n                        \", \",\r\n                        mround(r * (scr[2] - sqrt32)),\r\n                        \" l \",\r\n                        mround(r * (scr[1] - s05)),\r\n                        \", \",\r\n                        mround(r * (scr[2] + sqrt32)),\r\n                        \" l \",\r\n                        mround(r * (scr[1] + size)),\r\n                        \", \",\r\n                        mround(r * scr[2])\r\n                    ].join(\"\")\r\n                );\r\n            } else if (type === \"<\") {\r\n                s.push(\r\n                    [\r\n                        \" m \",\r\n                        mround(r * (scr[1] - size)),\r\n                        \", \",\r\n                        mround(r * scr[2]),\r\n                        \" l \",\r\n                        mround(r * (scr[1] + s05)),\r\n                        \", \",\r\n                        mround(r * (scr[2] - sqrt32)),\r\n                        \" l \",\r\n                        mround(r * (scr[1] + s05)),\r\n                        \", \",\r\n                        mround(r * (scr[2] + sqrt32)),\r\n                        \" x e \"\r\n                    ].join(\"\")\r\n                );\r\n            }\r\n\r\n            return s;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updatePathStringPrim: function (el) {\r\n            var i,\r\n                scr,\r\n                pStr = [],\r\n                r = this.resolution,\r\n                mround = Math.round,\r\n                symbm = \" m \",\r\n                symbl = \" l \",\r\n                symbc = \" c \",\r\n                nextSymb = symbm,\r\n                len = Math.min(el.numberPoints, 8192); // otherwise IE 7 crashes in hilbert.html\r\n\r\n            if (el.numberPoints <= 0) {\r\n                return \"\";\r\n            }\r\n            len = Math.min(len, el.points.length);\r\n\r\n            if (el.bezierDegree === 1) {\r\n                /*\r\n                if (isNotPlot && el.board.options.curve.RDPsmoothing) {\r\n                    el.points = Numerics.RamerDouglasPeucker(el.points, 1.0);\r\n                }\r\n                */\r\n\r\n                for (i = 0; i < len; i++) {\r\n                    scr = el.points[i].scrCoords;\r\n                    if (isNaN(scr[1]) || isNaN(scr[2])) {\r\n                        // PenUp\r\n                        nextSymb = symbm;\r\n                    } else {\r\n                        // IE has problems with values  being too far away.\r\n                        if (scr[1] > 20000.0) {\r\n                            scr[1] = 20000.0;\r\n                        } else if (scr[1] < -20000.0) {\r\n                            scr[1] = -20000.0;\r\n                        }\r\n\r\n                        if (scr[2] > 20000.0) {\r\n                            scr[2] = 20000.0;\r\n                        } else if (scr[2] < -20000.0) {\r\n                            scr[2] = -20000.0;\r\n                        }\r\n\r\n                        pStr.push(\r\n                            [nextSymb, mround(r * scr[1]), \", \", mround(r * scr[2])].join(\"\")\r\n                        );\r\n                        nextSymb = symbl;\r\n                    }\r\n                }\r\n            } else if (el.bezierDegree === 3) {\r\n                i = 0;\r\n                while (i < len) {\r\n                    scr = el.points[i].scrCoords;\r\n                    if (isNaN(scr[1]) || isNaN(scr[2])) {\r\n                        // PenUp\r\n                        nextSymb = symbm;\r\n                    } else {\r\n                        pStr.push(\r\n                            [nextSymb, mround(r * scr[1]), \", \", mround(r * scr[2])].join(\"\")\r\n                        );\r\n                        if (nextSymb === symbc) {\r\n                            i += 1;\r\n                            scr = el.points[i].scrCoords;\r\n                            pStr.push(\r\n                                [\" \", mround(r * scr[1]), \", \", mround(r * scr[2])].join(\"\")\r\n                            );\r\n                            i += 1;\r\n                            scr = el.points[i].scrCoords;\r\n                            pStr.push(\r\n                                [\" \", mround(r * scr[1]), \", \", mround(r * scr[2])].join(\"\")\r\n                            );\r\n                        }\r\n                        nextSymb = symbc;\r\n                    }\r\n                    i += 1;\r\n                }\r\n            }\r\n            pStr.push(\" e\");\r\n            return pStr;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updatePathStringBezierPrim: function (el) {\r\n            var i,\r\n                j,\r\n                k,\r\n                scr,\r\n                lx,\r\n                ly,\r\n                pStr = [],\r\n                f = el.evalVisProp('strokewidth'),\r\n                r = this.resolution,\r\n                mround = Math.round,\r\n                symbm = \" m \",\r\n                symbl = \" c \",\r\n                nextSymb = symbm,\r\n                isNoPlot = el.evalVisProp('curvetype') !== \"plot\",\r\n                len = Math.min(el.numberPoints, 8192); // otherwise IE 7 crashes in hilbert.html\r\n\r\n            if (el.numberPoints <= 0) {\r\n                return \"\";\r\n            }\r\n            if (isNoPlot && el.board.options.curve.RDPsmoothing) {\r\n                el.points = Numerics.RamerDouglasPeucker(el.points, 1.0);\r\n            }\r\n            len = Math.min(len, el.points.length);\r\n\r\n            for (j = 1; j < 3; j++) {\r\n                nextSymb = symbm;\r\n                for (i = 0; i < len; i++) {\r\n                    scr = el.points[i].scrCoords;\r\n                    if (isNaN(scr[1]) || isNaN(scr[2])) {\r\n                        // PenUp\r\n                        nextSymb = symbm;\r\n                    } else {\r\n                        // IE has problems with values  being too far away.\r\n                        if (scr[1] > 20000.0) {\r\n                            scr[1] = 20000.0;\r\n                        } else if (scr[1] < -20000.0) {\r\n                            scr[1] = -20000.0;\r\n                        }\r\n\r\n                        if (scr[2] > 20000.0) {\r\n                            scr[2] = 20000.0;\r\n                        } else if (scr[2] < -20000.0) {\r\n                            scr[2] = -20000.0;\r\n                        }\r\n\r\n                        if (nextSymb === symbm) {\r\n                            pStr.push(\r\n                                [nextSymb, mround(r * scr[1]), \" \", mround(r * scr[2])].join(\"\")\r\n                            );\r\n                        } else {\r\n                            k = 2 * j;\r\n                            pStr.push(\r\n                                [\r\n                                    nextSymb,\r\n                                    mround(\r\n                                        r *\r\n                                            (lx +\r\n                                                (scr[1] - lx) * 0.333 +\r\n                                                f * (k * Math.random() - j))\r\n                                    ),\r\n                                    \" \",\r\n                                    mround(\r\n                                        r *\r\n                                            (ly +\r\n                                                (scr[2] - ly) * 0.333 +\r\n                                                f * (k * Math.random() - j))\r\n                                    ),\r\n                                    \" \",\r\n                                    mround(\r\n                                        r *\r\n                                            (lx +\r\n                                                (scr[1] - lx) * 0.666 +\r\n                                                f * (k * Math.random() - j))\r\n                                    ),\r\n                                    \" \",\r\n                                    mround(\r\n                                        r *\r\n                                            (ly +\r\n                                                (scr[2] - ly) * 0.666 +\r\n                                                f * (k * Math.random() - j))\r\n                                    ),\r\n                                    \" \",\r\n                                    mround(r * scr[1]),\r\n                                    \" \",\r\n                                    mround(r * scr[2])\r\n                                ].join(\"\")\r\n                            );\r\n                        }\r\n                        nextSymb = symbl;\r\n                        lx = scr[1];\r\n                        ly = scr[2];\r\n                    }\r\n                }\r\n            }\r\n            pStr.push(\" e\");\r\n            return pStr;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updatePolygonPrim: function (node, el) {\r\n            var i,\r\n                len = el.vertices.length,\r\n                r = this.resolution,\r\n                scr,\r\n                pStr = [];\r\n\r\n            this._setAttr(node, \"stroked\", 'false');\r\n            scr = el.vertices[0].coords.scrCoords;\r\n\r\n            if (isNaN(scr[1] + scr[2])) {\r\n                return;\r\n            }\r\n\r\n            pStr.push(\r\n                [\"m \", Math.floor(r * scr[1]), \",\", Math.floor(r * scr[2]), \" l \"].join(\"\")\r\n            );\r\n\r\n            for (i = 1; i < len - 1; i++) {\r\n                if (el.vertices[i].isReal) {\r\n                    scr = el.vertices[i].coords.scrCoords;\r\n\r\n                    if (isNaN(scr[1] + scr[2])) {\r\n                        return;\r\n                    }\r\n\r\n                    pStr.push(Math.floor(r * scr[1]) + \",\" + Math.floor(r * scr[2]));\r\n                } else {\r\n                    this.updatePathPrim(node, \"\", el.board);\r\n                    return;\r\n                }\r\n                if (i < len - 2) {\r\n                    pStr.push(\", \");\r\n                }\r\n            }\r\n            pStr.push(\" x e\");\r\n            this.updatePathPrim(node, pStr, el.board);\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updateRectPrim: function (node, x, y, w, h) {\r\n            node.style.left = Math.floor(x) + 'px';\r\n            node.style.top = Math.floor(y) + 'px';\r\n\r\n            if (w >= 0) {\r\n                node.style.width = w + 'px';\r\n            }\r\n\r\n            if (h >= 0) {\r\n                node.style.height = h + 'px';\r\n            }\r\n        },\r\n\r\n        /* **************************\r\n         *  Set Attributes\r\n         * **************************/\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        setPropertyPrim: function (node, key, val) {\r\n            var keyVml = \"\",\r\n                v;\r\n\r\n            switch (key) {\r\n                case \"stroke\":\r\n                    keyVml = 'strokecolor';\r\n                    break;\r\n                case \"stroke-width\":\r\n                    keyVml = 'strokeweight';\r\n                    break;\r\n                case \"stroke-dasharray\":\r\n                    keyVml = 'dashstyle';\r\n                    break;\r\n            }\r\n\r\n            if (keyVml !== \"\") {\r\n                v = val;\r\n                this._setAttr(node, keyVml, v);\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        display: function (el, val) {\r\n            if (el && el.rendNode) {\r\n                el.visPropOld.visible = val;\r\n                if (val) {\r\n                    el.rendNode.style.visibility = 'inherit';\r\n                } else {\r\n                    el.rendNode.style.visibility = 'hidden';\r\n                }\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        show: function (el) {\r\n            JXG.deprecated(\"Board.renderer.show()\", \"Board.renderer.display()\");\r\n\r\n            if (el && el.rendNode) {\r\n                el.rendNode.style.visibility = 'inherit';\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        hide: function (el) {\r\n            JXG.deprecated(\"Board.renderer.hide()\", \"Board.renderer.display()\");\r\n\r\n            if (el && el.rendNode) {\r\n                el.rendNode.style.visibility = 'hidden';\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        setDashStyle: function (el, visProp) {\r\n            var node;\r\n            if (visProp.dash >= 0) {\r\n                node = el.rendNodeStroke;\r\n                this._setAttr(node, \"dashstyle\", this.dashArray[visProp.dash]);\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        setGradient: function (el) {\r\n            var nodeFill = el.rendNodeFill,\r\n                ev_g = el.evalVisProp('gradient');\r\n\r\n            if (ev_g === 'linear') {\r\n                this._setAttr(nodeFill, \"type\", 'gradient');\r\n                this._setAttr(\r\n                    nodeFill,\r\n                    \"color2\",\r\n                    el.evalVisProp('gradientsecondcolor')\r\n                );\r\n                this._setAttr(\r\n                    nodeFill,\r\n                    \"opacity2\",\r\n                    el.evalVisProp('gradientsecondopacity')\r\n                );\r\n                this._setAttr(nodeFill, \"angle\", el.evalVisProp('gradientangle'));\r\n            } else if (ev_g === 'radial') {\r\n                this._setAttr(nodeFill, \"type\", 'gradientradial');\r\n                this._setAttr(\r\n                    nodeFill,\r\n                    \"color2\",\r\n                    el.evalVisProp('gradientsecondcolor')\r\n                );\r\n                this._setAttr(\r\n                    nodeFill,\r\n                    \"opacity2\",\r\n                    el.evalVisProp('gradientsecondopacity')\r\n                );\r\n                this._setAttr(\r\n                    nodeFill,\r\n                    \"focusposition\",\r\n                    el.evalVisProp('gradientpositionx') * 100 +\r\n                        \"%,\" +\r\n                        el.evalVisProp('gradientpositiony') * 100 +\r\n                        \"%\"\r\n                );\r\n                this._setAttr(nodeFill, \"focussize\", \"0,0\");\r\n            } else {\r\n                this._setAttr(nodeFill, \"type\", 'solid');\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        setObjectFillColor: function (el, color, opacity) {\r\n            var rgba = color,\r\n                c,\r\n                rgbo,\r\n                o = opacity,\r\n                oo,\r\n                node = el.rendNode;\r\n\r\n            o = o > 0 ? o : 0;\r\n\r\n            if (el.visPropOld.fillcolor === rgba && el.visPropOld.fillopacity === o) {\r\n                return;\r\n            }\r\n\r\n            if (Type.exists(rgba) && rgba !== false) {\r\n                // RGB, not RGBA\r\n                if (rgba.length !== 9) {\r\n                    c = rgba;\r\n                    oo = o;\r\n                    // True RGBA, not RGB\r\n                } else {\r\n                    rgbo = Color.rgba2rgbo(rgba);\r\n                    c = rgbo[0];\r\n                    oo = o * rgbo[1];\r\n                }\r\n                if (c === \"none\" || c === false) {\r\n                    this._setAttr(el.rendNode, \"filled\", 'false');\r\n                } else {\r\n                    this._setAttr(el.rendNode, \"filled\", 'true');\r\n                    this._setAttr(el.rendNode, \"fillcolor\", c);\r\n\r\n                    if (Type.exists(oo) && el.rendNodeFill) {\r\n                        this._setAttr(el.rendNodeFill, \"opacity\", oo * 100 + \"%\");\r\n                    }\r\n                }\r\n                if (el.type === Const.OBJECT_TYPE_IMAGE) {\r\n                    /*\r\n                    t = el.rendNode.style.filter.toString();\r\n                    if (t.match(/alpha/)) {\r\n                        el.rendNode.style.filter = t.replace(/alpha\\(opacity *= *[0-9\\.]+\\)/, 'alpha(opacity = ' + (oo * 100) + ')');\r\n                    } else {\r\n                        el.rendNode.style.filter += ' alpha(opacity = ' + (oo * 100) + ')';\r\n                    }\r\n                    */\r\n                    if (node.filters.length > 1) {\r\n                        // Why am I sometimes seeing node.filters.length==0 here when I move the pointer around near [0,0]?\r\n                        // Setting axes:true shows text labels!\r\n                        node.filters.item(1).opacity = Math.round(oo * 100); // Why does setObjectFillColor not use Math.round?\r\n                        node.filters.item(1).enabled = true;\r\n                    }\r\n                }\r\n            }\r\n            el.visPropOld.fillcolor = rgba;\r\n            el.visPropOld.fillopacity = o;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        setObjectStrokeColor: function (el, color, opacity) {\r\n            var rgba = color,\r\n                c,\r\n                rgbo,\r\n                o = opacity,\r\n                oo,\r\n                node = el.rendNode,\r\n                nodeStroke;\r\n\r\n            o = o > 0 ? o : 0;\r\n\r\n            if (el.visPropOld.strokecolor === rgba && el.visPropOld.strokeopacity === o) {\r\n                return;\r\n            }\r\n\r\n            // this looks like it could be merged with parts of VMLRenderer.setObjectFillColor\r\n\r\n            if (Type.exists(rgba) && rgba !== false) {\r\n                // RGB, not RGBA\r\n                if (rgba.length !== 9) {\r\n                    c = rgba;\r\n                    oo = o;\r\n                    // True RGBA, not RGB\r\n                } else {\r\n                    rgbo = color.rgba2rgbo(rgba);\r\n                    c = rgbo[0];\r\n                    oo = o * rgbo[1];\r\n                }\r\n                if (el.elementClass === Const.OBJECT_CLASS_TEXT) {\r\n                    //node.style.filter = ' alpha(opacity = ' + oo + ')';\r\n                    /*\r\n                    t = node.style.filter.toString();\r\n                    if (t.match(/alpha/)) {\r\n                        node.style.filter =\r\n                        t.replace(/alpha\\(opacity *= *[0-9\\.]+\\)/, 'alpha(opacity = ' + oo + ')');\r\n                    } else {\r\n                        node.style.filter += ' alpha(opacity = ' + oo + ')';\r\n                    }\r\n                    */\r\n                    if (node.filters.length > 1) {\r\n                        // Why am I sometimes seeing node.filters.length==0 here when I move the pointer around near [0,0]?\r\n                        // Setting axes:true shows text labels!\r\n                        node.filters.item(1).opacity = Math.round(oo * 100);\r\n                        node.filters.item(1).enabled = true;\r\n                    }\r\n\r\n                    node.style.color = c;\r\n                } else {\r\n                    if (c !== false) {\r\n                        this._setAttr(node, \"stroked\", 'true');\r\n                        this._setAttr(node, \"strokecolor\", c);\r\n                    }\r\n\r\n                    nodeStroke = el.rendNodeStroke;\r\n                    if (Type.exists(oo) && el.type !== Const.OBJECT_TYPE_IMAGE) {\r\n                        this._setAttr(nodeStroke, \"opacity\", oo * 100 + \"%\");\r\n                    }\r\n                }\r\n            }\r\n            el.visPropOld.strokecolor = rgba;\r\n            el.visPropOld.strokeopacity = o;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        setObjectStrokeWidth: function (el, width) {\r\n            var w = Type.evaluate(width),\r\n                node;\r\n\r\n            if (isNaN(w) || el.visPropOld.strokewidth === w) {\r\n                return;\r\n            }\r\n\r\n            node = el.rendNode;\r\n            this.setPropertyPrim(node, \"stroked\", 'true');\r\n\r\n            if (Type.exists(w)) {\r\n                this.setPropertyPrim(node, \"stroke-width\", w);\r\n                if (w === 0 && Type.exists(el.rendNodeStroke)) {\r\n                    this._setAttr(node, \"stroked\", 'false');\r\n                }\r\n            }\r\n\r\n            el.visPropOld.strokewidth = w;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        setShadow: function (el) {\r\n            var nodeShadow = el.rendNodeShadow,\r\n                ev_s = el.evalVisProp('shadow');\r\n\r\n            if (!nodeShadow || el.visPropOld.shadow === ev_s) {\r\n                return;\r\n            }\r\n\r\n            if (ev_s) {\r\n                this._setAttr(nodeShadow, \"On\", 'True');\r\n                this._setAttr(nodeShadow, \"Offset\", \"3pt,3pt\");\r\n                this._setAttr(nodeShadow, \"Opacity\", \"60%\");\r\n                this._setAttr(nodeShadow, \"Color\", \"#aaaaaa\");\r\n            } else {\r\n                this._setAttr(nodeShadow, \"On\", 'False');\r\n            }\r\n\r\n            el.visPropOld.shadow = ev_s;\r\n        },\r\n\r\n        /* **************************\r\n         * renderer control\r\n         * **************************/\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        suspendRedraw: function () {\r\n            this.container.style.display = 'none';\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        unsuspendRedraw: function () {\r\n            this.container.style.display = \"\";\r\n        }\r\n    }\r\n);\r\n\r\nexport default JXG.VMLRenderer;\r\n","/**\r\n * Generate a random uuid.\r\n * Written by https://www.broofa.com (robert@broofa.com)\r\n *\r\n * Copyright (c) 2010 Robert Kieffer\r\n * Dual licensed under the MIT and GPL licenses.\r\n * @returns {String}\r\n * @example\r\n *   var uuid = JXG.Util.genUUID();\r\n *   > uuid = '92329D39-6F5C-4520-ABFC-AAB64544E172'\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true, bitwise: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\n\r\n// constants\r\nvar uuidCharsStr = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\",\r\n    uuidChars = uuidCharsStr.split(\"\");\r\n\r\n/**\r\n * General utility routines\r\n * @namespace\r\n */\r\nJXG.Util = JXG.Util || {};\r\n\r\nJXG.Util.genUUID = function (prefix) {\r\n    var r,\r\n        i,\r\n        uuid = [],\r\n        rnd = 0;\r\n\r\n    prefix = prefix || \"\";\r\n\r\n    if (prefix !== \"\" && prefix.slice(prefix.length - 1) !== \"-\") {\r\n        prefix = prefix + \"-\";\r\n    }\r\n\r\n    for (i = 0; i < 36; i++) {\r\n        if (i === 8 || i === 13 || i === 18 || i === 23) {\r\n            uuid[i] = \"-\";\r\n        } else if (i === 14) {\r\n            uuid[i] = '4';\r\n        } else {\r\n            if (rnd <= 0x02) {\r\n                rnd = (0x2000000 + Math.random() * 0x1000000) | 0;\r\n            }\r\n\r\n            r = rnd & 0xf;\r\n            rnd = rnd >> 4;\r\n            uuid[i] = uuidChars[i === 19 ? (r & 0x3) | 0x8 : r];\r\n        }\r\n    }\r\n\r\n    return prefix + uuid.join(\"\");\r\n};\r\n\r\nexport default JXG.Util;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, AMprocessNode: true, document: true, Image: true, module: true, require: true */\r\n/*jslint nomen: true, plusplus: true, newcap:true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport AbstractRenderer from \"./abstract.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Env from \"../utils/env.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport UUID from \"../utils/uuid.js\";\r\nimport Color from \"../utils/color.js\";\r\nimport Coords from \"../base/coords.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Numerics from \"../math/numerics.js\";\r\n// import $__canvas from 'canvas.js'\r\n\r\n/**\r\n * Uses HTML Canvas to implement the rendering methods defined in {@link JXG.AbstractRenderer}.\r\n *\r\n * @class JXG.CanvasRenderer\r\n * @augments JXG.AbstractRenderer\r\n * @param {Node} container Reference to a DOM node containing the board.\r\n * @param {Object} dim The dimensions of the board\r\n * @param {Number} dim.width\r\n * @param {Number} dim.height\r\n * @see JXG.AbstractRenderer\r\n */\r\nJXG.CanvasRenderer = function (container, dim) {\r\n    this.type = 'canvas';\r\n\r\n    this.canvasRoot = null;\r\n    this.suspendHandle = null;\r\n    this.canvasId = UUID.genUUID();\r\n\r\n    this.canvasNamespace = null;\r\n\r\n    if (Env.isBrowser) {\r\n        this.container = container;\r\n        this.container.style.MozUserSelect = 'none';\r\n        this.container.style.userSelect = 'none';\r\n\r\n        this.container.style.overflow = 'hidden';\r\n        if (this.container.style.position === \"\") {\r\n            this.container.style.position = 'relative';\r\n        }\r\n\r\n        this.container.innerHTML = [\r\n            '<canvas id=\"', this.canvasId, '\" width=\"', dim.width, 'px\" height=\"', dim.height, 'px\"></canvas>'\r\n        ].join(\"\");\r\n        this.canvasRoot = this.container.ownerDocument.getElementById(this.canvasId);\r\n        this.canvasRoot.style.display = 'block';\r\n        this.context = this.canvasRoot.getContext('2d');\r\n    } else if (Env.isNode()) {\r\n        try {\r\n            this.canvasRoot = JXG.createCanvas(500, 500);\r\n            this.context = this.canvasRoot.getContext('2d');\r\n        } catch (err) {\r\n            throw new Error('JXG.createCanvas not available.\\n' +\r\n                'Install the npm package `canvas`\\n' +\r\n                'and call:\\n' +\r\n                '    import { createCanvas } from \"canvas.js\"\\n' +\r\n                '    JXG.createCanvas = createCanvas;\\n');\r\n        }\r\n    }\r\n};\r\n\r\nJXG.CanvasRenderer.prototype = new AbstractRenderer();\r\n\r\nJXG.extend(\r\n    JXG.CanvasRenderer.prototype,\r\n    /** @lends JXG.CanvasRenderer.prototype */ {\r\n        /* **************************\r\n         *   private methods only used\r\n         *   in this renderer. Should\r\n         *   not be called from outside.\r\n         * **************************/\r\n\r\n        /**\r\n         * Draws a filled polygon.\r\n         * @param {Array} shape A matrix presented by a two dimensional array of numbers.\r\n         * @see JXG.AbstractRenderer#drawArrows\r\n         * @private\r\n         */\r\n        _drawPolygon: function (shape, degree, doFill) {\r\n            var i,\r\n                len = shape.length,\r\n                context = this.context;\r\n\r\n            if (len > 0) {\r\n                if (doFill) {\r\n                    context.lineWidth = 0;\r\n                }\r\n                context.beginPath();\r\n                context.moveTo(shape[0][0], shape[0][1]);\r\n                if (degree === 1) {\r\n                    for (i = 1; i < len; i++) {\r\n                        context.lineTo(shape[i][0], shape[i][1]);\r\n                    }\r\n                } else {\r\n                    for (i = 1; i < len; i += 3) {\r\n                        context.bezierCurveTo(\r\n                            shape[i][0],\r\n                            shape[i][1],\r\n                            shape[i + 1][0],\r\n                            shape[i + 1][1],\r\n                            shape[i + 2][0],\r\n                            shape[i + 2][1]\r\n                        );\r\n                    }\r\n                }\r\n                if (doFill) {\r\n                    context.lineTo(shape[0][0], shape[0][1]);\r\n                    context.closePath();\r\n                    context.fill('evenodd');\r\n                } else {\r\n                    context.stroke();\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Sets the fill color and fills an area.\r\n         * @param {JXG.GeometryElement} el An arbitrary JSXGraph element, preferably one with an area.\r\n         * @private\r\n         */\r\n        _fill: function (el) {\r\n            var context = this.context;\r\n\r\n            context.save();\r\n            if (this._setColor(el, 'fill')) {\r\n                context.fill('evenodd');\r\n            }\r\n            context.restore();\r\n        },\r\n\r\n        /**\r\n         * Rotates a point around <tt>(0, 0)</tt> by a given angle.\r\n         * @param {Number} angle An angle, given in rad.\r\n         * @param {Number} x X coordinate of the point.\r\n         * @param {Number} y Y coordinate of the point.\r\n         * @returns {Array} An array containing the x and y coordinate of the rotated point.\r\n         * @private\r\n         */\r\n        _rotatePoint: function (angle, x, y) {\r\n            return [\r\n                x * Math.cos(angle) - y * Math.sin(angle),\r\n                x * Math.sin(angle) + y * Math.cos(angle)\r\n            ];\r\n        },\r\n\r\n        /**\r\n         * Rotates an array of points around <tt>(0, 0)</tt>.\r\n         * @param {Array} shape An array of array of point coordinates.\r\n         * @param {Number} angle The angle in rad the points are rotated by.\r\n         * @returns {Array} Array of array of two dimensional point coordinates.\r\n         * @private\r\n         */\r\n        _rotateShape: function (shape, angle) {\r\n            var i,\r\n                rv = [],\r\n                len = shape.length;\r\n\r\n            if (len <= 0) {\r\n                return shape;\r\n            }\r\n\r\n            for (i = 0; i < len; i++) {\r\n                rv.push(this._rotatePoint(angle, shape[i][0], shape[i][1]));\r\n            }\r\n\r\n            return rv;\r\n        },\r\n\r\n        /**\r\n         * Set the gradient angle for linear color gradients.\r\n         *\r\n         * @private\r\n         * @param {JXG.GeometryElement} node An arbitrary JSXGraph element, preferably one with an area.\r\n         * @param {Number} radians angle value in radians. 0 is horizontal from left to right, Pi/4 is vertical from top to bottom.\r\n         */\r\n        updateGradientAngle: function (el, radians) {\r\n            // Angles:\r\n            // 0: ->\r\n            // 90: down\r\n            // 180: <-\r\n            // 90: up\r\n            var f = 1.0,\r\n                co = Math.cos(-radians),\r\n                si = Math.sin(-radians),\r\n                bb = el.getBoundingBox(),\r\n                c1, c2,\r\n                x1, x2,\r\n                y1, y2,\r\n                x1s, x2s, y1s, y2s,\r\n                dx, dy;\r\n\r\n            if (Math.abs(co) > Math.abs(si)) {\r\n                f /= Math.abs(co);\r\n            } else {\r\n                f /= Math.abs(si);\r\n            }\r\n            if (co >= 0) {\r\n                x1 = 0;\r\n                x2 = co * f;\r\n            } else {\r\n                x1 = -co * f;\r\n                x2 = 0;\r\n            }\r\n            if (si >= 0) {\r\n                y1 = 0;\r\n                y2 = si * f;\r\n            } else {\r\n                y1 = -si * f;\r\n                y2 = 0;\r\n            }\r\n\r\n            c1 = new Coords(Const.COORDS_BY_USER, [bb[0], bb[1]], el.board);\r\n            c2 = new Coords(Const.COORDS_BY_USER, [bb[2], bb[3]], el.board);\r\n            dx = c2.scrCoords[1] - c1.scrCoords[1];\r\n            dy = c2.scrCoords[2] - c1.scrCoords[2];\r\n\r\n            x1s = c1.scrCoords[1] + dx * x1;\r\n            y1s = c1.scrCoords[2] + dy * y1;\r\n            x2s = c1.scrCoords[1] + dx * x2;\r\n            y2s = c1.scrCoords[2] + dy * y2;\r\n\r\n            return this.context.createLinearGradient(x1s, y1s, x2s, y2s);\r\n        },\r\n\r\n        /**\r\n         * Set circles for radial color gradients.\r\n         *\r\n         * @private\r\n         * @param {SVGnode} node SVG gradient node\r\n         * @param {Number} cx Canvas value x1 (but value between 0 and 1)\r\n         * @param {Number} cy  Canvas value y1 (but value between 0 and 1)\r\n         * @param {Number} r  Canvas value r1 (but value between 0 and 1)\r\n         * @param {Number} fx  Canvas value x0 (but value between 0 and 1)\r\n         * @param {Number} fy  Canvas value x1 (but value between 0 and 1)\r\n         * @param {Number} fr  Canvas value r0 (but value between 0 and 1)\r\n         */\r\n        updateGradientCircle: function (el, cx, cy, r, fx, fy, fr) {\r\n            var bb = el.getBoundingBox(),\r\n                c1, c2,\r\n                cxs, cys, rs,\r\n                fxs, fys, frs,\r\n                dx, dy;\r\n\r\n            c1 = new Coords(Const.COORDS_BY_USER, [bb[0], bb[1]], el.board);\r\n            c2 = new Coords(Const.COORDS_BY_USER, [bb[2], bb[3]], el.board);\r\n            dx = c2.scrCoords[1] - c1.scrCoords[1];\r\n            dy = c1.scrCoords[2] - c2.scrCoords[2];\r\n\r\n            cxs = c1.scrCoords[1] + dx * cx;\r\n            cys = c2.scrCoords[2] + dy * cy;\r\n            fxs = c1.scrCoords[1] + dx * fx;\r\n            fys = c2.scrCoords[2] + dy * fy;\r\n            rs = r * (dx + dy) * 0.5;\r\n            frs = fr * (dx + dy) * 0.5;\r\n\r\n            return this.context.createRadialGradient(fxs, fys, frs, cxs, cys, rs);\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        updateGradient: function (el) {\r\n            var col,\r\n                // op,\r\n                ev_g = el.evalVisProp('gradient'),\r\n                gradient;\r\n\r\n            // op = el.evalVisProp('fillopacity');\r\n            // op = op > 0 ? op : 0;\r\n            col = el.evalVisProp('fillcolor');\r\n\r\n            if (ev_g === 'linear') {\r\n                gradient = this.updateGradientAngle(\r\n                    el,\r\n                    el.evalVisProp('gradientangle')\r\n                );\r\n            } else if (ev_g === 'radial') {\r\n                gradient = this.updateGradientCircle(\r\n                    el,\r\n                    el.evalVisProp('gradientcx'),\r\n                    el.evalVisProp('gradientcy'),\r\n                    el.evalVisProp('gradientr'),\r\n                    el.evalVisProp('gradientfx'),\r\n                    el.evalVisProp('gradientfy'),\r\n                    el.evalVisProp('gradientfr')\r\n                );\r\n            }\r\n\r\n            if (col !== \"none\" && col !== \"\" && col !== false) {\r\n                gradient.addColorStop(el.evalVisProp('gradientstartoffset'), col);\r\n                gradient.addColorStop(\r\n                    el.evalVisProp('gradientendoffset'),\r\n                    el.evalVisProp('gradientsecondcolor')\r\n                );\r\n            }\r\n            return gradient;\r\n        },\r\n\r\n        /**\r\n         * Sets color and opacity for filling and stroking.\r\n         * type is the attribute from visProp and targetType the context[targetTypeStyle].\r\n         * This is necessary, because the fill style of a text is set by the stroke attributes of the text element.\r\n         * @param {JXG.GeometryElement} el Any JSXGraph element.\r\n         * @param {String} [type='stroke'] Either <em>fill</em> or <em>stroke</em>.\r\n         * @param {String} [targetType=type] (optional) Either <em>fill</em> or <em>stroke</em>.\r\n         * @returns {Boolean} If the color could be set, <tt>true</tt> is returned.\r\n         * @private\r\n         */\r\n        _setColor: function (el, type, targetType) {\r\n            var hasColor = true,\r\n                lc, hl, sw,\r\n                rgba, rgbo,\r\n                c, o, oo,\r\n                grad;\r\n\r\n            type = type || 'stroke';\r\n            targetType = targetType || type;\r\n\r\n            hl = this._getHighlighted(el);\r\n\r\n            // type is equal to 'fill' or 'stroke'\r\n            rgba = el.evalVisProp(hl + type + 'color');\r\n            if (rgba !== \"none\" && rgba !== \"\" && rgba !== false) {\r\n                o = el.evalVisProp(hl + type + 'opacity');\r\n                o = o > 0 ? o : 0;\r\n\r\n                if (rgba.length !== 9) {\r\n                    // RGB\r\n                    c = rgba;\r\n                    oo = o;\r\n                    // True RGBA, not RGB\r\n                } else {\r\n                    // RGBA\r\n                    rgbo = Color.rgba2rgbo(rgba);\r\n                    c = rgbo[0];\r\n                    oo = o * rgbo[1];\r\n                }\r\n                this.context.globalAlpha = oo;\r\n\r\n                this.context[targetType + \"Style\"] = c;\r\n            } else {\r\n                hasColor = false;\r\n            }\r\n\r\n            if (type !== 'stroke') {\r\n                // For the time being, gradients are only supported for fills\r\n                grad = el.evalVisProp('gradient');\r\n                if (grad === \"linear\" || grad === 'radial') {\r\n                    this.context.globalAlpha = oo;\r\n                    this.context[targetType + \"Style\"] = this.updateGradient(el);\r\n                    return hasColor;\r\n                }\r\n            }\r\n\r\n            sw = parseFloat(el.evalVisProp(hl + 'strokewidth'));\r\n            if (type === \"stroke\" && !isNaN(sw)) {\r\n                if (sw === 0) {\r\n                    this.context.globalAlpha = 0;\r\n                } else {\r\n                    this.context.lineWidth = sw;\r\n                }\r\n            }\r\n\r\n            lc = el.evalVisProp('linecap');\r\n            if (type === \"stroke\" && lc !== undefined && lc !== \"\") {\r\n                this.context.lineCap = lc;\r\n            }\r\n\r\n            return hasColor;\r\n        },\r\n\r\n        /**\r\n         * Sets color and opacity for drawing paths and lines and draws the paths and lines.\r\n         * @param {JXG.GeometryElement} el An JSXGraph element with a stroke.\r\n         * @private\r\n         */\r\n        _stroke: function (el) {\r\n            var context = this.context,\r\n                ev_dash = el.evalVisProp('dash'),\r\n                ds = el.evalVisProp('dashscale'),\r\n                sw = ds ? 0.5 * el.evalVisProp('strokewidth') : 1;\r\n\r\n            context.save();\r\n\r\n            if (ev_dash > 0) {\r\n                if (context.setLineDash) {\r\n                    context.setLineDash(\r\n                        // sw could distinguish highlighting or not.\r\n                        // But it seems to preferable to ignore this.\r\n                        this.dashArray[ev_dash - 1].map(function (x) { return x * sw; })\r\n                    );\r\n                }\r\n            } else {\r\n                this.context.lineDashArray = [];\r\n            }\r\n\r\n            if (this._setColor(el, 'stroke')) {\r\n                context.stroke();\r\n            }\r\n\r\n            context.restore();\r\n        },\r\n\r\n        /**\r\n         * Translates a set of points.\r\n         * @param {Array} shape An array of point coordinates.\r\n         * @param {Number} x Translation in X direction.\r\n         * @param {Number} y Translation in Y direction.\r\n         * @returns {Array} An array of translated point coordinates.\r\n         * @private\r\n         */\r\n        _translateShape: function (shape, x, y) {\r\n            var i,\r\n                rv = [],\r\n                len = shape.length;\r\n\r\n            if (len <= 0) {\r\n                return shape;\r\n            }\r\n\r\n            for (i = 0; i < len; i++) {\r\n                rv.push([shape[i][0] + x, shape[i][1] + y]);\r\n            }\r\n\r\n            return rv;\r\n        },\r\n\r\n        /* ********* Point related stuff *********** */\r\n\r\n        // documented in AbstractRenderer\r\n        drawPoint: function (el) {\r\n            var f = el.evalVisProp('face'),\r\n                size = el.evalVisProp('size'),\r\n                scr = el.coords.scrCoords,\r\n                sqrt32 = size * Math.sqrt(3) * 0.5,\r\n                s05 = size * 0.5,\r\n                stroke05 = parseFloat(el.evalVisProp('strokewidth')) / 2.0,\r\n                context = this.context;\r\n\r\n            if (!el.visPropCalc.visible) {\r\n                return;\r\n            }\r\n\r\n            switch (f) {\r\n                case \"cross\": // x\r\n                case \"x\":\r\n                    context.beginPath();\r\n                    context.moveTo(scr[1] - size, scr[2] - size);\r\n                    context.lineTo(scr[1] + size, scr[2] + size);\r\n                    context.moveTo(scr[1] + size, scr[2] - size);\r\n                    context.lineTo(scr[1] - size, scr[2] + size);\r\n                    context.lineCap = 'round';\r\n                    context.lineJoin = 'round';\r\n                    context.closePath();\r\n                    this._stroke(el);\r\n                    break;\r\n                case \"circle\": // dot\r\n                case \"o\":\r\n                    context.beginPath();\r\n                    context.arc(scr[1], scr[2], size + 1 + stroke05, 0, 2 * Math.PI, false);\r\n                    context.closePath();\r\n                    this._fill(el);\r\n                    this._stroke(el);\r\n                    break;\r\n                case \"square\": // rectangle\r\n                case \"[]\":\r\n                    if (size <= 0) {\r\n                        break;\r\n                    }\r\n\r\n                    context.save();\r\n                    if (this._setColor(el, \"stroke\", 'fill')) {\r\n                        context.fillRect(\r\n                            scr[1] - size - stroke05,\r\n                            scr[2] - size - stroke05,\r\n                            size * 2 + 3 * stroke05,\r\n                            size * 2 + 3 * stroke05\r\n                        );\r\n                    }\r\n                    context.restore();\r\n                    context.save();\r\n                    this._setColor(el, 'fill');\r\n                    context.fillRect(\r\n                        scr[1] - size + stroke05,\r\n                        scr[2] - size + stroke05,\r\n                        size * 2 - stroke05,\r\n                        size * 2 - stroke05\r\n                    );\r\n                    context.restore();\r\n                    break;\r\n                case \"plus\": // +\r\n                case \"+\":\r\n                    context.beginPath();\r\n                    context.moveTo(scr[1] - size, scr[2]);\r\n                    context.lineTo(scr[1] + size, scr[2]);\r\n                    context.moveTo(scr[1], scr[2] - size);\r\n                    context.lineTo(scr[1], scr[2] + size);\r\n                    context.lineCap = 'round';\r\n                    context.lineJoin = 'round';\r\n                    context.closePath();\r\n                    this._stroke(el);\r\n                    break;\r\n                case \"divide\":\r\n                case \"|\":\r\n                    context.beginPath();\r\n                    context.moveTo(scr[1], scr[2] - size);\r\n                    context.lineTo(scr[1], scr[2] + size);\r\n                    context.lineCap = 'round';\r\n                    context.lineJoin = 'round';\r\n                    context.closePath();\r\n                    this._stroke(el);\r\n                    break;\r\n                case \"minus\":\r\n                case \"-\":\r\n                    context.beginPath();\r\n                    context.moveTo(scr[1] - size, scr[2]);\r\n                    context.lineTo(scr[1] + size, scr[2]);\r\n                    context.lineCap = 'round';\r\n                    context.lineJoin = 'round';\r\n                    context.closePath();\r\n                    this._stroke(el);\r\n                    break;\r\n                /* eslint-disable no-fallthrough */\r\n                case \"diamond2\":\r\n                case \"<<>>\":\r\n                    size *= 1.41;\r\n                case \"diamond\": // <>\r\n                case \"<>\":\r\n                    context.beginPath();\r\n                    context.moveTo(scr[1] - size, scr[2]);\r\n                    context.lineTo(scr[1], scr[2] + size);\r\n                    context.lineTo(scr[1] + size, scr[2]);\r\n                    context.lineTo(scr[1], scr[2] - size);\r\n                    context.closePath();\r\n                    this._fill(el);\r\n                    this._stroke(el);\r\n                    break;\r\n                /* eslint-enable no-fallthrough */\r\n                case \"triangleup\":\r\n                case \"A\":\r\n                case \"a\":\r\n                case \"^\":\r\n                    context.beginPath();\r\n                    context.moveTo(scr[1], scr[2] - size);\r\n                    context.lineTo(scr[1] - sqrt32, scr[2] + s05);\r\n                    context.lineTo(scr[1] + sqrt32, scr[2] + s05);\r\n                    context.closePath();\r\n                    this._fill(el);\r\n                    this._stroke(el);\r\n                    break;\r\n                case \"triangledown\":\r\n                case \"v\":\r\n                    context.beginPath();\r\n                    context.moveTo(scr[1], scr[2] + size);\r\n                    context.lineTo(scr[1] - sqrt32, scr[2] - s05);\r\n                    context.lineTo(scr[1] + sqrt32, scr[2] - s05);\r\n                    context.closePath();\r\n                    this._fill(el);\r\n                    this._stroke(el);\r\n                    break;\r\n                case \"triangleleft\":\r\n                case \"<\":\r\n                    context.beginPath();\r\n                    context.moveTo(scr[1] - size, scr[2]);\r\n                    context.lineTo(scr[1] + s05, scr[2] - sqrt32);\r\n                    context.lineTo(scr[1] + s05, scr[2] + sqrt32);\r\n                    context.closePath();\r\n                    this._fill(el);\r\n                    this._stroke(el);\r\n                    break;\r\n                case \"triangleright\":\r\n                case \">\":\r\n                    context.beginPath();\r\n                    context.moveTo(scr[1] + size, scr[2]);\r\n                    context.lineTo(scr[1] - s05, scr[2] - sqrt32);\r\n                    context.lineTo(scr[1] - s05, scr[2] + sqrt32);\r\n                    context.closePath();\r\n                    this._fill(el);\r\n                    this._stroke(el);\r\n                    break;\r\n            }\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        updatePoint: function (el) {\r\n            this.drawPoint(el);\r\n        },\r\n\r\n        /* ********* Line related stuff *********** */\r\n\r\n        /**\r\n         * Draws arrows of an element (usually a line) in canvas renderer.\r\n         * @param {JXG.GeometryElement} el Line to be drawn.\r\n         * @param {Array} scr1 Screen coordinates of the start position of the line or curve.\r\n         * @param {Array} scr2 Screen coordinates of the end position of the line or curve.\r\n         * @param {String} hl String which carries information if the element is highlighted. Used for getting the correct attribute.\r\n         * @private\r\n         */\r\n        drawArrows: function (el, scr1, scr2, hl, a) {\r\n            var x1, y1, x2, y2,\r\n                w, w0,\r\n                arrowHead, arrowTail,\r\n                context = this.context,\r\n                size = 6,\r\n                type = 1,\r\n                type_fa,\r\n                type_la,\r\n                degree_fa = 1,\r\n                degree_la = 1,\r\n                doFill,\r\n                i, len,\r\n                d1x, d1y,\r\n                d2x, d2y,\r\n                last,\r\n                ang1, ang2,\r\n                ev_fa = a.evFirst,\r\n                ev_la = a.evLast;\r\n\r\n            if (el.evalVisProp('strokecolor') !== \"none\" && (ev_fa || ev_la)) {\r\n                if (el.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                    x1 = scr1.scrCoords[1];\r\n                    y1 = scr1.scrCoords[2];\r\n                    x2 = scr2.scrCoords[1];\r\n                    y2 = scr2.scrCoords[2];\r\n                    ang1 = ang2 = Math.atan2(y2 - y1, x2 - x1);\r\n                } else {\r\n                    x1 = el.points[0].scrCoords[1];\r\n                    y1 = el.points[0].scrCoords[2];\r\n\r\n                    last = el.points.length - 1;\r\n                    if (last < 1) {\r\n                        // No arrows for curves consisting of 1 point\r\n                        return;\r\n                    }\r\n                    x2 = el.points[el.points.length - 1].scrCoords[1];\r\n                    y2 = el.points[el.points.length - 1].scrCoords[2];\r\n\r\n                    d1x = el.points[1].scrCoords[1] - el.points[0].scrCoords[1];\r\n                    d1y = el.points[1].scrCoords[2] - el.points[0].scrCoords[2];\r\n                    d2x = el.points[last].scrCoords[1] - el.points[last - 1].scrCoords[1];\r\n                    d2y = el.points[last].scrCoords[2] - el.points[last - 1].scrCoords[2];\r\n                    if (ev_fa) {\r\n                        ang1 = Math.atan2(d1y, d1x);\r\n                    }\r\n                    if (ev_la) {\r\n                        ang2 = Math.atan2(d2y, d2x);\r\n                    }\r\n                }\r\n\r\n                w0 = el.evalVisProp(hl + 'strokewidth');\r\n\r\n                if (ev_fa) {\r\n                    size = a.sizeFirst;\r\n\r\n                    w = w0 * size;\r\n\r\n                    type = a.typeFirst;\r\n                    type_fa = type;\r\n\r\n                    if (type === 2) {\r\n                        arrowTail = [\r\n                            [w, -w * 0.5],\r\n                            [0.0, 0.0],\r\n                            [w, w * 0.5],\r\n                            [w * 0.5, 0.0]\r\n                        ];\r\n                    } else if (type === 3) {\r\n                        arrowTail = [\r\n                            [w / 3.0, -w * 0.5],\r\n                            [0.0, -w * 0.5],\r\n                            [0.0, w * 0.5],\r\n                            [w / 3.0, w * 0.5]\r\n                        ];\r\n                    } else if (type === 4) {\r\n                        w /= 10;\r\n                        degree_fa = 3;\r\n                        arrowTail = [\r\n                            [10.0, 3.31],\r\n                            [6.47, 3.84],\r\n                            [2.87, 4.5],\r\n                            [0.0, 6.63],\r\n                            [0.67, 5.52],\r\n                            [1.33, 4.42],\r\n                            [2.0, 3.31],\r\n                            [1.33, 2.21],\r\n                            [0.67, 1.1],\r\n                            [0.0, 0.0],\r\n                            [2.87, 2.13],\r\n                            [6.47, 2.79],\r\n                            [10.0, 3.31]\r\n                        ];\r\n                        len = arrowTail.length;\r\n                        for (i = 0; i < len; i++) {\r\n                            arrowTail[i][0] *= -w;\r\n                            arrowTail[i][1] *= w;\r\n                            arrowTail[i][0] += 10 * w;\r\n                            arrowTail[i][1] -= 3.31 * w;\r\n                        }\r\n                    } else if (type === 5) {\r\n                        w /= 10;\r\n                        degree_fa = 3;\r\n                        arrowTail = [\r\n                            [10.0, 3.28],\r\n                            [6.61, 4.19],\r\n                            [3.19, 5.07],\r\n                            [0.0, 6.55],\r\n                            [0.62, 5.56],\r\n                            [1.0, 4.44],\r\n                            [1.0, 3.28],\r\n                            [1.0, 2.11],\r\n                            [0.62, 0.99],\r\n                            [0.0, 0.0],\r\n                            [3.19, 1.49],\r\n                            [6.61, 2.37],\r\n                            [10.0, 3.28]\r\n                        ];\r\n                        len = arrowTail.length;\r\n                        for (i = 0; i < len; i++) {\r\n                            arrowTail[i][0] *= -w;\r\n                            arrowTail[i][1] *= w;\r\n                            arrowTail[i][0] += 10 * w;\r\n                            arrowTail[i][1] -= 3.28 * w;\r\n                        }\r\n                    } else if (type === 6) {\r\n                        w /= 10;\r\n                        degree_fa = 3;\r\n                        arrowTail = [\r\n                            [10.0, 2.84],\r\n                            [6.61, 3.59],\r\n                            [3.21, 4.35],\r\n                            [0.0, 5.68],\r\n                            [0.33, 4.73],\r\n                            [0.67, 3.78],\r\n                            [1.0, 2.84],\r\n                            [0.67, 1.89],\r\n                            [0.33, 0.95],\r\n                            [0.0, 0.0],\r\n                            [3.21, 1.33],\r\n                            [6.61, 2.09],\r\n                            [10.0, 2.84]\r\n                        ];\r\n                        len = arrowTail.length;\r\n                        for (i = 0; i < len; i++) {\r\n                            arrowTail[i][0] *= -w;\r\n                            arrowTail[i][1] *= w;\r\n                            arrowTail[i][0] += 10 * w;\r\n                            arrowTail[i][1] -= 2.84 * w;\r\n                        }\r\n                    } else if (type === 7) {\r\n                        w = w0;\r\n                        degree_fa = 3;\r\n                        arrowTail = [\r\n                            [0.0, 10.39],\r\n                            [2.01, 6.92],\r\n                            [5.96, 5.2],\r\n                            [10.0, 5.2],\r\n                            [5.96, 5.2],\r\n                            [2.01, 3.47],\r\n                            [0.0, 0.0]\r\n                        ];\r\n                        len = arrowTail.length;\r\n                        for (i = 0; i < len; i++) {\r\n                            arrowTail[i][0] *= -w;\r\n                            arrowTail[i][1] *= w;\r\n                            arrowTail[i][0] += 10 * w;\r\n                            arrowTail[i][1] -= 5.2 * w;\r\n                        }\r\n                    } else {\r\n                        arrowTail = [\r\n                            [w, -w * 0.5],\r\n                            [0.0, 0.0],\r\n                            [w, w * 0.5]\r\n                        ];\r\n                    }\r\n                }\r\n\r\n                if (ev_la) {\r\n                    size = a.sizeLast;\r\n                    w = w0 * size;\r\n\r\n                    type = a.typeLast;\r\n                    type_la = type;\r\n                    if (type === 2) {\r\n                        arrowHead = [\r\n                            [-w, -w * 0.5],\r\n                            [0.0, 0.0],\r\n                            [-w, w * 0.5],\r\n                            [-w * 0.5, 0.0]\r\n                        ];\r\n                    } else if (type === 3) {\r\n                        arrowHead = [\r\n                            [-w / 3.0, -w * 0.5],\r\n                            [0.0, -w * 0.5],\r\n                            [0.0, w * 0.5],\r\n                            [-w / 3.0, w * 0.5]\r\n                        ];\r\n                    } else if (type === 4) {\r\n                        w /= 10;\r\n                        degree_la = 3;\r\n                        arrowHead = [\r\n                            [10.0, 3.31],\r\n                            [6.47, 3.84],\r\n                            [2.87, 4.5],\r\n                            [0.0, 6.63],\r\n                            [0.67, 5.52],\r\n                            [1.33, 4.42],\r\n                            [2.0, 3.31],\r\n                            [1.33, 2.21],\r\n                            [0.67, 1.1],\r\n                            [0.0, 0.0],\r\n                            [2.87, 2.13],\r\n                            [6.47, 2.79],\r\n                            [10.0, 3.31]\r\n                        ];\r\n                        len = arrowHead.length;\r\n                        for (i = 0; i < len; i++) {\r\n                            arrowHead[i][0] *= w;\r\n                            arrowHead[i][1] *= w;\r\n                            arrowHead[i][0] -= 10 * w;\r\n                            arrowHead[i][1] -= 3.31 * w;\r\n                        }\r\n                    } else if (type === 5) {\r\n                        w /= 10;\r\n                        degree_la = 3;\r\n                        arrowHead = [\r\n                            [10.0, 3.28],\r\n                            [6.61, 4.19],\r\n                            [3.19, 5.07],\r\n                            [0.0, 6.55],\r\n                            [0.62, 5.56],\r\n                            [1.0, 4.44],\r\n                            [1.0, 3.28],\r\n                            [1.0, 2.11],\r\n                            [0.62, 0.99],\r\n                            [0.0, 0.0],\r\n                            [3.19, 1.49],\r\n                            [6.61, 2.37],\r\n                            [10.0, 3.28]\r\n                        ];\r\n                        len = arrowHead.length;\r\n                        for (i = 0; i < len; i++) {\r\n                            arrowHead[i][0] *= w;\r\n                            arrowHead[i][1] *= w;\r\n                            arrowHead[i][0] -= 10 * w;\r\n                            arrowHead[i][1] -= 3.28 * w;\r\n                        }\r\n                    } else if (type === 6) {\r\n                        w /= 10;\r\n                        degree_la = 3;\r\n                        arrowHead = [\r\n                            [10.0, 2.84],\r\n                            [6.61, 3.59],\r\n                            [3.21, 4.35],\r\n                            [0.0, 5.68],\r\n                            [0.33, 4.73],\r\n                            [0.67, 3.78],\r\n                            [1.0, 2.84],\r\n                            [0.67, 1.89],\r\n                            [0.33, 0.95],\r\n                            [0.0, 0.0],\r\n                            [3.21, 1.33],\r\n                            [6.61, 2.09],\r\n                            [10.0, 2.84]\r\n                        ];\r\n                        len = arrowHead.length;\r\n                        for (i = 0; i < len; i++) {\r\n                            arrowHead[i][0] *= w;\r\n                            arrowHead[i][1] *= w;\r\n                            arrowHead[i][0] -= 10 * w;\r\n                            arrowHead[i][1] -= 2.84 * w;\r\n                        }\r\n                    } else if (type === 7) {\r\n                        w = w0;\r\n                        degree_la = 3;\r\n                        arrowHead = [\r\n                            [0.0, 10.39],\r\n                            [2.01, 6.92],\r\n                            [5.96, 5.2],\r\n                            [10.0, 5.2],\r\n                            [5.96, 5.2],\r\n                            [2.01, 3.47],\r\n                            [0.0, 0.0]\r\n                        ];\r\n                        len = arrowHead.length;\r\n                        for (i = 0; i < len; i++) {\r\n                            arrowHead[i][0] *= w;\r\n                            arrowHead[i][1] *= w;\r\n                            arrowHead[i][0] -= 10 * w;\r\n                            arrowHead[i][1] -= 5.2 * w;\r\n                        }\r\n                    } else {\r\n                        arrowHead = [\r\n                            [-w, -w * 0.5],\r\n                            [0.0, 0.0],\r\n                            [-w, w * 0.5]\r\n                        ];\r\n                    }\r\n                }\r\n\r\n                context.save();\r\n                if (this._setColor(el, \"stroke\", 'fill')) {\r\n                    this._setColor(el, 'stroke');\r\n                    if (ev_fa) {\r\n                        if (type_fa === 7) {\r\n                            doFill = false;\r\n                        } else {\r\n                            doFill = true;\r\n                        }\r\n                        this._drawPolygon(\r\n                            this._translateShape(this._rotateShape(arrowTail, ang1), x1, y1),\r\n                            degree_fa,\r\n                            doFill\r\n                        );\r\n                    }\r\n                    if (ev_la) {\r\n                        if (type_la === 7) {\r\n                            doFill = false;\r\n                        } else {\r\n                            doFill = true;\r\n                        }\r\n                        this._drawPolygon(\r\n                            this._translateShape(this._rotateShape(arrowHead, ang2), x2, y2),\r\n                            degree_la,\r\n                            doFill\r\n                        );\r\n                    }\r\n                }\r\n                context.restore();\r\n            }\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        drawLine: function (el) {\r\n            var c1_org,\r\n                c2_org,\r\n                c1 = new Coords(Const.COORDS_BY_USER, el.point1.coords.usrCoords, el.board),\r\n                c2 = new Coords(Const.COORDS_BY_USER, el.point2.coords.usrCoords, el.board),\r\n                margin = null,\r\n                hl,\r\n                w,\r\n                arrowData;\r\n\r\n            if (!el.visPropCalc.visible) {\r\n                return;\r\n            }\r\n\r\n            hl = this._getHighlighted(el);\r\n            w = el.evalVisProp(hl + 'strokewidth');\r\n            arrowData = this.getArrowHeadData(el, w, hl);\r\n\r\n            if (arrowData.evFirst || arrowData.evLast) {\r\n                margin = -4;\r\n            }\r\n            Geometry.calcStraight(el, c1, c2, margin);\r\n            this.handleTouchpoints(el, c1, c2, arrowData);\r\n\r\n            c1_org = new Coords(Const.COORDS_BY_USER, c1.usrCoords, el.board);\r\n            c2_org = new Coords(Const.COORDS_BY_USER, c2.usrCoords, el.board);\r\n\r\n\r\n            this.getPositionArrowHead(el, c1, c2, arrowData);\r\n\r\n            this.context.beginPath();\r\n            this.context.moveTo(c1.scrCoords[1], c1.scrCoords[2]);\r\n            this.context.lineTo(c2.scrCoords[1], c2.scrCoords[2]);\r\n            this._stroke(el);\r\n\r\n            if (\r\n                arrowData.evFirst /* && obj.sFirst > 0*/ ||\r\n                arrowData.evLast /* && obj.sLast > 0*/\r\n            ) {\r\n                this.drawArrows(el, c1_org, c2_org, hl, arrowData);\r\n            }\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        updateLine: function (el) {\r\n            this.drawLine(el);\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        drawTicks: function () {\r\n            // this function is supposed to initialize the svg/vml nodes in the SVG/VMLRenderer.\r\n            // but in canvas there are no such nodes, hence we just do nothing and wait until\r\n            // updateTicks is called.\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        updateTicks: function (ticks) {\r\n            var i,\r\n                c,\r\n                x,\r\n                y,\r\n                len = ticks.ticks.length,\r\n                len2,\r\n                j,\r\n                context = this.context;\r\n\r\n            context.beginPath();\r\n            for (i = 0; i < len; i++) {\r\n                c = ticks.ticks[i];\r\n                x = c[0];\r\n                y = c[1];\r\n\r\n                // context.moveTo(x[0], y[0]);\r\n                // context.lineTo(x[1], y[1]);\r\n                len2 = x.length;\r\n                context.moveTo(x[0], y[0]);\r\n                for (j = 1; j < len2; ++j) {\r\n                    context.lineTo(x[j], y[j]);\r\n                }\r\n            }\r\n            // Labels\r\n            // for (i = 0; i < len; i++) {\r\n            //     c = ticks.ticks[i].scrCoords;\r\n            //     if (ticks.ticks[i].major &&\r\n            //             (ticks.board.needsFullUpdate || ticks.needsRegularUpdate) &&\r\n            //             ticks.labels[i] &&\r\n            //             ticks.labels[i].visPropCalc.visible) {\r\n            //         this.updateText(ticks.labels[i]);\r\n            //     }\r\n            // }\r\n            context.lineCap = 'round';\r\n            this._stroke(ticks);\r\n        },\r\n\r\n        /* ********* Curve related stuff *********** */\r\n\r\n        // documented in AbstractRenderer\r\n        drawCurve: function (el) {\r\n            var hl, w, arrowData;\r\n\r\n            if (el.evalVisProp('handdrawing')) {\r\n                this.updatePathStringBezierPrim(el);\r\n            } else {\r\n                this.updatePathStringPrim(el);\r\n            }\r\n            if (el.numberPoints > 1) {\r\n                hl = this._getHighlighted(el);\r\n                w = el.evalVisProp(hl + 'strokewidth');\r\n                arrowData = this.getArrowHeadData(el, w, hl);\r\n                if (\r\n                    arrowData.evFirst /* && obj.sFirst > 0*/ ||\r\n                    arrowData.evLast /* && obj.sLast > 0*/\r\n                ) {\r\n                    this.drawArrows(el, null, null, hl, arrowData);\r\n                }\r\n            }\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        updateCurve: function (el) {\r\n            this.drawCurve(el);\r\n        },\r\n\r\n        /* ********* Circle related stuff *********** */\r\n\r\n        // documented in AbstractRenderer\r\n        drawEllipse: function (el) {\r\n            var m1 = el.center.coords.scrCoords[1],\r\n                m2 = el.center.coords.scrCoords[2],\r\n                sX = el.board.unitX,\r\n                sY = el.board.unitY,\r\n                rX = 2 * el.Radius(),\r\n                rY = 2 * el.Radius(),\r\n                aWidth = rX * sX,\r\n                aHeight = rY * sY,\r\n                aX = m1 - aWidth / 2,\r\n                aY = m2 - aHeight / 2,\r\n                hB = (aWidth / 2) * 0.5522848,\r\n                vB = (aHeight / 2) * 0.5522848,\r\n                eX = aX + aWidth,\r\n                eY = aY + aHeight,\r\n                mX = aX + aWidth / 2,\r\n                mY = aY + aHeight / 2,\r\n                context = this.context;\r\n\r\n            if (rX > 0.0 && rY > 0.0 && !isNaN(m1 + m2)) {\r\n                context.beginPath();\r\n                context.moveTo(aX, mY);\r\n                context.bezierCurveTo(aX, mY - vB, mX - hB, aY, mX, aY);\r\n                context.bezierCurveTo(mX + hB, aY, eX, mY - vB, eX, mY);\r\n                context.bezierCurveTo(eX, mY + vB, mX + hB, eY, mX, eY);\r\n                context.bezierCurveTo(mX - hB, eY, aX, mY + vB, aX, mY);\r\n                context.closePath();\r\n                this._fill(el);\r\n                this._stroke(el);\r\n            }\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        updateEllipse: function (el) {\r\n            return this.drawEllipse(el);\r\n        },\r\n\r\n        /* ********* Polygon related stuff *********** */\r\n\r\n        // nothing here, using AbstractRenderer implementations\r\n\r\n        /* ********* Text related stuff *********** */\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        displayCopyright: function (str, fontsize) {\r\n            var context = this.context,\r\n                x = 4 + 1.8 * fontsize,\r\n                y = 6 + fontsize,\r\n                alpha = 0.2;\r\n\r\n            // This should be called on EVERY update, otherwise it won't be shown after the first update\r\n            context.save();\r\n            context.font = fontsize + \"px Arial\";\r\n            context.globalAlpha = alpha;\r\n            context.lineWidth = 0.5;\r\n            context.fillText(str + '.', x, y); // Distinguish svg and canvas by this dot\r\n            context.restore();\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        displayLogo: function (str, fontsize, board) {\r\n            var context = this.context,\r\n                s = 1.5 * fontsize,\r\n                alpha = 0.2;\r\n\r\n            if (!Type.exists(board._logo_image)) {\r\n                board._logo_image = new Image();\r\n                board._logo_image.src = str;\r\n            }\r\n            board._logo_image.onload = function() {\r\n                context.save();\r\n                context.globalAlpha = alpha;\r\n                context.drawImage(board._logo_image, 5, 5, s, s);\r\n                context.restore();\r\n            };\r\n            context.save();\r\n            context.globalAlpha = alpha;\r\n            context.drawImage(board._logo_image, 5, 5, s, s);\r\n            context.restore();\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        drawInternalText: function (el) {\r\n            var ev_fs = el.evalVisProp('fontsize'),\r\n                fontUnit = el.evalVisProp('fontunit'),\r\n                ev_ax = el.getAnchorX(),\r\n                ev_ay = el.getAnchorY(),\r\n                context = this.context;\r\n\r\n            context.save();\r\n            if (\r\n                this._setColor(el, \"stroke\", 'fill') &&\r\n                !isNaN(el.coords.scrCoords[1] + el.coords.scrCoords[2])\r\n            ) {\r\n                context.font = (ev_fs > 0 ? ev_fs : 0) + fontUnit + \" Arial\";\r\n\r\n                this.transformRect(el, el.transformations);\r\n                if (ev_ax === 'left') {\r\n                    context.textAlign = 'left';\r\n                } else if (ev_ax === 'right') {\r\n                    context.textAlign = 'right';\r\n                } else if (ev_ax === 'middle') {\r\n                    context.textAlign = 'center';\r\n                }\r\n                if (ev_ay === 'bottom') {\r\n                    context.textBaseline = 'bottom';\r\n                } else if (ev_ay === 'top') {\r\n                    context.textBaseline = 'top';\r\n                } else if (ev_ay === 'middle') {\r\n                    context.textBaseline = 'middle';\r\n                }\r\n                context.fillText(el.plaintext, el.coords.scrCoords[1], el.coords.scrCoords[2]);\r\n            }\r\n            context.restore();\r\n            return null;\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updateInternalText: function (el) {\r\n            this.drawInternalText(el);\r\n        },\r\n\r\n        // documented in JXG.AbstractRenderer\r\n        // Only necessary for texts\r\n        setObjectStrokeColor: function (el, color, opacity) {\r\n            var rgba = color,\r\n                c,\r\n                rgbo,\r\n                o = opacity,\r\n                oo,\r\n                node;\r\n\r\n            o = o > 0 ? o : 0;\r\n\r\n            if (el.visPropOld.strokecolor === rgba && el.visPropOld.strokeopacity === o) {\r\n                return;\r\n            }\r\n\r\n            // Check if this could be merged with _setColor\r\n\r\n            if (Type.exists(rgba) && rgba !== false) {\r\n                // RGB, not RGBA\r\n                if (rgba.length !== 9) {\r\n                    c = rgba;\r\n                    oo = o;\r\n                    // True RGBA, not RGB\r\n                } else {\r\n                    rgbo = Color.rgba2rgbo(rgba);\r\n                    c = rgbo[0];\r\n                    oo = o * rgbo[1];\r\n                }\r\n                node = el.rendNode;\r\n                if (\r\n                    el.elementClass === Const.OBJECT_CLASS_TEXT &&\r\n                    el.evalVisProp('display') === \"html\"\r\n                ) {\r\n                    node.style.color = c;\r\n                    node.style.opacity = oo;\r\n                }\r\n            }\r\n\r\n            el.visPropOld.strokecolor = rgba;\r\n            el.visPropOld.strokeopacity = o;\r\n        },\r\n\r\n        /* ********* Image related stuff *********** */\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        drawImage: function (el) {\r\n            el.rendNode = new Image();\r\n            // Store the file name of the image.\r\n            // Before, this was done in el.rendNode.src\r\n            // But there, the file name is expanded to\r\n            // the full url. This may be different from\r\n            // the url computed in updateImageURL().\r\n            el._src = \"\";\r\n            this.updateImage(el);\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updateImage: function (el) {\r\n            var context = this.context,\r\n                o = el.evalVisProp('fillopacity'),\r\n                paintImg = Type.bind(function () {\r\n                    el.imgIsLoaded = true;\r\n                    if (el.size[0] <= 0 || el.size[1] <= 0) {\r\n                        return;\r\n                    }\r\n                    context.save();\r\n                    context.globalAlpha = o;\r\n                    // If det(el.transformations)=0, FireFox 3.6. breaks down.\r\n                    // This is tested in transformRect\r\n                    this.transformRect(el, el.transformations);\r\n                    context.drawImage(\r\n                        el.rendNode,\r\n                        el.coords.scrCoords[1],\r\n                        el.coords.scrCoords[2] - el.size[1],\r\n                        el.size[0],\r\n                        el.size[1]\r\n                    );\r\n                    context.restore();\r\n                }, this);\r\n\r\n            if (this.updateImageURL(el)) {\r\n                el.rendNode.onload = paintImg;\r\n            } else {\r\n                if (el.imgIsLoaded) {\r\n                    paintImg();\r\n                }\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        transformRect: function (el, t) {\r\n            var m, s, cx, cy, node,\r\n                len = t.length,\r\n                ctx = this.context;\r\n\r\n            if (len > 0) {\r\n                m = this.joinTransforms(el, t);\r\n                if (el.elementClass === Const.OBJECT_CLASS_TEXT && el.visProp.display === 'html') {\r\n                    s = \" matrix(\" + [m[1][1], m[2][1], m[1][2], m[2][2], m[1][0], m[2][0]].join(\",\") + \") \";\r\n                    if (s.indexOf('NaN') === -1) {\r\n                        node = el.rendNode;\r\n                        node.style.transform = s;\r\n                        cx = -el.coords.scrCoords[1];\r\n                        cy = -el.coords.scrCoords[2];\r\n                        switch (el.evalVisProp('anchorx')) {\r\n                            case 'right': cx += el.size[0]; break;\r\n                            case 'middle': cx += el.size[0] * 0.5; break;\r\n                        }\r\n                        switch (el.evalVisProp('anchory')) {\r\n                            case 'bottom': cy += el.size[1]; break;\r\n                            case 'middle': cy += el.size[1] * 0.5; break;\r\n                        }\r\n                        node.style['transform-origin'] = (cx) + 'px ' + (cy) + 'px';\r\n                    }\r\n                } else {\r\n                    if (Math.abs(Numerics.det(m)) >= Mat.eps) {\r\n                        ctx.transform(m[1][1], m[2][1], m[1][2], m[2][2], m[1][0], m[2][0]);\r\n                    }\r\n                }\r\n            }\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updateImageURL: function (el) {\r\n            var url;\r\n\r\n            url = el.eval(el.url);\r\n            if (el._src !== url) {\r\n                el.imgIsLoaded = false;\r\n                el.rendNode.src = url;\r\n                el._src = url;\r\n                return true;\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        /* ********* Render primitive objects *********** */\r\n\r\n        // documented in AbstractRenderer\r\n        remove: function (shape) {\r\n            // sounds odd for a pixel based renderer but we need this for html texts\r\n            if (Type.exists(shape) && Type.exists(shape.parentNode)) {\r\n                shape.parentNode.removeChild(shape);\r\n            }\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        updatePathStringPrim: function (el) {\r\n            var i,\r\n                scr,\r\n                scr1,\r\n                scr2,\r\n                len,\r\n                symbm = \"M\",\r\n                symbl = \"L\",\r\n                symbc = \"C\",\r\n                nextSymb = symbm,\r\n                maxSize = 5000.0,\r\n                context = this.context;\r\n\r\n            if (el.numberPoints <= 0) {\r\n                return;\r\n            }\r\n\r\n            len = Math.min(el.points.length, el.numberPoints);\r\n            context.beginPath();\r\n\r\n            if (el.bezierDegree === 1) {\r\n                /*\r\n                if (isNotPlot && el.board.options.curve.RDPsmoothing) {\r\n                    el.points = Numerics.RamerDouglasPeucker(el.points, 0.5);\r\n                }\r\n                */\r\n\r\n                for (i = 0; i < len; i++) {\r\n                    scr = el.points[i].scrCoords;\r\n\r\n                    if (isNaN(scr[1]) || isNaN(scr[2])) {\r\n                        // PenUp\r\n                        nextSymb = symbm;\r\n                    } else {\r\n                        // Chrome has problems with values  being too far away.\r\n                        if (scr[1] > maxSize) {\r\n                            scr[1] = maxSize;\r\n                        } else if (scr[1] < -maxSize) {\r\n                            scr[1] = -maxSize;\r\n                        }\r\n\r\n                        if (scr[2] > maxSize) {\r\n                            scr[2] = maxSize;\r\n                        } else if (scr[2] < -maxSize) {\r\n                            scr[2] = -maxSize;\r\n                        }\r\n\r\n                        if (nextSymb === symbm) {\r\n                            context.moveTo(scr[1], scr[2]);\r\n                        } else {\r\n                            context.lineTo(scr[1], scr[2]);\r\n                        }\r\n                        nextSymb = symbl;\r\n                    }\r\n                }\r\n            } else if (el.bezierDegree === 3) {\r\n                i = 0;\r\n                while (i < len) {\r\n                    scr = el.points[i].scrCoords;\r\n                    if (isNaN(scr[1]) || isNaN(scr[2])) {\r\n                        // PenUp\r\n                        nextSymb = symbm;\r\n                    } else {\r\n                        if (nextSymb === symbm) {\r\n                            context.moveTo(scr[1], scr[2]);\r\n                        } else {\r\n                            i += 1;\r\n                            scr1 = el.points[i].scrCoords;\r\n                            i += 1;\r\n                            scr2 = el.points[i].scrCoords;\r\n                            context.bezierCurveTo(\r\n                                scr[1],\r\n                                scr[2],\r\n                                scr1[1],\r\n                                scr1[2],\r\n                                scr2[1],\r\n                                scr2[2]\r\n                            );\r\n                        }\r\n                        nextSymb = symbc;\r\n                    }\r\n                    i += 1;\r\n                }\r\n            }\r\n            context.lineCap = 'round';\r\n            context.lineJoin = 'round';\r\n            this._fill(el);\r\n            this._stroke(el);\r\n        },\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        updatePathStringBezierPrim: function (el) {\r\n            var i, j, k,\r\n                scr, lx, ly, len,\r\n                symbm = \"M\",\r\n                symbl = \"C\",\r\n                nextSymb = symbm,\r\n                maxSize = 5000.0,\r\n                f = el.evalVisProp('strokewidth'),\r\n                isNoPlot = el.evalVisProp('curvetype') !== \"plot\",\r\n                context = this.context;\r\n\r\n            if (el.numberPoints <= 0) {\r\n                return;\r\n            }\r\n\r\n            if (isNoPlot && el.board.options.curve.RDPsmoothing) {\r\n                el.points = Numerics.RamerDouglasPeucker(el.points, 0.5);\r\n            }\r\n\r\n            len = Math.min(el.points.length, el.numberPoints);\r\n            context.beginPath();\r\n\r\n            for (j = 1; j < 3; j++) {\r\n                nextSymb = symbm;\r\n                for (i = 0; i < len; i++) {\r\n                    scr = el.points[i].scrCoords;\r\n\r\n                    if (isNaN(scr[1]) || isNaN(scr[2])) {\r\n                        // PenUp\r\n                        nextSymb = symbm;\r\n                    } else {\r\n                        // Chrome has problems with values being too far away.\r\n                        if (scr[1] > maxSize) {\r\n                            scr[1] = maxSize;\r\n                        } else if (scr[1] < -maxSize) {\r\n                            scr[1] = -maxSize;\r\n                        }\r\n\r\n                        if (scr[2] > maxSize) {\r\n                            scr[2] = maxSize;\r\n                        } else if (scr[2] < -maxSize) {\r\n                            scr[2] = -maxSize;\r\n                        }\r\n\r\n                        if (nextSymb === symbm) {\r\n                            context.moveTo(scr[1], scr[2]);\r\n                        } else {\r\n                            k = 2 * j;\r\n                            context.bezierCurveTo(\r\n                                lx + (scr[1] - lx) * 0.333 + f * (k * Math.random() - j),\r\n                                ly + (scr[2] - ly) * 0.333 + f * (k * Math.random() - j),\r\n                                lx + (scr[1] - lx) * 0.666 + f * (k * Math.random() - j),\r\n                                ly + (scr[2] - ly) * 0.666 + f * (k * Math.random() - j),\r\n                                scr[1],\r\n                                scr[2]\r\n                            );\r\n                        }\r\n                        nextSymb = symbl;\r\n                        lx = scr[1];\r\n                        ly = scr[2];\r\n                    }\r\n                }\r\n            }\r\n            context.lineCap = 'round';\r\n            context.lineJoin = 'round';\r\n            this._fill(el);\r\n            this._stroke(el);\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        updatePolygonPrim: function (node, el) {\r\n            var scrCoords,\r\n                i,\r\n                j,\r\n                len = el.vertices.length,\r\n                context = this.context,\r\n                isReal = true;\r\n\r\n            if (len <= 0 || !el.visPropCalc.visible) {\r\n                return;\r\n            }\r\n            if (el.elType === 'polygonalchain') {\r\n                len++;\r\n            }\r\n\r\n            context.beginPath();\r\n            i = 0;\r\n            while (!el.vertices[i].isReal && i < len - 1) {\r\n                i++;\r\n                isReal = false;\r\n            }\r\n            scrCoords = el.vertices[i].coords.scrCoords;\r\n            context.moveTo(scrCoords[1], scrCoords[2]);\r\n\r\n            for (j = i; j < len - 1; j++) {\r\n                if (!el.vertices[j].isReal) {\r\n                    isReal = false;\r\n                }\r\n                scrCoords = el.vertices[j].coords.scrCoords;\r\n                context.lineTo(scrCoords[1], scrCoords[2]);\r\n            }\r\n            context.closePath();\r\n\r\n            if (isReal) {\r\n                this._fill(el); // The edges of a polygon are displayed separately (as segments).\r\n            }\r\n        },\r\n\r\n        /* ********* Set attributes *********** */\r\n\r\n        // Already documented in JXG.AbstractRenderer\r\n        display: function (el, val) {\r\n            if (el && el.rendNode) {\r\n                el.visPropOld.visible = val;\r\n                if (val) {\r\n                    el.rendNode.style.visibility = 'inherit';\r\n                } else {\r\n                    el.rendNode.style.visibility = 'hidden';\r\n                }\r\n            }\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        show: function (el) {\r\n            JXG.deprecated(\"Board.renderer.show()\", \"Board.renderer.display()\");\r\n\r\n            if (Type.exists(el.rendNode)) {\r\n                el.rendNode.style.visibility = 'inherit';\r\n            }\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        hide: function (el) {\r\n            JXG.deprecated(\"Board.renderer.hide()\", \"Board.renderer.display()\");\r\n\r\n            if (Type.exists(el.rendNode)) {\r\n                el.rendNode.style.visibility = 'hidden';\r\n            }\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        setGradient: function (el) {\r\n            // var // col,\r\n            //     op;\r\n\r\n            // op = el.evalVisProp('fillopacity');\r\n            // op = op > 0 ? op : 0;\r\n\r\n            // col = el.evalVisProp('fillcolor');\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        setShadow: function (el) {\r\n            if (el.visPropOld.shadow === el.visProp.shadow) {\r\n                return;\r\n            }\r\n\r\n            // not implemented yet\r\n            // we simply have to redraw the element\r\n            // probably the best way to do so would be to call el.updateRenderer(), i think.\r\n\r\n            el.visPropOld.shadow = el.visProp.shadow;\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        highlight: function (obj) {\r\n            if (\r\n                obj.elementClass === Const.OBJECT_CLASS_TEXT &&\r\n                obj.evalVisProp('display') === \"html\"\r\n            ) {\r\n                this.updateTextStyle(obj, true);\r\n            } else {\r\n                obj.board.prepareUpdate();\r\n                obj.board.renderer.suspendRedraw(obj.board);\r\n                obj.board.updateRenderer();\r\n                obj.board.renderer.unsuspendRedraw();\r\n            }\r\n            return this;\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        noHighlight: function (obj) {\r\n            if (\r\n                obj.elementClass === Const.OBJECT_CLASS_TEXT &&\r\n                obj.evalVisProp('display') === \"html\"\r\n            ) {\r\n                this.updateTextStyle(obj, false);\r\n            } else {\r\n                obj.board.prepareUpdate();\r\n                obj.board.renderer.suspendRedraw(obj.board);\r\n                obj.board.updateRenderer();\r\n                obj.board.renderer.unsuspendRedraw();\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /* ********* Renderer control *********** */\r\n\r\n        // documented in AbstractRenderer\r\n        suspendRedraw: function (board) {\r\n            this.context.save();\r\n            this.context.clearRect(0, 0, this.canvasRoot.width, this.canvasRoot.height);\r\n\r\n            if (board && (board.attr.showcopyright || board.attr.showlogo)) {\r\n                this.displayLogo(JXG.licenseLogo, 12, board);\r\n            }\r\n\r\n            if (board && board.attr.showcopyright) {\r\n                this.displayCopyright(JXG.licenseText, 12);\r\n            }\r\n        },\r\n\r\n        // documented in AbstractRenderer\r\n        unsuspendRedraw: function () {\r\n            this.context.restore();\r\n        },\r\n\r\n        // document in AbstractRenderer\r\n        resize: function (w, h) {\r\n            if (this.container) {\r\n                this.canvasRoot.style.width = parseFloat(w) + 'px';\r\n                this.canvasRoot.style.height = parseFloat(h) + 'px';\r\n\r\n                this.canvasRoot.setAttribute(\"width\", 2 * parseFloat(w) + 'px');\r\n                this.canvasRoot.setAttribute(\"height\", 2 * parseFloat(h) + 'px');\r\n            } else {\r\n                this.canvasRoot.width = 2 * parseFloat(w);\r\n                this.canvasRoot.height = 2 * parseFloat(h);\r\n            }\r\n            this.context = this.canvasRoot.getContext('2d');\r\n            // The width and height of the canvas is set to twice the CSS values,\r\n            // followed by an appropriate scaling.\r\n            // See https://stackoverflow.com/questions/22416462/canvas-element-with-blurred-lines\r\n            this.context.scale(2, 2);\r\n        },\r\n\r\n        removeToInsertLater: function () {\r\n            return function () { };\r\n        }\r\n    }\r\n);\r\n\r\nexport default JXG.CanvasRenderer;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, AMprocessNode: true, MathJax: true, document: true */\r\n/*jslint nomen: true, plusplus: true, newcap:true, unparam: true*/\r\n/*eslint no-unused-vars: \"off\"*/\r\n\r\n/**\r\n * @fileoverview JSXGraph can use various technologies to render the contents of a construction, e.g.\r\n * SVG, VML, and HTML5 Canvas. To accomplish this, The rendering and the logic and control mechanisms\r\n * are completely separated from each other. Every rendering technology has it's own class, called\r\n * Renderer, e.g. SVGRenderer for SVG, the same for VML and Canvas. The common base for all available\r\n * renderers is the class AbstractRenderer.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport AbstractRenderer from \"./abstract.js\";\r\n\r\n/**\r\n * This renderer draws nothing. It is intended to be used in environments where none of our rendering engines\r\n * are available, e.g. WebWorkers. All methods are empty.\r\n *\r\n * @class JXG.NoRenderer\r\n * @augments JXG.AbstractRenderer\r\n * @see JXG.AbstractRenderer\r\n */\r\nJXG.NoRenderer = function () {\r\n    /**\r\n     * If this property is set to <tt>true</tt> the visual properties of the elements are updated\r\n     * on every update. Visual properties means: All the stuff stored in the\r\n     * {@link JXG.GeometryElement#visProp} property won't be set if enhancedRendering is <tt>false</tt>\r\n     * @type Boolean\r\n     * @default true\r\n     */\r\n    this.enhancedRendering = false;\r\n\r\n    /**\r\n     * This is used to easily determine which renderer we are using\r\n     * @example if (board.renderer.type === 'vml') {\r\n     *     // do something\r\n     * }\r\n     * @type String\r\n     */\r\n    this.type = 'no';\r\n};\r\n\r\nJXG.extend(\r\n    JXG.NoRenderer.prototype,\r\n    /** @lends JXG.NoRenderer.prototype */ {\r\n\r\n        // All methods are already documented in JXG.AbstractRenderer\r\n\r\n        /* ********* Point related stuff *********** */\r\n\r\n        drawPoint: function (el) {},\r\n\r\n        updatePoint: function (el) {},\r\n\r\n        changePointStyle: function (el) {},\r\n\r\n        /* ********* Line related stuff *********** */\r\n\r\n        drawLine: function (el) {},\r\n\r\n        updateLine: function (el) {},\r\n\r\n        drawTicks: function (el) {},\r\n\r\n        updateTicks: function (el) {},\r\n\r\n        /* ********* Curve related stuff *********** */\r\n\r\n        drawCurve: function (el) {},\r\n\r\n        updateCurve: function (el) {},\r\n\r\n        /* ********* Circle related stuff *********** */\r\n\r\n        drawEllipse: function (el) {},\r\n\r\n        updateEllipse: function (el) {},\r\n\r\n        /* ********* Polygon related stuff *********** */\r\n\r\n        drawPolygon: function (el) {},\r\n\r\n        updatePolygon: function (el) {},\r\n\r\n        /* ********* Text related stuff *********** */\r\n\r\n        displayCopyright: function (str, fontsize) {},\r\n\r\n        drawInternalText: function (el) {},\r\n\r\n        updateInternalText: function (el) {},\r\n\r\n        drawText: function (el) {},\r\n\r\n        updateText: function (el) {},\r\n\r\n        updateTextStyle: function (el, doHighlight) {},\r\n\r\n        updateInternalTextStyle: function (el, strokeColor, strokeOpacity) {},\r\n\r\n        /* ********* Image related stuff *********** */\r\n\r\n        drawImage: function (el) {},\r\n\r\n        updateImage: function (el) {},\r\n\r\n        updateImageURL: function (el) {},\r\n\r\n        /* ********* Render primitive objects *********** */\r\n\r\n        appendChildPrim: function (node, level) {},\r\n\r\n        appendNodesToElement: function (el, type) {},\r\n\r\n        remove: function (node) {},\r\n\r\n        makeArrows: function (el) {},\r\n\r\n        updateEllipsePrim: function (node, x, y, rx, ry) {},\r\n\r\n        updateLinePrim: function (node, p1x, p1y, p2x, p2y, board) {},\r\n\r\n        updatePathPrim: function (node, pathString, board) {},\r\n\r\n        updatePathStringPoint: function (el, size, type) {},\r\n\r\n        updatePathStringPrim: function (el) {},\r\n\r\n        updatePathStringBezierPrim: function (el) {},\r\n\r\n        updatePolygonPrim: function (node, el) {},\r\n\r\n        updateRectPrim: function (node, x, y, w, h) {},\r\n\r\n        setPropertyPrim: function (node, key, val) {},\r\n\r\n        /* ********* Set attributes *********** */\r\n\r\n        show: function (el) {},\r\n\r\n        hide: function (el) {},\r\n\r\n        setBuffering: function (node, type) {},\r\n\r\n        setDashStyle: function (el) {},\r\n\r\n        setDraft: function (el) {},\r\n\r\n        removeDraft: function (el) {},\r\n\r\n        setGradient: function (el) {},\r\n\r\n        updateGradient: function (el) {},\r\n\r\n        setObjectTransition: function (el, duration) {},\r\n\r\n        setObjectFillColor: function (el, color, opacity) {},\r\n\r\n        setObjectStrokeColor: function (el, color, opacity) {},\r\n\r\n        setObjectStrokeWidth: function (el, width) {},\r\n\r\n        setShadow: function (el) {},\r\n\r\n        highlight: function (el) {},\r\n\r\n        noHighlight: function (el) {},\r\n\r\n        /* ********* Renderer control *********** */\r\n\r\n        suspendRedraw: function () {},\r\n\r\n        unsuspendRedraw: function () {},\r\n\r\n        drawNavigationBar: function (board) {},\r\n\r\n        getElementById: function (id) { return null; },\r\n\r\n        resize: function (w, h) {},\r\n\r\n        removeToInsertLater: function () { return function () {}; }\r\n    }\r\n);\r\n\r\n/**\r\n * @ignore\r\n */\r\nJXG.NoRenderer.prototype = new AbstractRenderer();\r\n\r\nexport default JXG.NoRenderer;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, document:true, jQuery:true, define: true, window: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview The JSXGraph object is defined in this file. JXG.JSXGraph controls all boards.\r\n * It has methods to create, save, load and free boards. Additionally some helper functions are\r\n * defined in this file directly in the JXG namespace.\r\n *\r\n */\r\n\r\nimport JXG from \"./jxg.js\";\r\nimport Env from \"./utils/env.js\";\r\nimport Type from \"./utils/type.js\";\r\n// import Mat from \"./math/math.js\";\r\nimport Board from \"./base/board.js\";\r\nimport FileReader from \"./reader/file.js\";\r\nimport Options from \"./options.js\";\r\nimport SVGRenderer from \"./renderer/svg.js\";\r\nimport VMLRenderer from \"./renderer/vml.js\";\r\nimport CanvasRenderer from \"./renderer/canvas.js\";\r\nimport NoRenderer from \"./renderer/no.js\";\r\n\r\n/**\r\n * Constructs a new JSXGraph singleton object.\r\n * @class The JXG.JSXGraph singleton stores all properties required\r\n * to load, save, create and free a board.\r\n */\r\nJXG.JSXGraph = {\r\n    /**\r\n     * Stores the renderer that is used to draw the boards.\r\n     * @type String\r\n     */\r\n    rendererType: (function () {\r\n        Options.board.renderer = 'no';\r\n\r\n        if (Env.supportsVML()) {\r\n            Options.board.renderer = 'vml';\r\n            // Ok, this is some real magic going on here. IE/VML always was so\r\n            // terribly slow, except in one place: Examples placed in a moodle course\r\n            // was almost as fast as in other browsers. So i grabbed all the css and\r\n            // lib scripts from our moodle, added them to a jsxgraph example and it\r\n            // worked. next step was to strip all the css/lib code which didn't affect\r\n            // the VML update speed. The following five lines are what was left after\r\n            // the last step and yes - it basically does nothing but reads two\r\n            // properties of document.body on every mouse move. why? we don't know. if\r\n            // you know, please let us know.\r\n            //\r\n            // If we want to use the strict mode we have to refactor this a little bit. Let's\r\n            // hope the magic isn't gone now. Anywho... it's only useful in old versions of IE\r\n            // which should not be used anymore.\r\n            document.onmousemove = function () {\r\n                var t;\r\n\r\n                if (document.body) {\r\n                    t = document.body.scrollLeft;\r\n                    t += document.body.scrollTop;\r\n                }\r\n\r\n                return t;\r\n            };\r\n        }\r\n\r\n        if (Env.supportsCanvas()) {\r\n            Options.board.renderer = 'canvas';\r\n        }\r\n\r\n        if (Env.supportsSVG()) {\r\n            Options.board.renderer = 'svg';\r\n        }\r\n\r\n        // we are inside node\r\n        if (Env.isNode() && Env.supportsCanvas()) {\r\n            Options.board.renderer = 'canvas';\r\n        }\r\n\r\n        if (Env.isNode() || Options.renderer === 'no') {\r\n            Options.text.display = 'internal';\r\n            Options.infobox.display = 'internal';\r\n        }\r\n\r\n        return Options.board.renderer;\r\n    })(),\r\n\r\n    /**\r\n     * Initialize the rendering engine\r\n     *\r\n     * @param  {String} box        id of or reference to the div element which hosts the JSXGraph construction\r\n     * @param  {Object} dim        The dimensions of the board\r\n     * @param  {Object} doc        Usually, this is document object of the browser window.  If false or null, this defaults\r\n     * to the document object of the browser.\r\n     * @param  {Object} attrRenderer Attribute 'renderer', specifies the rendering engine. Possible values are 'auto', 'svg',\r\n     *  'canvas', 'no', and 'vml'.\r\n     * @returns {Object}           Reference to the rendering engine object.\r\n     * @private\r\n     */\r\n    initRenderer: function (box, dim, doc, attrRenderer) {\r\n        var boxid, renderer;\r\n\r\n        // Former version:\r\n        // doc = doc || document\r\n        if ((!Type.exists(doc) || doc === false) && typeof document === 'object') {\r\n            doc = document;\r\n        }\r\n\r\n        if (typeof doc === \"object\" && box !== null) {\r\n            boxid = (Type.isString(box)) ? doc.getElementById(box) : box;\r\n\r\n            // Remove everything from the container before initializing the renderer and the board\r\n            while (boxid.firstChild) {\r\n                boxid.removeChild(boxid.firstChild);\r\n            }\r\n        } else {\r\n            boxid = box;\r\n        }\r\n\r\n        // If attrRenderer is not supplied take the first available renderer\r\n        if (attrRenderer === undefined || attrRenderer === 'auto') {\r\n            attrRenderer = this.rendererType;\r\n        }\r\n        // create the renderer\r\n        if (attrRenderer === 'svg') {\r\n            renderer = new SVGRenderer(boxid, dim);\r\n        } else if (attrRenderer === 'vml') {\r\n            renderer = new VMLRenderer(boxid);\r\n        } else if (attrRenderer === 'canvas') {\r\n            renderer = new CanvasRenderer(boxid, dim);\r\n        } else {\r\n            renderer = new NoRenderer();\r\n        }\r\n\r\n        return renderer;\r\n    },\r\n\r\n    /**\r\n     * Merge the user supplied attributes with the attributes in options.js\r\n     *\r\n     * @param {Object} attributes User supplied attributes\r\n     * @returns {Object} Merged attributes for the board\r\n     *\r\n     * @private\r\n     */\r\n    _setAttributes: function (attributes, options) {\r\n        // merge attributes\r\n        var attr = Type.copyAttributes(attributes, options, 'board'),\r\n\r\n            // These attributes - which are objects - have to be copied separately.\r\n            list = [\r\n                'drag', 'fullscreen',\r\n                'intl',\r\n                'keyboard', 'logging',\r\n                'pan', 'resize',\r\n                'screenshot', 'selection',\r\n                'zoom'\r\n            ],\r\n            len = list.length, i, key;\r\n\r\n        for (i = 0; i < len; i++) {\r\n            key = list[i];\r\n            attr[key] = Type.copyAttributes(attr, options, 'board', key);\r\n        }\r\n        attr.navbar = Type.copyAttributes(attr.navbar, options, 'navbar');\r\n\r\n        // Treat moveTarget separately, because deepCopy will not work here.\r\n        // Reason: moveTarget will be an HTML node and it is prevented that Type.deepCopy will copy it.\r\n        attr.movetarget =\r\n            attributes.moveTarget || attributes.movetarget || options.board.moveTarget;\r\n\r\n        return attr;\r\n    },\r\n\r\n    /**\r\n     * Further initialization of the board. Set some properties from attribute values.\r\n     *\r\n     * @param {JXG.Board} board\r\n     * @param {Object} attr attributes object\r\n     * @param {Object} dimensions Object containing dimensions of the canvas\r\n     *\r\n     * @private\r\n     */\r\n    _fillBoard: function (board, attr, dimensions) {\r\n        board.initInfobox(attr.infobox);\r\n        board.maxboundingbox = attr.maxboundingbox;\r\n        board.resizeContainer(dimensions.width, dimensions.height, true, true);\r\n        board._createSelectionPolygon(attr);\r\n        board.renderer.drawNavigationBar(board, attr.navbar);\r\n        JXG.boards[board.id] = board;\r\n    },\r\n\r\n    /**\r\n     *\r\n     * @param {String|Object} container id of or reference to the HTML element in which the board is painted.\r\n     * @param {Object} attr An object that sets some of the board properties.\r\n     *\r\n     * @private\r\n     */\r\n    _setARIA: function (container, attr) {\r\n        var doc = attr.document,\r\n            node_jsx;\r\n            // Unused variables, made obsolete in db3e50f4dfa8b86b1ff619b578e243a97b41151c\r\n            // doc_glob,\r\n            // newNode,\r\n            // parent,\r\n            // id_label,\r\n            // id_description;\r\n\r\n            if (typeof doc !== 'object') {\r\n                if (!Env.isBrowser) {\r\n                    return;\r\n                }\r\n                doc = document;\r\n            }\r\n\r\n        node_jsx = (Type.isString(container)) ? doc.getElementById(container) : container;\r\n        node_jsx.setAttribute(\"role\", 'region');\r\n        node_jsx.setAttribute(\"aria-label\", attr.title);              // set by initBoard( {title:})\r\n\r\n        // doc_glob = node_jsx.ownerDocument; // This is the window.document element, needed below.\r\n        // parent = node_jsx.parentNode;\r\n\r\n    },\r\n\r\n    /**\r\n     * Remove the two corresponding ARIA divs when freeing a board\r\n     *\r\n     * @param {JXG.Board} board\r\n     *\r\n     * @private\r\n     */\r\n    _removeARIANodes: function (board) {\r\n        var node, id, doc;\r\n\r\n        doc = board.document || document;\r\n        if (typeof doc !== 'object') {\r\n            return;\r\n        }\r\n\r\n        id = board.containerObj.getAttribute(\"aria-labelledby\");\r\n        node = doc.getElementById(id);\r\n        if (node && node.parentNode) {\r\n            node.parentNode.removeChild(node);\r\n        }\r\n        id = board.containerObj.getAttribute(\"aria-describedby\");\r\n        node = doc.getElementById(id);\r\n        if (node && node.parentNode) {\r\n            node.parentNode.removeChild(node);\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Initialize a new board.\r\n     *\r\n     * @param {String|Object} box id of or reference to the HTML element in which the board is painted.\r\n     * @param {Object} attributes An object that sets some of the board properties.\r\n     * See {@link JXG.Board} for a list of available attributes of the board.\r\n     * Most of these attributes can also be set via {@link JXG.Options},\r\n     *\r\n     * @returns {JXG.Board} Reference to the created board.\r\n     *\r\n     * @see JXG.AbstractRenderer#drawNavigationBar\r\n     * @example\r\n     * var board = JXG.JSXGraph.initBoard('jxgbox', {\r\n     *     boundingbox: [-10, 5, 10, -5],\r\n     *     keepaspectratio: false,\r\n     *     axis: true\r\n     * });\r\n     *\r\n     * </pre><div id=\"JXGc0f76e98-20bc-4224-9016-7ffa10770dff\" class=\"jxgbox\" style=\"width: 600px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXGc0f76e98-20bc-4224-9016-7ffa10770dff', {\r\n     *         boundingbox: [-10, 5, 10, -5],\r\n     *         keepaspectratio: false,\r\n     *         axis: true\r\n     *     });\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     *\r\n     * @example\r\n     * const board = JXG.JSXGraph.initBoard('jxgbox', {\r\n     *   boundingbox: [-10, 10, 10, -10],\r\n     *   axis: true,\r\n     *   showCopyright: true,\r\n     *   showFullscreen: true,\r\n     *   showScreenshot: false,\r\n     *   showClearTraces: false,\r\n     *   showInfobox: false,\r\n     *   showNavigation: true,\r\n     *   grid: false,\r\n     *   defaultAxes: {\r\n     *     x: {\r\n     *       withLabel: true,\r\n     *       label: {\r\n     *         position: '95% left',\r\n     *         offset: [-10, 10]\r\n     *       },\r\n     *       lastArrow: {\r\n     *         type: 4,\r\n     *         size: 10\r\n     *       }\r\n     *     },\r\n     *     y: {\r\n     *       withLabel: true,\r\n     *       label: {\r\n     *         position: '0.90fr right',\r\n     *         offset: [6, -6]\r\n     *       },\r\n     *       lastArrow: {\r\n     *         type: 4,\r\n     *         size: 10\r\n     *       }\r\n     *     }\r\n     *   }\r\n     * });\r\n     *\r\n     * </pre><div id=\"JXG4ced167d-3235-48bc-84e9-1a28fce00f6a\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXG4ced167d-3235-48bc-84e9-1a28fce00f6a', {\r\n     *       boundingbox: [-10, 10, 10, -10],\r\n     *       axis: true,\r\n     *       showCopyright: true,\r\n     *       showFullscreen: true,\r\n     *       showScreenshot: false,\r\n     *       showClearTraces: false,\r\n     *       showInfobox: false,\r\n     *       showNavigation: true,\r\n     *       grid: false,\r\n     *       defaultAxes: {\r\n     *         x: {\r\n     *           withLabel: true,\r\n     *           label: {\r\n     *             position: '95% left',\r\n     *             offset: [0, 0]\r\n     *           },\r\n     *           lastArrow: {\r\n     *             type: 4,\r\n     *             size: 10\r\n     *           }\r\n     *         },\r\n     *         y: {\r\n     *           withLabel: true,\r\n     *           label: {\r\n     *             position: '0.90fr right',\r\n     *             offset: [0, 0]\r\n     *           },\r\n     *           lastArrow: {\r\n     *             type: 4,\r\n     *             size: 10\r\n     *           }\r\n     *         }\r\n     *       }\r\n     *     });\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     * @example\r\n     * const board = JXG.JSXGraph.initBoard('jxgbox', {\r\n     *     boundingbox: [-5, 5, 5, -5],\r\n     *     intl: {\r\n     *         enabled: false,\r\n     *         locale: 'en-EN'\r\n     *     },\r\n     *     keepaspectratio: true,\r\n     *     axis: true,\r\n     *     defaultAxes: {\r\n     *         x: {\r\n     *             ticks: {\r\n     *                 intl: {\r\n     *                         enabled: true,\r\n     *                         options: {\r\n     *                             style: 'unit',\r\n     *                             unit: 'kilometer-per-hour',\r\n     *                             unitDisplay: 'narrow'\r\n     *                         }\r\n     *                 }\r\n     *             }\r\n     *         },\r\n     *         y: {\r\n     *             ticks: {\r\n     *             }\r\n     *         }\r\n     *     },\r\n     *     infobox: {\r\n     *         fontSize: 20,\r\n     *         intl: {\r\n     *             enabled: true,\r\n     *             options: {\r\n     *                 minimumFractionDigits: 4,\r\n     *                 maximumFractionDigits: 5\r\n     *             }\r\n     *         }\r\n     *     }\r\n     * });\r\n     *\r\n     * </pre><div id=\"JXGdac54e59-f1e8-4fa6-bbcc-7486f7f6f960\" class=\"jxgbox\" style=\"width: 600px; height: 600px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXGdac54e59-f1e8-4fa6-bbcc-7486f7f6f960', {\r\n     *         boundingbox: [-5, 5, 5, -5],\r\n     *         intl: {\r\n     *             enabled: false,\r\n     *             locale: 'en-EN'\r\n     *         },\r\n     *         keepaspectratio: true,\r\n     *         axis: true,\r\n     *         defaultAxes: {\r\n     *             x: {\r\n     *                 ticks: {\r\n     *                     intl: {\r\n     *                             enabled: true,\r\n     *                             options: {\r\n     *                                 style: 'unit',\r\n     *                                 unit: 'kilometer-per-hour',\r\n     *                                 unitDisplay: 'narrow'\r\n     *                             }\r\n     *                     }\r\n     *                 }\r\n     *             },\r\n     *             y: {\r\n     *                 ticks: {\r\n     *                 }\r\n     *             }\r\n     *         },\r\n     *         infobox: {\r\n     *             fontSize: 20,\r\n     *             intl: {\r\n     *                 enabled: true,\r\n     *                 options: {\r\n     *                     minimumFractionDigits: 4,\r\n     *                     maximumFractionDigits: 5\r\n     *                 }\r\n     *             }\r\n     *         }\r\n     *     });\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     *\r\n     */\r\n    //  *\r\n    //  * @param {Array} [attributes.boundingbox=[-5, 5, 5, -5]] An array containing four numbers describing the left, top, right and bottom boundary of the board in user coordinates\r\n    //  * @param {Boolean} [attributes.keepaspectratio=false] If <tt>true</tt>, the bounding box is adjusted to the same aspect ratio as the aspect ratio of the div containing the board.\r\n    //  * @param {Boolean} [attributes.showCopyright=false] Show the copyright string in the top left corner.\r\n    //  * @param {Boolean} [attributes.showNavigation=false] Show the navigation buttons in the bottom right corner.\r\n    //  * @param {Object} [attributes.zoom] Allow the user to zoom with the mouse wheel or the two-fingers-zoom gesture.\r\n    //  * @param {Object} [attributes.pan] Allow the user to pan with shift+drag mouse or two-fingers-pan gesture.\r\n    //  * @param {Object} [attributes.drag] Allow the user to drag objects with a pointer device.\r\n    //  * @param {Object} [attributes.keyboard] Allow the user to drag objects with arrow keys on keyboard.\r\n    //  * @param {Boolean} [attributes.axis=false] If set to true, show the axis. Can also be set to an object that is given to both axes as an attribute object.\r\n    //  * @param {Boolean|Object} [attributes.grid] If set to true, shows the grid. Can also be set to an object that is given to the grid as its attribute object.\r\n    //  * @param {Boolean} [attributes.registerEvents=true] Register mouse / touch events.\r\n    initBoard: function (box, attributes) {\r\n        var originX, originY, unitX, unitY, w, h,\r\n            offX = 0, offY = 0,\r\n            renderer, dimensions, bbox,\r\n            attr, axattr, axattr_x, axattr_y,\r\n            options,\r\n            theme = {},\r\n            board;\r\n\r\n        attributes = attributes || {};\r\n        // Merge a possible theme\r\n        if (attributes.theme !== 'default' && Type.exists(JXG.themes[attributes.theme])) {\r\n            theme = JXG.themes[attributes.theme];\r\n        }\r\n        options = Type.deepCopy(Options, theme, true);\r\n        attr = this._setAttributes(attributes, options);\r\n\r\n        dimensions = Env.getDimensions(box, attr.document);\r\n\r\n        if (attr.unitx || attr.unity) {\r\n            originX = Type.def(attr.originx, 150);\r\n            originY = Type.def(attr.originy, 150);\r\n            unitX = Type.def(attr.unitx, 50);\r\n            unitY = Type.def(attr.unity, 50);\r\n        } else {\r\n            bbox = attr.boundingbox;\r\n            if (bbox[0] < attr.maxboundingbox[0]) {\r\n                bbox[0] = attr.maxboundingbox[0];\r\n            }\r\n            if (bbox[1] > attr.maxboundingbox[1]) {\r\n                bbox[1] = attr.maxboundingbox[1];\r\n            }\r\n            if (bbox[2] > attr.maxboundingbox[2]) {\r\n                bbox[2] = attr.maxboundingbox[2];\r\n            }\r\n            if (bbox[3] < attr.maxboundingbox[3]) {\r\n                bbox[3] = attr.maxboundingbox[3];\r\n            }\r\n\r\n            // Size of HTML div.\r\n            // If zero, the size is set to a small value to avoid\r\n            // division by zero.\r\n            // w = Math.max(parseInt(dimensions.width, 10), Mat.eps);\r\n            // h = Math.max(parseInt(dimensions.height, 10), Mat.eps);\r\n            w = parseInt(dimensions.width, 10);\r\n            h = parseInt(dimensions.height, 10);\r\n\r\n            if (Type.exists(bbox) && attr.keepaspectratio) {\r\n                /*\r\n                 * If the boundingbox attribute is given and the ratio of height and width of the\r\n                 * sides defined by the bounding box and the ratio of the dimensions of the div tag\r\n                 * which contains the board do not coincide, then the smaller side is chosen.\r\n                 */\r\n                unitX = w / (bbox[2] - bbox[0]);\r\n                unitY = h / (bbox[1] - bbox[3]);\r\n\r\n                if (Math.abs(unitX) < Math.abs(unitY)) {\r\n                    unitY = (Math.abs(unitX) * unitY) / Math.abs(unitY);\r\n                    // Add the additional units in equal portions above and below\r\n                    offY = (h / unitY - (bbox[1] - bbox[3])) * 0.5;\r\n                } else {\r\n                    unitX = (Math.abs(unitY) * unitX) / Math.abs(unitX);\r\n                    // Add the additional units in equal portions left and right\r\n                    offX = (w / unitX - (bbox[2] - bbox[0])) * 0.5;\r\n                }\r\n            } else {\r\n                unitX = w / (bbox[2] - bbox[0]);\r\n                unitY = h / (bbox[1] - bbox[3]);\r\n            }\r\n            originX = -unitX * (bbox[0] - offX);\r\n            originY = unitY * (bbox[1] + offY);\r\n        }\r\n\r\n        renderer = this.initRenderer(box, dimensions, attr.document, attr.renderer);\r\n        this._setARIA(box, attr);\r\n\r\n        // Create the board.\r\n        // board.options will contain the user supplied board attributes\r\n        board = new Board(\r\n            box,\r\n            renderer,\r\n            attr.id,\r\n            [originX, originY],\r\n            /*attr.zoomfactor * */ attr.zoomx,\r\n            /*attr.zoomfactor * */ attr.zoomy,\r\n            unitX,\r\n            unitY,\r\n            dimensions.width,\r\n            dimensions.height,\r\n            attr\r\n        );\r\n\r\n        board.keepaspectratio = attr.keepaspectratio;\r\n\r\n        this._fillBoard(board, attr, dimensions);\r\n\r\n        // Create elements like axes, grid, navigation, ...\r\n        board.suspendUpdate();\r\n        attr = board.attr;\r\n        if (attr.axis) {\r\n            axattr = typeof attr.axis === \"object\" ? attr.axis : {};\r\n\r\n            // The defaultAxes attributes are overwritten by user supplied axis object.\r\n            axattr_x = Type.deepCopy(options.board.defaultaxes.x, axattr);\r\n            axattr_y = Type.deepCopy(options.board.defaultaxes.y, axattr);\r\n\r\n            // The user supplied defaultAxes attributes are merged in.\r\n            if (attr.defaultaxes.x) {\r\n                axattr_x = Type.deepCopy(axattr_x, attr.defaultaxes.x);\r\n            }\r\n            if (attr.defaultaxes.y) {\r\n                axattr_y = Type.deepCopy(axattr_y, attr.defaultaxes.y);\r\n            }\r\n\r\n            board.defaultAxes = {};\r\n            board.defaultAxes.x = board.create(\"axis\", [[0, 0], [1, 0]], axattr_x);\r\n            board.defaultAxes.y = board.create(\"axis\", [[0, 0], [0, 1]], axattr_y);\r\n        }\r\n        if (attr.grid) {\r\n            board.create(\"grid\", [], typeof attr.grid === \"object\" ? attr.grid : {});\r\n        }\r\n        board.unsuspendUpdate();\r\n\r\n        return board;\r\n    },\r\n\r\n    /**\r\n     * Load a board from a file containing a construction made with either GEONExT,\r\n     * Intergeo, Geogebra, or Cinderella.\r\n     * @param {String|Object} box id of or reference to the HTML element in which the board is painted.\r\n     * @param {String} file base64 encoded string.\r\n     * @param {String} format containing the file format: 'Geonext' or 'Intergeo'.\r\n     * @param {Object} attributes Attributes for the board and 'encoding'.\r\n     *  Compressed files need encoding 'iso-8859-1'. Otherwise it probably is 'utf-8'.\r\n     * @param {Function} callback\r\n     * @returns {JXG.Board} Reference to the created board.\r\n     * @see JXG.FileReader\r\n     * @see JXG.GeonextReader\r\n     * @see JXG.GeogebraReader\r\n     * @see JXG.IntergeoReader\r\n     * @see JXG.CinderellaReader\r\n     *\r\n     * @example\r\n     * // Uncompressed file\r\n     * var board = JXG.JSXGraph.loadBoardFromFile('jxgbox', 'filename', 'geonext',\r\n     *      {encoding: 'utf-8'},\r\n     *      function (board) { console.log(\"Done loading\"); }\r\n     * );\r\n     * // Compressed file\r\n     * var board = JXG.JSXGraph.loadBoardFromFile('jxgbox', 'filename', 'geonext',\r\n     *      {encoding: 'iso-8859-1'},\r\n     *      function (board) { console.log(\"Done loading\"); }\r\n     * );\r\n     *\r\n     * @example\r\n     * // From <input type=\"file\" id=\"localfile\" />\r\n     * var file = document.getElementById('localfile').files[0];\r\n     * JXG.JSXGraph.loadBoardFromFile('jxgbox', file, 'geonext',\r\n     *      {encoding: 'utf-8'},\r\n     *      function (board) { console.log(\"Done loading\"); }\r\n     * );\r\n     */\r\n    loadBoardFromFile: function (box, file, format, attributes, callback) {\r\n        var attr, renderer, board, dimensions, encoding;\r\n\r\n        attributes = attributes || {};\r\n        attr = this._setAttributes(attributes);\r\n\r\n        dimensions = Env.getDimensions(box, attr.document);\r\n        renderer = this.initRenderer(box, dimensions, attr.document, attr.renderer);\r\n        this._setARIA(box, attr);\r\n\r\n        /* User default parameters, in parse* the values in the gxt files are submitted to board */\r\n        board = new Board(\r\n            box,\r\n            renderer,\r\n            \"\",\r\n            [150, 150],\r\n            1,\r\n            1,\r\n            50,\r\n            50,\r\n            dimensions.width,\r\n            dimensions.height,\r\n            attr\r\n        );\r\n        this._fillBoard(board, attr, dimensions);\r\n        encoding = attr.encoding || \"iso-8859-1\";\r\n        FileReader.parseFileContent(file, board, format, true, encoding, callback);\r\n\r\n        return board;\r\n    },\r\n\r\n    /**\r\n     * Load a board from a base64 encoded string containing a construction made with either GEONExT,\r\n     * Intergeo, Geogebra, or Cinderella.\r\n     * @param {String|Object} box id of or reference to the HTML element in which the board is painted.\r\n     * @param {String} string base64 encoded string.\r\n     * @param {String} format containing the file format: 'Geonext', 'Intergeo', 'Geogebra'.\r\n     * @param {Object} attributes Attributes for the board and 'encoding'.\r\n     *  Compressed files need encoding 'iso-8859-1'. Otherwise it probably is 'utf-8'.\r\n     * @param {Function} callback\r\n     * @returns {JXG.Board} Reference to the created board.\r\n     * @see JXG.FileReader\r\n     * @see JXG.GeonextReader\r\n     * @see JXG.GeogebraReader\r\n     * @see JXG.IntergeoReader\r\n     * @see JXG.CinderellaReader\r\n     */\r\n    loadBoardFromString: function (box, string, format, attributes, callback) {\r\n        var attr, renderer, board, dimensions;\r\n\r\n        attributes = attributes || {};\r\n        attr = this._setAttributes(attributes);\r\n\r\n        dimensions = Env.getDimensions(box, attr.document);\r\n        renderer = this.initRenderer(box, dimensions, attr.document, attr.renderer);\r\n        this._setARIA(box, attr);\r\n\r\n        /* User default parameters, in parse* the values in the gxt files are submitted to board */\r\n        board = new Board(\r\n            box,\r\n            renderer,\r\n            \"\",\r\n            [150, 150],\r\n            1.0,\r\n            1.0,\r\n            50,\r\n            50,\r\n            dimensions.width,\r\n            dimensions.height,\r\n            attr\r\n        );\r\n        this._fillBoard(board, attr, dimensions);\r\n        FileReader.parseString(string, board, format, true, callback);\r\n\r\n        return board;\r\n    },\r\n\r\n    /**\r\n     * Delete a board and all its contents.\r\n     * @param {JXG.Board|String} board id of or reference to the DOM element in which the board is drawn.\r\n     *\r\n     */\r\n    freeBoard: function (board) {\r\n        var el;\r\n\r\n        if (typeof board === 'string') {\r\n            board = JXG.boards[board];\r\n        }\r\n\r\n        this._removeARIANodes(board);\r\n        board.removeEventHandlers();\r\n        board.suspendUpdate();\r\n\r\n        // Remove all objects from the board.\r\n        for (el in board.objects) {\r\n            if (board.objects.hasOwnProperty(el)) {\r\n                board.objects[el].remove();\r\n            }\r\n        }\r\n\r\n        // Remove all the other things, left on the board, XHTML save\r\n        while (board.containerObj.firstChild) {\r\n            board.containerObj.removeChild(board.containerObj.firstChild);\r\n        }\r\n\r\n        // Tell the browser the objects aren't needed anymore\r\n        for (el in board.objects) {\r\n            if (board.objects.hasOwnProperty(el)) {\r\n                delete board.objects[el];\r\n            }\r\n        }\r\n\r\n        // Free the renderer and the algebra object\r\n        delete board.renderer;\r\n\r\n        // clear the creator cache\r\n        board.jc.creator.clearCache();\r\n        delete board.jc;\r\n\r\n        // Finally remove the board itself from the boards array\r\n        delete JXG.boards[board.id];\r\n    },\r\n\r\n    /**\r\n     * @deprecated Use JXG#registerElement\r\n     * @param element\r\n     * @param creator\r\n     */\r\n    registerElement: function (element, creator) {\r\n        JXG.deprecated(\"JXG.JSXGraph.registerElement()\", \"JXG.registerElement()\");\r\n        JXG.registerElement(element, creator);\r\n    }\r\n};\r\n\r\n// JessieScript/JessieCode startup:\r\n// Search for script tags of type text/jessiecode and execute them.\r\nif (Env.isBrowser && typeof window === 'object' && typeof document === 'object') {\r\n    Env.addEvent(window, 'load',\r\n        function () {\r\n            var type, i, j, div, id,\r\n                board, txt, width, height, maxWidth, aspectRatio,\r\n                cssClasses, bbox, axis, grid, code, src, request,\r\n                postpone = false,\r\n\r\n                scripts = document.getElementsByTagName('script'),\r\n                init = function (code, type, bbox) {\r\n                    var board = JXG.JSXGraph.initBoard(id, {\r\n                        boundingbox: bbox,\r\n                        keepaspectratio: true,\r\n                        grid: grid,\r\n                        axis: axis,\r\n                        showReload: true\r\n                    });\r\n\r\n                    if (type.toLowerCase().indexOf('script') > -1) {\r\n                        board.construct(code);\r\n                    } else {\r\n                        try {\r\n                            board.jc.parse(code);\r\n                        } catch (e2) {\r\n                            JXG.debug(e2);\r\n                        }\r\n                    }\r\n\r\n                    return board;\r\n                },\r\n                makeReload = function (board, code, type, bbox) {\r\n                    return function () {\r\n                        var newBoard;\r\n\r\n                        JXG.JSXGraph.freeBoard(board);\r\n                        newBoard = init(code, type, bbox);\r\n                        newBoard.reload = makeReload(newBoard, code, type, bbox);\r\n                    };\r\n                };\r\n\r\n            for (i = 0; i < scripts.length; i++) {\r\n                type = scripts[i].getAttribute(\"type\", false);\r\n\r\n                if (\r\n                    Type.exists(type) &&\r\n                    (type.toLowerCase() === \"text/jessiescript\" ||\r\n                        type.toLowerCase() === \"jessiescript\" ||\r\n                        type.toLowerCase() === \"text/jessiecode\" ||\r\n                        type.toLowerCase() === 'jessiecode')\r\n                ) {\r\n                    cssClasses = scripts[i].getAttribute(\"class\", false) || \"\";\r\n                    width = scripts[i].getAttribute(\"width\", false) || \"\";\r\n                    height = scripts[i].getAttribute(\"height\", false) || \"\";\r\n                    maxWidth = scripts[i].getAttribute(\"maxwidth\", false) || \"100%\";\r\n                    aspectRatio = scripts[i].getAttribute(\"aspectratio\", false) || \"1/1\";\r\n                    bbox = scripts[i].getAttribute(\"boundingbox\", false) || \"-5, 5, 5, -5\";\r\n                    id = scripts[i].getAttribute(\"container\", false);\r\n                    src = scripts[i].getAttribute(\"src\", false);\r\n\r\n                    bbox = bbox.split(\",\");\r\n                    if (bbox.length !== 4) {\r\n                        bbox = [-5, 5, 5, -5];\r\n                    } else {\r\n                        for (j = 0; j < bbox.length; j++) {\r\n                            bbox[j] = parseFloat(bbox[j]);\r\n                        }\r\n                    }\r\n                    axis = Type.str2Bool(scripts[i].getAttribute(\"axis\", false) || 'false');\r\n                    grid = Type.str2Bool(scripts[i].getAttribute(\"grid\", false) || 'false');\r\n\r\n                    if (!Type.exists(id)) {\r\n                        id = \"jessiescript_autgen_jxg_\" + i;\r\n                        div = document.createElement('div');\r\n                        div.setAttribute(\"id\", id);\r\n\r\n                        txt = width !== \"\" ? \"width:\" + width + \";\" : \"\";\r\n                        txt += height !== \"\" ? \"height:\" + height + \";\" : \"\";\r\n                        txt += maxWidth !== \"\" ? \"max-width:\" + maxWidth + \";\" : \"\";\r\n                        txt += aspectRatio !== \"\" ? \"aspect-ratio:\" + aspectRatio + \";\" : \"\";\r\n\r\n                        div.setAttribute(\"style\", txt);\r\n                        div.setAttribute(\"class\", \"jxgbox \" + cssClasses);\r\n                        try {\r\n                            document.body.insertBefore(div, scripts[i]);\r\n                        } catch (e) {\r\n                            // there's probably jquery involved...\r\n                            if (Type.exists(jQuery) && typeof jQuery === 'object') {\r\n                                jQuery(div).insertBefore(scripts[i]);\r\n                            }\r\n                        }\r\n                    } else {\r\n                        div = document.getElementById(id);\r\n                    }\r\n\r\n                    code = \"\";\r\n\r\n                    if (Type.exists(src)) {\r\n                        postpone = true;\r\n                        request = new XMLHttpRequest();\r\n                        request.open(\"GET\", src);\r\n                        request.overrideMimeType(\"text/plain; charset=x-user-defined\");\r\n                        /* jshint ignore:start */\r\n                        request.addEventListener(\"load\", function () {\r\n                            if (this.status < 400) {\r\n                                code = this.responseText + \"\\n\" + code;\r\n                                board = init(code, type, bbox);\r\n                                board.reload = makeReload(board, code, type, bbox);\r\n                            } else {\r\n                                throw new Error(\r\n                                    \"\\nJSXGraph: failed to load file\",\r\n                                    src,\r\n                                    \":\",\r\n                                    this.responseText\r\n                                );\r\n                            }\r\n                        });\r\n                        request.addEventListener(\"error\", function (e) {\r\n                            throw new Error(\"\\nJSXGraph: failed to load file\", src, \":\", e);\r\n                        });\r\n                        /* jshint ignore:end */\r\n                        request.send();\r\n                    } else {\r\n                        postpone = false;\r\n                    }\r\n\r\n                    if (document.getElementById(id)) {\r\n                        code = scripts[i].innerHTML;\r\n                        code = code.replace(/<!\\[CDATA\\[/g, \"\").replace(/\\]\\]>/g, \"\");\r\n                        scripts[i].innerHTML = code;\r\n\r\n                        if (!postpone) {\r\n                            // Do no wait for data from \"src\" attribute\r\n                            board = init(code, type, bbox);\r\n                            board.reload = makeReload(board, code, type, bbox);\r\n                        }\r\n                    } else {\r\n                        JXG.debug(\r\n                            \"JSXGraph: Apparently the div injection failed. Can't create a board, sorry.\"\r\n                        );\r\n                    }\r\n                }\r\n            }\r\n        },\r\n        window\r\n    );\r\n}\r\n\r\nexport default JXG.JSXGraph;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, console: true, window: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview The geometry object Point is defined in this file. Point stores all\r\n * style and functional properties that are required to draw and move a point on\r\n * a board.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Options from \"../options.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Const from \"./constants.js\";\r\nimport GeometryElement from \"./element.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport CoordsElement from \"./coordselement.js\";\r\n\r\n/**\r\n * A point is the basic geometric element. Based on points lines and circles can be constructed which can be intersected\r\n * which in turn are points again which can be used to construct new lines, circles, polygons, etc. This class holds methods for\r\n * all kind of points like free points, gliders, and intersection points.\r\n * @class Creates a new point object. Do not use this constructor to create a point. Use {@link JXG.Board#create} with\r\n * type {@link Point}, {@link Glider}, or {@link Intersection} instead.\r\n * @augments JXG.GeometryElement\r\n * @augments JXG.CoordsElement\r\n * @param {string|JXG.Board} board The board the new point is drawn on.\r\n * @param {Array} coordinates An array with the user coordinates of the point.\r\n * @param {Object} attributes An object containing visual properties like in {@link JXG.Options#point} and\r\n * {@link JXG.Options#elements}, and optional a name and an id.\r\n * @see JXG.Board#generateName\r\n */\r\nJXG.Point = function (board, coordinates, attributes) {\r\n    this.constructor(board, attributes, Const.OBJECT_TYPE_POINT, Const.OBJECT_CLASS_POINT);\r\n    this.element = this.board.select(attributes.anchor);\r\n    this.coordsConstructor(coordinates);\r\n\r\n    this.elType = 'point';\r\n\r\n    /* Register point at board. */\r\n    this.id = this.board.setId(this, 'P');\r\n    this.board.renderer.drawPoint(this);\r\n    this.board.finalizeAdding(this);\r\n\r\n    this.createGradient();\r\n    this.createLabel();\r\n};\r\n\r\n/**\r\n * Inherits here from {@link JXG.GeometryElement}.\r\n */\r\nJXG.Point.prototype = new GeometryElement();\r\nType.copyPrototypeMethods(JXG.Point, CoordsElement, 'coordsConstructor');\r\n\r\nJXG.extend(\r\n    JXG.Point.prototype,\r\n    /** @lends JXG.Point.prototype */ {\r\n        /**\r\n         * Checks whether (x,y) is near the point.\r\n         * @param {Number} x Coordinate in x direction, screen coordinates.\r\n         * @param {Number} y Coordinate in y direction, screen coordinates.\r\n         * @returns {Boolean} True if (x,y) is near the point, False otherwise.\r\n         * @private\r\n         */\r\n        hasPoint: function (x, y) {\r\n            var coordsScr = this.coords.scrCoords,\r\n                r,\r\n                prec,\r\n                type,\r\n                unit = this.evalVisProp('sizeunit');\r\n\r\n            if (Type.isObject(this.evalVisProp('precision'))) {\r\n                type = this.board._inputDevice;\r\n                prec = this.evalVisProp('precision.' + type);\r\n            } else {\r\n                // 'inherit'\r\n                prec = this.board.options.precision.hasPoint;\r\n            }\r\n            r = parseFloat(this.evalVisProp('size'));\r\n            if (unit === 'user') {\r\n                r *= Math.sqrt(Math.abs(this.board.unitX * this.board.unitY));\r\n            }\r\n\r\n            r += parseFloat(this.evalVisProp('strokewidth')) * 0.5;\r\n            if (r < prec) {\r\n                r = prec;\r\n            }\r\n\r\n            return Math.abs(coordsScr[1] - x) < r + 2 && Math.abs(coordsScr[2] - y) < r + 2;\r\n        },\r\n\r\n        /**\r\n         * Updates the position of the point.\r\n         */\r\n        update: function (fromParent) {\r\n            if (!this.needsUpdate) {\r\n                return this;\r\n            }\r\n\r\n            this.updateCoords(fromParent);\r\n\r\n            if (this.evalVisProp('trace')) {\r\n                this.cloneToBackground(true);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Applies the transformations of the element to {@link JXG.Point#baseElement}.\r\n         * Point transformations are relative to a base element.\r\n         * @param {Boolean} fromParent True if the drag comes from a child element. This is the case if a line\r\n         *    through two points is dragged. Otherwise, the element is the drag element and we apply the\r\n         *    the inverse transformation to the baseElement if is different from the element.\r\n         * @returns {JXG.CoordsElement} Reference to this object.\r\n         */\r\n        updateTransform: function (fromParent) {\r\n            var c, i;\r\n\r\n            if (this.transformations.length === 0 || this.baseElement === null) {\r\n                return this;\r\n            }\r\n\r\n            this.transformations[0].update();\r\n            if (this === this.baseElement) {\r\n                // Case of bindTo\r\n                c = this.transformations[0].apply(this, 'self');\r\n            } else {\r\n                c = this.transformations[0].apply(this.baseElement);\r\n            }\r\n            for (i = 1; i < this.transformations.length; i++) {\r\n                this.transformations[i].update();\r\n                c = Mat.matVecMult(this.transformations[i].matrix, c);\r\n            }\r\n            this.coords.setCoordinates(Const.COORDS_BY_USER, c);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Calls the renderer to update the drawing.\r\n         * @private\r\n         */\r\n        updateRenderer: function () {\r\n            this.updateRendererGeneric('updatePoint');\r\n            return this;\r\n        },\r\n\r\n        // documented in JXG.GeometryElement\r\n        bounds: function () {\r\n            return this.coords.usrCoords.slice(1).concat(this.coords.usrCoords.slice(1));\r\n        },\r\n\r\n        /**\r\n         * Convert the point to intersection point and update the construction.\r\n         * To move the point visual onto the intersection, a call of board update is necessary.\r\n         *\r\n         * @param {String|Object} el1, el2, i, j The intersecting objects and the numbers.\r\n         **/\r\n        makeIntersection: function (el1, el2, i, j) {\r\n            var func;\r\n\r\n            el1 = this.board.select(el1);\r\n            el2 = this.board.select(el2);\r\n\r\n            func = Geometry.intersectionFunction(\r\n                this.board,\r\n                el1, el2, i, j,\r\n                this.visProp.alwaysintersect\r\n            );\r\n            this.addConstraint([func]);\r\n\r\n            try {\r\n                el1.addChild(this);\r\n                el2.addChild(this);\r\n            } catch (e) {\r\n                throw new Error(\r\n                    \"JSXGraph: Can't create 'intersection' with parent types '\" +\r\n                        typeof el1 +\r\n                        \"' and '\" +\r\n                        typeof el2 +\r\n                        \"'.\"\r\n                );\r\n            }\r\n\r\n            this.type = Const.OBJECT_TYPE_INTERSECTION;\r\n            this.elType = 'intersection';\r\n            this.parents = [el1.id, el2.id, i, j];\r\n\r\n            this.generatePolynomial = function () {\r\n                var poly1 = el1.generatePolynomial(this),\r\n                    poly2 = el2.generatePolynomial(this);\r\n\r\n                if (poly1.length === 0 || poly2.length === 0) {\r\n                    return [];\r\n                }\r\n\r\n                return [poly1[0], poly2[0]];\r\n            };\r\n\r\n            this.prepareUpdate().update();\r\n        },\r\n\r\n        /**\r\n         * Set the style of a point.\r\n         * Used for GEONExT import and should not be used to set the point's face and size.\r\n         * @param {Number} i Integer to determine the style.\r\n         * @private\r\n         */\r\n        setStyle: function (i) {\r\n            var facemap = [\r\n                    // 0-2\r\n                    \"cross\",\r\n                    \"cross\",\r\n                    \"cross\",\r\n                    // 3-6\r\n                    \"circle\",\r\n                    \"circle\",\r\n                    \"circle\",\r\n                    \"circle\",\r\n                    // 7-9\r\n                    \"square\",\r\n                    \"square\",\r\n                    \"square\",\r\n                    // 10-12\r\n                    \"plus\",\r\n                    \"plus\",\r\n                    \"plus\"\r\n                ],\r\n                sizemap = [\r\n                    // 0-2\r\n                    2, 3, 4,\r\n                    // 3-6\r\n                    1, 2, 3, 4,\r\n                    // 7-9\r\n                    2, 3, 4,\r\n                    // 10-12\r\n                    2, 3, 4\r\n                ];\r\n\r\n            this.visProp.face = facemap[i];\r\n            this.visProp.size = sizemap[i];\r\n\r\n            this.board.renderer.changePointStyle(this);\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @deprecated Use JXG#normalizePointFace instead\r\n         * @param s\r\n         * @returns {*}\r\n         */\r\n        normalizeFace: function (s) {\r\n            JXG.deprecated(\"Point.normalizeFace()\", \"JXG.normalizePointFace()\");\r\n            return Options.normalizePointFace(s);\r\n        },\r\n\r\n        /**\r\n         * Set the face of a point element.\r\n         * @param {String} f String which determines the face of the point. See {@link JXG.GeometryElement#face} for a list of available faces.\r\n         * @see JXG.GeometryElement#face\r\n         * @deprecated Use setAttribute()\r\n         */\r\n        face: function (f) {\r\n            JXG.deprecated(\"Point.face()\", \"Point.setAttribute()\");\r\n            this.setAttribute({ face: f });\r\n        },\r\n\r\n        /**\r\n         * Set the size of a point element\r\n         * @param {Number} s Integer which determines the size of the point.\r\n         * @see JXG.GeometryElement#size\r\n         * @deprecated Use setAttribute()\r\n         */\r\n        size: function (s) {\r\n            JXG.deprecated(\"Point.size()\", \"Point.setAttribute()\");\r\n            this.setAttribute({ size: s });\r\n        },\r\n\r\n        /**\r\n         * Test if the point is on (is incident with) element \"el\".\r\n         *\r\n         * @param {JXG.GeometryElement} el\r\n         * @param {Number} tol\r\n         * @returns {Boolean}\r\n         *\r\n         * @example\r\n         * var circ = board.create('circle', [[-2, -2], 1]);\r\n         * var seg = board.create('segment', [[-1, -3], [0,0]]);\r\n         * var line = board.create('line', [[1, 3], [2, -2]]);\r\n         * var po = board.create('point', [-1, 0], {color: 'blue'});\r\n         * var curve = board.create('functiongraph', ['sin(x)'], {strokeColor: 'blue'});\r\n         * var pol = board.create('polygon', [[2,2], [4,2], [4,3]], {strokeColor: 'blue'});\r\n         *\r\n         * var point = board.create('point', [-1, 1], {\r\n         *               attractors: [line, seg, circ, po, curve, pol],\r\n         *               attractorDistance: 0.2\r\n         *             });\r\n         *\r\n         * var txt = board.create('text', [-4, 3, function() {\r\n         *              return 'point on line: ' + point.isOn(line) + '<br>' +\r\n         *                 'point on seg: ' + point.isOn(seg) + '<br>' +\r\n         *                 'point on circ = ' + point.isOn(circ) + '<br>' +\r\n         *                 'point on point = ' + point.isOn(po) + '<br>' +\r\n         *                 'point on curve = ' + point.isOn(curve) + '<br>' +\r\n         *                 'point on polygon = ' + point.isOn(pol) + '<br>';\r\n         * }]);\r\n         *\r\n         * </pre><div id=\"JXG6c7d7404-758a-44eb-802c-e9644b9fab71\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG6c7d7404-758a-44eb-802c-e9644b9fab71',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var circ = board.create('circle', [[-2, -2], 1]);\r\n         *     var seg = board.create('segment', [[-1, -3], [0,0]]);\r\n         *     var line = board.create('line', [[1, 3], [2, -2]]);\r\n         *     var po = board.create('point', [-1, 0], {color: 'blue'});\r\n         *     var curve = board.create('functiongraph', ['sin(x)'], {strokeColor: 'blue'});\r\n         *     var pol = board.create('polygon', [[2,2], [4,2], [4,3]], {strokeColor: 'blue'});\r\n         *\r\n         *     var point = board.create('point', [-1, 1], {\r\n         *                   attractors: [line, seg, circ, po, curve, pol],\r\n         *                   attractorDistance: 0.2\r\n         *                 });\r\n         *\r\n         *     var txt = board.create('text', [-4, 3, function() {\r\n         *             return 'point on line: ' + point.isOn(line) + '<br>' +\r\n         *                     'point on seg: ' + point.isOn(seg) + '<br>' +\r\n         *                     'point on circ = ' + point.isOn(circ) + '<br>' +\r\n         *                     'point on point = ' + point.isOn(po) + '<br>' +\r\n         *                     'point on curve = ' + point.isOn(curve) + '<br>' +\r\n         *                     'point on polygon = ' + point.isOn(pol) + '<br>';\r\n         *     }]);\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        isOn: function (el, tol) {\r\n            var arr, crds;\r\n\r\n            tol = tol || Mat.eps;\r\n\r\n            if (Type.isPoint(el)) {\r\n                return this.Dist(el) < tol;\r\n            } else if (el.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                if (el.elType === \"segment\" && !this.evalVisProp('alwaysintersect')) {\r\n                    arr = JXG.Math.Geometry.projectCoordsToSegment(\r\n                        this.coords.usrCoords,\r\n                        el.point1.coords.usrCoords,\r\n                        el.point2.coords.usrCoords\r\n                    );\r\n                    if (\r\n                        arr[1] >= 0 &&\r\n                        arr[1] <= 1 &&\r\n                        Geometry.distPointLine(this.coords.usrCoords, el.stdform) < tol\r\n                    ) {\r\n                        return true;\r\n                    } else {\r\n                        return false;\r\n                    }\r\n                } else {\r\n                    return Geometry.distPointLine(this.coords.usrCoords, el.stdform) < tol;\r\n                }\r\n            } else if (el.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n                if (el.evalVisProp('hasinnerpoints')) {\r\n                    return this.Dist(el.center) < el.Radius() + tol;\r\n                }\r\n                return Math.abs(this.Dist(el.center) - el.Radius()) < tol;\r\n            } else if (el.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n                crds = Geometry.projectPointToCurve(this, el, this.board)[0];\r\n                return Geometry.distance(this.coords.usrCoords, crds.usrCoords, 3) < tol;\r\n            } else if (el.type === Const.OBJECT_TYPE_POLYGON) {\r\n                if (el.evalVisProp('hasinnerpoints')) {\r\n                    if (\r\n                        el.pnpoly(\r\n                            this.coords.usrCoords[1],\r\n                            this.coords.usrCoords[2],\r\n                            JXG.COORDS_BY_USER\r\n                        )\r\n                    ) {\r\n                        return true;\r\n                    }\r\n                }\r\n                arr = Geometry.projectCoordsToPolygon(this.coords.usrCoords, el);\r\n                return Geometry.distance(this.coords.usrCoords, arr, 3) < tol;\r\n            } else if (el.type === Const.OBJECT_TYPE_TURTLE) {\r\n                crds = Geometry.projectPointToTurtle(this, el, this.board);\r\n                return Geometry.distance(this.coords.usrCoords, crds.usrCoords, 3) < tol;\r\n            }\r\n\r\n            // TODO: Arc, Sector\r\n            return false;\r\n        },\r\n\r\n        // Already documented in GeometryElement\r\n        cloneToBackground: function () {\r\n            var copy = Type.getCloneObject(this);\r\n\r\n            this.board.renderer.drawPoint(copy);\r\n            this.traces[copy.id] = copy.rendNode;\r\n\r\n            return this;\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * @class Construct a free or a fixed point. A free point is created if the given parent elements are all numbers\r\n * and the property fixed is not set or set to false. If one or more parent elements is not a number but a string containing a GEONE<sub>x</sub>T\r\n * constraint or a function the point will be considered as constrained). That means that the user won't be able to change the point's\r\n * position directly.\r\n * @see Glider for a non-free point that is attached to another geometric element.\r\n * @pseudo\r\n * @name Point\r\n * @augments JXG.Point\r\n * @constructor\r\n * @type JXG.Point\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Number,string,function_Number,string,function_Number,string,function} z_,x,y Parent elements can be two or three elements of type number, a string containing a GEONE<sub>x</sub>T\r\n * constraint, or a function which takes no parameter and returns a number. Every parent element determines one coordinate. If a coordinate is\r\n * given by a number, the number determines the initial position of a free point. If given by a string or a function that coordinate will be constrained\r\n * that means the user won't be able to change the point's position directly by mouse because it will be calculated automatically depending on the string\r\n * or the function's return value. If two parent elements are given the coordinates will be interpreted as 2D affine Euclidean coordinates, if three such\r\n * parent elements are given they will be interpreted as homogeneous coordinates.\r\n * @param {JXG.Point_JXG.Transformation_Array} Point,Transformation A point can also be created providing a transformation or an array of transformations.\r\n * The resulting point is a clone of the base point transformed by the given Transformation. {@see JXG.Transformation}.\r\n *\r\n * @example\r\n * // Create a free point using affine Euclidean coordinates\r\n * var p1 = board.create('point', [3.5, 2.0]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG672f1764-7dfa-4abc-a2c6-81fbbf83e44b\" style=\"width: 200px; height: 200px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var board = JXG.JSXGraph.initBoard('JXG672f1764-7dfa-4abc-a2c6-81fbbf83e44b', {boundingbox: [-1, 5, 5, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var p1 = board.create('point', [3.5, 2.0]);\r\n * </script><pre>\r\n * @example\r\n * // Create a constrained point using anonymous function\r\n * var p2 = board.create('point', [3.5, function () { return p1.X(); }]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG4fd4410c-3383-4e80-b1bb-961f5eeef224\" style=\"width: 200px; height: 200px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var fpex1_board = JXG.JSXGraph.initBoard('JXG4fd4410c-3383-4e80-b1bb-961f5eeef224', {boundingbox: [-1, 5, 5, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var fpex1_p1 = fpex1_board.create('point', [3.5, 2.0]);\r\n *   var fpex1_p2 = fpex1_board.create('point', [3.5, function () { return fpex1_p1.X(); }]);\r\n * </script><pre>\r\n * @example\r\n * // Create a point using transformations\r\n * var trans = board.create('transform', [2, 0.5], {type:'scale'});\r\n * var p3 = board.create('point', [p2, trans]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG630afdf3-0a64-46e0-8a44-f51bd197bb8d\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var fpex2_board = JXG.JSXGraph.initBoard('JXG630afdf3-0a64-46e0-8a44-f51bd197bb8d', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var fpex2_trans = fpex2_board.create('transform', [2, 0.5], {type:'scale'});\r\n *   var fpex2_p2 = fpex2_board.create('point', [3.5, 2.0]);\r\n *   var fpex2_p3 = fpex2_board.create('point', [fpex2_p2, fpex2_trans]);\r\n * </script><pre>\r\n */\r\nJXG.createPoint = function (board, parents, attributes) {\r\n    var el, attr;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'point');\r\n    el = CoordsElement.create(JXG.Point, board, parents, attr);\r\n    if (!el) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create point with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [x,y], [z,x,y], [element,transformation]\"\r\n        );\r\n    }\r\n\r\n    return el;\r\n};\r\n\r\n/**\r\n * @class A glider is a point bound to a line, circle or curve or even another point.\r\n * @pseudo\r\n * @description A glider is a point which lives on another geometric element like a line, circle, curve, turtle.\r\n * @name Glider\r\n * @augments JXG.Point\r\n * @constructor\r\n * @type JXG.Point\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Number_Number_Number_JXG.GeometryElement} z_,x_,y_,GlideObject Parent elements can be two or three elements of type number and the object the glider lives on.\r\n * The coordinates are completely optional. If not given the origin is used. If you provide two numbers for coordinates they will be interpreted as affine Euclidean\r\n * coordinates, otherwise they will be interpreted as homogeneous coordinates. In any case the point will be projected on the glide object.\r\n * @example\r\n * // Create a glider with user defined coordinates. If the coordinates are not on\r\n * // the circle (like in this case) the point will be projected onto the circle.\r\n * var p1 = board.create('point', [2.0, 2.0]);\r\n * var c1 = board.create('circle', [p1, 2.0]);\r\n * var p2 = board.create('glider', [2.0, 1.5, c1]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG4f65f32f-e50a-4b50-9b7c-f6ec41652930\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var gpex1_board = JXG.JSXGraph.initBoard('JXG4f65f32f-e50a-4b50-9b7c-f6ec41652930', {boundingbox: [-1, 5, 5, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var gpex1_p1 = gpex1_board.create('point', [2.0, 2.0]);\r\n *   var gpex1_c1 = gpex1_board.create('circle', [gpex1_p1, 2.0]);\r\n *   var gpex1_p2 = gpex1_board.create('glider', [2.0, 1.5, gpex1_c1]);\r\n * </script><pre>\r\n * @example\r\n * // Create a glider with default coordinates (1,0,0). Same premises as above.\r\n * var p1 = board.create('point', [2.0, 2.0]);\r\n * var c1 = board.create('circle', [p1, 2.0]);\r\n * var p2 = board.create('glider', [c1]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG4de7f181-631a-44b1-a12f-bc4d995609e8\" style=\"width: 200px; height: 200px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var gpex2_board = JXG.JSXGraph.initBoard('JXG4de7f181-631a-44b1-a12f-bc4d995609e8', {boundingbox: [-1, 5, 5, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var gpex2_p1 = gpex2_board.create('point', [2.0, 2.0]);\r\n *   var gpex2_c1 = gpex2_board.create('circle', [gpex2_p1, 2.0]);\r\n *   var gpex2_p2 = gpex2_board.create('glider', [gpex2_c1]);\r\n * </script><pre>\r\n *@example\r\n * //animate example 2\r\n * var p1 = board.create('point', [2.0, 2.0]);\r\n * var c1 = board.create('circle', [p1, 2.0]);\r\n * var p2 = board.create('glider', [c1]);\r\n * var button1 = board.create('button', [1, 7, 'start animation',function(){p2.startAnimation(1,4)}]);\r\n * var button2 = board.create('button', [1, 5, 'stop animation',function(){p2.stopAnimation()}]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG4de7f181-631a-44b1-a12f-bc4d133709e8\" style=\"width: 200px; height: 200px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var gpex3_board = JXG.JSXGraph.initBoard('JXG4de7f181-631a-44b1-a12f-bc4d133709e8', {boundingbox: [-1, 10, 10, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var gpex3_p1 = gpex3_board.create('point', [2.0, 2.0]);\r\n *   var gpex3_c1 = gpex3_board.create('circle', [gpex3_p1, 2.0]);\r\n *   var gpex3_p2 = gpex3_board.create('glider', [gpex3_c1]);\r\n *   gpex3_board.create('button', [1, 7, 'start animation',function(){gpex3_p2.startAnimation(1,4)}]);\r\n *   gpex3_board.create('button', [1, 5, 'stop animation',function(){gpex3_p2.stopAnimation()}]);\r\n * </script><pre>\r\n */\r\nJXG.createGlider = function (board, parents, attributes) {\r\n    var el,\r\n        coords,\r\n        attr = Type.copyAttributes(attributes, board.options, 'glider');\r\n\r\n    if (parents.length === 1) {\r\n        coords = [0, 0];\r\n    } else {\r\n        coords = parents.slice(0, 2);\r\n    }\r\n    el = board.create(\"point\", coords, attr);\r\n\r\n    // eltype is set in here\r\n    el.makeGlider(parents[parents.length - 1]);\r\n\r\n    return el;\r\n};\r\n\r\n/**\r\n * @class A point intersecting two 1-dimensional elements.\r\n * It is one point of the set  * consisting of the intersection points of the two elements.\r\n * The following element types can be (mutually) intersected: line, circle,\r\n * curve, polygon, polygonal chain.\r\n *\r\n * @pseudo\r\n * @name Intersection\r\n * @augments JXG.Point\r\n * @constructor\r\n * @type JXG.Point\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Line,JXG.Circle_JXG.Line,JXG.Circle_Number|Function} el1,el2,i The result will be a intersection point on el1 and el2. i determines the\r\n * intersection point if two points are available: <ul>\r\n *   <li>i==0: use the positive square root,</li>\r\n *   <li>i==1: use the negative square root.</li></ul>\r\n * @example\r\n * // Create an intersection point of circle and line\r\n * var p1 = board.create('point', [4.0, 4.0]);\r\n * var c1 = board.create('circle', [p1, 2.0]);\r\n *\r\n * var p2 = board.create('point', [1.0, 1.0]);\r\n * var p3 = board.create('point', [5.0, 3.0]);\r\n * var l1 = board.create('line', [p2, p3]);\r\n *\r\n * var i = board.create('intersection', [c1, l1, 0]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGe5b0e190-5200-4bc3-b995-b6cc53dc5dc0\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var ipex1_board = JXG.JSXGraph.initBoard('JXGe5b0e190-5200-4bc3-b995-b6cc53dc5dc0', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var ipex1_p1 = ipex1_board.create('point', [4.0, 4.0]);\r\n *   var ipex1_c1 = ipex1_board.create('circle', [ipex1_p1, 2.0]);\r\n *   var ipex1_p2 = ipex1_board.create('point', [1.0, 1.0]);\r\n *   var ipex1_p3 = ipex1_board.create('point', [5.0, 3.0]);\r\n *   var ipex1_l1 = ipex1_board.create('line', [ipex1_p2, ipex1_p3]);\r\n *   var ipex1_i = ipex1_board.create('intersection', [ipex1_c1, ipex1_l1, 0]);\r\n * </script><pre>\r\n */\r\nJXG.createIntersectionPoint = function (board, parents, attributes) {\r\n    var el, el1, el2, func,\r\n        i, j,\r\n        attr = Type.copyAttributes(attributes, board.options, 'intersection');\r\n\r\n    // make sure we definitely have the indices\r\n    parents.push(0, 0);\r\n\r\n    el1 = board.select(parents[0]);\r\n    el2 = board.select(parents[1]);\r\n\r\n    i = parents[2] || 0;\r\n    j = parents[3] || 0;\r\n\r\n    el = board.create(\"point\", [0, 0, 0], attr);\r\n\r\n    // el.visProp.alwaysintersect is evaluated as late as in the returned function\r\n    func = Geometry.intersectionFunction(board, el1, el2, i, j, el.visProp.alwaysintersect);\r\n    el.addConstraint([func]);\r\n\r\n    try {\r\n        el1.addChild(el);\r\n        el2.addChild(el);\r\n    } catch (e) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create 'intersection' with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\"\r\n        );\r\n    }\r\n\r\n    el.type = Const.OBJECT_TYPE_INTERSECTION;\r\n    el.elType = 'intersection';\r\n    el.setParents([el1.id, el2.id]);\r\n\r\n    /**\r\n     * Array of length 2 containing the numbers i and j.\r\n     * The intersection point is i-th intersection point.\r\n     * j is unused.\r\n     * @type Array\r\n     * @name intersectionNumbers\r\n     * @memberOf Intersection\r\n     * @private\r\n     */\r\n    el.intersectionNumbers = [i, j];\r\n    el.getParents = function () {\r\n        return this.parents.concat(this.intersectionNumbers);\r\n    };\r\n\r\n    el.generatePolynomial = function () {\r\n        var poly1 = el1.generatePolynomial(el),\r\n            poly2 = el2.generatePolynomial(el);\r\n\r\n        if (poly1.length === 0 || poly2.length === 0) {\r\n            return [];\r\n        }\r\n\r\n        return [poly1[0], poly2[0]];\r\n    };\r\n\r\n    return el;\r\n};\r\n\r\n/**\r\n * @class Given a set of intersection points, this is another ('other') intersection point,\r\n * @pseudo\r\n * @description If two elements of type curve, circle or line intersect in more than one point, with this element it is possible\r\n * to construct the \"other\" intersection. This is a an intersection which is different from a supplied point or different from any\r\n * point in an array of supplied points. This might be helpful in situtations where one intersection point is already part of the construction\r\n * or in situtation where the order of the intersection points changes while interacting with the construction.\r\n *\r\n * @name OtherIntersection\r\n * @augments JXG.Point\r\n * @constructor\r\n * @type JXG.Point\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Line,JXG.Circle_JXG.Line,JXG.Circle_JXG.Point,Array} el1,el2,p Two elements which are intersected and a point or an array of points\r\n * which have to be different from the new intersection point.\r\n *\r\n * @example\r\n * // Create an intersection point of circle and line\r\n * var p1 = board.create('point', [2.0, 2.0]);\r\n * var c1 = board.create('circle', [p1, 2.0]);\r\n *\r\n * var p2 = board.create('point', [2.0, 2.0]);\r\n * var p3 = board.create('point', [2.0, 2.0]);\r\n * var l1 = board.create('line', [p2, p3]);\r\n *\r\n * var p1 = board.create('intersection', [c1, l1, 0]);\r\n * var p2 = board.create('otherintersection', [c1, l1, p1]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG45e25f12-a1de-4257-a466-27a2ae73614c\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var ipex2_board = JXG.JSXGraph.initBoard('JXG45e25f12-a1de-4257-a466-27a2ae73614c', {boundingbox: [-1, 7, 7, -1], axis: false, showcopyright: false, shownavigation: false});\r\n *   var ipex2_p1 = ipex2_board.create('point', [4.0, 4.0]);\r\n *   var ipex2_c1 = ipex2_board.create('circle', [ipex2_p1, 2.0]);\r\n *   var ipex2_p2 = ipex2_board.create('point', [1.0, 1.0]);\r\n *   var ipex2_p3 = ipex2_board.create('point', [5.0, 3.0]);\r\n *   var ipex2_l1 = ipex2_board.create('line', [ipex2_p2, ipex2_p3]);\r\n *   var ipex2_i = ipex2_board.create('intersection', [ipex2_c1, ipex2_l1, 0], {name:'D'});\r\n *   var ipex2_j = ipex2_board.create('otherintersection', [ipex2_c1, ipex2_l1, ipex2_i], {name:'E'});\r\n * </script><pre>\r\n *\r\n * @example\r\n *  // circle / circle\r\n *  var c1 = board.create('circle', [[0, 0], 3]);\r\n *  var c2 = board.create('circle', [[2, 2], 3]);\r\n *\r\n *  var p1 = board.create('intersection', [c1, c2, 0]);\r\n *  var p2 = board.create('otherintersection', [c1, c2, p1]);\r\n *\r\n * </pre><div id=\"JXGdb5c974c-3092-4cdf-b5ef-d0af4a912581\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGdb5c974c-3092-4cdf-b5ef-d0af4a912581',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *           var c1 = board.create('circle', [[0, 0], 3]);\r\n *           var c2 = board.create('circle', [[2, 2], 3]);\r\n *\r\n *           var p1 = board.create('intersection', [c1, c2, 0]);\r\n *           var p2 = board.create('otherintersection', [c1, c2, p1]);\r\n *     })();\r\n * </script><pre>\r\n *\r\n * @example\r\n *  // curve / line\r\n *  var curve = board.create('implicitcurve', ['-(y**2) + x**3 - 2 * x + 1'], { strokeWidth: 2 });\r\n *  var A = board.create('glider', [-1.5, 1, curve]);\r\n *  var B = board.create('glider', [0.5, 0.5, curve]);\r\n *  var line = board.create('line', [A, B], { color: 'black', strokeWidth: 1 });\r\n *  var C = board.create('otherintersection', [curve, line, [A, B]], {precision: 0.01});\r\n *  var D = board.create('point', [() => C.X(), () => -C.Y()], { name: '-C = A + B' });\r\n *\r\n * </pre><div id=\"JXG033f15b0-f5f1-4003-ab6a-b7e13e867fbd\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG033f15b0-f5f1-4003-ab6a-b7e13e867fbd',\r\n *             {boundingbox: [-2, 2, 2, -2], axis: false, showcopyright: false, shownavigation: false});\r\n *           var curve = board.create('implicitcurve', ['-(y**2) + x**3 - 2 * x + 1'], { strokeWidth: 2 });\r\n *           var A = board.create('glider', [-1.5, 1, curve]);\r\n *           var B = board.create('glider', [0.5, 0.5, curve]);\r\n *           var line = board.create('line', [A, B], { color: 'black', strokeWidth: 1 });\r\n *           var C = board.create('otherintersection', [curve, line, [A, B]], {precision: 0.01});\r\n *           var D = board.create('point', [() => C.X(), () => -C.Y()], { name: '-C = A + B' });\r\n *     })();\r\n * </script><pre>\r\n *\r\n * @example\r\n *  // curve / curve\r\n *  var c1 = board.create('functiongraph', ['x**2 - 3'], { strokeWidth: 2 });\r\n *  var A = board.create('point', [0, 2]);\r\n *  var c2 = board.create('functiongraph', [(x) => -(x**2) + 2 * A.X() * x + A.Y() - A.X()**2], { strokeWidth: 2 });\r\n *  var p1 = board.create('intersection', [c1, c2]);\r\n *  var p2 = board.create('otherintersection', [c1, c2, [p1]]);\r\n *\r\n * </pre><div id=\"JXG29359aa9-3066-4f45-9e5d-d74201b991d3\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG29359aa9-3066-4f45-9e5d-d74201b991d3',\r\n *             {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false});\r\n *           var c1 = board.create('functiongraph', ['x**2 - 3'], { strokeWidth: 2 });\r\n *           var A = board.create('point', [0, 2]);\r\n *           var c2 = board.create('functiongraph', [(x) => -(x**2) + 2 * A.X() * x + A.Y() - A.X()**2], { strokeWidth: 2 });\r\n *           var p1 = board.create('intersection', [c1, c2]);\r\n *           var p2 = board.create('otherintersection', [c1, c2, [p1]]);\r\n *     })();\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createOtherIntersectionPoint = function (board, parents, attributes) {\r\n    var el, el1, el2, i,\r\n    others, func, input,\r\n    isGood = true,\r\n    attr = Type.copyAttributes(attributes, board.options, 'otherintersection');\r\n\r\n    if (parents.length !== 3) {\r\n        isGood = false;\r\n    } else {\r\n        el1 = board.select(parents[0]);\r\n        el2 = board.select(parents[1]);\r\n        if (Type.isArray(parents[2])) {\r\n            others = parents[2];\r\n        } else {\r\n            others = [parents[2]];\r\n        }\r\n\r\n        for (i = 0; i < others.length; i++) {\r\n            others[i] = board.select(others[i]);\r\n            if (!Type.isPoint(others[i])) {\r\n                isGood = false;\r\n                break;\r\n            }\r\n        }\r\n        if (isGood) {\r\n            input = [el1, el2];\r\n            // Sort parent elements in order: curve, circle, line\r\n            input.sort(function (a, b) { return b.elementClass - a.elementClass; });\r\n\r\n            // Two lines are forbidden:\r\n            if ([Const.OBJECT_CLASS_CIRCLE, Const.OBJECT_CLASS_CURVE].indexOf(input[0].elementClass) < 0) {\r\n                isGood = false;\r\n            } else if ([Const.OBJECT_CLASS_CIRCLE, Const.OBJECT_CLASS_CURVE, Const.OBJECT_CLASS_LINE].indexOf(input[1].elementClass) < 0) {\r\n                isGood = false;\r\n            }\r\n        }\r\n    }\r\n\r\n    if (!isGood) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create 'other intersection point' with parent types '\" +\r\n                typeof parents[0] + \"',  '\" + typeof parents[1] + \"'and  '\" + typeof parents[2] + \"'.\" +\r\n                \"\\nPossible parent types: [circle|curve|line,circle|curve|line, point], not two lines\"\r\n        );\r\n    }\r\n\r\n    el = board.create('point', [0, 0, 0], attr);\r\n    // el.visProp.alwaysintersect is evaluated as late as in the returned function\r\n    func = Geometry.otherIntersectionFunction(input, others, el.visProp.alwaysintersect, el.visProp.precision);\r\n    el.addConstraint([func]);\r\n\r\n    el.type = Const.OBJECT_TYPE_INTERSECTION;\r\n    el.elType = 'otherintersection';\r\n    el.setParents([el1.id, el2.id]);\r\n    el.addParents(others);\r\n\r\n    el1.addChild(el);\r\n    el2.addChild(el);\r\n\r\n    if (el1.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n        // circle, circle|line\r\n        el.generatePolynomial = function () {\r\n            var poly1 = el1.generatePolynomial(el),\r\n                poly2 = el2.generatePolynomial(el);\r\n\r\n            if (poly1.length === 0 || poly2.length === 0) {\r\n                return [];\r\n            }\r\n\r\n            return [poly1[0], poly2[0]];\r\n        };\r\n    }\r\n\r\n    return el;\r\n};\r\n\r\n/**\r\n * @class This element is used to provide a constructor for the pole point of a line with respect to a conic or a circle.\r\n * @pseudo\r\n * @description The pole point is the unique reciprocal relationship of a line with respect to a conic.\r\n * The lines tangent to the intersections of a conic and a line intersect at the pole point of that line with respect to that conic.\r\n * A line tangent to a conic has the pole point of that line with respect to that conic as the tangent point.\r\n * See {@link https://en.wikipedia.org/wiki/Pole_and_polar} for more information on pole and polar.\r\n * @name PolePoint\r\n * @augments JXG.Point\r\n * @constructor\r\n * @type JXG.Point\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Conic,JXG.Circle_JXG.Point} el1,el2 or\r\n * @param {JXG.Point_JXG.Conic,JXG.Circle} el1,el2 The result will be the pole point of the line with respect to the conic or the circle.\r\n * @example\r\n * // Create the pole point of a line with respect to a conic\r\n * var p1 = board.create('point', [-1, 2]);\r\n * var p2 = board.create('point', [ 1, 4]);\r\n * var p3 = board.create('point', [-1,-2]);\r\n * var p4 = board.create('point', [ 0, 0]);\r\n * var p5 = board.create('point', [ 4,-2]);\r\n * var c1 = board.create('conic',[p1,p2,p3,p4,p5]);\r\n * var p6 = board.create('point', [-1, 4]);\r\n * var p7 = board.create('point', [2, -2]);\r\n * var l1 = board.create('line', [p6, p7]);\r\n * var p8 = board.create('polepoint', [c1, l1]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG7b7233a0-f363-47dd-9df5-8018d0d17a98\" class=\"jxgbox\" style=\"width:400px; height:400px;\"></div>\r\n * <script type='text/javascript'>\r\n * var ppex1_board = JXG.JSXGraph.initBoard('JXG7b7233a0-f363-47dd-9df5-8018d0d17a98', {boundingbox: [-3, 5, 5, -3], axis: true, showcopyright: false, shownavigation: false});\r\n * var ppex1_p1 = ppex1_board.create('point', [-1, 2]);\r\n * var ppex1_p2 = ppex1_board.create('point', [ 1, 4]);\r\n * var ppex1_p3 = ppex1_board.create('point', [-1,-2]);\r\n * var ppex1_p4 = ppex1_board.create('point', [ 0, 0]);\r\n * var ppex1_p5 = ppex1_board.create('point', [ 4,-2]);\r\n * var ppex1_c1 = ppex1_board.create('conic',[ppex1_p1,ppex1_p2,ppex1_p3,ppex1_p4,ppex1_p5]);\r\n * var ppex1_p6 = ppex1_board.create('point', [-1, 4]);\r\n * var ppex1_p7 = ppex1_board.create('point', [2, -2]);\r\n * var ppex1_l1 = ppex1_board.create('line', [ppex1_p6, ppex1_p7]);\r\n * var ppex1_p8 = ppex1_board.create('polepoint', [ppex1_c1, ppex1_l1]);\r\n * </script><pre>\r\n * @example\r\n * // Create the pole point of a line with respect to a circle\r\n * var p1 = board.create('point', [1, 1]);\r\n * var p2 = board.create('point', [2, 3]);\r\n * var c1 = board.create('circle',[p1,p2]);\r\n * var p3 = board.create('point', [-1, 4]);\r\n * var p4 = board.create('point', [4, -1]);\r\n * var l1 = board.create('line', [p3, p4]);\r\n * var p5 = board.create('polepoint', [c1, l1]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG7b7233a0-f363-47dd-9df5-9018d0d17a98\" class=\"jxgbox\" style=\"width:400px; height:400px;\"></div>\r\n * <script type='text/javascript'>\r\n * var ppex2_board = JXG.JSXGraph.initBoard('JXG7b7233a0-f363-47dd-9df5-9018d0d17a98', {boundingbox: [-3, 7, 7, -3], axis: true, showcopyright: false, shownavigation: false});\r\n * var ppex2_p1 = ppex2_board.create('point', [1, 1]);\r\n * var ppex2_p2 = ppex2_board.create('point', [2, 3]);\r\n * var ppex2_c1 = ppex2_board.create('circle',[ppex2_p1,ppex2_p2]);\r\n * var ppex2_p3 = ppex2_board.create('point', [-1, 4]);\r\n * var ppex2_p4 = ppex2_board.create('point', [4, -1]);\r\n * var ppex2_l1 = ppex2_board.create('line', [ppex2_p3, ppex2_p4]);\r\n * var ppex2_p5 = ppex2_board.create('polepoint', [ppex2_c1, ppex2_l1]);\r\n * </script><pre>\r\n */\r\nJXG.createPolePoint = function (board, parents, attributes) {\r\n    var el,\r\n        el1,\r\n        el2,\r\n        firstParentIsConic,\r\n        secondParentIsConic,\r\n        firstParentIsLine,\r\n        secondParentIsLine;\r\n\r\n    if (parents.length > 1) {\r\n        firstParentIsConic =\r\n            parents[0].type === Const.OBJECT_TYPE_CONIC ||\r\n            parents[0].elementClass === Const.OBJECT_CLASS_CIRCLE;\r\n        secondParentIsConic =\r\n            parents[1].type === Const.OBJECT_TYPE_CONIC ||\r\n            parents[1].elementClass === Const.OBJECT_CLASS_CIRCLE;\r\n\r\n        firstParentIsLine = parents[0].elementClass === Const.OBJECT_CLASS_LINE;\r\n        secondParentIsLine = parents[1].elementClass === Const.OBJECT_CLASS_LINE;\r\n    }\r\n\r\n    /*        if (parents.length !== 2 || !((\r\n                parents[0].type === Const.OBJECT_TYPE_CONIC ||\r\n                parents[0].elementClass === Const.OBJECT_CLASS_CIRCLE) &&\r\n                parents[1].elementClass === Const.OBJECT_CLASS_LINE ||\r\n                parents[0].elementClass === Const.OBJECT_CLASS_LINE && (\r\n                parents[1].type === Const.OBJECT_TYPE_CONIC ||\r\n                parents[1].elementClass === Const.OBJECT_CLASS_CIRCLE))) {*/\r\n    if (\r\n        parents.length !== 2 ||\r\n        !(\r\n            (firstParentIsConic && secondParentIsLine) ||\r\n            (firstParentIsLine && secondParentIsConic)\r\n        )\r\n    ) {\r\n        // Failure\r\n        throw new Error(\r\n            \"JSXGraph: Can't create 'pole point' with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent type: [conic|circle,line], [line,conic|circle]\"\r\n        );\r\n    }\r\n\r\n    if (secondParentIsLine) {\r\n        el1 = board.select(parents[0]);\r\n        el2 = board.select(parents[1]);\r\n    } else {\r\n        el1 = board.select(parents[1]);\r\n        el2 = board.select(parents[0]);\r\n    }\r\n\r\n    el = board.create(\r\n        \"point\",\r\n        [\r\n            function () {\r\n                var q = el1.quadraticform,\r\n                    s = el2.stdform.slice(0, 3);\r\n\r\n                return [\r\n                    JXG.Math.Numerics.det([s, q[1], q[2]]),\r\n                    JXG.Math.Numerics.det([q[0], s, q[2]]),\r\n                    JXG.Math.Numerics.det([q[0], q[1], s])\r\n                ];\r\n            }\r\n        ],\r\n        attributes\r\n    );\r\n\r\n    el.elType = 'polepoint';\r\n    el.setParents([el1.id, el2.id]);\r\n\r\n    el1.addChild(el);\r\n    el2.addChild(el);\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"point\", JXG.createPoint);\r\nJXG.registerElement(\"glider\", JXG.createGlider);\r\nJXG.registerElement(\"intersection\", JXG.createIntersectionPoint);\r\nJXG.registerElement(\"otherintersection\", JXG.createOtherIntersectionPoint);\r\nJXG.registerElement(\"polepoint\", JXG.createPolePoint);\r\n\r\nexport default JXG.Point;\r\n// export default {\r\n//     Point: JXG.Point,\r\n//     createPoint: JXG.createPoint,\r\n//     createGlider: JXG.createGlider,\r\n//     createIntersection: JXG.createIntersectionPoint,\r\n//     createOtherIntersection: JXG.createOtherIntersectionPoint,\r\n//     createPolePoint: JXG.createPolePoint\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*\r\n    Some functionalities in this file were developed as part of a software project\r\n    with students. We would like to thank all contributors for their help:\r\n\r\n    Winter semester 2023/2024:\r\n        Matti Kirchbach\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview The geometry object Line is defined in this file. Line stores all\r\n * style and functional properties that are required to draw and move a line on\r\n * a board.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Numerics from \"../math/numerics.js\";\r\nimport Statistics from \"../math/statistics.js\";\r\nimport Const from \"./constants.js\";\r\nimport Coords from \"./coords.js\";\r\nimport GeometryElement from \"./element.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * The Line class is a basic class for all kind of line objects, e.g. line, arrow, and axis. It is usually defined by two points and can\r\n * be intersected with some other geometry elements.\r\n * @class Creates a new basic line object. Do not use this constructor to create a line.\r\n * Use {@link JXG.Board#create} with\r\n * type {@link Line}, {@link Arrow}, or {@link Axis} instead.\r\n * @constructor\r\n * @augments JXG.GeometryElement\r\n * @param {String|JXG.Board} board The board the new line is drawn on.\r\n * @param {Point} p1 Startpoint of the line.\r\n * @param {Point} p2 Endpoint of the line.\r\n * @param {Object} attributes Javascript object containing attributes like name, id and colors.\r\n */\r\nJXG.Line = function (board, p1, p2, attributes) {\r\n    this.constructor(board, attributes, Const.OBJECT_TYPE_LINE, Const.OBJECT_CLASS_LINE);\r\n\r\n    /**\r\n     * Startpoint of the line. You really should not set this field directly as it may break JSXGraph's\r\n     * update system so your construction won't be updated properly.\r\n     * @type JXG.Point\r\n     */\r\n    this.point1 = this.board.select(p1);\r\n\r\n    /**\r\n     * Endpoint of the line. Just like {@link JXG.Line.point1} you shouldn't write this field directly.\r\n     * @type JXG.Point\r\n     */\r\n    this.point2 = this.board.select(p2);\r\n\r\n    /**\r\n     * Array of ticks storing all the ticks on this line. Do not set this field directly and use\r\n     * {@link JXG.Line#addTicks} and {@link JXG.Line#removeTicks} to add and remove ticks to and from the line.\r\n     * @type Array\r\n     * @see JXG.Ticks\r\n     */\r\n    this.ticks = [];\r\n\r\n    /**\r\n     * Reference of the ticks created automatically when constructing an axis.\r\n     * @type JXG.Ticks\r\n     * @see JXG.Ticks\r\n     */\r\n    this.defaultTicks = null;\r\n\r\n    /**\r\n     * If the line is the border of a polygon, the polygon object is stored, otherwise null.\r\n     * @type JXG.Polygon\r\n     * @default null\r\n     * @private\r\n     */\r\n    this.parentPolygon = null;\r\n\r\n    /* Register line at board */\r\n    this.id = this.board.setId(this, 'L');\r\n    this.board.renderer.drawLine(this);\r\n    this.board.finalizeAdding(this);\r\n\r\n    this.elType = 'line';\r\n\r\n    /* Add line as child to defining points */\r\n    if (this.point1._is_new) {\r\n        this.addChild(this.point1);\r\n        delete this.point1._is_new;\r\n    } else {\r\n        this.point1.addChild(this);\r\n    }\r\n    if (this.point2._is_new) {\r\n        this.addChild(this.point2);\r\n        delete this.point2._is_new;\r\n    } else {\r\n        this.point2.addChild(this);\r\n    }\r\n\r\n    this.inherits.push(this.point1, this.point2);\r\n\r\n    this.updateStdform(); // This is needed in the following situation:\r\n    // * the line is defined by three coordinates\r\n    // * and it will have a glider\r\n    // * and board.suspendUpdate() has been called.\r\n\r\n    // create Label\r\n    this.createLabel();\r\n\r\n    this.methodMap = JXG.deepCopy(this.methodMap, {\r\n        point1: \"point1\",\r\n        point2: \"point2\",\r\n        getSlope: \"Slope\",\r\n        Slope: \"Slope\",\r\n        Direction: \"Direction\",\r\n        getRise: \"getRise\",\r\n        Rise: \"getRise\",\r\n        getYIntersect: \"getRise\",\r\n        YIntersect: \"getRise\",\r\n        getAngle: \"getAngle\",\r\n        Angle: \"getAngle\",\r\n        L: \"L\",\r\n        length: \"L\",\r\n        setFixedLength: \"setFixedLength\",\r\n        setStraight: \"setStraight\"\r\n    });\r\n};\r\n\r\nJXG.Line.prototype = new GeometryElement();\r\n\r\nJXG.extend(\r\n    JXG.Line.prototype,\r\n    /** @lends JXG.Line.prototype */ {\r\n        /**\r\n         * Checks whether (x,y) is near the line.\r\n         * @param {Number} x Coordinate in x direction, screen coordinates.\r\n         * @param {Number} y Coordinate in y direction, screen coordinates.\r\n         * @returns {Boolean} True if (x,y) is near the line, False otherwise.\r\n         */\r\n        hasPoint: function (x, y) {\r\n            // Compute the stdform of the line in screen coordinates.\r\n            var c = [],\r\n                v = [1, x, y],\r\n                s, vnew, p1c, p2c, d, pos, i, prec, type,\r\n                sw = this.evalVisProp('strokewidth');\r\n\r\n            if (Type.isObject(this.evalVisProp('precision'))) {\r\n                type = this.board._inputDevice;\r\n                prec = this.evalVisProp('precision.' + type);\r\n            } else {\r\n                // 'inherit'\r\n                prec = this.board.options.precision.hasPoint;\r\n            }\r\n            prec += sw * 0.5;\r\n\r\n            c[0] =\r\n                this.stdform[0] -\r\n                (this.stdform[1] * this.board.origin.scrCoords[1]) / this.board.unitX +\r\n                (this.stdform[2] * this.board.origin.scrCoords[2]) / this.board.unitY;\r\n            c[1] = this.stdform[1] / this.board.unitX;\r\n            c[2] = this.stdform[2] / -this.board.unitY;\r\n\r\n            s = Geometry.distPointLine(v, c);\r\n            if (isNaN(s) || s > prec) {\r\n                return false;\r\n            }\r\n\r\n            if (\r\n                this.evalVisProp('straightfirst') &&\r\n                this.evalVisProp('straightlast')\r\n            ) {\r\n                return true;\r\n            }\r\n\r\n            // If the line is a ray or segment we have to check if the projected point is between P1 and P2.\r\n            p1c = this.point1.coords;\r\n            p2c = this.point2.coords;\r\n\r\n            // Project the point orthogonally onto the line\r\n            vnew = [0, c[1], c[2]];\r\n            // Orthogonal line to c through v\r\n            vnew = Mat.crossProduct(vnew, v);\r\n            // Intersect orthogonal line with line\r\n            vnew = Mat.crossProduct(vnew, c);\r\n\r\n            // Normalize the projected point\r\n            vnew[1] /= vnew[0];\r\n            vnew[2] /= vnew[0];\r\n            vnew[0] = 1;\r\n\r\n            vnew = new Coords(Const.COORDS_BY_SCREEN, vnew.slice(1), this.board).usrCoords;\r\n            d = p1c.distance(Const.COORDS_BY_USER, p2c);\r\n            p1c = p1c.usrCoords.slice(0);\r\n            p2c = p2c.usrCoords.slice(0);\r\n\r\n            // The defining points are identical\r\n            if (d < Mat.eps) {\r\n                pos = 0;\r\n            } else {\r\n                /*\r\n                 * Handle the cases, where one of the defining points is an ideal point.\r\n                 * d is set to something close to infinity, namely 1/eps.\r\n                 * The ideal point is (temporarily) replaced by a finite point which has\r\n                 * distance d from the other point.\r\n                 * This is accomplished by extracting the x- and y-coordinates (x,y)=:v of the ideal point.\r\n                 * v determines the direction of the line. v is normalized, i.e. set to length 1 by dividing through its length.\r\n                 * Finally, the new point is the sum of the other point and v*d.\r\n                 *\r\n                 */\r\n\r\n                // At least one point is an ideal point\r\n                if (d === Number.POSITIVE_INFINITY) {\r\n                    d = 1 / Mat.eps;\r\n\r\n                    // The second point is an ideal point\r\n                    if (Math.abs(p2c[0]) < Mat.eps) {\r\n                        d /= Geometry.distance([0, 0, 0], p2c);\r\n                        p2c = [1, p1c[1] + p2c[1] * d, p1c[2] + p2c[2] * d];\r\n                        // The first point is an ideal point\r\n                    } else {\r\n                        d /= Geometry.distance([0, 0, 0], p1c);\r\n                        p1c = [1, p2c[1] + p1c[1] * d, p2c[2] + p1c[2] * d];\r\n                    }\r\n                }\r\n                i = 1;\r\n                d = p2c[i] - p1c[i];\r\n\r\n                if (Math.abs(d) < Mat.eps) {\r\n                    i = 2;\r\n                    d = p2c[i] - p1c[i];\r\n                }\r\n                pos = (vnew[i] - p1c[i]) / d;\r\n            }\r\n\r\n            if (!this.evalVisProp('straightfirst') && pos < 0) {\r\n                return false;\r\n            }\r\n\r\n            return !(!this.evalVisProp('straightlast') && pos > 1);\r\n        },\r\n\r\n        // documented in base/element\r\n        update: function () {\r\n            var funps;\r\n\r\n            if (!this.needsUpdate) {\r\n                return this;\r\n            }\r\n\r\n            if (this.constrained) {\r\n                if (Type.isFunction(this.funps)) {\r\n                    funps = this.funps();\r\n                    if (funps && funps.length && funps.length === 2) {\r\n                        this.point1 = funps[0];\r\n                        this.point2 = funps[1];\r\n                    }\r\n                } else {\r\n                    if (Type.isFunction(this.funp1)) {\r\n                        funps = this.funp1();\r\n                        if (Type.isPoint(funps)) {\r\n                            this.point1 = funps;\r\n                        } else if (funps && funps.length && funps.length === 2) {\r\n                            this.point1.setPositionDirectly(Const.COORDS_BY_USER, funps);\r\n                        }\r\n                    }\r\n\r\n                    if (Type.isFunction(this.funp2)) {\r\n                        funps = this.funp2();\r\n                        if (Type.isPoint(funps)) {\r\n                            this.point2 = funps;\r\n                        } else if (funps && funps.length && funps.length === 2) {\r\n                            this.point2.setPositionDirectly(Const.COORDS_BY_USER, funps);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            this.updateSegmentFixedLength();\r\n            this.updateStdform();\r\n\r\n            if (this.evalVisProp('trace')) {\r\n                this.cloneToBackground(true);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Update segments with fixed length and at least one movable point.\r\n         * @private\r\n         */\r\n        updateSegmentFixedLength: function () {\r\n            var d, d_new, d1, d2, drag1, drag2, x, y;\r\n\r\n            if (!this.hasFixedLength) {\r\n                return this;\r\n            }\r\n\r\n            // Compute the actual length of the segment\r\n            d = this.point1.Dist(this.point2);\r\n            // Determine the length the segment ought to have\r\n            d_new = (this.evalVisProp('nonnegativeonly')) ?\r\n                Math.max(0.0, this.fixedLength()) :\r\n                Math.abs(this.fixedLength());\r\n\r\n            // Distances between the two points and their respective\r\n            // position before the update\r\n            d1 = this.fixedLengthOldCoords[0].distance(\r\n                Const.COORDS_BY_USER,\r\n                this.point1.coords\r\n            );\r\n            d2 = this.fixedLengthOldCoords[1].distance(\r\n                Const.COORDS_BY_USER,\r\n                this.point2.coords\r\n            );\r\n\r\n            // If the position of the points or the fixed length function has been changed we have to work.\r\n            if (d1 > Mat.eps || d2 > Mat.eps || d !== d_new) {\r\n                drag1 =\r\n                    this.point1.isDraggable &&\r\n                    this.point1.type !== Const.OBJECT_TYPE_GLIDER &&\r\n                    !this.point1.evalVisProp('fixed');\r\n                drag2 =\r\n                    this.point2.isDraggable &&\r\n                    this.point2.type !== Const.OBJECT_TYPE_GLIDER &&\r\n                    !this.point2.evalVisProp('fixed');\r\n\r\n                // First case: the two points are different\r\n                // Then we try to adapt the point that was not dragged\r\n                // If this point can not be moved (e.g. because it is a glider)\r\n                // we try move the other point\r\n                if (d > Mat.eps) {\r\n                    if ((d1 > d2 && drag2) || (d1 <= d2 && drag2 && !drag1)) {\r\n                        this.point2.setPositionDirectly(Const.COORDS_BY_USER, [\r\n                            this.point1.X() + ((this.point2.X() - this.point1.X()) * d_new) / d,\r\n                            this.point1.Y() + ((this.point2.Y() - this.point1.Y()) * d_new) / d\r\n                        ]);\r\n                        this.point2.fullUpdate();\r\n                    } else if ((d1 <= d2 && drag1) || (d1 > d2 && drag1 && !drag2)) {\r\n                        this.point1.setPositionDirectly(Const.COORDS_BY_USER, [\r\n                            this.point2.X() + ((this.point1.X() - this.point2.X()) * d_new) / d,\r\n                            this.point2.Y() + ((this.point1.Y() - this.point2.Y()) * d_new) / d\r\n                        ]);\r\n                        this.point1.fullUpdate();\r\n                    }\r\n                    // Second case: the two points are identical. In this situation\r\n                    // we choose a random direction.\r\n                } else {\r\n                    x = Math.random() - 0.5;\r\n                    y = Math.random() - 0.5;\r\n                    d = Mat.hypot(x, y);\r\n\r\n                    if (drag2) {\r\n                        this.point2.setPositionDirectly(Const.COORDS_BY_USER, [\r\n                            this.point1.X() + (x * d_new) / d,\r\n                            this.point1.Y() + (y * d_new) / d\r\n                        ]);\r\n                        this.point2.fullUpdate();\r\n                    } else if (drag1) {\r\n                        this.point1.setPositionDirectly(Const.COORDS_BY_USER, [\r\n                            this.point2.X() + (x * d_new) / d,\r\n                            this.point2.Y() + (y * d_new) / d\r\n                        ]);\r\n                        this.point1.fullUpdate();\r\n                    }\r\n                }\r\n                // Finally, we save the position of the two points.\r\n                this.fixedLengthOldCoords[0].setCoordinates(\r\n                    Const.COORDS_BY_USER,\r\n                    this.point1.coords.usrCoords\r\n                );\r\n                this.fixedLengthOldCoords[1].setCoordinates(\r\n                    Const.COORDS_BY_USER,\r\n                    this.point2.coords.usrCoords\r\n                );\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Updates the stdform derived from the parent point positions.\r\n         * @private\r\n         */\r\n        updateStdform: function () {\r\n            var v = Mat.crossProduct(\r\n                this.point1.coords.usrCoords,\r\n                this.point2.coords.usrCoords\r\n            );\r\n\r\n            this.stdform[0] = v[0];\r\n            this.stdform[1] = v[1];\r\n            this.stdform[2] = v[2];\r\n            this.stdform[3] = 0;\r\n\r\n            this.normalize();\r\n        },\r\n\r\n        /**\r\n         * Uses the boards renderer to update the line.\r\n         * @private\r\n         */\r\n        updateRenderer: function () {\r\n            //var wasReal;\r\n\r\n            if (!this.needsUpdate) {\r\n                return this;\r\n            }\r\n\r\n            if (this.visPropCalc.visible) {\r\n                // wasReal = this.isReal;\r\n                this.isReal =\r\n                    !isNaN(\r\n                        this.point1.coords.usrCoords[1] +\r\n                        this.point1.coords.usrCoords[2] +\r\n                        this.point2.coords.usrCoords[1] +\r\n                        this.point2.coords.usrCoords[2]\r\n                    ) && Mat.innerProduct(this.stdform, this.stdform, 3) >= Mat.eps * Mat.eps;\r\n\r\n                if (\r\n                    //wasReal &&\r\n                    !this.isReal\r\n                ) {\r\n                    this.updateVisibility(false);\r\n                }\r\n            }\r\n\r\n            if (this.visPropCalc.visible) {\r\n                this.board.renderer.updateLine(this);\r\n            }\r\n\r\n            /* Update the label if visible. */\r\n            if (\r\n                this.hasLabel &&\r\n                this.visPropCalc.visible &&\r\n                this.label &&\r\n                this.label.visPropCalc.visible &&\r\n                this.isReal\r\n            ) {\r\n                this.label.update();\r\n                this.board.renderer.updateText(this.label);\r\n            }\r\n\r\n            // Update rendNode display\r\n            this.setDisplayRendNode();\r\n\r\n            this.needsUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        // /**\r\n        //  * Used to generate a polynomial for a point p that lies on this line, i.e. p is collinear to\r\n        //  * {@link JXG.Line#point1} and {@link JXG.Line#point2}.\r\n        //  *\r\n        //  * @param {JXG.Point} p The point for that the polynomial is generated.\r\n        //  * @returns {Array} An array containing the generated polynomial.\r\n        //  * @private\r\n        //  */\r\n        generatePolynomial: function (p) {\r\n            var u1 = this.point1.symbolic.x,\r\n                u2 = this.point1.symbolic.y,\r\n                v1 = this.point2.symbolic.x,\r\n                v2 = this.point2.symbolic.y,\r\n                w1 = p.symbolic.x,\r\n                w2 = p.symbolic.y;\r\n\r\n            /*\r\n             * The polynomial in this case is determined by three points being collinear:\r\n             *\r\n             *      U (u1,u2)      W (w1,w2)                V (v1,v2)\r\n             *  ----x--------------x------------------------x----------------\r\n             *\r\n             *  The collinearity condition is\r\n             *\r\n             *      u2-w2       w2-v2\r\n             *     -------  =  -------           (1)\r\n             *      u1-w1       w1-v1\r\n             *\r\n             * Multiplying (1) with denominators and simplifying is\r\n             *\r\n             *    u2w1 - u2v1 + w2v1 - u1w2 + u1v2 - w1v2 = 0\r\n             */\r\n\r\n            return [\r\n                [\r\n                    \"(\", u2, \")*(\", w1, \")-(\", u2, \")*(\", v1, \")+(\", w2, \")*(\", v1, \")-(\", u1, \")*(\", w2, \")+(\", u1, \")*(\", v2, \")-(\", w1, \")*(\", v2, \")\"\r\n                ].join(\"\")\r\n            ];\r\n        },\r\n\r\n        /**\r\n         * Calculates the y intersect of the line.\r\n         * @returns {Number} The y intersect.\r\n         */\r\n        getRise: function () {\r\n            if (Math.abs(this.stdform[2]) >= Mat.eps) {\r\n                return -this.stdform[0] / this.stdform[2];\r\n            }\r\n\r\n            return Infinity;\r\n        },\r\n\r\n        /**\r\n         * Calculates the slope of the line.\r\n         * @returns {Number} The slope of the line or Infinity if the line is parallel to the y-axis.\r\n         */\r\n        Slope: function () {\r\n            if (Math.abs(this.stdform[2]) >= Mat.eps) {\r\n                return -this.stdform[1] / this.stdform[2];\r\n            }\r\n\r\n            return Infinity;\r\n        },\r\n\r\n        /**\r\n         * Alias for line.Slope\r\n         * @returns {Number} The slope of the line or Infinity if the line is parallel to the y-axis.\r\n         * @deprecated\r\n         * @see Line#Slope\r\n         */\r\n        getSlope: function () {\r\n            return this.Slope();\r\n        },\r\n\r\n        /**\r\n         * Determines the angle between the positive x axis and the line.\r\n         * @returns {Number}\r\n         */\r\n        getAngle: function () {\r\n            return Math.atan2(-this.stdform[1], this.stdform[2]);\r\n        },\r\n\r\n        /**\r\n         * Returns the direction vector of the line. This is an array of length two\r\n         * containing the direction vector as [x, y]. It is defined as\r\n         *  <li> the difference of the x- and y-coordinate of the second and first point, in case both points are finite or both points are infinite.\r\n         *  <li> [x, y] coordinates of point2, in case only point2 is infinite.\r\n         *  <li> [-x, -y] coordinates of point1, in case only point1 is infinite.\r\n         * @function\r\n         * @returns {Array} of length 2.\r\n         */\r\n        Direction: function () {\r\n            var coords1 = this.point1.coords.usrCoords,\r\n                coords2 = this.point2.coords.usrCoords;\r\n\r\n            if (coords2[0] === 0 && coords1[0] !== 0) {\r\n                return coords2.slice(1);\r\n            }\r\n\r\n            if (coords1[0] === 0 && coords2[0] !== 0) {\r\n                return [-coords1[1], -coords1[2]];\r\n            }\r\n\r\n            return [\r\n                coords2[1] - coords1[1],\r\n                coords2[2] - coords1[2]\r\n            ];\r\n        },\r\n\r\n        /**\r\n         * Returns true, if the line is vertical (if the x coordinate of the direction vector is 0).\r\n         * @function\r\n         * @returns {Boolean}\r\n         */\r\n        isVertical: function () {\r\n            var dir = this.Direction();\r\n            return dir[0] === 0 && dir[1] !== 0;\r\n        },\r\n\r\n        /**\r\n         * Returns true, if the line is horizontal (if the y coordinate of the direction vector is 0).\r\n         * @function\r\n         * @returns {Boolean}\r\n         */\r\n        isHorizontal: function () {\r\n            var dir = this.Direction();\r\n            return dir[1] === 0 && dir[0] !== 0;\r\n        },\r\n\r\n        /**\r\n         * Determines whether the line is drawn beyond {@link JXG.Line#point1} and\r\n         * {@link JXG.Line#point2} and updates the line.\r\n         * @param {Boolean} straightFirst True if the Line shall be drawn beyond\r\n         * {@link JXG.Line#point1}, false otherwise.\r\n         * @param {Boolean} straightLast True if the Line shall be drawn beyond\r\n         * {@link JXG.Line#point2}, false otherwise.\r\n         * @see Line#straightFirst\r\n         * @see Line#straightLast\r\n         * @private\r\n         */\r\n        setStraight: function (straightFirst, straightLast) {\r\n            this.visProp.straightfirst = straightFirst;\r\n            this.visProp.straightlast = straightLast;\r\n\r\n            this.board.renderer.updateLine(this);\r\n            return this;\r\n        },\r\n\r\n        // documented in geometry element\r\n        getTextAnchor: function () {\r\n            return new Coords(\r\n                Const.COORDS_BY_USER,\r\n                [\r\n                    0.5 * (this.point2.X() + this.point1.X()),\r\n                    0.5 * (this.point2.Y() + this.point1.Y())\r\n                ],\r\n                this.board\r\n            );\r\n        },\r\n\r\n        /**\r\n         * Adjusts Label coords relative to Anchor. DESCRIPTION\r\n         * @private\r\n         */\r\n        setLabelRelativeCoords: function (relCoords) {\r\n            if (Type.exists(this.label)) {\r\n                this.label.relativeCoords = new Coords(\r\n                    Const.COORDS_BY_SCREEN,\r\n                    [relCoords[0], -relCoords[1]],\r\n                    this.board\r\n                );\r\n            }\r\n        },\r\n\r\n        // documented in geometry element\r\n        getLabelAnchor: function () {\r\n            var x, y, pos,\r\n                xy, lbda, dx, dy, d,\r\n                dist = 1.5,\r\n                fs = 0,\r\n                c1 = new Coords(Const.COORDS_BY_USER, this.point1.coords.usrCoords, this.board),\r\n                c2 = new Coords(Const.COORDS_BY_USER, this.point2.coords.usrCoords, this.board),\r\n                ev_sf = this.evalVisProp('straightfirst'),\r\n                ev_sl = this.evalVisProp('straightlast');\r\n\r\n            if (ev_sf || ev_sl) {\r\n                Geometry.calcStraight(this, c1, c2, 0);\r\n            }\r\n\r\n            c1 = c1.scrCoords;\r\n            c2 = c2.scrCoords;\r\n\r\n            if (!Type.exists(this.label)) {\r\n                return new Coords(Const.COORDS_BY_SCREEN, [NaN, NaN], this.board);\r\n            }\r\n\r\n            pos = this.label.evalVisProp('position');\r\n            if (!Type.isString(pos)) {\r\n                return new Coords(Const.COORDS_BY_SCREEN, [NaN, NaN], this.board);\r\n            }\r\n\r\n            if (pos.indexOf('right') < 0 && pos.indexOf('left') < 0) {\r\n                // Old positioning commands\r\n                switch (pos) {\r\n                    case 'last':\r\n                        x = c2[1];\r\n                        y = c2[2];\r\n                        break;\r\n                    case 'first':\r\n                        x = c1[1];\r\n                        y = c1[2];\r\n                        break;\r\n                    case \"lft\":\r\n                    case \"llft\":\r\n                    case \"ulft\":\r\n                        if (c1[1] < c2[1] + Mat.eps) {\r\n                            x = c1[1];\r\n                            y = c1[2];\r\n                        } else {\r\n                            x = c2[1];\r\n                            y = c2[2];\r\n                        }\r\n                        break;\r\n                    case \"rt\":\r\n                    case \"lrt\":\r\n                    case \"urt\":\r\n                        if (c1[1] > c2[1] + Mat.eps) {\r\n                            x = c1[1];\r\n                            y = c1[2];\r\n                        } else {\r\n                            x = c2[1];\r\n                            y = c2[2];\r\n                        }\r\n                        break;\r\n                    default:\r\n                        x = 0.5 * (c1[1] + c2[1]);\r\n                        y = 0.5 * (c1[2] + c2[2]);\r\n                }\r\n            } else {\r\n                // New positioning\r\n                xy = Type.parsePosition(pos);\r\n                lbda = Type.parseNumber(xy.pos, 1, 1);\r\n\r\n                dx = c2[1] - c1[1];\r\n                dy = c2[2] - c1[2];\r\n                d = Mat.hypot(dx, dy);\r\n\r\n                if (xy.pos.indexOf('px') >= 0 ||\r\n                    xy.pos.indexOf('fr') >= 0 ||\r\n                    xy.pos.indexOf('%') >= 0) {\r\n                    // lbda is interpreted in screen coords\r\n\r\n                    if (xy.pos.indexOf('px') >= 0) {\r\n                        // Pixel values are supported\r\n                        lbda /= d;\r\n                    }\r\n\r\n                    // Position along the line\r\n                    x = c1[1] + lbda * dx;\r\n                    y = c1[2] + lbda * dy;\r\n                } else {\r\n                    // lbda is given as number or as a number string\r\n                    // Then, lbda is interpreted in user coords\r\n                    x = c1[1] + lbda * this.board.unitX * dx / d;\r\n                    y = c1[2] + lbda * this.board.unitY * dy / d;\r\n                }\r\n\r\n                // Position left or right\r\n                if (xy.side === 'left') {\r\n                    dx *= -1;\r\n                } else {\r\n                    dy *= -1;\r\n                }\r\n                if (Type.exists(this.label)) {\r\n                    dist = 0.5 * this.label.evalVisProp('distance') / d;\r\n                }\r\n                x += dy * this.label.size[0] * dist;\r\n                y += dx * this.label.size[1] * dist;\r\n            }\r\n\r\n            // Correct coordinates if the label seems to be outside of canvas.\r\n            if (ev_sf || ev_sl) {\r\n                if (Type.exists(this.label)) {\r\n                    // Does not exist during createLabel\r\n                    fs = this.label.evalVisProp('fontsize');\r\n                }\r\n\r\n                if (Math.abs(x) < Mat.eps) {\r\n                    x = fs;\r\n                } else if (\r\n                    this.board.canvasWidth + Mat.eps > x &&\r\n                    x > this.board.canvasWidth - fs - Mat.eps\r\n                ) {\r\n                    x = this.board.canvasWidth - fs;\r\n                }\r\n\r\n                if (Mat.eps + fs > y && y > -Mat.eps) {\r\n                    y = fs;\r\n                } else if (\r\n                    this.board.canvasHeight + Mat.eps > y &&\r\n                    y > this.board.canvasHeight - fs - Mat.eps\r\n                ) {\r\n                    y = this.board.canvasHeight - fs;\r\n                }\r\n            }\r\n\r\n            return new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board);\r\n        },\r\n\r\n        // documented in geometry element\r\n        cloneToBackground: function () {\r\n            var copy = Type.getCloneObject(this),\r\n                r, s,\r\n                er;\r\n\r\n            copy.point1 = this.point1;\r\n            copy.point2 = this.point2;\r\n            copy.stdform = this.stdform;\r\n\r\n            s = this.getSlope();\r\n            r = this.getRise();\r\n            copy.getSlope = function () {\r\n                return s;\r\n            };\r\n            copy.getRise = function () {\r\n                return r;\r\n            };\r\n\r\n            er = this.board.renderer.enhancedRendering;\r\n            this.board.renderer.enhancedRendering = true;\r\n            this.board.renderer.drawLine(copy);\r\n            this.board.renderer.enhancedRendering = er;\r\n            this.traces[copy.id] = copy.rendNode;\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Add transformations to this line.\r\n         * @param {JXG.Transformation|Array} transform Either one {@link JXG.Transformation} or an array of\r\n         * {@link JXG.Transformation}s.\r\n         * @returns {JXG.Line} Reference to this line object.\r\n         */\r\n        addTransform: function (transform) {\r\n            var i,\r\n                list = Type.isArray(transform) ? transform : [transform],\r\n                len = list.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                this.point1.transformations.push(list[i]);\r\n                this.point2.transformations.push(list[i]);\r\n            }\r\n\r\n            // Why not like this?\r\n            // The difference is in setting baseElement\r\n            // var list = Type.isArray(transform) ? transform : [transform];\r\n            // this.point1.addTransform(this, list);\r\n            // this.point2.addTransform(this, list);\r\n\r\n            return this;\r\n        },\r\n\r\n        // see GeometryElement.js\r\n        snapToGrid: function (pos) {\r\n            var c1, c2, dc, t, ticks, x, y, sX, sY;\r\n\r\n            if (this.evalVisProp('snaptogrid')) {\r\n                if (this.parents.length < 3) {\r\n                    // Line through two points\r\n                    this.point1.handleSnapToGrid(true, true);\r\n                    this.point2.handleSnapToGrid(true, true);\r\n                } else if (Type.exists(pos)) {\r\n                    // Free line\r\n                    sX = this.evalVisProp('snapsizex');\r\n                    sY = this.evalVisProp('snapsizey');\r\n\r\n                    c1 = new Coords(Const.COORDS_BY_SCREEN, [pos.Xprev, pos.Yprev], this.board);\r\n\r\n                    x = c1.usrCoords[1];\r\n                    y = c1.usrCoords[2];\r\n\r\n                    if (\r\n                        sX <= 0 &&\r\n                        this.board.defaultAxes &&\r\n                        this.board.defaultAxes.x.defaultTicks\r\n                    ) {\r\n                        ticks = this.board.defaultAxes.x.defaultTicks;\r\n                        sX = ticks.ticksDelta * (ticks.evalVisProp('minorticks') + 1);\r\n                    }\r\n                    if (\r\n                        sY <= 0 &&\r\n                        this.board.defaultAxes &&\r\n                        this.board.defaultAxes.y.defaultTicks\r\n                    ) {\r\n                        ticks = this.board.defaultAxes.y.defaultTicks;\r\n                        sY = ticks.ticksDelta * (ticks.evalVisProp('minorticks') + 1);\r\n                    }\r\n\r\n                    // if no valid snap sizes are available, don't change the coords.\r\n                    if (sX > 0 && sY > 0) {\r\n                        // projectCoordsToLine\r\n                        /*\r\n                        v = [0, this.stdform[1], this.stdform[2]];\r\n                        v = Mat.crossProduct(v, c1.usrCoords);\r\n                        c2 = Geometry.meetLineLine(v, this.stdform, 0, this.board);\r\n                        */\r\n                        c2 = Geometry.projectPointToLine({ coords: c1 }, this, this.board);\r\n\r\n                        dc = Statistics.subtract(\r\n                            [1, Math.round(x / sX) * sX, Math.round(y / sY) * sY],\r\n                            c2.usrCoords\r\n                        );\r\n                        t = this.board.create(\"transform\", dc.slice(1), {\r\n                            type: \"translate\"\r\n                        });\r\n                        t.applyOnce([this.point1, this.point2]);\r\n                    }\r\n                }\r\n            } else {\r\n                this.point1.handleSnapToGrid(false, true);\r\n                this.point2.handleSnapToGrid(false, true);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        // see element.js\r\n        snapToPoints: function () {\r\n            var forceIt = this.evalVisProp('snaptopoints');\r\n\r\n            if (this.parents.length < 3) {\r\n                // Line through two points\r\n                this.point1.handleSnapToPoints(forceIt);\r\n                this.point2.handleSnapToPoints(forceIt);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Treat the line as parametric curve in homogeneous coordinates, where the parameter t runs from 0 to 1.\r\n         * First we transform the interval [0,1] to [-1,1].\r\n         * If the line has homogeneous coordinates [c, a, b] = stdform[] then the direction of the line is [b, -a].\r\n         * Now, we take one finite point that defines the line, i.e. we take either point1 or point2\r\n         * (in case the line is not the ideal line).\r\n         * Let the coordinates of that point be [z, x, y].\r\n         * Then, the curve runs linearly from\r\n         * [0, b, -a] (t=-1) to [z, x, y] (t=0)\r\n         * and\r\n         * [z, x, y] (t=0) to [0, -b, a] (t=1)\r\n         *\r\n         * @param {Number} t Parameter running from 0 to 1.\r\n         * @returns {Number} X(t) x-coordinate of the line treated as parametric curve.\r\n         * */\r\n        X: function (t) {\r\n            // var x,\r\n            //     c = this.point1.coords.usrCoords,\r\n            //     b = this.stdform[2];\r\n\r\n            // x = (Math.abs(c[0]) > Mat.eps) ? c[1] : c[1];\r\n            // t = (t - 0.5) * 2;\r\n\r\n            // return (1 - Math.abs(t)) * x - t * b;\r\n\r\n            var c1 = this.point1.coords.usrCoords,\r\n                c2 = this.point2.coords.usrCoords,\r\n                b = this.stdform[2];\r\n\r\n            if (c1[0] !== 0) {\r\n                if (c2[0] !== 0) {\r\n                    return c1[1] + (c2[1] - c1[1]) * t;\r\n                } else {\r\n                    return c1[1] + b * 1.e5 * t;\r\n                }\r\n            } else {\r\n                if (c1[0] !== 0) {\r\n                    return c2[1] - (c1[1] - c2[1]) * t;\r\n                } else {\r\n                    return c2[1] + b * 1.e5 * t;\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Treat the line as parametric curve in homogeneous coordinates.\r\n         * See {@link JXG.Line#X} for a detailed description.\r\n         * @param {Number} t Parameter running from 0 to 1.\r\n         * @returns {Number} Y(t) y-coordinate of the line treated as parametric curve.\r\n         * @see Line#X\r\n         */\r\n        Y: function (t) {\r\n            // var y,\r\n            //     c = this.point1.coords.usrCoords,\r\n            //     a = this.stdform[1];\r\n\r\n            // y = (Math.abs(c[0]) > Mat.eps) ? c[2] : c[2];\r\n            // t = (t - 0.5) * 2;\r\n\r\n            // return (1 - Math.abs(t)) * y + t * a;\r\n\r\n            var c1 = this.point1.coords.usrCoords,\r\n                c2 = this.point2.coords.usrCoords,\r\n                a = this.stdform[1];\r\n\r\n            if (c1[0] !== 0) {\r\n                if (c2[0] !== 0) {\r\n                    return c1[2] + (c2[2] - c1[2]) * t;\r\n                } else {\r\n                    return c1[2] - a * 1.e5 * t;\r\n                }\r\n            } else {\r\n                if (c1[0] !== 0) {\r\n                    return c2[2] - (c1[2] - c2[2]) * t;\r\n                } else {\r\n                    return c2[2] - a * 1.e5 * t;\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Treat the line as parametric curve in homogeneous coordinates.\r\n         * See {@link JXG.Line#X} for a detailed description.\r\n         *\r\n         * @param {Number} t Parameter running from 0 to 1.\r\n         * @returns {Number} Z(t) z-coordinate of the line treated as parametric curve.\r\n         * @see Line#Z\r\n         */\r\n        Z: function (t) {\r\n            // var z,\r\n            //     c = this.point1.coords.usrCoords;\r\n\r\n            // z = (Math.abs(c[0]) > Mat.eps) ? c[0] : c[0];\r\n            // t = (t - 0.5) * 2;\r\n\r\n            // return (1 - Math.abs(t)) * z;\r\n\r\n            var c1 = this.point1.coords.usrCoords,\r\n                c2 = this.point2.coords.usrCoords;\r\n\r\n            if (t === 1 && c1[0] * c2[0] === 0) {\r\n                return 0;\r\n            }\r\n            return 1;\r\n        },\r\n\r\n        /**\r\n         * Return the homogeneous coordinates of the line treated as curve at t - including all transformations\r\n         * applied to the curve.\r\n         * @param {Number} t A number\r\n         * @returns {Array} [Z(t), X(t), Y(t)]\r\n         * @see Line#X\r\n         */\r\n        Ft: function(t) {\r\n            var c = [this.Z(t), this.X(t), this.Y(t)];\r\n            c[1] /= c[0];\r\n            c[2] /= c[0];\r\n            c[0] /= c[0];\r\n            // c[0] = 1;\r\n            // c[1] = t;\r\n            // c[2] = 3;\r\n\r\n            return c;\r\n        },\r\n\r\n        /**\r\n         * The distance between the two points defining the line.\r\n         * @returns {Number}\r\n         */\r\n        L: function () {\r\n            return this.point1.Dist(this.point2);\r\n        },\r\n\r\n        /**\r\n         * Set a new fixed length, then update the board.\r\n         * @param {String|Number|function} l A string, function or number describing the new length.\r\n         * @returns {JXG.Line} Reference to this line\r\n         */\r\n        setFixedLength: function (l) {\r\n            if (!this.hasFixedLength) {\r\n                return this;\r\n            }\r\n\r\n            this.fixedLength = Type.createFunction(l, this.board);\r\n            this.hasFixedLength = true;\r\n            this.addParentsFromJCFunctions([this.fixedLength]);\r\n            this.board.update();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Treat the element  as a parametric curve\r\n         * @private\r\n         */\r\n        minX: function () {\r\n            return 0.0;\r\n        },\r\n\r\n        /**\r\n         * Treat the element as parametric curve\r\n         * @private\r\n         */\r\n        maxX: function () {\r\n            return 1.0;\r\n        },\r\n\r\n        // documented in geometry element\r\n        bounds: function () {\r\n            var p1c = this.point1.coords.usrCoords,\r\n                p2c = this.point2.coords.usrCoords;\r\n\r\n            return [\r\n                Math.min(p1c[1], p2c[1]),\r\n                Math.max(p1c[2], p2c[2]),\r\n                Math.max(p1c[1], p2c[1]),\r\n                Math.min(p1c[2], p2c[2])\r\n            ];\r\n        },\r\n\r\n        // documented in GeometryElement.js\r\n        remove: function () {\r\n            this.removeAllTicks();\r\n            GeometryElement.prototype.remove.call(this);\r\n        }\r\n\r\n        // hideElement: function () {\r\n        //     var i;\r\n        //\r\n        //     GeometryElement.prototype.hideElement.call(this);\r\n        //\r\n        //     for (i = 0; i < this.ticks.length; i++) {\r\n        //         this.ticks[i].hideElement();\r\n        //     }\r\n        // },\r\n        //\r\n        // showElement: function () {\r\n        //     var i;\r\n        //     GeometryElement.prototype.showElement.call(this);\r\n        //\r\n        //     for (i = 0; i < this.ticks.length; i++) {\r\n        //         this.ticks[i].showElement();\r\n        //     }\r\n        // }\r\n\r\n    }\r\n);\r\n\r\n/**\r\n * @class A general line is given by two points or three coordinates.\r\n * By setting additional properties a line can be used as an arrow and/or axis.\r\n * @pseudo\r\n * @name Line\r\n * @augments JXG.Line\r\n * @constructor\r\n * @type JXG.Line\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point,array,function_JXG.Point,array,function} point1,point2 Parent elements can be two elements either of type {@link JXG.Point} or array of\r\n * numbers describing the coordinates of a point. In the latter case the point will be constructed automatically as a fixed invisible point.\r\n * It is possible to provide a function returning an array or a point, instead of providing an array or a point.\r\n * @param {Number,function_Number,function_Number,function} a,b,c A line can also be created providing three numbers. The line is then described by\r\n * the set of solutions of the equation <tt>a*z+b*x+c*y = 0</tt>. For all finite points, z is normalized to the value 1.\r\n * It is possible to provide three functions returning numbers, too.\r\n * @param {function} f This function must return an array containing three numbers forming the line's homogeneous coordinates.\r\n * <p>\r\n * Additionally, a line can be created by providing a line and a transformation (or an array of transformations).\r\n * Then, the result is a line which is the transformation of the supplied line.\r\n * @example\r\n * // Create a line using point and coordinates/\r\n * // The second point will be fixed and invisible.\r\n * var p1 = board.create('point', [4.5, 2.0]);\r\n * var l1 = board.create('line', [p1, [1.0, 1.0]]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGc0ae3461-10c4-4d39-b9be-81d74759d122\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var glex1_board = JXG.JSXGraph.initBoard('JXGc0ae3461-10c4-4d39-b9be-81d74759d122', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var glex1_p1 = glex1_board.create('point', [4.5, 2.0]);\r\n *   var glex1_l1 = glex1_board.create('line', [glex1_p1, [1.0, 1.0]]);\r\n * </script><pre>\r\n * @example\r\n * // Create a line using three coordinates\r\n * var l1 = board.create('line', [1.0, -2.0, 3.0]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGcf45e462-f964-4ba4-be3a-c9db94e2593f\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var glex2_board = JXG.JSXGraph.initBoard('JXGcf45e462-f964-4ba4-be3a-c9db94e2593f', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var glex2_l1 = glex2_board.create('line', [1.0, -2.0, 3.0]);\r\n * </script><pre>\r\n * @example\r\n *         // Create a line (l2) as reflection of another line (l1)\r\n *         // reflection line\r\n *         var li = board.create('line', [1,1,1], {strokeColor: '#aaaaaa'});\r\n *         var reflect = board.create('transform', [li], {type: 'reflect'});\r\n *\r\n *         var l1 = board.create('line', [1,-5,1]);\r\n *         var l2 = board.create('line', [l1, reflect]);\r\n *\r\n * </pre><div id=\"JXGJXGa00d7dd6-d38c-11e7-93b3-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGJXGa00d7dd6-d38c-11e7-93b3-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *             // reflection line\r\n *             var li = board.create('line', [1,1,1], {strokeColor: '#aaaaaa'});\r\n *             var reflect = board.create('transform', [li], {type: 'reflect'});\r\n *\r\n *             var l1 = board.create('line', [1,-5,1]);\r\n *             var l2 = board.create('line', [l1, reflect]);\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var t = board.create('transform', [2, 1.5], {type: 'scale'});\r\n * var l1 = board.create('line', [1, -5, 1]);\r\n * var l2 = board.create('line', [l1, t]);\r\n *\r\n * </pre><div id=\"d16d5b58-6338-11e8-9fb9-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('d16d5b58-6338-11e8-9fb9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var t = board.create('transform', [2, 1.5], {type: 'scale'});\r\n *     var l1 = board.create('line', [1, -5, 1]);\r\n *     var l2 = board.create('line', [l1, t]);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * //create line between two points\r\n * var p1 = board.create('point', [0,0]);\r\n * var p2 = board.create('point', [2,2]);\r\n * var l1 = board.create('line', [p1,p2], {straightFirst:false, straightLast:false});\r\n * </pre><div id=\"d21d5b58-6338-11e8-9fb9-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('d21d5b58-6338-11e8-9fb9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *             var ex5p1 = board.create('point', [0,0]);\r\n *             var ex5p2 = board.create('point', [2,2]);\r\n *             var ex5l1 = board.create('line', [ex5p1,ex5p2], {straightFirst:false, straightLast:false});\r\n *     })();\r\n *\r\n * </script><pre>\r\n */\r\nJXG.createLine = function (board, parents, attributes) {\r\n    var ps, el, p1, p2, i, attr,\r\n        c = [],\r\n        doTransform = false,\r\n        constrained = false,\r\n        isDraggable;\r\n\r\n    if (parents.length === 2) {\r\n        // The line is defined by two points or coordinates of two points.\r\n        // In the latter case, the points are created.\r\n        attr = Type.copyAttributes(attributes, board.options, \"line\", 'point1');\r\n        if (Type.isArray(parents[0]) && parents[0].length > 1) {\r\n            p1 = board.create(\"point\", parents[0], attr);\r\n        } else if (Type.isString(parents[0]) || Type.isPoint(parents[0])) {\r\n            p1 = board.select(parents[0]);\r\n        } else if (Type.isFunction(parents[0]) && Type.isPoint(parents[0]())) {\r\n            p1 = parents[0]();\r\n            constrained = true;\r\n        } else if (\r\n            Type.isFunction(parents[0]) &&\r\n            parents[0]().length &&\r\n            parents[0]().length >= 2\r\n        ) {\r\n            p1 = JXG.createPoint(board, parents[0](), attr);\r\n            constrained = true;\r\n        } else if (Type.isObject(parents[0]) && Type.isTransformationOrArray(parents[1])) {\r\n            doTransform = true;\r\n            p1 = board.create(\"point\", [parents[0].point1, parents[1]], attr);\r\n        } else {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create line with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [point,point], [[x1,y1],[x2,y2]], [a,b,c]\"\r\n            );\r\n        }\r\n\r\n        // point 2 given by coordinates\r\n        attr = Type.copyAttributes(attributes, board.options, \"line\", 'point2');\r\n        if (doTransform) {\r\n            p2 = board.create(\"point\", [parents[0].point2, parents[1]], attr);\r\n        } else if (Type.isArray(parents[1]) && parents[1].length > 1) {\r\n            p2 = board.create(\"point\", parents[1], attr);\r\n        } else if (Type.isString(parents[1]) || Type.isPoint(parents[1])) {\r\n            p2 = board.select(parents[1]);\r\n        } else if (Type.isFunction(parents[1]) && Type.isPoint(parents[1]())) {\r\n            p2 = parents[1]();\r\n            constrained = true;\r\n        } else if (\r\n            Type.isFunction(parents[1]) &&\r\n            parents[1]().length &&\r\n            parents[1]().length >= 2\r\n        ) {\r\n            p2 = JXG.createPoint(board, parents[1](), attr);\r\n            constrained = true;\r\n        } else {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create line with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [point,point], [[x1,y1],[x2,y2]], [a,b,c]\"\r\n            );\r\n        }\r\n\r\n        attr = Type.copyAttributes(attributes, board.options, 'line');\r\n        el = new JXG.Line(board, p1, p2, attr);\r\n\r\n        if (constrained) {\r\n            el.constrained = true;\r\n            el.funp1 = parents[0];\r\n            el.funp2 = parents[1];\r\n        } else if (!doTransform) {\r\n            el.isDraggable = true;\r\n        }\r\n\r\n        //if (!el.constrained) {\r\n        el.setParents([p1.id, p2.id]);\r\n        //}\r\n\r\n    } else if (parents.length === 3) {\r\n        // Free line:\r\n        // Line is defined by three homogeneous coordinates.\r\n        // Also in this case points are created.\r\n        isDraggable = true;\r\n        for (i = 0; i < 3; i++) {\r\n            if (Type.isNumber(parents[i])) {\r\n                // createFunction will just wrap a function around our constant number\r\n                // that does nothing else but to return that number.\r\n                c[i] = Type.createFunction(parents[i]);\r\n            } else if (Type.isFunction(parents[i])) {\r\n                c[i] = parents[i];\r\n                isDraggable = false;\r\n            } else {\r\n                throw new Error(\r\n                    \"JSXGraph: Can't create line with parent types '\" +\r\n                    typeof parents[0] +\r\n                    \"' and '\" +\r\n                    typeof parents[1] +\r\n                    \"' and '\" +\r\n                    typeof parents[2] +\r\n                    \"'.\" +\r\n                    \"\\nPossible parent types: [point,point], [[x1,y1],[x2,y2]], [a,b,c]\"\r\n                );\r\n            }\r\n        }\r\n\r\n        // point 1 is the midpoint between (0, c, -b) and point 2. => point1 is finite.\r\n        attr = Type.copyAttributes(attributes, board.options, \"line\", 'point1');\r\n        if (isDraggable) {\r\n            p1 = board.create(\"point\", [\r\n                c[2]() * c[2]() + c[1]() * c[1](),\r\n                c[2]() - c[1]() * c[0]() + c[2](),\r\n                -c[1]() - c[2]() * c[0]() - c[1]()\r\n            ], attr);\r\n        } else {\r\n            p1 = board.create(\"point\", [\r\n                function () {\r\n                    return (c[2]() * c[2]() + c[1]() * c[1]()) * 0.5;\r\n                },\r\n                function () {\r\n                    return (c[2]() - c[1]() * c[0]() + c[2]()) * 0.5;\r\n                },\r\n                function () {\r\n                    return (-c[1]() - c[2]() * c[0]() - c[1]()) * 0.5;\r\n                }\r\n            ], attr);\r\n        }\r\n\r\n        // point 2: (b^2+c^2,-ba+c,-ca-b)\r\n        attr = Type.copyAttributes(attributes, board.options, \"line\", 'point2');\r\n        if (isDraggable) {\r\n            p2 = board.create(\"point\", [\r\n                c[2]() * c[2]() + c[1]() * c[1](),\r\n                -c[1]() * c[0]() + c[2](),\r\n                -c[2]() * c[0]() - c[1]()\r\n            ], attr);\r\n        } else {\r\n            p2 = board.create(\"point\", [\r\n                function () {\r\n                    return c[2]() * c[2]() + c[1]() * c[1]();\r\n                },\r\n                function () {\r\n                    return -c[1]() * c[0]() + c[2]();\r\n                },\r\n                function () {\r\n                    return -c[2]() * c[0]() - c[1]();\r\n                }\r\n            ], attr);\r\n        }\r\n\r\n        // If the line will have a glider and board.suspendUpdate() has been called, we\r\n        // need to compute the initial position of the two points p1 and p2.\r\n        p1.prepareUpdate().update();\r\n        p2.prepareUpdate().update();\r\n        attr = Type.copyAttributes(attributes, board.options, 'line');\r\n        el = new JXG.Line(board, p1, p2, attr);\r\n        // Not yet working, because the points are not draggable.\r\n        el.isDraggable = isDraggable;\r\n        el.setParents([p1, p2]);\r\n\r\n    } else if (\r\n        // The parent array contains a function which returns two points.\r\n        parents.length === 1 &&\r\n        Type.isFunction(parents[0]) &&\r\n        parents[0]().length === 2 &&\r\n        Type.isPoint(parents[0]()[0]) &&\r\n        Type.isPoint(parents[0]()[1])\r\n    ) {\r\n        ps = parents[0]();\r\n        attr = Type.copyAttributes(attributes, board.options, 'line');\r\n        el = new JXG.Line(board, ps[0], ps[1], attr);\r\n        el.constrained = true;\r\n        el.funps = parents[0];\r\n        el.setParents(ps);\r\n    } else if (\r\n        parents.length === 1 &&\r\n        Type.isFunction(parents[0]) &&\r\n        parents[0]().length === 3 &&\r\n        Type.isNumber(parents[0]()[0]) &&\r\n        Type.isNumber(parents[0]()[1]) &&\r\n        Type.isNumber(parents[0]()[2])\r\n    ) {\r\n        ps = parents[0];\r\n\r\n        attr = Type.copyAttributes(attributes, board.options, \"line\", 'point1');\r\n        p1 = board.create(\"point\", [\r\n            function () {\r\n                var c = ps();\r\n\r\n                return [\r\n                    (c[2] * c[2] + c[1] * c[1]) * 0.5,\r\n                    (c[2] - c[1] * c[0] + c[2]) * 0.5,\r\n                    (-c[1] - c[2] * c[0] - c[1]) * 0.5\r\n                ];\r\n            }\r\n        ], attr);\r\n\r\n        attr = Type.copyAttributes(attributes, board.options, \"line\", 'point2');\r\n        p2 = board.create(\"point\", [\r\n            function () {\r\n                var c = ps();\r\n\r\n                return [\r\n                    c[2] * c[2] + c[1] * c[1],\r\n                    -c[1] * c[0] + c[2],\r\n                    -c[2] * c[0] - c[1]\r\n                ];\r\n            }\r\n        ], attr);\r\n\r\n        attr = Type.copyAttributes(attributes, board.options, 'line');\r\n        el = new JXG.Line(board, p1, p2, attr);\r\n\r\n        el.constrained = true;\r\n        el.funps = parents[0];\r\n        el.setParents([p1, p2]);\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create line with parent types '\" +\r\n            typeof parents[0] +\r\n            \"' and '\" +\r\n            typeof parents[1] +\r\n            \"'.\" +\r\n            \"\\nPossible parent types: [point,point], [[x1,y1],[x2,y2]], [a,b,c]\"\r\n        );\r\n    }\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"line\", JXG.createLine);\r\n\r\n/**\r\n * @class A (line) segment defined by two points.\r\n * It's strictly spoken just a wrapper for element {@link Line} with {@link Line#straightFirst}\r\n * and {@link Line#straightLast} properties set to false. If there is a third variable then the\r\n * segment has a fixed length (which may be a function, too) determined by the absolute value of\r\n * that number.\r\n * @pseudo\r\n * @name Segment\r\n * @augments JXG.Line\r\n * @constructor\r\n * @type JXG.Line\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point,array_JXG.Point,array} point1,point2 Parent elements can be two elements either of type {@link JXG.Point}\r\n * or array of numbers describing the\r\n * coordinates of a point. In the latter case the point will be constructed automatically as a fixed invisible point.\r\n * @param {number,function} [length] The points are adapted - if possible - such that their distance\r\n * is equal to the absolute value of this number.\r\n * @see Line\r\n * @example\r\n * // Create a segment providing two points.\r\n *   var p1 = board.create('point', [4.5, 2.0]);\r\n *   var p2 = board.create('point', [1.0, 1.0]);\r\n *   var l1 = board.create('segment', [p1, p2]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGd70e6aac-7c93-4525-a94c-a1820fa38e2f\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var slex1_board = JXG.JSXGraph.initBoard('JXGd70e6aac-7c93-4525-a94c-a1820fa38e2f', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var slex1_p1 = slex1_board.create('point', [4.5, 2.0]);\r\n *   var slex1_p2 = slex1_board.create('point', [1.0, 1.0]);\r\n *   var slex1_l1 = slex1_board.create('segment', [slex1_p1, slex1_p2]);\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Create a segment providing two points.\r\n *   var p1 = board.create('point', [4.0, 1.0]);\r\n *   var p2 = board.create('point', [1.0, 1.0]);\r\n *   // AB\r\n *   var l1 = board.create('segment', [p1, p2]);\r\n *   var p3 = board.create('point', [4.0, 2.0]);\r\n *   var p4 = board.create('point', [1.0, 2.0]);\r\n *   // CD\r\n *   var l2 = board.create('segment', [p3, p4, 3]); // Fixed length\r\n *   var p5 = board.create('point', [4.0, 3.0]);\r\n *   var p6 = board.create('point', [1.0, 4.0]);\r\n *   // EF\r\n *   var l3 = board.create('segment', [p5, p6, function(){ return l1.L();} ]); // Fixed, but dependent length\r\n * </pre><div class=\"jxgbox\" id=\"JXG617336ba-0705-4b2b-a236-c87c28ef25be\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var slex2_board = JXG.JSXGraph.initBoard('JXG617336ba-0705-4b2b-a236-c87c28ef25be', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var slex2_p1 = slex2_board.create('point', [4.0, 1.0]);\r\n *   var slex2_p2 = slex2_board.create('point', [1.0, 1.0]);\r\n *   var slex2_l1 = slex2_board.create('segment', [slex2_p1, slex2_p2]);\r\n *   var slex2_p3 = slex2_board.create('point', [4.0, 2.0]);\r\n *   var slex2_p4 = slex2_board.create('point', [1.0, 2.0]);\r\n *   var slex2_l2 = slex2_board.create('segment', [slex2_p3, slex2_p4, 3]);\r\n *   var slex2_p5 = slex2_board.create('point', [4.0, 2.0]);\r\n *   var slex2_p6 = slex2_board.create('point', [1.0, 2.0]);\r\n *   var slex2_l3 = slex2_board.create('segment', [slex2_p5, slex2_p6, function(){ return slex2_l1.L();}]);\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createSegment = function (board, parents, attributes) {\r\n    var el, attr;\r\n\r\n    attributes.straightFirst = false;\r\n    attributes.straightLast = false;\r\n    attr = Type.copyAttributes(attributes, board.options, 'segment');\r\n\r\n    el = board.create(\"line\", parents.slice(0, 2), attr);\r\n\r\n    if (parents.length === 3) {\r\n        try {\r\n            el.hasFixedLength = true;\r\n            el.fixedLengthOldCoords = [];\r\n            el.fixedLengthOldCoords[0] = new Coords(\r\n                Const.COORDS_BY_USER,\r\n                el.point1.coords.usrCoords.slice(1, 3),\r\n                board\r\n            );\r\n            el.fixedLengthOldCoords[1] = new Coords(\r\n                Const.COORDS_BY_USER,\r\n                el.point2.coords.usrCoords.slice(1, 3),\r\n                board\r\n            );\r\n\r\n            el.setFixedLength(parents[2]);\r\n        } catch (err) {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create segment with third parent type '\" +\r\n                typeof parents[2] +\r\n                \"'.\" +\r\n                \"\\nPossible third parent types: number or function\"\r\n            );\r\n        }\r\n        // if (Type.isNumber(parents[2])) {\r\n        //     el.fixedLength = function () {\r\n        //         return parents[2];\r\n        //     };\r\n        // } else if (Type.isFunction(parents[2])) {\r\n        //     el.fixedLength = Type.createFunction(parents[2], this.board);\r\n        // } else {\r\n        //     throw new Error(\r\n        //         \"JSXGraph: Can't create segment with third parent type '\" +\r\n        //             typeof parents[2] +\r\n        //             \"'.\" +\r\n        //             \"\\nPossible third parent types: number or function\"\r\n        //     );\r\n        // }\r\n\r\n        el.getParents = function () {\r\n            return this.parents.concat(this.fixedLength());\r\n        };\r\n\r\n    }\r\n\r\n    el.elType = 'segment';\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"segment\", JXG.createSegment);\r\n\r\n/**\r\n * @class A segment with an arrow head.\r\n * This element is just a wrapper for element\r\n * {@link Line} with {@link Line#straightFirst}\r\n * and {@link Line#straightLast} properties set to false and {@link Line#lastArrow} set to true.\r\n * @pseudo\r\n * @name Arrow\r\n * @augments JXG.Line\r\n * @constructor\r\n * @type JXG.Line\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point,array_JXG.Point,array} point1,point2 Parent elements can be two elements either of type {@link JXG.Point} or array of numbers describing the\r\n * coordinates of a point. In the latter case the point will be constructed automatically as a fixed invisible point.\r\n * @param {Number_Number_Number} a,b,c A line can also be created providing three numbers. The line is then described by the set of solutions\r\n * of the equation <tt>a*x+b*y+c*z = 0</tt>.\r\n * @see Line\r\n * @example\r\n * // Create an arrow providing two points.\r\n *   var p1 = board.create('point', [4.5, 2.0]);\r\n *   var p2 = board.create('point', [1.0, 1.0]);\r\n *   var l1 = board.create('arrow', [p1, p2]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG1d26bd22-7d6d-4018-b164-4c8bc8d22ccf\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var alex1_board = JXG.JSXGraph.initBoard('JXG1d26bd22-7d6d-4018-b164-4c8bc8d22ccf', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var alex1_p1 = alex1_board.create('point', [4.5, 2.0]);\r\n *   var alex1_p2 = alex1_board.create('point', [1.0, 1.0]);\r\n *   var alex1_l1 = alex1_board.create('arrow', [alex1_p1, alex1_p2]);\r\n * </script><pre>\r\n */\r\nJXG.createArrow = function (board, parents, attributes) {\r\n    var el, attr;\r\n\r\n    attributes.straightFirst = false;\r\n    attributes.straightLast = false;\r\n    attr = Type.copyAttributes(attributes, board.options, 'arrow');\r\n    el = board.create(\"line\", parents, attr);\r\n    //el.setArrow(false, true);\r\n    el.type = Const.OBJECT_TYPE_VECTOR;\r\n    el.elType = 'arrow';\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"arrow\", JXG.createArrow);\r\n\r\n/**\r\n * @class Axis is a line with optional ticks and labels.\r\n * It's strictly spoken just a wrapper for element {@link Line} with {@link Line#straightFirst}\r\n * and {@link Line#straightLast} properties set to true. Additionally {@link Line#lastArrow} is set to true and default {@link Ticks} will be created.\r\n * @pseudo\r\n * @name Axis\r\n * @augments JXG.Line\r\n * @constructor\r\n * @type JXG.Line\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point,array_JXG.Point,array} point1,point2 Parent elements can be two elements either of type {@link JXG.Point} or array of numbers describing the\r\n * coordinates of a point. In the latter case, the point will be constructed automatically as a fixed invisible point.\r\n * @param {Number_Number_Number} a,b,c A line can also be created providing three numbers. The line is then described by the set of solutions\r\n * of the equation <tt>a*x+b*y+c*z = 0</tt>.\r\n * @example\r\n * // Create an axis providing two coords pairs.\r\n *   var l1 = board.create('axis', [[0.0, 1.0], [1.0, 1.3]]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG4f414733-624c-42e4-855c-11f5530383ae\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var axex1_board = JXG.JSXGraph.initBoard('JXG4f414733-624c-42e4-855c-11f5530383ae', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var axex1_l1 = axex1_board.create('axis', [[0.0, 1.0], [1.0, 1.3]]);\r\n * </script><pre>\r\n * @example\r\n *  // Create ticks labels as fractions\r\n *  board.create('axis', [[0,1], [1,1]], {\r\n *      ticks: {\r\n *          label: {\r\n *              toFraction: true,\r\n *              useMathjax: false,\r\n *              anchorX: 'middle',\r\n *              offset: [0, -10]\r\n *          }\r\n *      }\r\n *  });\r\n *\r\n *\r\n * </pre><div id=\"JXG34174cc4-0050-4ab4-af69-e91365d0666f\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script src=\"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js\" id=\"MathJax-script\"></script>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG34174cc4-0050-4ab4-af69-e91365d0666f',\r\n *             {boundingbox: [-1.2, 2.3, 1.2, -2.3], axis: true, showcopyright: false, shownavigation: false});\r\n *             board.create('axis', [[0,1], [1,1]], {\r\n *                 ticks: {\r\n *                     label: {\r\n *                         toFraction: true,\r\n *                         useMathjax: false,\r\n *                         anchorX: 'middle',\r\n *                         offset: [0, -10]\r\n *                     }\r\n *                 }\r\n *             });\r\n *\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createAxis = function (board, parents, attributes) {\r\n    var axis, attr,\r\n        ancestor, ticksDist;\r\n\r\n    // Create line\r\n    attr = Type.copyAttributes(attributes, board.options, 'axis');\r\n    try {\r\n        axis = board.create(\"line\", parents, attr);\r\n    } catch (err) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create axis with parent types '\" +\r\n            typeof parents[0] +\r\n            \"' and '\" +\r\n            typeof parents[1] +\r\n            \"'.\" +\r\n            \"\\nPossible parent types: [point,point], [[x1,y1],[x2,y2]]\"\r\n        );\r\n    }\r\n\r\n    axis.type = Const.OBJECT_TYPE_AXIS;\r\n    axis.isDraggable = false;\r\n    axis.point1.isDraggable = false;\r\n    axis.point2.isDraggable = false;\r\n\r\n    // Save usrCoords of points\r\n    axis._point1UsrCoordsOrg = axis.point1.coords.usrCoords.slice();\r\n    axis._point2UsrCoordsOrg = axis.point2.coords.usrCoords.slice();\r\n\r\n    for (ancestor in axis.ancestors) {\r\n        if (axis.ancestors.hasOwnProperty(ancestor)) {\r\n            axis.ancestors[ancestor].type = Const.OBJECT_TYPE_AXISPOINT;\r\n        }\r\n    }\r\n\r\n    // Create ticks\r\n    // attrTicks = attr.ticks;\r\n    if (Type.exists(attr.ticks.ticksdistance)) {\r\n        ticksDist = attr.ticks.ticksdistance;\r\n    } else if (Type.isArray(attr.ticks.ticks)) {\r\n        ticksDist = attr.ticks.ticks;\r\n    } else {\r\n        ticksDist = 1.0;\r\n    }\r\n\r\n    /**\r\n     * The ticks attached to the axis.\r\n     * @memberOf Axis.prototype\r\n     * @name defaultTicks\r\n     * @type JXG.Ticks\r\n     */\r\n    axis.defaultTicks = board.create(\"ticks\", [axis, ticksDist], attr.ticks);\r\n    axis.defaultTicks.dump = false;\r\n    axis.elType = 'axis';\r\n    axis.subs = {\r\n        ticks: axis.defaultTicks\r\n    };\r\n    axis.inherits.push(axis.defaultTicks);\r\n\r\n    axis.update = function () {\r\n        var bbox,\r\n            position, i,\r\n            direction, horizontal, vertical,\r\n            ticksAutoPos, ticksAutoPosThres, dist,\r\n            anchor, left, right,\r\n            distUsr,\r\n            newPosP1, newPosP2,\r\n            locationOrg,\r\n            visLabel, anchr, off;\r\n\r\n        if (!this.needsUpdate) {\r\n            return this;\r\n        }\r\n\r\n        bbox = this.board.getBoundingBox();\r\n        position = this.evalVisProp('position');\r\n        direction = this.Direction();\r\n        horizontal = this.isHorizontal();\r\n        vertical = this.isVertical();\r\n        ticksAutoPos = this.evalVisProp('ticksautopos');\r\n        ticksAutoPosThres = this.evalVisProp('ticksautoposthreshold');\r\n\r\n        if (horizontal) {\r\n            ticksAutoPosThres = Type.parseNumber(ticksAutoPosThres, Math.abs(bbox[1] - bbox[3]), 1 / this.board.unitX) * this.board.unitX;\r\n        } else if (vertical) {\r\n            ticksAutoPosThres = Type.parseNumber(ticksAutoPosThres, Math.abs(bbox[1] - bbox[3]), 1 / this.board.unitY) * this.board.unitY;\r\n        } else {\r\n            ticksAutoPosThres = Type.parseNumber(ticksAutoPosThres, 1, 1);\r\n        }\r\n\r\n        anchor = this.evalVisProp('anchor');\r\n        left = anchor.indexOf('left') > -1;\r\n        right = anchor.indexOf('right') > -1;\r\n\r\n        distUsr = this.evalVisProp('anchordist');\r\n        if (horizontal) {\r\n            distUsr = Type.parseNumber(distUsr, Math.abs(bbox[1] - bbox[3]), 1 / this.board.unitX);\r\n        } else if (vertical) {\r\n            distUsr = Type.parseNumber(distUsr, Math.abs(bbox[0] - bbox[2]), 1 / this.board.unitY);\r\n        } else {\r\n            distUsr = 0;\r\n        }\r\n\r\n        locationOrg = this.board.getPointLoc(this._point1UsrCoordsOrg, distUsr);\r\n\r\n        // Set position of axis\r\n        newPosP1 = this.point1.coords.usrCoords.slice();\r\n        newPosP2 = this.point2.coords.usrCoords.slice();\r\n\r\n        if (position === 'static' || (!vertical && !horizontal)) {\r\n            // Do nothing\r\n\r\n        } else if (position === 'fixed') {\r\n            if (horizontal) { // direction[1] === 0\r\n                if ((direction[0] > 0 && right) || (direction[0] < 0 && left)) {\r\n                    newPosP1[2] = bbox[3] + distUsr;\r\n                    newPosP2[2] = bbox[3] + distUsr;\r\n                } else if ((direction[0] > 0 && left) || (direction[0] < 0 && right)) {\r\n                    newPosP1[2] = bbox[1] - distUsr;\r\n                    newPosP2[2] = bbox[1] - distUsr;\r\n\r\n                } else {\r\n                    newPosP1 = this._point1UsrCoordsOrg.slice();\r\n                    newPosP2 = this._point2UsrCoordsOrg.slice();\r\n                }\r\n            }\r\n            if (vertical) { // direction[0] === 0\r\n                if ((direction[1] > 0 && left) || (direction[1] < 0 && right)) {\r\n                    newPosP1[1] = bbox[0] + distUsr;\r\n                    newPosP2[1] = bbox[0] + distUsr;\r\n\r\n                } else if ((direction[1] > 0 && right) || (direction[1] < 0 && left)) {\r\n                    newPosP1[1] = bbox[2] - distUsr;\r\n                    newPosP2[1] = bbox[2] - distUsr;\r\n\r\n                } else {\r\n                    newPosP1 = this._point1UsrCoordsOrg.slice();\r\n                    newPosP2 = this._point2UsrCoordsOrg.slice();\r\n                }\r\n            }\r\n\r\n        } else if (position === 'sticky') {\r\n            if (horizontal) { // direction[1] === 0\r\n                if (locationOrg[1] < 0 && ((direction[0] > 0 && right) || (direction[0] < 0 && left))) {\r\n                    newPosP1[2] = bbox[3] + distUsr;\r\n                    newPosP2[2] = bbox[3] + distUsr;\r\n\r\n                } else if (locationOrg[1] > 0 && ((direction[0] > 0 && left) || (direction[0] < 0 && right))) {\r\n                    newPosP1[2] = bbox[1] - distUsr;\r\n                    newPosP2[2] = bbox[1] - distUsr;\r\n\r\n                } else {\r\n                    newPosP1 = this._point1UsrCoordsOrg.slice();\r\n                    newPosP2 = this._point2UsrCoordsOrg.slice();\r\n                }\r\n            }\r\n            if (vertical) { // direction[0] === 0\r\n                if (locationOrg[0] < 0 && ((direction[1] > 0 && left) || (direction[1] < 0 && right))) {\r\n                    newPosP1[1] = bbox[0] + distUsr;\r\n                    newPosP2[1] = bbox[0] + distUsr;\r\n\r\n                } else if (locationOrg[0] > 0 && ((direction[1] > 0 && right) || (direction[1] < 0 && left))) {\r\n                    newPosP1[1] = bbox[2] - distUsr;\r\n                    newPosP2[1] = bbox[2] - distUsr;\r\n\r\n                } else {\r\n                    newPosP1 = this._point1UsrCoordsOrg.slice();\r\n                    newPosP2 = this._point2UsrCoordsOrg.slice();\r\n                }\r\n            }\r\n        }\r\n\r\n        this.point1.setPositionDirectly(JXG.COORDS_BY_USER, newPosP1);\r\n        this.point2.setPositionDirectly(JXG.COORDS_BY_USER, newPosP2);\r\n\r\n        // Set position of tick labels\r\n        if (Type.exists(this.defaultTicks)) {\r\n            visLabel = this.defaultTicks.visProp.label;\r\n            if (ticksAutoPos && (horizontal || vertical)) {\r\n\r\n                if (!Type.exists(visLabel._anchorx_org)) {\r\n                    visLabel._anchorx_org = Type.def(visLabel.anchorx, this.board.options.text.anchorX);\r\n                }\r\n                if (!Type.exists(visLabel._anchory_org)) {\r\n                    visLabel._anchory_org = Type.def(visLabel.anchory, this.board.options.text.anchorY);\r\n                }\r\n                if (!Type.exists(visLabel._offset_org)) {\r\n                    visLabel._offset_org = visLabel.offset.slice();\r\n                }\r\n\r\n                off = visLabel.offset;\r\n                if (horizontal) {\r\n                    dist = axis.point1.coords.scrCoords[2] - (this.board.canvasHeight * 0.5);\r\n\r\n                    anchr = visLabel.anchory;\r\n\r\n                    // The last position of the labels is stored in visLabel._side\r\n                    if (dist < 0 && Math.abs(dist) > ticksAutoPosThres) {\r\n                        // Put labels on top of the line\r\n                        if (visLabel._side === 'bottom') {\r\n                            // Switch position\r\n                            if (visLabel.anchory === 'top') {\r\n                                anchr = 'bottom';\r\n                            }\r\n                            off[1] *= -1;\r\n                            visLabel._side = 'top';\r\n                        }\r\n\r\n                    } else if (dist > 0 && Math.abs(dist) > ticksAutoPosThres) {\r\n                        // Put labels below the line\r\n                        if (visLabel._side === 'top') {\r\n                            // Switch position\r\n                            if (visLabel.anchory === 'bottom') {\r\n                                anchr = 'top';\r\n                            }\r\n                            off[1] *= -1;\r\n                            visLabel._side = 'bottom';\r\n                        }\r\n\r\n                    } else {\r\n                        // Put to original position\r\n                        anchr = visLabel._anchory_org;\r\n                        off = visLabel._offset_org.slice();\r\n\r\n                        if (anchr === 'top') {\r\n                            visLabel._side = 'bottom';\r\n                        } else if (anchr === 'bottom') {\r\n                            visLabel._side = 'top';\r\n                        } else if (off[1] < 0) {\r\n                            visLabel._side = 'bottom';\r\n                        } else {\r\n                            visLabel._side = 'top';\r\n                        }\r\n                    }\r\n\r\n                    for (i = 0; i < axis.defaultTicks.labels.length; i++) {\r\n                        this.defaultTicks.labels[i].visProp.anchory = anchr;\r\n                    }\r\n                    visLabel.anchory = anchr;\r\n\r\n                } else if (vertical) {\r\n                    dist = axis.point1.coords.scrCoords[1] - (this.board.canvasWidth * 0.5);\r\n\r\n                    if (dist < 0 && Math.abs(dist) > ticksAutoPosThres) {\r\n                        // Put labels to the left of the line\r\n                        if (visLabel._side === 'right') {\r\n                            // Switch position\r\n                            if (visLabel.anchorx === 'left') {\r\n                                anchr = 'right';\r\n                            }\r\n                            off[0] *= -1;\r\n                            visLabel._side = 'left';\r\n                        }\r\n\r\n                    } else if (dist > 0 && Math.abs(dist) > ticksAutoPosThres) {\r\n                        // Put labels to the right of the line\r\n                        if (visLabel._side === 'left') {\r\n                            // Switch position\r\n                            if (visLabel.anchorx === 'right') {\r\n                                anchr = 'left';\r\n                            }\r\n                            off[0] *= -1;\r\n                            visLabel._side = 'right';\r\n                        }\r\n\r\n                    } else {\r\n                        // Put to original position\r\n                        anchr = visLabel._anchorx_org;\r\n                        off = visLabel._offset_org.slice();\r\n\r\n                        if (anchr === 'left') {\r\n                            visLabel._side = 'right';\r\n                        } else if (anchr === 'right') {\r\n                            visLabel._side = 'left';\r\n                        } else if (off[0] < 0) {\r\n                            visLabel._side = 'left';\r\n                        } else {\r\n                            visLabel._side = 'right';\r\n                        }\r\n                    }\r\n\r\n                    for (i = 0; i < axis.defaultTicks.labels.length; i++) {\r\n                        this.defaultTicks.labels[i].visProp.anchorx = anchr;\r\n                    }\r\n                    visLabel.anchorx = anchr;\r\n                }\r\n                visLabel.offset = off;\r\n\r\n            } else {\r\n                delete visLabel._anchorx_org;\r\n                delete visLabel._anchory_org;\r\n                delete visLabel._offset_org;\r\n            }\r\n            this.defaultTicks.needsUpdate = true;\r\n        }\r\n\r\n        JXG.Line.prototype.update.call(this);\r\n\r\n        return this;\r\n    };\r\n\r\n    return axis;\r\n};\r\n\r\nJXG.registerElement(\"axis\", JXG.createAxis);\r\n\r\n/**\r\n * @class The tangent line at a point on a line, circle, conic, turtle, or curve.\r\n * A tangent line is always constructed\r\n * by a point on a line, circle, or curve and describes the tangent in the point on that line, circle, or curve.\r\n * <p>\r\n * If the point is not on the object (line, circle, conic, curve, turtle) the output depends on the type of the object.\r\n * For conics and circles, the polar line will be constructed. For function graphs,\r\n * the tangent of the vertical projection of the point to the function graph is constructed. For all other objects, the tangent\r\n * in the orthogonal projection of the point to the object will be constructed.\r\n * @pseudo\r\n * @name Tangent\r\n * @augments JXG.Line\r\n * @constructor\r\n * @type JXG.Line\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Glider} g A glider on a line, circle, or curve.\r\n * @param {JXG.GeometryElement} [c] Optional element for which the tangent is constructed\r\n * @example\r\n * // Create a tangent providing a glider on a function graph\r\n *   var c1 = board.create('curve', [function(t){return t},function(t){return t*t*t;}]);\r\n *   var g1 = board.create('glider', [0.6, 1.2, c1]);\r\n *   var t1 = board.create('tangent', [g1]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG7b7233a0-f363-47dd-9df5-4018d0d17a98\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var tlex1_board = JXG.JSXGraph.initBoard('JXG7b7233a0-f363-47dd-9df5-4018d0d17a98', {boundingbox: [-6, 6, 6, -6], axis: true, showcopyright: false, shownavigation: false});\r\n *   var tlex1_c1 = tlex1_board.create('curve', [function(t){return t},function(t){return t*t*t;}]);\r\n *   var tlex1_g1 = tlex1_board.create('glider', [0.6, 1.2, tlex1_c1]);\r\n *   var tlex1_t1 = tlex1_board.create('tangent', [tlex1_g1]);\r\n * </script><pre>\r\n */\r\nJXG.createTangent = function (board, parents, attributes) {\r\n    var p, c, j, el, tangent, attr,\r\n        getCurveTangentDir,\r\n        res, isTransformed,\r\n        slides = [];\r\n\r\n    if (parents.length === 1) {\r\n        // One argument: glider on line, circle or curve\r\n        p = parents[0];\r\n        c = p.slideObject;\r\n\r\n    } else if (parents.length === 2) {\r\n        // Two arguments: (point,line|curve|circle|conic) or (line|curve|circle|conic,point).\r\n        // In fact, for circles and conics it is the polar\r\n        if (Type.isPoint(parents[0])) {\r\n            p = parents[0];\r\n            c = parents[1];\r\n        } else if (Type.isPoint(parents[1])) {\r\n            c = parents[0];\r\n            p = parents[1];\r\n        } else {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create tangent with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [glider|point], [point,line|curve|circle|conic]\"\r\n            );\r\n        }\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create tangent with parent types '\" +\r\n            typeof parents[0] +\r\n            \"' and '\" +\r\n            typeof parents[1] +\r\n            \"'.\" +\r\n            \"\\nPossible parent types: [glider|point], [point,line|curve|circle|conic]\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'tangent');\r\n    if (c.elementClass === Const.OBJECT_CLASS_LINE) {\r\n        tangent = board.create(\"line\", [c.point1, c.point2], attr);\r\n        tangent.glider = p;\r\n    } else if (\r\n        c.elementClass === Const.OBJECT_CLASS_CURVE &&\r\n        c.type !== Const.OBJECT_TYPE_CONIC\r\n    ) {\r\n        res = c.getTransformationSource();\r\n        isTransformed = res[0];\r\n        if (isTransformed) {\r\n            // Curve is result of a transformation\r\n            // We recursively collect all curves from which\r\n            // the curve is transformed.\r\n            slides.push(c);\r\n            while (res[0] && Type.exists(res[1]._transformationSource)) {\r\n                slides.push(res[1]);\r\n                res = res[1].getTransformationSource();\r\n            }\r\n        }\r\n\r\n        if (c.evalVisProp('curvetype') !== \"plot\" || isTransformed) {\r\n            // Functiongraph or parametric curve or\r\n            // transformed curve thereof.\r\n            tangent = board.create(\r\n                \"line\",\r\n                [\r\n                    function () {\r\n                        var g = c.X,\r\n                            f = c.Y,\r\n                            df, dg,\r\n                            li, i, c_org, invMat, po,\r\n                            t;\r\n\r\n                        if (p.type === Const.OBJECT_TYPE_GLIDER) {\r\n                            t = p.position;\r\n                        } else if (c.evalVisProp('curvetype') === 'functiongraph') {\r\n                            t = p.X();\r\n                        } else {\r\n                            t = Geometry.projectPointToCurve(p, c, board)[1];\r\n                        }\r\n\r\n                        // po are the coordinates of the point\r\n                        // on the \"original\" curve. That is the curve or\r\n                        // the original curve which is transformed (maybe multiple times)\r\n                        // to this curve.\r\n                        // t is the position of the point on the \"original\" curve\r\n                        po = p.Coords(true);\r\n                        if (isTransformed) {\r\n                            c_org = slides[slides.length - 1]._transformationSource;\r\n                            g = c_org.X;\r\n                            f = c_org.Y;\r\n                            for (i = 0; i < slides.length; i++) {\r\n                                slides[i].updateTransformMatrix();\r\n                                invMat = Mat.inverse(slides[i].transformMat);\r\n                                po = Mat.matVecMult(invMat, po);\r\n                            }\r\n\r\n                            if (p.type !== Const.OBJECT_TYPE_GLIDER) {\r\n                                po[1] /= po[0];\r\n                                po[2] /= po[0];\r\n                                po[0] /= po[0];\r\n                                t = Geometry.projectCoordsToCurve(po[1], po[2], 0, c_org, board)[1];\r\n                            }\r\n                        }\r\n\r\n                        // li are the coordinates of the line on the \"original\" curve\r\n                        df = Numerics.D(f)(t);\r\n                        dg = Numerics.D(g)(t);\r\n                        li = [\r\n                            -po[1] * df + po[2] * dg,\r\n                            po[0] * df,\r\n                            -po[0] * dg\r\n                        ];\r\n\r\n                        if (isTransformed) {\r\n                            // Transform the line to the transformed curve\r\n                            for (i = slides.length - 1; i >= 0; i--) {\r\n                                invMat = Mat.transpose(Mat.inverse(slides[i].transformMat));\r\n                                li = Mat.matVecMult(invMat, li);\r\n                            }\r\n                        }\r\n\r\n                        return li;\r\n                    }\r\n                ],\r\n                attr\r\n            );\r\n\r\n            p.addChild(tangent);\r\n            // this is required for the geogebra reader to display a slope\r\n            tangent.glider = p;\r\n        } else {\r\n            // curveType 'plot': discrete data\r\n            /**\r\n             * @ignore\r\n             *\r\n             * In case of bezierDegree == 1:\r\n             * Find two points p1, p2 enclosing the glider.\r\n             * Then the equation of the line segment is: 0 = y*(x1-x2) + x*(y2-y1) + y1*x2-x1*y2,\r\n             * which is the cross product of p1 and p2.\r\n             *\r\n             * In case of bezierDegree === 3:\r\n             * The slope dy / dx of the tangent is determined. Then the\r\n             * tangent is computed as cross product between\r\n             * the glider p and [1, p.X() + dx, p.Y() + dy]\r\n             *\r\n             */\r\n            getCurveTangentDir = function (position, c, num) {\r\n                var i = Math.floor(position),\r\n                    p1, p2, t, A, B, C, D, dx, dy, d,\r\n                    points, le;\r\n\r\n                if (c.bezierDegree === 1) {\r\n                    if (i === c.numberPoints - 1) {\r\n                        i--;\r\n                    }\r\n                } else if (c.bezierDegree === 3) {\r\n                    // i is start of the Bezier segment\r\n                    // t is the position in the Bezier segment\r\n                    if (c.elType === 'sector') {\r\n                        points = c.points.slice(3, c.numberPoints - 3);\r\n                        le = points.length;\r\n                    } else {\r\n                        points = c.points;\r\n                        le = points.length;\r\n                    }\r\n                    i = Math.floor((position * (le - 1)) / 3) * 3;\r\n                    t = (position * (le - 1) - i) / 3;\r\n                    if (i >= le - 1) {\r\n                        i = le - 4;\r\n                        t = 1;\r\n                    }\r\n                } else {\r\n                    return 0;\r\n                }\r\n\r\n                if (i < 0) {\r\n                    return 1;\r\n                }\r\n\r\n                // The curve points are transformed (if there is a transformation)\r\n                // c.X(i) is not transformed.\r\n                if (c.bezierDegree === 1) {\r\n                    p1 = c.points[i].usrCoords;\r\n                    p2 = c.points[i + 1].usrCoords;\r\n                } else {\r\n                    A = points[i].usrCoords;\r\n                    B = points[i + 1].usrCoords;\r\n                    C = points[i + 2].usrCoords;\r\n                    D = points[i + 3].usrCoords;\r\n                    dx = (1 - t) * (1 - t) * (B[1] - A[1]) +\r\n                        2 * (1 - t) * t * (C[1] - B[1]) +\r\n                        t * t * (D[1] - C[1]);\r\n                    dy = (1 - t) * (1 - t) * (B[2] - A[2]) +\r\n                        2 * (1 - t) * t * (C[2] - B[2]) +\r\n                        t * t * (D[2] - C[2]);\r\n                    d = Mat.hypot(dx, dy);\r\n                    dx /= d;\r\n                    dy /= d;\r\n                    p1 = p.coords.usrCoords;\r\n                    p2 = [1, p1[1] + dx, p1[2] + dy];\r\n                }\r\n\r\n                switch (num) {\r\n                    case 0:\r\n                        return p1[2] * p2[1] - p1[1] * p2[2];\r\n                    case 1:\r\n                        return p2[2] - p1[2];\r\n                    case 2:\r\n                        return p1[1] - p2[1];\r\n                    default:\r\n                        return [\r\n                            p1[2] * p2[1] - p1[1] * p2[2],\r\n                            p2[2] - p1[2],\r\n                            p1[1] - p2[1]\r\n                        ];\r\n                }\r\n            };\r\n\r\n            tangent = board.create(\r\n                \"line\",\r\n                [\r\n                    function () {\r\n                        var t;\r\n\r\n                        if (p.type === Const.OBJECT_TYPE_GLIDER) {\r\n                            t = p.position;\r\n                        } else {\r\n                            t = Geometry.projectPointToCurve(p, c, board)[1];\r\n                        }\r\n\r\n                        return getCurveTangentDir(t, c);\r\n                    }\r\n                ],\r\n                attr\r\n            );\r\n\r\n            p.addChild(tangent);\r\n            // this is required for the geogebra reader to display a slope\r\n            tangent.glider = p;\r\n        }\r\n    } else if (c.type === Const.OBJECT_TYPE_TURTLE) {\r\n        tangent = board.create(\r\n            \"line\",\r\n            [\r\n                function () {\r\n                    var i, t;\r\n                    if (p.type === Const.OBJECT_TYPE_GLIDER) {\r\n                        t = p.position;\r\n                    } else {\r\n                        t = Geometry.projectPointToTurtle(p, c, board)[1];\r\n                    }\r\n\r\n                    i = Math.floor(t);\r\n\r\n                    // run through all curves of this turtle\r\n                    for (j = 0; j < c.objects.length; j++) {\r\n                        el = c.objects[j];\r\n\r\n                        if (el.type === Const.OBJECT_TYPE_CURVE) {\r\n                            if (i < el.numberPoints) {\r\n                                break;\r\n                            }\r\n\r\n                            i -= el.numberPoints;\r\n                        }\r\n                    }\r\n\r\n                    if (i === el.numberPoints - 1) {\r\n                        i--;\r\n                    }\r\n\r\n                    if (i < 0) {\r\n                        return [1, 0, 0];\r\n                    }\r\n\r\n                    return [\r\n                        el.Y(i) * el.X(i + 1) - el.X(i) * el.Y(i + 1),\r\n                        el.Y(i + 1) - el.Y(i),\r\n                        el.X(i) - el.X(i + 1)\r\n                    ];\r\n                }\r\n            ],\r\n            attr\r\n        );\r\n        p.addChild(tangent);\r\n\r\n        // this is required for the geogebra reader to display a slope\r\n        tangent.glider = p;\r\n    } else if (\r\n        c.elementClass === Const.OBJECT_CLASS_CIRCLE ||\r\n        c.type === Const.OBJECT_TYPE_CONIC\r\n    ) {\r\n        // If p is not on c, the tangent is the polar.\r\n        // This construction should work on conics, too. p has to lie on c.\r\n        tangent = board.create(\r\n            \"line\",\r\n            [\r\n                function () {\r\n                    return Mat.matVecMult(c.quadraticform, p.coords.usrCoords);\r\n                }\r\n            ],\r\n            attr\r\n        );\r\n\r\n        p.addChild(tangent);\r\n        // this is required for the geogebra reader to display a slope\r\n        tangent.glider = p;\r\n    }\r\n\r\n    if (!Type.exists(tangent)) {\r\n        throw new Error(\"JSXGraph: Couldn't create tangent with the given parents.\");\r\n    }\r\n\r\n    tangent.elType = 'tangent';\r\n    tangent.type = Const.OBJECT_TYPE_TANGENT;\r\n    tangent.setParents(parents);\r\n\r\n    return tangent;\r\n};\r\n\r\n/**\r\n * @class A normal is the line perpendicular to a line or to a tangent of a circle or curve.\r\n * @pseudo\r\n * @description A normal is a line through a given point on an element of type line, circle, curve, or turtle and orthogonal to that object.\r\n * @constructor\r\n * @name Normal\r\n * @type JXG.Line\r\n * @augments JXG.Line\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Line,JXG.Circle,JXG.Curve,JXG.Turtle_JXG.Point} o,p The constructed line contains p which lies on the object and is orthogonal\r\n * to the tangent to the object in the given point.\r\n * @param {Glider} p Works like above, however the object is given by {@link JXG.CoordsElement#slideObject}.\r\n * @example\r\n * // Create a normal to a circle.\r\n * var p1 = board.create('point', [2.0, 2.0]);\r\n * var p2 = board.create('point', [3.0, 2.0]);\r\n * var c1 = board.create('circle', [p1, p2]);\r\n *\r\n * var norm1 = board.create('normal', [c1, p2]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG4154753d-3d29-40fb-a860-0b08aa4f3743\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var nlex1_board = JXG.JSXGraph.initBoard('JXG4154753d-3d29-40fb-a860-0b08aa4f3743', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var nlex1_p1 = nlex1_board.create('point', [2.0, 2.0]);\r\n *   var nlex1_p2 = nlex1_board.create('point', [3.0, 2.0]);\r\n *   var nlex1_c1 = nlex1_board.create('circle', [nlex1_p1, nlex1_p2]);\r\n *\r\n *   // var nlex1_p3 = nlex1_board.create('point', [1.0, 2.0]);\r\n *   var nlex1_norm1 = nlex1_board.create('normal', [nlex1_c1, nlex1_p2]);\r\n * </script><pre>\r\n */\r\nJXG.createNormal = function (board, parents, attributes) {\r\n    var p, c, l, i, attr, pp, attrp,\r\n        getCurveNormalDir,\r\n        res, isTransformed,\r\n        slides = [];\r\n\r\n    for (i = 0; i < parents.length; ++i) {\r\n        parents[i] = board.select(parents[i]);\r\n    }\r\n    // One arguments: glider on line, circle or curve\r\n    if (parents.length === 1) {\r\n        p = parents[0];\r\n        c = p.slideObject;\r\n        // Two arguments: (point,line), (point,circle), (line,point) or (circle,point)\r\n    } else if (parents.length === 2) {\r\n        if (Type.isPointType(board, parents[0])) {\r\n            p = Type.providePoints(board, [parents[0]], attributes, 'point')[0];\r\n            c = parents[1];\r\n        } else if (Type.isPointType(board, parents[1])) {\r\n            c = parents[0];\r\n            p = Type.providePoints(board, [parents[1]], attributes, 'point')[0];\r\n        } else {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create normal with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [point,line], [point,circle], [glider]\"\r\n            );\r\n        }\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create normal with parent types '\" +\r\n            typeof parents[0] +\r\n            \"' and '\" +\r\n            typeof parents[1] +\r\n            \"'.\" +\r\n            \"\\nPossible parent types: [point,line], [point,circle], [glider]\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'normal');\r\n    if (c.elementClass === Const.OBJECT_CLASS_LINE) {\r\n        // Private point\r\n        attrp = Type.copyAttributes(attributes, board.options, \"normal\", 'point');\r\n        pp = board.create(\r\n            \"point\",\r\n            [\r\n                function () {\r\n                    var p = Mat.crossProduct([1, 0, 0], c.stdform);\r\n                    return [p[0], -p[2], p[1]];\r\n                }\r\n            ],\r\n            attrp\r\n        );\r\n        pp.isDraggable = true;\r\n\r\n        l = board.create(\"line\", [p, pp], attr);\r\n\r\n        /**\r\n         * A helper point used to create a normal to a {@link JXG.Line} object. For normals to circles or curves this\r\n         * element is <tt>undefined</tt>.\r\n         * @type JXG.Point\r\n         * @name point\r\n         * @memberOf Normal.prototype\r\n         */\r\n        l.point = pp;\r\n        l.subs = {\r\n            point: pp\r\n        };\r\n        l.inherits.push(pp);\r\n    } else if (c.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n        l = board.create(\"line\", [c.midpoint, p], attr);\r\n    } else if (c.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n        res = c.getTransformationSource();\r\n        isTransformed = res[0];\r\n        if (isTransformed) {\r\n            // Curve is result of a transformation\r\n            // We recursively collect all curves from which\r\n            // the curve is transformed.\r\n            slides.push(c);\r\n            while (res[0] && Type.exists(res[1]._transformationSource)) {\r\n                slides.push(res[1]);\r\n                res = res[1].getTransformationSource();\r\n            }\r\n        }\r\n\r\n        if (c.evalVisProp('curvetype') !== \"plot\" || isTransformed) {\r\n            // Functiongraph or parametric curve or\r\n            // transformed curve thereof.\r\n            l = board.create(\r\n                \"line\",\r\n                [\r\n                    function () {\r\n                        var g = c.X,\r\n                            f = c.Y,\r\n                            df, dg,\r\n                            li, i, c_org, invMat, po,\r\n                            t;\r\n\r\n                        if (p.type === Const.OBJECT_TYPE_GLIDER) {\r\n                            t = p.position;\r\n                        } else if (c.evalVisProp('curvetype') === 'functiongraph') {\r\n                            t = p.X();\r\n                        } else {\r\n                            t = Geometry.projectPointToCurve(p, c, board)[1];\r\n                        }\r\n\r\n                        // po are the coordinates of the point\r\n                        // on the \"original\" curve. That is the curve or\r\n                        // the original curve which is transformed (maybe multiple times)\r\n                        // to this curve.\r\n                        // t is the position of the point on the \"original\" curve\r\n                        po = p.Coords(true);\r\n                        if (isTransformed) {\r\n                            c_org = slides[slides.length - 1]._transformationSource;\r\n                            g = c_org.X;\r\n                            f = c_org.Y;\r\n                            for (i = 0; i < slides.length; i++) {\r\n                                slides[i].updateTransformMatrix();\r\n                                invMat = Mat.inverse(slides[i].transformMat);\r\n                                po = Mat.matVecMult(invMat, po);\r\n                            }\r\n\r\n                            if (p.type !== Const.OBJECT_TYPE_GLIDER) {\r\n                                po[1] /= po[0];\r\n                                po[2] /= po[0];\r\n                                po[0] /= po[0];\r\n                                t = Geometry.projectCoordsToCurve(po[1], po[2], 0, c_org, board)[1];\r\n                            }\r\n                        }\r\n\r\n                        df = Numerics.D(f)(t);\r\n                        dg = Numerics.D(g)(t);\r\n                        li = [\r\n                            -po[1] * dg - po[2] * df,\r\n                            po[0] * dg,\r\n                            po[0] * df\r\n                        ];\r\n\r\n                        if (isTransformed) {\r\n                            // Transform the line to the transformed curve\r\n                            for (i = slides.length - 1; i >= 0; i--) {\r\n                                invMat = Mat.transpose(Mat.inverse(slides[i].transformMat));\r\n                                li = Mat.matVecMult(invMat, li);\r\n                            }\r\n                        }\r\n\r\n                        return li;\r\n                    }\r\n                ],\r\n                attr\r\n            );\r\n        } else {\r\n            // curveType 'plot': discrete data\r\n            getCurveNormalDir = function (position, c, num) {\r\n                var i = Math.floor(position),\r\n                    lbda,\r\n                    p1, p2, t, A, B, C, D, dx, dy, d,\r\n                    li, p_org, pp,\r\n                    points, le;\r\n\r\n\r\n                if (c.bezierDegree === 1) {\r\n                    if (i === c.numberPoints - 1) {\r\n                        i--;\r\n                    }\r\n                    t = position;\r\n                } else if (c.bezierDegree === 3) {\r\n                    // i is start of the Bezier segment\r\n                    // t is the position in the Bezier segment\r\n                    if (c.elType === 'sector') {\r\n                        points = c.points.slice(3, c.numberPoints - 3);\r\n                        le = points.length;\r\n                    } else {\r\n                        points = c.points;\r\n                        le = points.length;\r\n                    }\r\n                    i = Math.floor((position * (le - 1)) / 3) * 3;\r\n                    t = (position * (le - 1) - i) / 3;\r\n                    if (i >= le - 1) {\r\n                        i = le - 4;\r\n                        t = 1;\r\n                    }\r\n                } else {\r\n                    return 0;\r\n                }\r\n\r\n                if (i < 0) {\r\n                    return 1;\r\n                }\r\n\r\n                lbda = t - i;\r\n                if (c.bezierDegree === 1) {\r\n                    p1 = c.points[i].usrCoords;\r\n                    p2 = c.points[i + 1].usrCoords;\r\n                    p_org = [\r\n                        p1[0] + lbda * (p2[0] - p1[0]),\r\n                        p1[1] + lbda * (p2[1] - p1[1]),\r\n                        p1[2] + lbda * (p2[2] - p1[2])\r\n                    ];\r\n                    li = Mat.crossProduct(p1, p2);\r\n                    pp = Mat.crossProduct([1, 0, 0], li);\r\n                    pp = [pp[0], -pp[2], pp[1]];\r\n                    li = Mat.crossProduct(p_org, pp);\r\n\r\n                } else {\r\n                    A = points[i].usrCoords;\r\n                    B = points[i + 1].usrCoords;\r\n                    C = points[i + 2].usrCoords;\r\n                    D = points[i + 3].usrCoords;\r\n                    dx =\r\n                        (1 - t) * (1 - t) * (B[1] - A[1]) +\r\n                        2 * (1 - t) * t * (C[1] - B[1]) +\r\n                        t * t * (D[1] - C[1]);\r\n                    dy =\r\n                        (1 - t) * (1 - t) * (B[2] - A[2]) +\r\n                        2 * (1 - t) * t * (C[2] - B[2]) +\r\n                        t * t * (D[2] - C[2]);\r\n                    d = Mat.hypot(dx, dy);\r\n                    dx /= d;\r\n                    dy /= d;\r\n                    p1 = p.coords.usrCoords;\r\n                    p2 = [1, p1[1] - dy, p1[2] + dx];\r\n\r\n                    li = [\r\n                        p1[2] * p2[1] - p1[1] * p2[2],\r\n                        p2[2] - p1[2],\r\n                        p1[1] - p2[1]\r\n                    ];\r\n                }\r\n\r\n                switch (num) {\r\n                    case 0:\r\n                        return li[0];\r\n                    case 1:\r\n                        return li[1];\r\n                    case 2:\r\n                        return li[2];\r\n                    default:\r\n                        return li;\r\n                }\r\n            };\r\n\r\n            l = board.create(\r\n                \"line\",\r\n                [\r\n                    function () {\r\n                        var t;\r\n\r\n                        if (p.type === Const.OBJECT_TYPE_GLIDER) {\r\n                            t = p.position;\r\n                        } else {\r\n                            t = Geometry.projectPointToCurve(p, c, board)[1];\r\n                        }\r\n\r\n                        return getCurveNormalDir(t, c);\r\n                    }\r\n                ],\r\n                attr\r\n            );\r\n            p.addChild(l);\r\n            l.glider = p;\r\n        }\r\n    } else if (c.type === Const.OBJECT_TYPE_TURTLE) {\r\n        l = board.create(\r\n            \"line\",\r\n            [\r\n                function () {\r\n                    var el,\r\n                        j,\r\n                        i = Math.floor(p.position),\r\n                        lbda = p.position - i;\r\n\r\n                    // run through all curves of this turtle\r\n                    for (j = 0; j < c.objects.length; j++) {\r\n                        el = c.objects[j];\r\n\r\n                        if (el.type === Const.OBJECT_TYPE_CURVE) {\r\n                            if (i < el.numberPoints) {\r\n                                break;\r\n                            }\r\n\r\n                            i -= el.numberPoints;\r\n                        }\r\n                    }\r\n\r\n                    if (i === el.numberPoints - 1) {\r\n                        i -= 1;\r\n                        lbda = 1;\r\n                    }\r\n\r\n                    if (i < 0) {\r\n                        return 1;\r\n                    }\r\n\r\n                    return (\r\n                        (el.Y(i) + lbda * (el.Y(i + 1) - el.Y(i))) * (el.Y(i) - el.Y(i + 1)) -\r\n                        (el.X(i) + lbda * (el.X(i + 1) - el.X(i))) * (el.X(i + 1) - el.X(i))\r\n                    );\r\n                },\r\n                function () {\r\n                    var el,\r\n                        j,\r\n                        i = Math.floor(p.position);\r\n\r\n                    // run through all curves of this turtle\r\n                    for (j = 0; j < c.objects.length; j++) {\r\n                        el = c.objects[j];\r\n                        if (el.type === Const.OBJECT_TYPE_CURVE) {\r\n                            if (i < el.numberPoints) {\r\n                                break;\r\n                            }\r\n\r\n                            i -= el.numberPoints;\r\n                        }\r\n                    }\r\n\r\n                    if (i === el.numberPoints - 1) {\r\n                        i -= 1;\r\n                    }\r\n\r\n                    if (i < 0) {\r\n                        return 0;\r\n                    }\r\n\r\n                    return el.X(i + 1) - el.X(i);\r\n                },\r\n                function () {\r\n                    var el,\r\n                        j,\r\n                        i = Math.floor(p.position);\r\n\r\n                    // run through all curves of this turtle\r\n                    for (j = 0; j < c.objects.length; j++) {\r\n                        el = c.objects[j];\r\n                        if (el.type === Const.OBJECT_TYPE_CURVE) {\r\n                            if (i < el.numberPoints) {\r\n                                break;\r\n                            }\r\n\r\n                            i -= el.numberPoints;\r\n                        }\r\n                    }\r\n\r\n                    if (i === el.numberPoints - 1) {\r\n                        i -= 1;\r\n                    }\r\n\r\n                    if (i < 0) {\r\n                        return 0;\r\n                    }\r\n\r\n                    return el.Y(i + 1) - el.Y(i);\r\n                }\r\n            ],\r\n            attr\r\n        );\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create normal with parent types '\" +\r\n            typeof parents[0] +\r\n            \"' and '\" +\r\n            typeof parents[1] +\r\n            \"'.\" +\r\n            \"\\nPossible parent types: [point,line], [point,circle], [glider]\"\r\n        );\r\n    }\r\n\r\n    l.elType = 'normal';\r\n    l.setParents(parents);\r\n\r\n    if (Type.exists(p._is_new)) {\r\n        l.addChild(p);\r\n        delete p._is_new;\r\n    } else {\r\n        p.addChild(l);\r\n    }\r\n    c.addChild(l);\r\n\r\n    return l;\r\n};\r\n\r\n/**\r\n * @class The radical axis is the line connecting the two interstion points of two circles with distinct centers.\r\n * The angular bisector of the polar lines of the circle centers with respect to the other circle is always the radical axis.\r\n * The radical axis passes through the intersection points when the circles intersect.\r\n * When a circle about the midpoint of circle centers, passing through the circle centers, intersects the circles, the polar lines pass through those intersection points.\r\n * @pseudo\r\n * @name RadicalAxis\r\n * @augments JXG.Line\r\n * @constructor\r\n * @type JXG.Line\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Circle} circle one of the two respective circles.\r\n * @param {JXG.Circle} circle the other of the two respective circles.\r\n * @example\r\n * // Create the radical axis line with respect to two circles\r\n *   var board = JXG.JSXGraph.initBoard('7b7233a0-f363-47dd-9df5-5018d0d17a98', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var p1 = board.create('point', [2, 3]);\r\n *   var p2 = board.create('point', [1, 4]);\r\n *   var c1 = board.create('circle', [p1, p2]);\r\n *   var p3 = board.create('point', [6, 5]);\r\n *   var p4 = board.create('point', [8, 6]);\r\n *   var c2 = board.create('circle', [p3, p4]);\r\n *   var r1 = board.create('radicalaxis', [c1, c2]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG7b7233a0-f363-47dd-9df5-5018d0d17a98\" class=\"jxgbox\" style=\"width:400px; height:400px;\"></div>\r\n * <script type='text/javascript'>\r\n *   var rlex1_board = JXG.JSXGraph.initBoard('JXG7b7233a0-f363-47dd-9df5-5018d0d17a98', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var rlex1_p1 = rlex1_board.create('point', [2, 3]);\r\n *   var rlex1_p2 = rlex1_board.create('point', [1, 4]);\r\n *   var rlex1_c1 = rlex1_board.create('circle', [rlex1_p1, rlex1_p2]);\r\n *   var rlex1_p3 = rlex1_board.create('point', [6, 5]);\r\n *   var rlex1_p4 = rlex1_board.create('point', [8, 6]);\r\n *   var rlex1_c2 = rlex1_board.create('circle', [rlex1_p3, rlex1_p4]);\r\n *   var rlex1_r1 = rlex1_board.create('radicalaxis', [rlex1_c1, rlex1_c2]);\r\n * </script><pre>\r\n */\r\nJXG.createRadicalAxis = function (board, parents, attributes) {\r\n    var el, el1, el2;\r\n\r\n    if (\r\n        parents.length !== 2 ||\r\n        parents[0].elementClass !== Const.OBJECT_CLASS_CIRCLE ||\r\n        parents[1].elementClass !== Const.OBJECT_CLASS_CIRCLE\r\n    ) {\r\n        // Failure\r\n        throw new Error(\r\n            \"JSXGraph: Can't create 'radical axis' with parent types '\" +\r\n            typeof parents[0] +\r\n            \"' and '\" +\r\n            typeof parents[1] +\r\n            \"'.\" +\r\n            \"\\nPossible parent type: [circle,circle]\"\r\n        );\r\n    }\r\n\r\n    el1 = board.select(parents[0]);\r\n    el2 = board.select(parents[1]);\r\n\r\n    el = board.create(\r\n        \"line\",\r\n        [\r\n            function () {\r\n                var a = el1.stdform,\r\n                    b = el2.stdform;\r\n\r\n                return Mat.matVecMult(Mat.transpose([a.slice(0, 3), b.slice(0, 3)]), [\r\n                    b[3],\r\n                    -a[3]\r\n                ]);\r\n            }\r\n        ],\r\n        attributes\r\n    );\r\n\r\n    el.elType = 'radicalaxis';\r\n    el.setParents([el1.id, el2.id]);\r\n\r\n    el1.addChild(el);\r\n    el2.addChild(el);\r\n\r\n    return el;\r\n};\r\n\r\n/**\r\n * @class The polar line of a point with respect to a conic or a circle.\r\n * @pseudo\r\n * @description The polar line is the unique reciprocal relationship of a point with respect to a conic.\r\n * The lines through the intersections of a conic and the polar line of a point\r\n * with respect to that conic and through that point are tangent to the conic.\r\n * A point on a conic has the polar line of that point with respect to that\r\n * conic as the tangent line to that conic at that point.\r\n * See {@link https://en.wikipedia.org/wiki/Pole_and_polar} for more information on pole and polar.\r\n * @name PolarLine\r\n * @augments JXG.Line\r\n * @constructor\r\n * @type JXG.Line\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Conic,JXG.Circle_JXG.Point} el1,el2 or\r\n * @param {JXG.Point_JXG.Conic,JXG.Circle} el1,el2 The result will be the polar line of the point with respect to the conic or the circle.\r\n * @example\r\n * // Create the polar line of a point with respect to a conic\r\n * var p1 = board.create('point', [-1, 2]);\r\n * var p2 = board.create('point', [ 1, 4]);\r\n * var p3 = board.create('point', [-1,-2]);\r\n * var p4 = board.create('point', [ 0, 0]);\r\n * var p5 = board.create('point', [ 4,-2]);\r\n * var c1 = board.create('conic',[p1,p2,p3,p4,p5]);\r\n * var p6 = board.create('point', [-1, 1]);\r\n * var l1 = board.create('polarline', [c1, p6]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG7b7233a0-f363-47dd-9df5-6018d0d17a98\" class=\"jxgbox\" style=\"width:400px; height:400px;\"></div>\r\n * <script type='text/javascript'>\r\n * var plex1_board = JXG.JSXGraph.initBoard('JXG7b7233a0-f363-47dd-9df5-6018d0d17a98', {boundingbox: [-3, 5, 5, -3], axis: true, showcopyright: false, shownavigation: false});\r\n * var plex1_p1 = plex1_board.create('point', [-1, 2]);\r\n * var plex1_p2 = plex1_board.create('point', [ 1, 4]);\r\n * var plex1_p3 = plex1_board.create('point', [-1,-2]);\r\n * var plex1_p4 = plex1_board.create('point', [ 0, 0]);\r\n * var plex1_p5 = plex1_board.create('point', [ 4,-2]);\r\n * var plex1_c1 = plex1_board.create('conic',[plex1_p1,plex1_p2,plex1_p3,plex1_p4,plex1_p5]);\r\n * var plex1_p6 = plex1_board.create('point', [-1, 1]);\r\n * var plex1_l1 = plex1_board.create('polarline', [plex1_c1, plex1_p6]);\r\n * </script><pre>\r\n * @example\r\n * // Create the polar line of a point with respect to a circle.\r\n * var p1 = board.create('point', [ 1, 1]);\r\n * var p2 = board.create('point', [ 2, 3]);\r\n * var c1 = board.create('circle',[p1,p2]);\r\n * var p3 = board.create('point', [ 6, 6]);\r\n * var l1 = board.create('polarline', [c1, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG7b7233a0-f363-47dd-9df5-7018d0d17a98\" class=\"jxgbox\" style=\"width:400px; height:400px;\"></div>\r\n * <script type='text/javascript'>\r\n * var plex2_board = JXG.JSXGraph.initBoard('JXG7b7233a0-f363-47dd-9df5-7018d0d17a98', {boundingbox: [-3, 7, 7, -3], axis: true, showcopyright: false, shownavigation: false});\r\n * var plex2_p1 = plex2_board.create('point', [ 1, 1]);\r\n * var plex2_p2 = plex2_board.create('point', [ 2, 3]);\r\n * var plex2_c1 = plex2_board.create('circle',[plex2_p1,plex2_p2]);\r\n * var plex2_p3 = plex2_board.create('point', [ 6, 6]);\r\n * var plex2_l1 = plex2_board.create('polarline', [plex2_c1, plex2_p3]);\r\n * </script><pre>\r\n */\r\nJXG.createPolarLine = function (board, parents, attributes) {\r\n    var el,\r\n        el1,\r\n        el2,\r\n        firstParentIsConic,\r\n        secondParentIsConic,\r\n        firstParentIsPoint,\r\n        secondParentIsPoint;\r\n\r\n    if (parents.length > 1) {\r\n        firstParentIsConic =\r\n            parents[0].type === Const.OBJECT_TYPE_CONIC ||\r\n            parents[0].elementClass === Const.OBJECT_CLASS_CIRCLE;\r\n        secondParentIsConic =\r\n            parents[1].type === Const.OBJECT_TYPE_CONIC ||\r\n            parents[1].elementClass === Const.OBJECT_CLASS_CIRCLE;\r\n\r\n        firstParentIsPoint = Type.isPoint(parents[0]);\r\n        secondParentIsPoint = Type.isPoint(parents[1]);\r\n    }\r\n\r\n    if (\r\n        parents.length !== 2 ||\r\n        !(\r\n            (firstParentIsConic && secondParentIsPoint) ||\r\n            (firstParentIsPoint && secondParentIsConic)\r\n        )\r\n    ) {\r\n        // Failure\r\n        throw new Error(\r\n            \"JSXGraph: Can't create 'polar line' with parent types '\" +\r\n            typeof parents[0] +\r\n            \"' and '\" +\r\n            typeof parents[1] +\r\n            \"'.\" +\r\n            \"\\nPossible parent type: [conic|circle,point], [point,conic|circle]\"\r\n        );\r\n    }\r\n\r\n    if (secondParentIsPoint) {\r\n        el1 = board.select(parents[0]);\r\n        el2 = board.select(parents[1]);\r\n    } else {\r\n        el1 = board.select(parents[1]);\r\n        el2 = board.select(parents[0]);\r\n    }\r\n\r\n    // Polar lines have been already provided in the tangent element.\r\n    el = board.create(\"tangent\", [el1, el2], attributes);\r\n\r\n    el.elType = 'polarline';\r\n    return el;\r\n};\r\n\r\n/**\r\n *\r\n * @class One of the two tangent lines to a conic or a circle through an external point.\r\n * @pseudo\r\n * @description Construct the tangent line through a point to a conic or a circle. There will be either two, one or no\r\n * such tangent, depending if the point is outside of the conic, on the conic, or inside of the conic.\r\n * Similar to the intersection of a line with a circle, the specific tangent can be chosen with a third (optional) parameter\r\n * <i>number</i>.\r\n * <p>\r\n * Attention: from a technical point of view, the point from which the tangent to the conic/circle is constructed is not an element of\r\n * the tangent line.\r\n * @name TangentTo\r\n * @augments JXG.Line\r\n * @constructor\r\n * @type JXG.Line\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Conic,JXG.Circle_JXG.Point_Number} conic,point,[number=0] The result will be the tangent line through\r\n * the point with respect to the conic or circle.\r\n *\r\n * @example\r\n *  var c = board.create('circle', [[3, 0], [3, 4]]);\r\n *  var p = board.create('point', [0, 6]);\r\n *  var t0 = board.create('tangentto', [c, p, 0], { color: 'black', polar: {visible: true}, point: {visible: true} });\r\n *  var t1 = board.create('tangentto', [c, p, 1], { color: 'black' });\r\n *\r\n * </pre><div id=\"JXGd4b359c7-3a29-44c3-a19d-d51b42a00c8b\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGd4b359c7-3a29-44c3-a19d-d51b42a00c8b',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *             var c = board.create('circle', [[3, 0], [3, 4]]);\r\n *             var p = board.create('point', [0, 6]);\r\n *             var t0 = board.create('tangentto', [c, p, 0], { color: 'black', polar: {visible: true}, point: {visible: true} });\r\n *             var t1 = board.create('tangentto', [c, p, 1], { color: 'black' });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *  var p = board.create('point', [0, 6]);\r\n *  var ell = board.create('ellipse', [[-5, 1], [-2, -1], [-3, 2]]);\r\n *  var t0 = board.create('tangentto', [ell, p, 0]);\r\n *  var t1 = board.create('tangentto', [ell, p, 1]);\r\n *\r\n * </pre><div id=\"JXG6e625663-1c3e-4e08-a9df-574972a374e8\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG6e625663-1c3e-4e08-a9df-574972a374e8',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *             var p = board.create('point', [0, 6]);\r\n *             var ell = board.create('ellipse', [[-5, 1], [-2, -1], [-3, 2]]);\r\n *             var t0 = board.create('tangentto', [ell, p, 0]);\r\n *             var t1 = board.create('tangentto', [ell, p, 1]);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createTangentTo = function (board, parents, attributes) {\r\n    var el, attr,\r\n        conic, pointFrom, num,\r\n        intersect, polar;\r\n\r\n    conic = board.select(parents[0]);\r\n    pointFrom = Type.providePoints(board, parents[1], attributes, 'point')[0];\r\n    num = Type.def(parents[2], 0);\r\n\r\n    if (\r\n        (conic.type !== Const.OBJECT_TYPE_CIRCLE && conic.type !== Const.OBJECT_TYPE_CONIC) ||\r\n        (pointFrom.elementClass !== Const.OBJECT_CLASS_POINT)\r\n    ) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create tangentto with parent types '\" +\r\n            typeof parents[0] +\r\n            \"' and '\" +\r\n            typeof parents[1] +\r\n            \"' and '\" +\r\n            typeof parents[2] +\r\n            \"'.\" +\r\n            \"\\nPossible parent types: [circle|conic,point,number]\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'tangentto');\r\n    // A direct analytic geometry approach would be in\r\n    // Richter-Gebert: Perspectives on projective geometry, 11.3\r\n    polar = board.create('polar', [conic, pointFrom], attr.polar);\r\n    intersect = board.create('intersection', [polar, conic, num], attr.point);\r\n\r\n    el = board.create('tangent', [conic, intersect], attr);\r\n\r\n    /**\r\n     * The intersection point of the conic/circle with the polar line of the tangentto construction.\r\n     * @memberOf TangentTo.prototype\r\n     * @name point\r\n     * @type JXG.Point\r\n     */\r\n    el.point = intersect;\r\n\r\n    /**\r\n     * The polar line of the tangentto construction.\r\n     * @memberOf TangentTo.prototype\r\n     * @name polar\r\n     * @type JXG.Line\r\n     */\r\n    el.polar = polar;\r\n\r\n    el.elType = 'tangentto';\r\n\r\n    return el;\r\n};\r\n\r\n/**\r\n * Register the element type tangent at JSXGraph\r\n * @private\r\n */\r\nJXG.registerElement(\"tangent\", JXG.createTangent);\r\nJXG.registerElement(\"normal\", JXG.createNormal);\r\nJXG.registerElement('tangentto', JXG.createTangentTo);\r\nJXG.registerElement(\"polar\", JXG.createTangent);\r\nJXG.registerElement(\"radicalaxis\", JXG.createRadicalAxis);\r\nJXG.registerElement(\"polarline\", JXG.createPolarLine);\r\n\r\nexport default JXG.Line;\r\n// export default {\r\n//     Line: JXG.Line,\r\n//     createLine: JXG.createLine,\r\n//     createTangent: JXG.createTangent,\r\n//     createPolar: JXG.createTangent,\r\n//     createSegment: JXG.createSegment,\r\n//     createAxis: JXG.createAxis,\r\n//     createArrow: JXG.createArrow,\r\n//     createRadicalAxis: JXG.createRadicalAxis,\r\n//     createPolarLine: JXG.createPolarLine\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview In this file the class Group is defined, a class for\r\n * managing grouping of points.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"./constants.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Creates a new instance of Group.\r\n * @class In this class all group management is done.\r\n * @param {JXG.Board} board\r\n * @param {String} id Unique identifier for this object.  If null or an empty string is given,\r\n * an unique id will be generated by Board\r\n * @param {String} name Not necessarily unique name, displayed on the board.  If null or an\r\n * empty string is given, an unique name will be generated.\r\n * @param {Array} objects Array of points to add to this group.\r\n * @param {Object} attributes Defines the visual appearance of the group.\r\n * @constructor\r\n */\r\nJXG.Group = function (board, id, name, objects, attributes) {\r\n    var number, objArray, i, obj;\r\n\r\n    this.board = board;\r\n    this.objects = {};\r\n    number = this.board.numObjects;\r\n    this.board.numObjects += 1;\r\n\r\n    if (id === \"\" || !Type.exists(id)) {\r\n        this.id = this.board.id + \"Group\" + number;\r\n    } else {\r\n        this.id = id;\r\n    }\r\n    this.board.groups[this.id] = this;\r\n\r\n    this.type = Const.OBJECT_TYPE_POINT;\r\n    this.elementClass = Const.OBJECT_CLASS_POINT;\r\n\r\n    if (name === \"\" || !Type.exists(name)) {\r\n        this.name = \"group_\" + this.board.generateName(this);\r\n    } else {\r\n        this.name = name;\r\n    }\r\n    delete this.type;\r\n\r\n    /**\r\n     * Cache coordinates of points. From this and the actual position\r\n     * of the points, the translation is determined.\r\n     * It has to be kept updated in this class \"by hand\"-\r\n     *\r\n     * @private\r\n     * @type Object\r\n     * @see JXG.Group#_updateCoordsCache\r\n     */\r\n    this.coords = {};\r\n    this.needsRegularUpdate = attributes.needsregularupdate;\r\n\r\n    this.rotationCenter = 'centroid';\r\n    this.scaleCenter = null;\r\n    this.rotationPoints = [];\r\n    this.translationPoints = [];\r\n    this.scalePoints = [];\r\n    this.scaleDirections = {};\r\n\r\n    this.parents = [];\r\n\r\n    if (Type.isArray(objects)) {\r\n        objArray = objects;\r\n    } else {\r\n        objArray = Array.prototype.slice.call(arguments, 3);\r\n    }\r\n\r\n    for (i = 0; i < objArray.length; i++) {\r\n        obj = this.board.select(objArray[i]);\r\n\r\n        if (!obj.evalVisProp('fixed') && Type.exists(obj.coords)) {\r\n            this.addPoint(obj);\r\n        }\r\n    }\r\n\r\n    this.methodMap = {\r\n        ungroup: \"ungroup\",\r\n        add: \"addPoint\",\r\n        addPoint: \"addPoint\",\r\n        addPoints: \"addPoints\",\r\n        addGroup: \"addGroup\",\r\n        remove: \"removePoint\",\r\n        removePoint: \"removePoint\",\r\n        setAttribute: \"setAttribute\",\r\n        setProperty: \"setAttribute\"\r\n    };\r\n};\r\n\r\nJXG.extend(\r\n    JXG.Group.prototype,\r\n    /** @lends JXG.Group.prototype */ {\r\n        /**\r\n         * Releases all elements of this group.\r\n         * @returns {JXG.Group} returns this (empty) group\r\n         */\r\n        ungroup: function () {\r\n            var el, p, i;\r\n            for (el in this.objects) {\r\n                if (this.objects.hasOwnProperty(el)) {\r\n                    p = this.objects[el].point;\r\n                    if (Type.isArray(p.groups)) {\r\n                        i = Type.indexOf(p.groups, this.id);\r\n                        if (i >= 0) {\r\n                            delete p.groups[i];\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            this.objects = {};\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Adds ids of elements to the array this.parents. This is a copy\r\n         * of {@link Element.addParents}.\r\n         * @param {Array} parents Array of elements or ids of elements.\r\n         * Alternatively, one can give a list of objects as parameters.\r\n         * @returns {JXG.Object} reference to the object itself.\r\n         **/\r\n        addParents: function (parents) {\r\n            var i, len, par;\r\n\r\n            if (Type.isArray(parents)) {\r\n                par = parents;\r\n            } else {\r\n                par = arguments;\r\n            }\r\n\r\n            len = par.length;\r\n            for (i = 0; i < len; ++i) {\r\n                if (Type.isId(this.board, par[i])) {\r\n                    this.parents.push(par[i]);\r\n                } else if (Type.exists(par[i].id)) {\r\n                    this.parents.push(par[i].id);\r\n                }\r\n            }\r\n\r\n            this.parents = Type.uniqueArray(this.parents);\r\n        },\r\n\r\n        /**\r\n         * Sets ids of elements to the array this.parents. This is a copy\r\n         * of {@link Element.setParents}\r\n         * First, this.parents is cleared. See {@link Group#addParents}.\r\n         * @param {Array} parents Array of elements or ids of elements.\r\n         * Alternatively, one can give a list of objects as parameters.\r\n         * @returns {JXG.Object} reference to the object itself.\r\n         **/\r\n        setParents: function (parents) {\r\n            this.parents = [];\r\n            this.addParents(parents);\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * List of the element ids resp. values used as parents in {@link JXG.Board#create}.\r\n         * @returns {Array}\r\n         */\r\n        getParents: function () {\r\n            return Type.isArray(this.parents) ? this.parents : [];\r\n        },\r\n\r\n        /**\r\n         * Update the cached coordinates of a group element.\r\n         * @param  {String} el element id of the group element whose cached coordinates\r\n         * are going to be updated.\r\n         * @return null\r\n         */\r\n        _updateCoordsCache: function (el) {\r\n            var obj;\r\n            if (el !== \"\" && Type.exists(this.objects[el])) {\r\n                obj = this.objects[el].point;\r\n                this.coords[obj.id] = { usrCoords: obj.coords.usrCoords.slice(0) };\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Sends an update to all group members.\r\n         * This method is called from the points' coords object event listeners\r\n         * and not by the board.\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        update: function () {\r\n            var i, drag, el,\r\n                actionCenter,\r\n                desc,\r\n                s, sx, sy,\r\n                alpha,\r\n                t, T,\r\n                center,\r\n                obj = null;\r\n\r\n            if (!this.needsUpdate) {\r\n                return this;\r\n            }\r\n\r\n            drag = this._update_find_drag_type();\r\n            if (drag.action === 'nothing') {\r\n                this._updateCoordsCache(drag.id);\r\n                return this;\r\n            }\r\n\r\n            obj = this.objects[drag.id].point;\r\n\r\n            // Prepare translation, scaling or rotation.\r\n            // Scaling and rotation is handled by transformations for all elements.\r\n            // Translation is handled by direct coordinate manipulation for points.\r\n            // For images and texts, all translation, scaling and rotation is\r\n            // done by binding a transformation to the element.\r\n            if (drag.action === 'translation') {\r\n                t = [\r\n                    obj.coords.usrCoords[1] - this.coords[drag.id].usrCoords[1],\r\n                    obj.coords.usrCoords[2] - this.coords[drag.id].usrCoords[2]\r\n                ];\r\n\r\n                if (obj.elementClass !== Const.OBJECT_CLASS_POINT) {\r\n                    // For images and texts we have to update the drag direction\r\n                    // by reapplying all transformations.\r\n\r\n                    t.unshift(0);\r\n                    for (i = 0; i < obj.transformations.length; i++) {\r\n                        t = Mat.matVecMult(obj.transformations[i].matrix, t);\r\n                    }\r\n                    t.shift();\r\n                }\r\n\r\n                // For images and texts\r\n                T = this.board.create(\"transform\", t, { type: \"translate\" });\r\n                T.update();\r\n            } else if (drag.action === \"rotation\" || drag.action === 'scaling') {\r\n                if (drag.action === 'rotation') {\r\n                    actionCenter = 'rotationCenter';\r\n                } else {\r\n                    actionCenter = 'scaleCenter';\r\n                }\r\n\r\n                // if (Type.isPoint(this.board, this[actionCenter])) {\r\n                if (Type.exists(this[actionCenter].coords)) {\r\n                    center = this[actionCenter].coords.usrCoords.slice(1);\r\n                } else if (this[actionCenter] === 'centroid') {\r\n                    center = this._update_centroid_center();\r\n                } else if (Type.isArray(this[actionCenter])) {\r\n                    center = this[actionCenter];\r\n                } else if (Type.isFunction(this[actionCenter])) {\r\n                    center = this[actionCenter]();\r\n                } else {\r\n                    // No valid center for this transformation, get out of here.\r\n                    JXG.debug('Group.update: No valid center for this transformation, get out of here.');\r\n                    return this;\r\n                }\r\n\r\n                if (drag.action === 'rotation') {\r\n                    alpha = Geometry.rad(\r\n                        this.coords[drag.id].usrCoords.slice(1),\r\n                        center,\r\n                        this.objects[drag.id].point\r\n                    );\r\n                    t = this.board.create(\"transform\", [alpha, center[0], center[1]], {\r\n                        type: \"rotate\"\r\n                    });\r\n                    t.update(); // t.update initializes t.matrix, which is needed if the action element is the first group element.\r\n                } else if (drag.action === 'scaling') {\r\n                    s = Geometry.distance(this.coords[drag.id].usrCoords.slice(1), center);\r\n                    if (Math.abs(s) < Mat.eps) {\r\n                        return this;\r\n                    }\r\n                    s = Geometry.distance(obj.coords.usrCoords.slice(1), center) / s;\r\n                    sx = this.scaleDirections[drag.id].indexOf('x') >= 0 ? s : 1.0;\r\n                    sy = this.scaleDirections[drag.id].indexOf('y') >= 0 ? s : 1.0;\r\n\r\n                    // Shift scale center to origin, scale and shift the scale center back.\r\n                    t = this.board.create(\r\n                        \"transform\",\r\n                        [1, 0, 0, center[0] * (1 - sx), sx, 0, center[1] * (1 - sy), 0, sy],\r\n                        { type: \"generic\" }\r\n                    );\r\n                    t.update(); // This initializes t.matrix, which is needed if the action element is the first group element.\r\n                } else {\r\n                    // This should not be reached\r\n                    return this;\r\n                }\r\n            }\r\n\r\n            // Bind the transformation to any images and texts\r\n            for (el in this.objects) {\r\n                obj = this.objects[el].point;\r\n                if (obj.elementClass !== Const.OBJECT_CLASS_POINT) {\r\n                    if (Type.exists(t.board)) {\r\n                        // t itself is a transformation\r\n                        t.meltTo(obj);\r\n                    } else {\r\n                        // Drag element is a point, therefore\r\n                        // t is an array and we have to use the transformation T.\r\n                        if (drag.id !== obj.id) {\r\n                            T.meltTo(obj);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            this._update_apply_transformation(drag, t);\r\n\r\n            this.needsUpdate = false; // This is needed here to prevent infinite recursion because\r\n            // of the board.updateElements call below,\r\n\r\n            // Prepare dependent objects for update\r\n            for (el in this.objects) {\r\n                if (this.objects.hasOwnProperty(el)) {\r\n                    for (desc in this.objects[el].descendants) {\r\n                        if (this.objects[el].descendants.hasOwnProperty(desc)) {\r\n                            this.objects[el].descendants.needsUpdate =\r\n                                this.objects[el].descendants.needsRegularUpdate ||\r\n                                this.board.needsFullUpdate;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            this.board.updateElements(drag);\r\n\r\n            // Now, all group elements have their new position and\r\n            // we can update the bookkeeping of the coordinates of the group elements.\r\n            for (el in this.objects) {\r\n                if (this.objects.hasOwnProperty(el)) {\r\n                    this._updateCoordsCache(el);\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @private\r\n        */\r\n        //  Determine what the dragging of a group element should do:\r\n        //  rotation, translation, scaling or nothing.\r\n        _update_find_drag_type: function () {\r\n            var el,\r\n                obj,\r\n                action = \"nothing\",\r\n                changed = [],\r\n                dragObjId;\r\n\r\n            // Determine how many elements have changed their position\r\n            // If more than one element changed its position, it is a translation.\r\n            // If exactly one element changed its position we have to find the type of the point.\r\n            for (el in this.objects) {\r\n                if (this.objects.hasOwnProperty(el)) {\r\n                    obj = this.objects[el].point;\r\n\r\n                    if (obj.coords.distance(Const.COORDS_BY_USER, this.coords[el]) > Mat.eps) {\r\n                        changed.push(obj.id);\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Determine type of action: translation, scaling or rotation\r\n            if (changed.length === 0) {\r\n                return {\r\n                    action: action,\r\n                    id: \"\",\r\n                    changed: changed\r\n                };\r\n            }\r\n\r\n            dragObjId = changed[0];\r\n            obj = this.objects[dragObjId].point;\r\n\r\n            if (changed.length > 1) {\r\n                // More than one point moved => translation\r\n                action = 'translation';\r\n            } else {\r\n                // One point moved => we have to determine the type\r\n                if (\r\n                    Type.isInArray(this.rotationPoints, obj) &&\r\n                    Type.exists(this.rotationCenter)\r\n                ) {\r\n                    action = 'rotation';\r\n                } else if (\r\n                    Type.isInArray(this.scalePoints, obj) &&\r\n                    Type.exists(this.scaleCenter)\r\n                ) {\r\n                    action = 'scaling';\r\n                } else if (Type.isInArray(this.translationPoints, obj)) {\r\n                    action = 'translation';\r\n                }\r\n            }\r\n\r\n            return {\r\n                action: action,\r\n                id: dragObjId,\r\n                changed: changed\r\n            };\r\n        },\r\n\r\n        /**\r\n         * Determine the Euclidean (affine) coordinates of the centroid of the group.\r\n         * @private\r\n         * @returns {Array} array of length two,\r\n        */\r\n        _update_centroid_center: function () {\r\n            var center, len, el;\r\n\r\n            center = [0, 0];\r\n            len = 0;\r\n            for (el in this.coords) {\r\n                if (this.coords.hasOwnProperty(el)) {\r\n                    center[0] += this.coords[el].usrCoords[1];\r\n                    center[1] += this.coords[el].usrCoords[2];\r\n                    ++len;\r\n                }\r\n            }\r\n            if (len > 0) {\r\n                center[0] /= len;\r\n                center[1] /= len;\r\n            }\r\n\r\n            return center;\r\n        },\r\n\r\n        /**\r\n         * @private\r\n        */\r\n        // Apply the transformation to all elements of the group\r\n        _update_apply_transformation: function (drag, t) {\r\n            var el, obj;\r\n\r\n            for (el in this.objects) {\r\n                if (this.objects.hasOwnProperty(el)) {\r\n                    if (Type.exists(this.board.objects[el])) {\r\n                        obj = this.objects[el].point;\r\n\r\n                        // Here, it is important that we change the position\r\n                        // of elements by using setCoordinates.\r\n                        // Thus, we avoid the call of snapToGrid().\r\n                        // This is done in the subsequent call of board.updateElements()\r\n                        // in Group.update() above.\r\n                        if (obj.id !== drag.id) {\r\n                            if (drag.action === 'translation') {\r\n                                if (!Type.isInArray(drag.changed, obj.id)) {\r\n                                    if (obj.elementClass === Const.OBJECT_CLASS_POINT) {\r\n                                        obj.coords.setCoordinates(Const.COORDS_BY_USER, [\r\n                                            this.coords[el].usrCoords[1] + t[0],\r\n                                            this.coords[el].usrCoords[2] + t[1]\r\n                                        ]);\r\n                                    }\r\n                                }\r\n                            } else if (\r\n                                drag.action === \"rotation\" ||\r\n                                drag.action === \"scaling\"\r\n                            ) {\r\n                                if (obj.elementClass === Const.OBJECT_CLASS_POINT) {\r\n                                    t.applyOnce([obj]);\r\n                                }\r\n                            }\r\n                        } else {\r\n                            if (drag.action === \"rotation\" || drag.action === 'scaling') {\r\n                                obj.coords.setCoordinates(\r\n                                    Const.COORDS_BY_USER,\r\n                                    Mat.matVecMult(t.matrix, this.coords[obj.id].usrCoords)\r\n                                );\r\n                            }\r\n                        }\r\n                    } else {\r\n                        delete this.objects[el];\r\n                    }\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Adds an Point to this group.\r\n         * @param {JXG.Point} object The point added to the group.\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        addPoint: function (object) {\r\n            this.objects[object.id] = { point: this.board.select(object) };\r\n            this._updateCoordsCache(object.id);\r\n            this.translationPoints.push(object);\r\n\r\n            object.groups.push(this.id);\r\n            object.groups = Type.uniqueArray(object.groups);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Adds multiple points to this group.\r\n         * @param {Array} objects An array of points to add to the group.\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        addPoints: function (objects) {\r\n            var p;\r\n\r\n            for (p = 0; p < objects.length; p++) {\r\n                this.addPoint(objects[p]);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Adds all points in a group to this group.\r\n         * @param {JXG.Group} group The group added to this group.\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        addGroup: function (group) {\r\n            var el;\r\n\r\n            for (el in group.objects) {\r\n                if (group.objects.hasOwnProperty(el)) {\r\n                    this.addPoint(group.objects[el].point);\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Removes a point from the group.\r\n         * @param {JXG.Point} point\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        removePoint: function (point) {\r\n            delete this.objects[point.id];\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Sets the center of rotation for the group. This is either a point or the centroid of the group.\r\n         * @param {JXG.Point|String|Array|Function} object A point which will be the center of rotation, the string \"centroid\", or\r\n         * an array of length two, or a function returning an array of length two.\r\n         * @default 'centroid'\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        setRotationCenter: function (object) {\r\n            this.rotationCenter = object;\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Sets the rotation points of the group. Dragging at one of these points results into a rotation of the whole group around\r\n         * the rotation center of the group {@see JXG.Group#setRotationCenter}.\r\n         * @param {Array|JXG.Point} objects Array of {@link JXG.Point} or arbitrary number of {@link JXG.Point} elements.\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        setRotationPoints: function (objects) {\r\n            return this._setActionPoints(\"rotation\", objects);\r\n        },\r\n\r\n        /**\r\n         * Adds a point to the set of rotation points of the group. Dragging at one of these points results into a rotation of the whole group around\r\n         * the rotation center of the group {@see JXG.Group#setRotationCenter}.\r\n         * @param {JXG.Point} point {@link JXG.Point} element.\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        addRotationPoint: function (point) {\r\n            return this._addActionPoint(\"rotation\", point);\r\n        },\r\n\r\n        /**\r\n         * Removes the rotation property from a point of the group.\r\n         * @param {JXG.Point} point {@link JXG.Point} element.\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        removeRotationPoint: function (point) {\r\n            return this._removeActionPoint(\"rotation\", point);\r\n        },\r\n\r\n        /**\r\n         * Sets the translation points of the group. Dragging at one of these points results into a translation of the whole group.\r\n         * @param {Array|JXG.Point} objects Array of {@link JXG.Point} or arbitrary number of {@link JXG.Point} elements.\r\n         *\r\n         * By default, all points of the group are translation points.\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        setTranslationPoints: function (objects) {\r\n            return this._setActionPoints(\"translation\", objects);\r\n        },\r\n\r\n        /**\r\n         * Adds a point to the set of the translation points of the group.\r\n         * Dragging one of these points results into a translation of the whole group.\r\n         * @param {JXG.Point} point {@link JXG.Point} element.\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        addTranslationPoint: function (point) {\r\n            return this._addActionPoint(\"translation\", point);\r\n        },\r\n\r\n        /**\r\n         * Removes the translation property from a point of the group.\r\n         * @param {JXG.Point} point {@link JXG.Point} element.\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        removeTranslationPoint: function (point) {\r\n            return this._removeActionPoint(\"translation\", point);\r\n        },\r\n\r\n        /**\r\n         * Sets the center of scaling for the group. This is either a point or the centroid of the group.\r\n         * @param {JXG.Point|String} object A point which will be the center of scaling, the string \"centroid\", or\r\n         * an array of length two, or a function returning an array of length two.\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        setScaleCenter: function (object) {\r\n            this.scaleCenter = object;\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Sets the scale points of the group. Dragging at one of these points results into a scaling of the whole group.\r\n         * @param {Array|JXG.Point} objects Array of {@link JXG.Point} or arbitrary number of {@link JXG.Point} elements.\r\n         * @param {String} direction Restricts the directions to be scaled. Possible values are 'x', 'y', 'xy'. Default value is 'xy'.\r\n         *\r\n         * By default, all points of the group are translation points.\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        setScalePoints: function (objects, direction) {\r\n            var objs, i, len;\r\n            if (Type.isArray(objects)) {\r\n                objs = objects;\r\n            } else {\r\n                objs = arguments;\r\n            }\r\n\r\n            len = objs.length;\r\n            for (i = 0; i < len; ++i) {\r\n                this.scaleDirections[this.board.select(objs[i]).id] = direction || 'xy';\r\n            }\r\n\r\n            return this._setActionPoints(\"scale\", objects);\r\n        },\r\n\r\n        /**\r\n         * Adds a point to the set of the scale points of the group. Dragging at one of these points results into a scaling of the whole group.\r\n         * @param {JXG.Point} point {@link JXG.Point} element.\r\n         * @param {String} direction Restricts the directions to be scaled. Possible values are 'x', 'y', 'xy'. Default value is 'xy'.\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        addScalePoint: function (point, direction) {\r\n            this._addActionPoint(\"scale\", point);\r\n            this.scaleDirections[this.board.select(point).id] = direction || 'xy';\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Removes the scaling property from a point of the group.\r\n         * @param {JXG.Point} point {@link JXG.Point} element.\r\n         * @returns {JXG.Group} returns this group\r\n         */\r\n        removeScalePoint: function (point) {\r\n            return this._removeActionPoint(\"scale\", point);\r\n        },\r\n\r\n        /**\r\n         * Generic method for {@link JXG.Group@setTranslationPoints} and {@link JXG.Group@setRotationPoints}\r\n         * @private\r\n         */\r\n        _setActionPoints: function (action, objects) {\r\n            var objs, i, len;\r\n            if (Type.isArray(objects)) {\r\n                objs = objects;\r\n            } else {\r\n                objs = arguments;\r\n            }\r\n\r\n            len = objs.length;\r\n            this[action + \"Points\"] = [];\r\n            for (i = 0; i < len; ++i) {\r\n                this._addActionPoint(action, objs[i]);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Generic method for {@link JXG.Group@addTranslationPoint} and {@link JXG.Group@addRotationPoint}\r\n         * @private\r\n         */\r\n        _addActionPoint: function (action, point) {\r\n            this[action + \"Points\"].push(this.board.select(point));\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Generic method for {@link JXG.Group@removeTranslationPoint} and {@link JXG.Group@removeRotationPoint}\r\n         * @private\r\n         */\r\n        _removeActionPoint: function (action, point) {\r\n            var idx = this[action + \"Points\"].indexOf(this.board.select(point));\r\n            if (idx > -1) {\r\n                this[action + \"Points\"].splice(idx, 1);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * @deprecated\r\n         * Use setAttribute\r\n         */\r\n        setProperty: function () {\r\n            JXG.deprecated(\"Group.setProperty\", \"Group.setAttribute()\");\r\n            this.setAttribute.apply(this, arguments);\r\n        },\r\n\r\n        setAttribute: function () {\r\n            var el;\r\n\r\n            for (el in this.objects) {\r\n                if (this.objects.hasOwnProperty(el)) {\r\n                    this.objects[el].point.setAttribute.apply(\r\n                        this.objects[el].point,\r\n                        arguments\r\n                    );\r\n                }\r\n            }\r\n\r\n            return this;\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * @class A container element to control the movement of given set of point, image or text elements simultaneously.\r\n * The elements of the group and dependent elements can be translated, rotated and scaled by\r\n * dragging one of the group elements.\r\n *\r\n * @pseudo\r\n * @name Group\r\n * @augments JXG.Group\r\n * @constructor\r\n * @type JXG.Group\r\n * @param {JXG.Board} board The board the points are on.\r\n * @param {Array} parents Array of points to group.\r\n * @param {Object} attributes Visual properties (unused).\r\n * @returns {JXG.Group}\r\n *\r\n * @example\r\n *\r\n *  // Create some free points. e.g. A, B, C, D\r\n *  // Create a group\r\n *\r\n *  var p, col, g;\r\n *  col = 'blue';\r\n *  p = [];\r\n *  p.push(board.create('point',[-2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, 1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[-2, 1], {size: 5, strokeColor:col, fillColor:col}));\r\n *  g = board.create('group', p);\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXGa2204533-db91-4af9-b720-70394de4d367\" style=\"width: 400px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *  (function () {\r\n *  var board, p, col, g;\r\n *  board = JXG.JSXGraph.initBoard('JXGa2204533-db91-4af9-b720-70394de4d367', {boundingbox:[-5,5,5,-5], keepaspectratio:true, axis:true, showcopyright: false});\r\n *  col = 'blue';\r\n *  p = [];\r\n *  p.push(board.create('point',[-2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, 1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[-2, 1], {size: 5, strokeColor:col, fillColor:col}));\r\n *  g = board.create('group', p);\r\n *  })();\r\n * </script><pre>\r\n *\r\n *\r\n * @example\r\n *\r\n *  // Create some free points. e.g. A, B, C, D\r\n *  // Create a group\r\n *  // If the points define a polygon and the polygon has the attribute hasInnerPoints:true,\r\n *  // the polygon can be dragged around.\r\n *\r\n *  var p, col, pol, g;\r\n *  col = 'blue';\r\n *  p = [];\r\n *  p.push(board.create('point',[-2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, 1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[-2, 1], {size: 5, strokeColor:col, fillColor:col}));\r\n *\r\n *  pol = board.create('polygon', p, {hasInnerPoints: true});\r\n *  g = board.create('group', p);\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXG781b5564-a671-4327-81c6-de915c8f924e\" style=\"width: 400px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *  (function () {\r\n *  var board, p, col, pol, g;\r\n *  board = JXG.JSXGraph.initBoard('JXG781b5564-a671-4327-81c6-de915c8f924e', {boundingbox:[-5,5,5,-5], keepaspectratio:true, axis:true, showcopyright: false});\r\n *  col = 'blue';\r\n *  p = [];\r\n *  p.push(board.create('point',[-2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, 1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[-2, 1], {size: 5, strokeColor:col, fillColor:col}));\r\n *  pol = board.create('polygon', p, {hasInnerPoints: true});\r\n *  g = board.create('group', p);\r\n *  })();\r\n * </script><pre>\r\n *\r\n *  @example\r\n *\r\n *  // Allow rotations:\r\n *  // Define a center of rotation and declare points of the group as \"rotation points\".\r\n *\r\n *  var p, col, pol, g;\r\n *  col = 'blue';\r\n *  p = [];\r\n *  p.push(board.create('point',[-2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, -1 ], {size: 5, strokeColor:'red', fillColor:'red'}));\r\n *  p.push(board.create('point',[2, 1 ], {size: 5, strokeColor:'red', fillColor:'red'}));\r\n *  p.push(board.create('point',[-2, 1], {size: 5, strokeColor:col, fillColor:col}));\r\n *\r\n *  pol = board.create('polygon', p, {hasInnerPoints: true});\r\n *  g = board.create('group', p);\r\n *  g.setRotationCenter(p[0]);\r\n *  g.setRotationPoints([p[1], p[2]]);\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXGf0491b62-b377-42cb-b55c-4ef5374b39fc\" style=\"width: 400px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *  (function () {\r\n *  var board, p, col, pol, g;\r\n *  board = JXG.JSXGraph.initBoard('JXGf0491b62-b377-42cb-b55c-4ef5374b39fc', {boundingbox:[-5,5,5,-5], keepaspectratio:true, axis:true, showcopyright: false});\r\n *  col = 'blue';\r\n *  p = [];\r\n *  p.push(board.create('point',[-2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, -1 ], {size: 5, strokeColor:'red', fillColor:'red'}));\r\n *  p.push(board.create('point',[2, 1 ], {size: 5, strokeColor:'red', fillColor:'red'}));\r\n *  p.push(board.create('point',[-2, 1], {size: 5, strokeColor:col, fillColor:col}));\r\n *  pol = board.create('polygon', p, {hasInnerPoints: true});\r\n *  g = board.create('group', p);\r\n *  g.setRotationCenter(p[0]);\r\n *  g.setRotationPoints([p[1], p[2]]);\r\n *  })();\r\n * </script><pre>\r\n *\r\n *  @example\r\n *\r\n *  // Allow rotations:\r\n *  // As rotation center, arbitrary points, coordinate arrays,\r\n *  // or functions returning coordinate arrays can be given.\r\n *  // Another possibility is to use the predefined string 'centroid'.\r\n *\r\n *  // The methods to define the rotation points can be chained.\r\n *\r\n *  var p, col, pol, g;\r\n *  col = 'blue';\r\n *  p = [];\r\n *  p.push(board.create('point',[-2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, -1 ], {size: 5, strokeColor:'red', fillColor:'red'}));\r\n *  p.push(board.create('point',[2, 1 ], {size: 5, strokeColor:'red', fillColor:'red'}));\r\n *  p.push(board.create('point',[-2, 1], {size: 5, strokeColor:col, fillColor:col}));\r\n *\r\n *  pol = board.create('polygon', p, {hasInnerPoints: true});\r\n *  g = board.create('group', p).setRotationCenter('centroid').setRotationPoints([p[1], p[2]]);\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXG8785b099-a75e-4769-bfd8-47dd4376fe27\" style=\"width: 400px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *  (function () {\r\n *  var board, p, col, pol, g;\r\n *  board = JXG.JSXGraph.initBoard('JXG8785b099-a75e-4769-bfd8-47dd4376fe27', {boundingbox:[-5,5,5,-5], keepaspectratio:true, axis:true, showcopyright: false});\r\n *  col = 'blue';\r\n *  p = [];\r\n *  p.push(board.create('point',[-2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, -1 ], {size: 5, strokeColor:'red', fillColor:'red'}));\r\n *  p.push(board.create('point',[2, 1 ], {size: 5, strokeColor:'red', fillColor:'red'}));\r\n *  p.push(board.create('point',[-2, 1], {size: 5, strokeColor:col, fillColor:col}));\r\n *  pol = board.create('polygon', p, {hasInnerPoints: true});\r\n *  g = board.create('group', p).setRotationCenter('centroid').setRotationPoints([p[1], p[2]]);\r\n *  })();\r\n * </script><pre>\r\n *\r\n *  @example\r\n *\r\n *  // Allow scaling:\r\n *  // As for rotation one can declare points of the group to trigger a scaling operation.\r\n *  // For this, one has to define a scaleCenter, in analogy to rotations.\r\n *\r\n *  // Here, the yellow  point enables scaling, the red point a rotation.\r\n *\r\n *  var p, col, pol, g;\r\n *  col = 'blue';\r\n *  p = [];\r\n *  p.push(board.create('point',[-2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, -1 ], {size: 5, strokeColor:'yellow', fillColor:'yellow'}));\r\n *  p.push(board.create('point',[2, 1 ], {size: 5, strokeColor:'red', fillColor:'red'}));\r\n *  p.push(board.create('point',[-2, 1], {size: 5, strokeColor:col, fillColor:col}));\r\n *\r\n *  pol = board.create('polygon', p, {hasInnerPoints: true});\r\n *  g = board.create('group', p).setRotationCenter('centroid').setRotationPoints([p[2]]);\r\n *  g.setScaleCenter(p[0]).setScalePoints(p[1]);\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXGc3ca436b-e4fc-4de5-bab4-09790140c675\" style=\"width: 400px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *  (function () {\r\n *  var board, p, col, pol, g;\r\n *  board = JXG.JSXGraph.initBoard('JXGc3ca436b-e4fc-4de5-bab4-09790140c675', {boundingbox:[-5,5,5,-5], keepaspectratio:true, axis:true, showcopyright: false});\r\n *  col = 'blue';\r\n *  p = [];\r\n *  p.push(board.create('point',[-2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, -1 ], {size: 5, strokeColor:'yellow', fillColor:'yellow'}));\r\n *  p.push(board.create('point',[2, 1 ], {size: 5, strokeColor:'red', fillColor:'red'}));\r\n *  p.push(board.create('point',[-2, 1], {size: 5, strokeColor:col, fillColor:col}));\r\n *  pol = board.create('polygon', p, {hasInnerPoints: true});\r\n *  g = board.create('group', p).setRotationCenter('centroid').setRotationPoints([p[2]]);\r\n *  g.setScaleCenter(p[0]).setScalePoints(p[1]);\r\n *  })();\r\n * </script><pre>\r\n *\r\n *  @example\r\n *\r\n *  // Allow Translations:\r\n *  // By default, every point of a group triggers a translation.\r\n *  // There may be situations, when this is not wanted.\r\n *\r\n *  // In this example, E triggers nothing, but itself is rotation center\r\n *  // and is translated, if other points are moved around.\r\n *\r\n *  var p, q, col, pol, g;\r\n *  col = 'blue';\r\n *  p = [];\r\n *  p.push(board.create('point',[-2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, -1 ], {size: 5, strokeColor:'yellow', fillColor:'yellow'}));\r\n *  p.push(board.create('point',[2, 1 ], {size: 5, strokeColor:'red', fillColor:'red'}));\r\n *  p.push(board.create('point',[-2, 1], {size: 5, strokeColor:col, fillColor:col}));\r\n *  q = board.create('point',[0, 0], {size: 5, strokeColor:col, fillColor:col});\r\n *\r\n *  pol = board.create('polygon', p, {hasInnerPoints: true});\r\n *  g = board.create('group', p.concat(q)).setRotationCenter('centroid').setRotationPoints([p[2]]);\r\n *  g.setScaleCenter(p[0]).setScalePoints(p[1]);\r\n *  g.removeTranslationPoint(q);\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXGd19b800a-57a9-4303-b49a-8f5b7a5488f0\" style=\"width: 400px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *  (function () {\r\n *  var board, p, q, col, pol, g;\r\n *  board = JXG.JSXGraph.initBoard('JXGd19b800a-57a9-4303-b49a-8f5b7a5488f0', {boundingbox:[-5,5,5,-5], keepaspectratio:true, axis:true, showcopyright: false});\r\n *  col = 'blue';\r\n *  p = [];\r\n *  p.push(board.create('point',[-2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, -1 ], {size: 5, strokeColor:'yellow', fillColor:'yellow'}));\r\n *  p.push(board.create('point',[2, 1 ], {size: 5, strokeColor:'red', fillColor:'red'}));\r\n *  p.push(board.create('point',[-2, 1], {size: 5, strokeColor:col, fillColor:col}));\r\n *  q = board.create('point',[0, 0], {size: 5, strokeColor:col, fillColor:col});\r\n *\r\n *  pol = board.create('polygon', p, {hasInnerPoints: true});\r\n *  g = board.create('group', p.concat(q)).setRotationCenter('centroid').setRotationPoints([p[2]]);\r\n *  g.setScaleCenter(p[0]).setScalePoints(p[1]);\r\n *  g.removeTranslationPoint(q);\r\n *  })();\r\n * </script><pre>\r\n *\r\n *  @example\r\n *\r\n *        // Add an image and use the group tools to manipulate it\r\n *       let urlImg = \"https://jsxgraph.org/distrib/images/uccellino.jpg\";\r\n *       let lowleft = [-2, -1]\r\n *\r\n *       let col = 'blue';\r\n *       let p = [];\r\n *       p.push(board.create('point', lowleft, { size: 5, strokeColor: col, fillColor: col }));\r\n *       p.push(board.create('point', [2, -1], { size: 5, strokeColor: 'yellow', fillColor: 'yellow', name: 'scale' }));\r\n *       p.push(board.create('point', [2, 1], { size: 5, strokeColor: 'red', fillColor: 'red', name: 'rotate' }));\r\n *       p.push(board.create('point', [-2, 1], { size: 5, strokeColor: col, fillColor: col, name: 'translate' }));\r\n *\r\n *       let im = board.create('image', [urlImg, lowleft, [2, 2]]);\r\n *       let pol = board.create('polygon', p, { hasInnerPoints: true });\r\n *\r\n *       let g = board.create('group', p.concat(im))\r\n *       // g.addPoint(im)   // image, but adds as a point\r\n *\r\n *       g.setRotationCenter(lowleft)\r\n *       g.setRotationPoints([p[2]]);\r\n *\r\n *       g.setScaleCenter(p[0]).setScalePoints(p[1]);\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXGd19b800a-57a9-4303-b49a-8f5b7a5489f1\" style=\"width: 400px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *  (function () {\r\n *       let board = JXG.JSXGraph.initBoard('JXGd19b800a-57a9-4303-b49a-8f5b7a5489f1')\r\n *\r\n *       // Add an image and use the group tools to manipulate it\r\n *       let urlImg = \"https://jsxgraph.org/distrib/images/uccellino.jpg\";\r\n *       let lowleft = [-2, -1]\r\n *\r\n *       let col = 'blue';\r\n *       let p = [];\r\n *       p.push(board.create('point', lowleft, { size: 5, strokeColor: col, fillColor: col }));\r\n *       p.push(board.create('point', [2, -1], { size: 5, strokeColor: 'yellow', fillColor: 'yellow', name: 'scale' }));\r\n *       p.push(board.create('point', [2, 1], { size: 5, strokeColor: 'red', fillColor: 'red', name: 'rotate' }));\r\n *       p.push(board.create('point', [-2, 1], { size: 5, strokeColor: col, fillColor: col, name: 'translate' }));\r\n *\r\n *       let im = board.create('image', [urlImg, lowleft, [2, 2]]);\r\n *       let pol = board.create('polygon', p, { hasInnerPoints: true });\r\n *\r\n *       let g = board.create('group', p.concat(im))\r\n *       // g.addPoint(im)   // image, but adds as a point\r\n *\r\n *       g.setRotationCenter(lowleft)\r\n *       g.setRotationPoints([p[2]]);\r\n *\r\n *       g.setScaleCenter(p[0]).setScalePoints(p[1]);\r\n *  })();\r\n * </script><pre>\r\n */\r\nJXG.createGroup = function (board, parents, attributes) {\r\n    var attr = Type.copyAttributes(attributes, board.options, 'group'),\r\n        g = new JXG.Group(board, attr.id, attr.name, parents, attr);\r\n\r\n    g.elType = 'group';\r\n    g.setParents(parents);\r\n\r\n    return g;\r\n};\r\n\r\nJXG.registerElement(\"group\", JXG.createGroup);\r\n\r\nexport default JXG.Group;\r\n// export default {\r\n//     Group: JXG.Group,\r\n//     createGroup: JXG.createGroup\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview The geometry object Circle is defined in this file. Circle stores all\r\n * style and functional properties that are required to draw and move a circle on\r\n * a board.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport GeometryElement from \"./element.js\";\r\nimport Coords from \"./coords.js\";\r\nimport Const from \"./constants.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport GeonextParser from \"../parser/geonext.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * A circle consists of all points with a given distance from one point. This point is called center, the distance is called radius.\r\n * A circle can be constructed by providing a center and a point on the circle or a center and a radius (given as a number, function,\r\n * line, or circle).\r\n * @class Creates a new circle object. Do not use this constructor to create a circle. Use {@link JXG.Board#create} with\r\n * type {@link Circle} instead.\r\n * @constructor\r\n * @augments JXG.GeometryElement\r\n * @param {JXG.Board} board The board the new circle is drawn on.\r\n * @param {String} method Can be\r\n * <ul><li> <b>'twoPoints'</b> which means the circle is defined by its center and a point on the circle.</li>\r\n * <li><b>'pointRadius'</b> which means the circle is defined by its center and its radius in user units</li>\r\n * <li><b>'pointLine'</b> which means the circle is defined by its center and its radius given by the distance from the startpoint and the endpoint of the line</li>\r\n * <li><b>'pointCircle'</b> which means the circle is defined by its center and its radius given by the radius of another circle</li></ul>\r\n * The parameters p1, p2 and radius must be set according to this method parameter.\r\n * @param {JXG.Point} par1 center of the circle.\r\n * @param {JXG.Point|JXG.Line|JXG.Circle} par2 Can be\r\n * <ul><li>a point on the circle if method is 'twoPoints'</li>\r\n * <li>a line if the method is 'pointLine'</li>\r\n * <li>a circle if the method is 'pointCircle'</li></ul>\r\n * @param {Object} attributes\r\n * @see JXG.Board#generateName\r\n */\r\nJXG.Circle = function (board, method, par1, par2, attributes) {\r\n    // Call the constructor of GeometryElement\r\n    this.constructor(board, attributes, Const.OBJECT_TYPE_CIRCLE, Const.OBJECT_CLASS_CIRCLE);\r\n\r\n    /**\r\n     * Stores the given method.\r\n     * Can be\r\n     * <ul><li><b>'twoPoints'</b> which means the circle is defined by its center and a point on the circle.</li>\r\n     * <li><b>'pointRadius'</b> which means the circle is defined by its center and its radius given in user units or as term.</li>\r\n     * <li><b>'pointLine'</b> which means the circle is defined by its center and its radius given by the distance from the startpoint and the endpoint of the line.</li>\r\n     * <li><b>'pointCircle'</b> which means the circle is defined by its center and its radius given by the radius of another circle.</li></ul>\r\n     * @type String\r\n     * @see JXG.Circle#center\r\n     * @see JXG.Circle#point2\r\n     * @see JXG.Circle#radius\r\n     * @see JXG.Circle#line\r\n     * @see JXG.Circle#circle\r\n     */\r\n    this.method = method;\r\n\r\n    // this is kept so existing code won't ne broken\r\n    this.midpoint = this.board.select(par1);\r\n\r\n    /**\r\n     * The circles center. Do not set this parameter directly as it will break JSXGraph's update system.\r\n     * @type JXG.Point\r\n     */\r\n    this.center = this.board.select(par1);\r\n\r\n    /** Point on the circle only set if method equals 'twoPoints'. Do not set this parameter directly as it will break JSXGraph's update system.\r\n     * @type JXG.Point\r\n     * @see JXG.Circle#method\r\n     */\r\n    this.point2 = null;\r\n\r\n    /** Radius of the circle\r\n     * only set if method equals 'pointRadius'\r\n     * @type Number\r\n     * @default null\r\n     * @see JXG.Circle#method\r\n     */\r\n    this.radius = 0;\r\n\r\n    /** Line defining the radius of the circle given by the distance from the startpoint and the endpoint of the line\r\n     * only set if method equals 'pointLine'. Do not set this parameter directly as it will break JSXGraph's update system.\r\n     * @type JXG.Line\r\n     * @default null\r\n     * @see JXG.Circle#method\r\n     */\r\n    this.line = null;\r\n\r\n    /** Circle defining the radius of the circle given by the radius of the other circle\r\n     * only set if method equals 'pointLine'. Do not set this parameter directly as it will break JSXGraph's update system.\r\n     * @type JXG.Circle\r\n     * @default null\r\n     * @see JXG.Circle#method\r\n     */\r\n    this.circle = null;\r\n\r\n    this.points = [];\r\n\r\n    if (method === 'twoPoints') {\r\n        this.point2 = board.select(par2);\r\n        this.radius = this.Radius();\r\n    } else if (method === 'pointRadius') {\r\n        this.gxtterm = par2;\r\n        // Converts JessieCode syntax into JavaScript syntax and generally ensures that the radius is a function\r\n        this.updateRadius = Type.createFunction(par2, this.board);\r\n        // First evaluation of the radius function\r\n        this.updateRadius();\r\n        this.addParentsFromJCFunctions([this.updateRadius]);\r\n    } else if (method === 'pointLine') {\r\n        // dann ist p2 die Id eines Objekts vom Typ Line!\r\n        this.line = board.select(par2);\r\n        this.radius = this.line.point1.coords.distance(\r\n            Const.COORDS_BY_USER,\r\n            this.line.point2.coords\r\n        );\r\n    } else if (method === 'pointCircle') {\r\n        // dann ist p2 die Id eines Objekts vom Typ Circle!\r\n        this.circle = board.select(par2);\r\n        this.radius = this.circle.Radius();\r\n    }\r\n\r\n    // create Label\r\n    this.id = this.board.setId(this, 'C');\r\n    this.board.renderer.drawEllipse(this);\r\n    this.board.finalizeAdding(this);\r\n\r\n    this.createGradient();\r\n    this.elType = 'circle';\r\n    this.createLabel();\r\n\r\n    if (Type.exists(this.center._is_new)) {\r\n        this.addChild(this.center);\r\n        delete this.center._is_new;\r\n    } else {\r\n        this.center.addChild(this);\r\n    }\r\n\r\n    if (method === 'pointRadius') {\r\n        this.notifyParents(par2);\r\n    } else if (method === 'pointLine') {\r\n        this.line.addChild(this);\r\n    } else if (method === 'pointCircle') {\r\n        this.circle.addChild(this);\r\n    } else if (method === 'twoPoints') {\r\n        if (Type.exists(this.point2._is_new)) {\r\n            this.addChild(this.point2);\r\n            delete this.point2._is_new;\r\n        } else {\r\n            this.point2.addChild(this);\r\n        }\r\n    }\r\n\r\n    this.methodMap = Type.deepCopy(this.methodMap, {\r\n        setRadius: \"setRadius\",\r\n        getRadius: \"getRadius\",\r\n        Area: \"Area\",\r\n        area: \"Area\",\r\n        Perimeter: \"Perimeter\",\r\n        Circumference: \"Perimeter\",\r\n        radius: \"Radius\",\r\n        Radius: \"Radius\",\r\n        Diameter: \"Diameter\",\r\n        center: \"center\",\r\n        line: \"line\",\r\n        point2: \"point2\"\r\n    });\r\n};\r\n\r\nJXG.Circle.prototype = new GeometryElement();\r\n\r\nJXG.extend(\r\n    JXG.Circle.prototype,\r\n    /** @lends JXG.Circle.prototype */ {\r\n        /**\r\n         * Checks whether (x,y) is near the circle line or inside of the ellipse\r\n         * (in case JXG.Options.conic#hasInnerPoints is true).\r\n         * @param {Number} x Coordinate in x direction, screen coordinates.\r\n         * @param {Number} y Coordinate in y direction, screen coordinates.\r\n         * @returns {Boolean} True if (x,y) is near the circle, False otherwise.\r\n         * @private\r\n         */\r\n        hasPoint: function (x, y) {\r\n            var prec, type,\r\n                mp = this.center.coords.usrCoords,\r\n                p = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board),\r\n                r = this.Radius(),\r\n                dx, dy, dist;\r\n\r\n            if (Type.isObject(this.evalVisProp('precision'))) {\r\n                type = this.board._inputDevice;\r\n                prec = this.evalVisProp('precision.' + type);\r\n            } else {\r\n                // 'inherit'\r\n                prec = this.board.options.precision.hasPoint;\r\n            }\r\n            dx = mp[1] - p.usrCoords[1];\r\n            dy = mp[2] - p.usrCoords[2];\r\n            dist = Mat.hypot(dx, dy);\r\n\r\n            // We have to use usrCoords, since Radius is available in usrCoords only.\r\n            prec += this.evalVisProp('strokewidth') * 0.5;\r\n            prec /= Math.sqrt(Math.abs(this.board.unitX * this.board.unitY));\r\n\r\n            if (this.evalVisProp('hasinnerpoints')) {\r\n                return dist < r + prec;\r\n            }\r\n\r\n            return Math.abs(dist - r) < prec;\r\n        },\r\n\r\n        // /**\r\n        //  * Used to generate a polynomial for a point p that lies on this circle.\r\n        //  * @param {JXG.Point} p The point for which the polynomial is generated.\r\n        //  * @returns {Array} An array containing the generated polynomial.\r\n        //  * @private\r\n        //  */\r\n        generatePolynomial: function (p) {\r\n            /*\r\n             * We have four methods to construct a circle:\r\n             *   (a) Two points\r\n             *   (b) center and radius\r\n             *   (c) center and radius given by length of a segment\r\n             *   (d) center and radius given by another circle\r\n             *\r\n             * In case (b) we have to distinguish two cases:\r\n             *  (i)  radius is given as a number\r\n             *  (ii) radius is given as a function\r\n             * In the latter case there's no guarantee the radius depends on other geometry elements\r\n             * in a polynomial way so this case has to be omitted.\r\n             *\r\n             * Another tricky case is case (d):\r\n             * The radius depends on another circle so we have to cycle through the ancestors of each circle\r\n             * until we reach one that's radius does not depend on another circles radius.\r\n             *\r\n             *\r\n             * All cases (a) to (d) vary only in calculation of the radius. So the basic formulae for\r\n             * a glider G (g1,g2) on a circle with center M (m1,m2) and radius r is just:\r\n             *\r\n             *     (g1-m1)^2 + (g2-m2)^2 - r^2 = 0\r\n             *\r\n             * So the easiest case is (b) with a fixed radius given as a number. The other two cases (a)\r\n             * and (c) are quite the same: Euclidean distance between two points A (a1,a2) and B (b1,b2),\r\n             * squared:\r\n             *\r\n             *     r^2 = (a1-b1)^2 + (a2-b2)^2\r\n             *\r\n             * For case (d) we have to cycle recursively through all defining circles and finally return the\r\n             * formulae for calculating r^2. For that we use JXG.Circle.symbolic.generateRadiusSquared().\r\n             */\r\n            var m1 = this.center.symbolic.x,\r\n                m2 = this.center.symbolic.y,\r\n                g1 = p.symbolic.x,\r\n                g2 = p.symbolic.y,\r\n                rsq = this.generateRadiusSquared();\r\n\r\n            /* No radius can be calculated (Case b.ii) */\r\n            if (rsq === \"\") {\r\n                return [];\r\n            }\r\n\r\n            return [\r\n                \"((\" + g1 + \")-(\" + m1 + \"))^2 + ((\" + g2 + \")-(\" + m2 + \"))^2 - (\" + rsq + \")\"\r\n            ];\r\n        },\r\n\r\n        /**\r\n         * Generate symbolic radius calculation for loci determination with Groebner-Basis algorithm.\r\n         * @returns {String} String containing symbolic calculation of the circle's radius or an empty string\r\n         * if the radius can't be expressed in a polynomial equation.\r\n         * @private\r\n         */\r\n        generateRadiusSquared: function () {\r\n            /*\r\n             * Four cases:\r\n             *\r\n             *   (a) Two points\r\n             *   (b) center and radius\r\n             *   (c) center and radius given by length of a segment\r\n             *   (d) center and radius given by another circle\r\n             */\r\n            var m1,\r\n                m2,\r\n                p1,\r\n                p2,\r\n                q1,\r\n                q2,\r\n                rsq = \"\";\r\n\r\n            if (this.method === 'twoPoints') {\r\n                m1 = this.center.symbolic.x;\r\n                m2 = this.center.symbolic.y;\r\n                p1 = this.point2.symbolic.x;\r\n                p2 = this.point2.symbolic.y;\r\n\r\n                rsq = \"((\" + p1 + \")-(\" + m1 + \"))^2 + ((\" + p2 + \")-(\" + m2 + \"))^2\";\r\n            } else if (this.method === 'pointRadius') {\r\n                if (Type.isNumber(this.radius)) {\r\n                    rsq = (this.radius * this.radius).toString();\r\n                }\r\n            } else if (this.method === 'pointLine') {\r\n                p1 = this.line.point1.symbolic.x;\r\n                p2 = this.line.point1.symbolic.y;\r\n\r\n                q1 = this.line.point2.symbolic.x;\r\n                q2 = this.line.point2.symbolic.y;\r\n\r\n                rsq = \"((\" + p1 + \")-(\" + q1 + \"))^2 + ((\" + p2 + \")-(\" + q2 + \"))^2\";\r\n            } else if (this.method === 'pointCircle') {\r\n                rsq = this.circle.Radius();\r\n            }\r\n\r\n            return rsq;\r\n        },\r\n\r\n        /**\r\n         * Uses the boards renderer to update the circle.\r\n         */\r\n        update: function () {\r\n            var x, y, z, r, c, i;\r\n\r\n            if (this.needsUpdate) {\r\n                if (this.evalVisProp('trace')) {\r\n                    this.cloneToBackground(true);\r\n                }\r\n\r\n                if (this.method === 'pointLine') {\r\n                    this.radius = this.line.point1.coords.distance(\r\n                        Const.COORDS_BY_USER,\r\n                        this.line.point2.coords\r\n                    );\r\n                } else if (this.method === 'pointCircle') {\r\n                    this.radius = this.circle.Radius();\r\n                } else if (this.method === 'pointRadius') {\r\n                    this.radius = this.updateRadius();\r\n                }\r\n                this.radius = Math.abs(this.radius);\r\n\r\n                this.updateStdform();\r\n                this.updateQuadraticform();\r\n\r\n                // Approximate the circle by 4 Bezier segments\r\n                // This will be used for intersections of type curve / circle.\r\n                // See https://spencermortensen.com/articles/bezier-circle/\r\n                z = this.center.coords.usrCoords[0];\r\n                x = this.center.coords.usrCoords[1] / z;\r\n                y = this.center.coords.usrCoords[2] / z;\r\n                z /= z;\r\n                r = this.Radius();\r\n                c = 0.551915024494;\r\n\r\n                this.numberPoints = 13;\r\n                this.dataX = [\r\n                    x + r, x + r, x + r * c, x, x - r * c, x - r, x - r, x - r, x - r * c, x, x + r * c, x + r, x + r\r\n                ];\r\n                this.dataY = [\r\n                    y, y + r * c, y + r, y + r, y + r, y + r * c, y, y - r * c, y - r, y - r, y - r, y - r * c, y\r\n                ];\r\n                this.bezierDegree = 3;\r\n                for (i = 0; i < this.numberPoints; i++) {\r\n                    this.points[i] = new Coords(\r\n                        Const.COORDS_BY_USER,\r\n                        [this.dataX[i], this.dataY[i]],\r\n                        this.board\r\n                    );\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Updates this circle's {@link JXG.Circle#quadraticform}.\r\n         * @private\r\n         */\r\n        updateQuadraticform: function () {\r\n            var m = this.center,\r\n                mX = m.X(),\r\n                mY = m.Y(),\r\n                r = this.Radius();\r\n\r\n            this.quadraticform = [\r\n                [mX * mX + mY * mY - r * r, -mX, -mY],\r\n                [-mX, 1, 0],\r\n                [-mY, 0, 1]\r\n            ];\r\n        },\r\n\r\n        /**\r\n         * Updates the stdform derived from the position of the center and the circle's radius.\r\n         * @private\r\n         */\r\n        updateStdform: function () {\r\n            this.stdform[3] = 0.5;\r\n            this.stdform[4] = this.Radius();\r\n            this.stdform[1] = -this.center.coords.usrCoords[1];\r\n            this.stdform[2] = -this.center.coords.usrCoords[2];\r\n            if (!isFinite(this.stdform[4])) {\r\n                this.stdform[0] = Type.exists(this.point2)\r\n                    ? -(\r\n                          this.stdform[1] * this.point2.coords.usrCoords[1] +\r\n                          this.stdform[2] * this.point2.coords.usrCoords[2]\r\n                      )\r\n                    : 0;\r\n            }\r\n            this.normalize();\r\n        },\r\n\r\n        /**\r\n         * Uses the boards renderer to update the circle.\r\n         * @private\r\n         */\r\n        updateRenderer: function () {\r\n            // var wasReal;\r\n\r\n            if (!this.needsUpdate) {\r\n                return this;\r\n            }\r\n\r\n            if (this.visPropCalc.visible) {\r\n                // wasReal = this.isReal;\r\n                this.isReal =\r\n                    !isNaN(\r\n                        this.center.coords.usrCoords[1] +\r\n                            this.center.coords.usrCoords[2] +\r\n                            this.Radius()\r\n                    ) && this.center.isReal;\r\n\r\n                if (\r\n                    //wasReal &&\r\n                    !this.isReal\r\n                ) {\r\n                    this.updateVisibility(false);\r\n                }\r\n            }\r\n\r\n            // Update the position\r\n            if (this.visPropCalc.visible) {\r\n                this.board.renderer.updateEllipse(this);\r\n            }\r\n\r\n            // Update the label if visible.\r\n            if (\r\n                this.hasLabel &&\r\n                this.visPropCalc.visible &&\r\n                this.label &&\r\n                this.label.visPropCalc.visible &&\r\n                this.isReal\r\n            ) {\r\n                this.label.update();\r\n                this.board.renderer.updateText(this.label);\r\n            }\r\n\r\n            // Update rendNode display\r\n            this.setDisplayRendNode();\r\n            // if (this.visPropCalc.visible !== this.visPropOld.visible) {\r\n            //     this.board.renderer.display(this, this.visPropCalc.visible);\r\n            //     this.visPropOld.visible = this.visPropCalc.visible;\r\n            //\r\n            //     if (this.hasLabel) {\r\n            //         this.board.renderer.display(this.label, this.label.visPropCalc.visible);\r\n            //     }\r\n            // }\r\n\r\n            this.needsUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Finds dependencies in a given term and resolves them by adding the elements referenced in this\r\n         * string to the circle's list of ancestors.\r\n         * @param {String} contentStr\r\n         * @private\r\n         */\r\n        notifyParents: function (contentStr) {\r\n            if (Type.isString(contentStr)) {\r\n                GeonextParser.findDependencies(this, contentStr, this.board);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Set a new radius, then update the board.\r\n         * @param {String|Number|function} r A string, function or number describing the new radius.\r\n         * @returns {JXG.Circle} Reference to this circle\r\n         */\r\n        setRadius: function (r) {\r\n            this.updateRadius = Type.createFunction(r, this.board);\r\n            this.addParentsFromJCFunctions([this.updateRadius]);\r\n            this.board.update();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Calculates the radius of the circle.\r\n         * @param {String|Number|function} [value] Set new radius\r\n         * @returns {Number} The radius of the circle\r\n         */\r\n        Radius: function (value) {\r\n            if (Type.exists(value)) {\r\n                this.setRadius(value);\r\n                return this.Radius();\r\n            }\r\n\r\n            if (this.method === 'twoPoints') {\r\n                if (\r\n                    Type.cmpArrays(this.point2.coords.usrCoords, [0, 0, 0]) ||\r\n                    Type.cmpArrays(this.center.coords.usrCoords, [0, 0, 0])\r\n                ) {\r\n                    return NaN;\r\n                }\r\n\r\n                return this.center.Dist(this.point2);\r\n            }\r\n\r\n            if (this.method === \"pointLine\" || this.method === 'pointCircle') {\r\n                return this.radius;\r\n            }\r\n\r\n            if (this.method === 'pointRadius') {\r\n                return (this.evalVisProp('nonnegativeonly')) ?\r\n                    Math.max(0.0, this.updateRadius()) :\r\n                    Math.abs(this.updateRadius());\r\n            }\r\n\r\n            return NaN;\r\n        },\r\n\r\n        /**\r\n         * Calculates the diameter of the circle.\r\n         * @returns {Number} The Diameter of the circle\r\n         */\r\n        Diameter: function () {\r\n            return 2 * this.Radius();\r\n        },\r\n\r\n        /**\r\n         * Use {@link JXG.Circle#Radius}.\r\n         * @deprecated\r\n         */\r\n        getRadius: function () {\r\n            JXG.deprecated(\"Circle.getRadius()\", \"Circle.Radius()\");\r\n            return this.Radius();\r\n        },\r\n\r\n        // documented in geometry element\r\n        getTextAnchor: function () {\r\n            return this.center.coords;\r\n        },\r\n\r\n        // documented in geometry element\r\n        getLabelAnchor: function () {\r\n            var x, y, pos,\r\n                xy, lbda, sgn,\r\n                dist = 1.5,\r\n                r = this.Radius(),\r\n                c = this.center.coords.usrCoords,\r\n                SQRTH = 7.071067811865e-1; // sqrt(2)/2\r\n\r\n            if (!Type.exists(this.label)) {\r\n                return new Coords(Const.COORDS_BY_SCREEN, [NaN, NaN], this.board);\r\n            }\r\n\r\n            pos = this.label.evalVisProp('position');\r\n            if (!Type.isString(pos)) {\r\n                return new Coords(Const.COORDS_BY_SCREEN, [NaN, NaN], this.board);\r\n            }\r\n\r\n            if (pos.indexOf('right') < 0 && pos.indexOf('left') < 0) {\r\n                switch (this.evalVisProp('label.position')) {\r\n                    case \"lft\":\r\n                        x = c[1] - r;\r\n                        y = c[2];\r\n                        break;\r\n                    case \"llft\":\r\n                        x = c[1] - SQRTH * r;\r\n                        y = c[2] - SQRTH * r;\r\n                        break;\r\n                    case \"rt\":\r\n                        x = c[1] + r;\r\n                        y = c[2];\r\n                        break;\r\n                    case \"lrt\":\r\n                        x = c[1] + SQRTH * r;\r\n                        y = c[2] - SQRTH * r;\r\n                        break;\r\n                    case \"urt\":\r\n                        x = c[1] + SQRTH * r;\r\n                        y = c[2] + SQRTH * r;\r\n                        break;\r\n                    case \"top\":\r\n                        x = c[1];\r\n                        y = c[2] + r;\r\n                        break;\r\n                    case \"bot\":\r\n                        x = c[1];\r\n                        y = c[2] - r;\r\n                        break;\r\n                    default:\r\n                        // includes case 'ulft'\r\n                        x = c[1] - SQRTH * r;\r\n                        y = c[2] + SQRTH * r;\r\n                        break;\r\n                }\r\n            } else {\r\n                // New positioning\r\n                c = this.center.coords.scrCoords;\r\n\r\n                xy = Type.parsePosition(pos);\r\n                lbda = Type.parseNumber(xy.pos, 2 * Math.PI, 1);\r\n                if (xy.pos.indexOf('fr') < 0 &&\r\n                    xy.pos.indexOf('%') < 0) {\r\n                    if (xy.pos.indexOf('px') >= 0) {\r\n                        // 'px' or numbers are not supported\r\n                        lbda = 0;\r\n                    } else {\r\n                        // Pure numbers are interpreted as degrees\r\n                        lbda *= Math.PI / 180;\r\n                    }\r\n                }\r\n\r\n                // Position left or right\r\n                sgn = 1;\r\n                if (xy.side === 'left') {\r\n                    sgn = -1;\r\n                }\r\n\r\n                if (Type.exists(this.label)) {\r\n                    dist = sgn * 0.5 * this.label.evalVisProp('distance');\r\n                }\r\n\r\n                x = c[1] + (r * this.board.unitX + this.label.size[0] * dist) * Math.cos(lbda);\r\n                y = c[2] - (r * this.board.unitY + this.label.size[1] * dist) * Math.sin(lbda);\r\n\r\n                return new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board);\r\n            }\r\n\r\n            return new Coords(Const.COORDS_BY_USER, [x, y], this.board);\r\n        },\r\n\r\n        // documented in geometry element\r\n        cloneToBackground: function () {\r\n            var er,\r\n                r = this.Radius(),\r\n                copy = Type.getCloneObject(this);\r\n\r\n            copy.center = {\r\n                coords: this.center.coords\r\n            };\r\n            copy.Radius = function () {\r\n                return r;\r\n            };\r\n            copy.getRadius = function () {\r\n                return r;\r\n            };\r\n\r\n            er = this.board.renderer.enhancedRendering;\r\n            this.board.renderer.enhancedRendering = true;\r\n            this.board.renderer.drawEllipse(copy);\r\n            this.board.renderer.enhancedRendering = er;\r\n            this.traces[copy.id] = copy.rendNode;\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Add transformations to this circle.\r\n         * @param {JXG.Transformation|Array} transform Either one {@link JXG.Transformation} or an array of {@link JXG.Transformation}s.\r\n         * @returns {JXG.Circle} Reference to this circle object.\r\n         */\r\n        addTransform: function (transform) {\r\n            var i,\r\n                list = Type.isArray(transform) ? transform : [transform],\r\n                len = list.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                this.center.transformations.push(list[i]);\r\n\r\n                if (this.method === 'twoPoints') {\r\n                    this.point2.transformations.push(list[i]);\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        // see element.js\r\n        snapToGrid: function () {\r\n            var forceIt = this.evalVisProp('snaptogrid');\r\n\r\n            this.center.handleSnapToGrid(forceIt, true);\r\n            if (this.method === 'twoPoints') {\r\n                this.point2.handleSnapToGrid(forceIt, true);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        // see element.js\r\n        snapToPoints: function () {\r\n            var forceIt = this.evalVisProp('snaptopoints');\r\n\r\n            this.center.handleSnapToPoints(forceIt);\r\n            if (this.method === 'twoPoints') {\r\n                this.point2.handleSnapToPoints(forceIt);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Treats the circle as parametric curve and calculates its X coordinate.\r\n         * @param {Number} t Number between 0 and 1.\r\n         * @returns {Number} <tt>X(t)= radius*cos(t)+centerX</tt>.\r\n         */\r\n        X: function (t) {\r\n            return this.Radius() * Math.cos(t * 2 * Math.PI) + this.center.coords.usrCoords[1];\r\n        },\r\n\r\n        /**\r\n         * Treats the circle as parametric curve and calculates its Y coordinate.\r\n         * @param {Number} t Number between 0 and 1.\r\n         * @returns {Number} <tt>X(t)= radius*sin(t)+centerY</tt>.\r\n         */\r\n        Y: function (t) {\r\n            return this.Radius() * Math.sin(t * 2 * Math.PI) + this.center.coords.usrCoords[2];\r\n        },\r\n\r\n        /**\r\n         * Treat the circle as parametric curve and calculates its Z coordinate.\r\n         * @param {Number} t ignored\r\n         * @returns {Number} 1.0\r\n         */\r\n        Z: function (t) {\r\n            return 1.0;\r\n        },\r\n\r\n        /**\r\n         * Returns 0.\r\n         * @private\r\n         */\r\n        minX: function () {\r\n            return 0.0;\r\n        },\r\n\r\n        /**\r\n         * Returns 1.\r\n         * @private\r\n         */\r\n        maxX: function () {\r\n            return 1.0;\r\n        },\r\n\r\n        /**\r\n         * Circle area\r\n         * @returns {Number} area of the circle.\r\n         */\r\n        Area: function () {\r\n            var r = this.Radius();\r\n\r\n            return r * r * Math.PI;\r\n        },\r\n\r\n        /**\r\n         * Perimeter (circumference) of circle.\r\n         * @returns {Number} Perimeter of circle in user units.\r\n         */\r\n        Perimeter: function () {\r\n            return 2 * this.Radius() * Math.PI;\r\n        },\r\n\r\n        /**\r\n         * Get bounding box of the circle.\r\n         * @returns {Array} [x1, y1, x2, y2]\r\n         */\r\n        bounds: function () {\r\n            var uc = this.center.coords.usrCoords,\r\n                r = this.Radius();\r\n\r\n            return [uc[1] - r, uc[2] + r, uc[1] + r, uc[2] - r];\r\n        },\r\n\r\n        /**\r\n         * Get data to construct this element. Data consists of the parent elements\r\n         * and static data like radius.\r\n         * @returns {Array} data necessary to construct this element\r\n         */\r\n        getParents: function () {\r\n            if (this.parents.length === 1) {\r\n                // i.e. this.method === 'pointRadius'\r\n                return this.parents.concat(this.radius);\r\n            }\r\n            return this.parents;\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * @class A circle can be defined by various combinations of points and numbers.\r\n * @pseudo\r\n * @description  A circle consists of all points with a given distance from one point. This point is called center, the distance is called radius.\r\n * A circle can be constructed by providing a center and a point on the circle or a center and a radius (given as a number, function,\r\n * line, or circle). If the radius is a negative value, its absolute values is taken.\r\n * @name Circle\r\n * @augments JXG.Circle\r\n * @constructor\r\n * @type JXG.Circle\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_number,JXG.Point,JXG.Line,JXG.Circle} center,radius The center must be given as a {@link JXG.Point},\r\n * see {@link JXG.providePoints}, but the radius can be given\r\n * as a number (which will create a circle with a fixed radius),\r\n * another {@link JXG.Point}, a {@link JXG.Line} (the distance of start and end point of the\r\n * line will determine the radius), or another {@link JXG.Circle}.\r\n * <p>\r\n * If the radius is supplied as number or output of a function, its absolute value is taken.\r\n *\r\n * @example\r\n * // Create a circle providing two points\r\n * var p1 = board.create('point', [2.0, 2.0]),\r\n *     p2 = board.create('point', [2.0, 0.0]),\r\n *     c1 = board.create('circle', [p1, p2]);\r\n *\r\n * // Create another circle using the above circle\r\n * var p3 = board.create('point', [3.0, 2.0]),\r\n *     c2 = board.create('circle', [p3, c1]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG5f304d31-ef20-4a8e-9c0e-ea1a2b6c79e0\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function() {\r\n *   var cex1_board = JXG.JSXGraph.initBoard('JXG5f304d31-ef20-4a8e-9c0e-ea1a2b6c79e0', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *       cex1_p1 = cex1_board.create('point', [2.0, 2.0]),\r\n *       cex1_p2 = cex1_board.create('point', [2.0, 0.0]),\r\n *       cex1_c1 = cex1_board.create('circle', [cex1_p1, cex1_p2]),\r\n *       cex1_p3 = cex1_board.create('point', [3.0, 2.0]),\r\n *       cex1_c2 = cex1_board.create('circle', [cex1_p3, cex1_c1]);\r\n * })();\r\n * </script><pre>\r\n * @example\r\n * // Create a circle providing two points\r\n * var p1 = board.create('point', [2.0, 2.0]),\r\n *     c1 = board.create('circle', [p1, 3]);\r\n *\r\n * // Create another circle using the above circle\r\n * var c2 = board.create('circle', [function() { return [p1.X(), p1.Y() + 1];}, function() { return c1.Radius(); }]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG54165f60-93b9-441d-8979-ac5d0f193020\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function() {\r\n * var board = JXG.JSXGraph.initBoard('JXG54165f60-93b9-441d-8979-ac5d0f193020', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n * var p1 = board.create('point', [2.0, 2.0]);\r\n * var c1 = board.create('circle', [p1, 3]);\r\n *\r\n * // Create another circle using the above circle\r\n * var c2 = board.create('circle', [function() { return [p1.X(), p1.Y() + 1];}, function() { return c1.Radius(); }]);\r\n * })();\r\n * </script><pre>\r\n * @example\r\n * var li = board.create('line', [1,1,1], {strokeColor: '#aaaaaa'});\r\n * var reflect = board.create('transform', [li], {type: 'reflect'});\r\n *\r\n * var c1 = board.create('circle', [[-2,-2], [-2, -1]], {center: {visible:true}});\r\n * var c2 = board.create('circle', [c1, reflect]);\r\n *      * </pre><div id=\"JXGa2a5a870-5dbb-11e8-9fb9-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGa2a5a870-5dbb-11e8-9fb9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *             var li = board.create('line', [1,1,1], {strokeColor: '#aaaaaa'});\r\n *             var reflect = board.create('transform', [li], {type: 'reflect'});\r\n *\r\n *             var c1 = board.create('circle', [[-2,-2], [-2, -1]], {center: {visible:true}});\r\n *             var c2 = board.create('circle', [c1, reflect]);\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var t = board.create('transform', [2, 1.5], {type: 'scale'});\r\n * var c1 = board.create('circle', [[1.3, 1.3], [0, 1.3]], {strokeColor: 'black', center: {visible:true}});\r\n * var c2 = board.create('circle', [c1, t], {strokeColor: 'black'});\r\n *\r\n * </pre><div id=\"JXG0686a222-6339-11e8-9fb9-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG0686a222-6339-11e8-9fb9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var t = board.create('transform', [2, 1.5], {type: 'scale'});\r\n *     var c1 = board.create('circle', [[1.3, 1.3], [0, 1.3]], {strokeColor: 'black', center: {visible:true}});\r\n *     var c2 = board.create('circle', [c1, t], {strokeColor: 'black'});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createCircle = function (board, parents, attributes) {\r\n    var el,\r\n        p,\r\n        i,\r\n        attr,\r\n        obj,\r\n        isDraggable = true,\r\n        point_style = [\"center\", \"point2\"];\r\n\r\n    p = [];\r\n    obj = board.select(parents[0]);\r\n    if (\r\n        Type.isObject(obj) &&\r\n        obj.elementClass === Const.OBJECT_CLASS_CIRCLE &&\r\n        Type.isTransformationOrArray(parents[1])\r\n    ) {\r\n        attr = Type.copyAttributes(attributes, board.options, 'circle');\r\n        // if (!Type.exists(attr.type) || attr.type.toLowerCase() !== 'euclidean') {\r\n        //     // Create a circle element from a circle and a Euclidean transformation\r\n        //     el = JXG.createCircle(board, [obj.center, function() { return obj.Radius(); }], attr);\r\n        // } else {\r\n        // Create a conic element from a circle and a projective transformation\r\n        el = JXG.createEllipse(\r\n            board,\r\n            [\r\n                obj.center,\r\n                obj.center,\r\n                function () {\r\n                    return 2 * obj.Radius();\r\n                }\r\n            ],\r\n            attr\r\n        );\r\n        // }\r\n        el.addTransform(parents[1]);\r\n        return el;\r\n    }\r\n    // Circle defined by points\r\n    for (i = 0; i < parents.length; i++) {\r\n        if (Type.isPointType(board, parents[i])) {\r\n            if (parents.length < 3) {\r\n                p.push(\r\n                    Type.providePoints(board, [parents[i]], attributes, \"circle\", [point_style[i]])[0]\r\n                );\r\n            } else {\r\n                p.push(\r\n                    Type.providePoints(board, [parents[i]], attributes, 'point')[0]\r\n                );\r\n            }\r\n            if (p[p.length - 1] === false) {\r\n                throw new Error(\r\n                    \"JSXGraph: Can't create circle from this type. Please provide a point type.\"\r\n                );\r\n            }\r\n        } else {\r\n            p.push(parents[i]);\r\n        }\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'circle');\r\n\r\n    if (p.length === 2 && Type.isPoint(p[0]) && Type.isPoint(p[1])) {\r\n        // Point/Point\r\n        el = new JXG.Circle(board, \"twoPoints\", p[0], p[1], attr);\r\n    } else if (\r\n        (Type.isNumber(p[0]) || Type.isFunction(p[0]) || Type.isString(p[0])) &&\r\n        Type.isPoint(p[1])\r\n    ) {\r\n        // Number/Point\r\n        el = new JXG.Circle(board, \"pointRadius\", p[1], p[0], attr);\r\n    } else if (\r\n        (Type.isNumber(p[1]) || Type.isFunction(p[1]) || Type.isString(p[1])) &&\r\n        Type.isPoint(p[0])\r\n    ) {\r\n        // Point/Number\r\n        el = new JXG.Circle(board, \"pointRadius\", p[0], p[1], attr);\r\n    } else if (p[0].elementClass === Const.OBJECT_CLASS_CIRCLE && Type.isPoint(p[1])) {\r\n        // Circle/Point\r\n        el = new JXG.Circle(board, \"pointCircle\", p[1], p[0], attr);\r\n    } else if (p[1].elementClass === Const.OBJECT_CLASS_CIRCLE && Type.isPoint(p[0])) {\r\n        // Point/Circle\r\n        el = new JXG.Circle(board, \"pointCircle\", p[0], p[1], attr);\r\n    } else if (p[0].elementClass === Const.OBJECT_CLASS_LINE && Type.isPoint(p[1])) {\r\n        // Line/Point\r\n        el = new JXG.Circle(board, \"pointLine\", p[1], p[0], attr);\r\n    } else if (p[1].elementClass === Const.OBJECT_CLASS_LINE && Type.isPoint(p[0])) {\r\n        // Point/Line\r\n        el = new JXG.Circle(board, \"pointLine\", p[0], p[1], attr);\r\n    } else if (\r\n        parents.length === 3 &&\r\n        Type.isPoint(p[0]) &&\r\n        Type.isPoint(p[1]) &&\r\n        Type.isPoint(p[2])\r\n    ) {\r\n        // Circle through three points\r\n        // Check if circumcircle element is available\r\n        if (JXG.elements.circumcircle) {\r\n            el = JXG.elements.circumcircle(board, p, attr);\r\n        } else {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create circle with three points. Please include the circumcircle element (element/composition).\"\r\n            );\r\n        }\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create circle with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [point,point], [point,number], [point,function], [point,circle], [point,point,point], [circle,transformation]\"\r\n        );\r\n    }\r\n\r\n    el.isDraggable = isDraggable;\r\n    el.setParents(p);\r\n    el.elType = 'circle';\r\n    for (i = 0; i < p.length; i++) {\r\n        if (Type.isPoint(p[i])) {\r\n            el.inherits.push(p[i]);\r\n        }\r\n    }\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"circle\", JXG.createCircle);\r\n\r\nexport default JXG.Circle;\r\n// export default {\r\n//     Circle: JXG.Circle,\r\n//     createCircle: JXG.createCircle\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview In this file the conic sections defined.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Coords from \"../base/coords.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Numerics from \"../math/numerics.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * @class An ellipse is a special conic section given by two points (the foci) and a third point on the ellipse or\r\n * the length of the major axis.\r\n * @pseudo\r\n * @name Ellipse\r\n * @augments Conic\r\n * @constructor\r\n * @type JXG.Curve\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point,array_JXG.Point,array_JXG.Point,array} point1,point2,point3 Parent elements can be three elements either of type {@link JXG.Point} or array of\r\n * numbers describing the coordinates of a point. In the latter case the point will be constructed automatically as a fixed invisible point.\r\n * @param {JXG.Point,array_JXG.Point,array_number,function} point1,point2,number Parent elements can be two elements either of type {@link JXG.Point} or array of\r\n * numbers describing the coordinates of a point. The third parameter is a number/function which defines the length of the major axis\r\n * @param {Number} start (Optional) parameter of the curve start, default: 0.\r\n * @param {Number} end (Optional) parameter for the curve end, default: 2&pi;.\r\n * @example\r\n * // Create an Ellipse by three points\r\n * var A = board.create('point', [-1,4]);\r\n * var B = board.create('point', [-1,-4]);\r\n * var C = board.create('point', [1,1]);\r\n * var el = board.create('ellipse',[A,B,C]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGa4d7fb6f-8708-4e45-87f2-2379ae2bd2c0\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   (function() {\r\n *   var glex1_board = JXG.JSXGraph.initBoard('JXGa4d7fb6f-8708-4e45-87f2-2379ae2bd2c0', {boundingbox:[-6,6,6,-6], keepaspectratio:true, showcopyright: false, shownavigation: false});\r\n *   var A = glex1_board.create('point', [-1,4]);\r\n *   var B = glex1_board.create('point', [-1,-4]);\r\n *   var C = glex1_board.create('point', [1,1]);\r\n *   var el = glex1_board.create('ellipse',[A,B,C]);\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Create an elliptical arc\r\n * var p1 = board.create('point', [-1, 2]);\r\n * var p2 = board.create('point', [ 1, 2]);\r\n * var p3 = board.create('point', [0, 3]);\r\n *\r\n * var ell = board.create('ellipse', [\r\n *   p1, p2, p3, 0, Math.PI], {\r\n *   lastArrow: {type: 7}\r\n * });\r\n *\r\n * </pre><div id=\"JXG950f7c07-27a4-4c67-9505-c73c22ce9345\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG950f7c07-27a4-4c67-9505-c73c22ce9345',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p1 = board.create('point', [-1, 2]);\r\n *     var p2 = board.create('point', [ 1, 2]);\r\n *     var p3 = board.create('point', [0, 3]);\r\n *\r\n *     var ell = board.create('ellipse', [\r\n *       p1, p2, p3, 0, Math.PI], {\r\n *       lastArrow: {type: 7}\r\n *     });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n *\r\n */\r\nJXG.createEllipse = function (board, parents, attributes) {\r\n    var polarForm,\r\n        curve,\r\n        M,\r\n        C,\r\n        majorAxis,\r\n        i,\r\n        hasPointOrg,\r\n        // focus 1 and focus 2\r\n        F = [],\r\n        attr_foci = Type.copyAttributes(attributes, board.options, \"conic\", 'foci'),\r\n        attr_center = Type.copyAttributes(attributes, board.options, \"conic\", 'center'),\r\n        attr_curve = Type.copyAttributes(attributes, board.options, 'conic');\r\n\r\n    // The foci and the third point are either points or coordinate arrays.\r\n    for (i = 0; i < 2; i++) {\r\n        // focus i given by coordinates\r\n        if (parents[i].length > 1) {\r\n            F[i] = board.create(\"point\", parents[i], attr_foci);\r\n            // focus i given by point\r\n        } else if (Type.isPoint(parents[i])) {\r\n            F[i] = board.select(parents[i]);\r\n            // given by function\r\n        } else if (Type.isFunction(parents[i]) && Type.isPoint(parents[i]())) {\r\n            F[i] = parents[i]();\r\n            // focus i given by point name\r\n        } else if (Type.isString(parents[i])) {\r\n            F[i] = board.select(parents[i]);\r\n        } else {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create Ellipse with parent types '\" +\r\n                    typeof parents[0] +\r\n                    \"' and '\" +\r\n                    typeof parents[1] +\r\n                    \"'.\" +\r\n                    \"\\nPossible parent types: [point,point,point], [point,point,number|function]\"\r\n            );\r\n        }\r\n    }\r\n\r\n    // length of major axis\r\n    if (Type.isNumber(parents[2])) {\r\n        majorAxis = Type.createFunction(parents[2], board);\r\n    } else if (Type.isFunction(parents[2]) && Type.isNumber(parents[2]())) {\r\n        majorAxis = parents[2];\r\n    } else {\r\n        // point on ellipse\r\n        if (Type.isPoint(parents[2])) {\r\n            C = board.select(parents[2]);\r\n            // point on ellipse given by coordinates\r\n        } else if (parents[2].length > 1) {\r\n            C = board.create(\"point\", parents[2], attr_foci);\r\n            // given by function\r\n        } else if (Type.isFunction(parents[2]) && Type.isPoint(parents[2]())) {\r\n            C = parents[2]();\r\n            // focus i given by point name\r\n        } else if (Type.isString(parents[2])) {\r\n            C = board.select(parents[2]);\r\n        } else {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create Ellipse with parent types '\" +\r\n                    typeof parents[0] +\r\n                    \"' and '\" +\r\n                    typeof parents[1] +\r\n                    \"' and '\" +\r\n                    typeof parents[2] +\r\n                    \"'.\" +\r\n                    \"\\nPossible parent types: [point,point,point], [point,point,number|function]\"\r\n            );\r\n        }\r\n        /** @ignore */\r\n        majorAxis = function () {\r\n            return C.Dist(F[0]) + C.Dist(F[1]);\r\n        };\r\n    }\r\n\r\n    // to\r\n    if (!Type.exists(parents[4])) {\r\n        parents[4] = 2 * Math.PI;\r\n    }\r\n\r\n    // from\r\n    if (!Type.exists(parents[3])) {\r\n        parents[3] = 0.0;\r\n    }\r\n\r\n    M = board.create(\r\n        \"point\",\r\n        [\r\n            function () {\r\n                return (F[0].X() + F[1].X()) * 0.5;\r\n            },\r\n            function () {\r\n                return (F[0].Y() + F[1].Y()) * 0.5;\r\n            }\r\n        ],\r\n        attr_center\r\n    );\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    curve = board.create(\r\n        \"curve\",\r\n        [\r\n            function (x) {\r\n                return 0;\r\n            },\r\n            function (x) {\r\n                return 0;\r\n            },\r\n            parents[3],\r\n            parents[4]\r\n        ],\r\n        attr_curve\r\n    );\r\n\r\n    curve.majorAxis = majorAxis;\r\n\r\n    // Save the original hasPoint method. It will be called inside of the new hasPoint method.\r\n    hasPointOrg = curve.hasPoint;\r\n\r\n    /** @ignore */\r\n    polarForm = function (phi, suspendUpdate) {\r\n        var r, rr, ax, ay, bx, by, axbx, ayby, f;\r\n\r\n        if (!suspendUpdate) {\r\n            r = majorAxis();\r\n            rr = r * r;\r\n            ax = F[0].X();\r\n            ay = F[0].Y();\r\n            bx = F[1].X();\r\n            by = F[1].Y();\r\n            axbx = ax - bx;\r\n            ayby = ay - by;\r\n            f = (rr - ax * ax - ay * ay + bx * bx + by * by) / (2 * r);\r\n\r\n            curve.quadraticform = [\r\n                [f * f - bx * bx - by * by, (f * axbx) / r + bx, (f * ayby) / r + by],\r\n                [(f * axbx) / r + bx, (axbx * axbx) / rr - 1, (axbx * ayby) / rr],\r\n                [(f * ayby) / r + by, (axbx * ayby) / rr, (ayby * ayby) / rr - 1]\r\n            ];\r\n        }\r\n    };\r\n\r\n    /** @ignore */\r\n    curve.X = function (phi, suspendUpdate) {\r\n        var r = majorAxis(),\r\n            c = F[1].Dist(F[0]),\r\n            b = (0.5 * (c * c - r * r)) / (c * Math.cos(phi) - r),\r\n            beta = Math.atan2(F[1].Y() - F[0].Y(), F[1].X() - F[0].X());\r\n\r\n        if (!suspendUpdate) {\r\n            polarForm(phi, suspendUpdate);\r\n        }\r\n\r\n        return F[0].X() + Math.cos(beta + phi) * b;\r\n    };\r\n\r\n    /** @ignore */\r\n    curve.Y = function (phi, suspendUpdate) {\r\n        var r = majorAxis(),\r\n            c = F[1].Dist(F[0]),\r\n            b = (0.5 * (c * c - r * r)) / (c * Math.cos(phi) - r),\r\n            beta = Math.atan2(F[1].Y() - F[0].Y(), F[1].X() - F[0].X());\r\n\r\n        return F[0].Y() + Math.sin(beta + phi) * b;\r\n    };\r\n\r\n    curve.midpoint = curve.center = M;\r\n    curve.type = Const.OBJECT_TYPE_CONIC;\r\n    curve.subs = {\r\n        center: curve.center\r\n    };\r\n    curve.inherits.push(curve.center, F[0], F[1]);\r\n    if (Type.isPoint(C)) {\r\n        curve.inherits.push(C);\r\n    }\r\n\r\n    /**\r\n     * Checks whether (x,y) is near the ellipse line or inside of the ellipse\r\n     * (in case JXG.Options.conic#hasInnerPoints is true).\r\n     * @param {Number} x Coordinate in x direction, screen coordinates.\r\n     * @param {Number} y Coordinate in y direction, screen coordinates.\r\n     * @returns {Boolean} True if (x,y) is near the ellipse, False otherwise.\r\n     * @private\r\n     * @ignore\r\n     */\r\n    curve.hasPoint = function (x, y) {\r\n        var ac, bc, r, p, dist;\r\n\r\n        if (this.evalVisProp('hasinnerpoints')) {\r\n            ac = F[0].coords;\r\n            bc = F[1].coords;\r\n            r = this.majorAxis();\r\n            p = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board);\r\n            dist = p.distance(Const.COORDS_BY_USER, ac) + p.distance(Const.COORDS_BY_USER, bc);\r\n\r\n            return dist <= r;\r\n        }\r\n\r\n        return hasPointOrg.apply(this, arguments);\r\n    };\r\n\r\n    M.addChild(curve);\r\n    for (i = 0; i < 2; i++) {\r\n        if (Type.isPoint(F[i])) {\r\n            F[i].addChild(curve);\r\n        }\r\n    }\r\n    if (Type.isPoint(C)) {\r\n        C.addChild(curve);\r\n    }\r\n    curve.setParents(parents);\r\n\r\n    return curve;\r\n};\r\n\r\n/**\r\n * @class A hyperbola is a special conic section given by two points (the foci) and a third point on the hyperbola or\r\n * the length of the major axis.\r\n * @pseudo\r\n * @name Hyperbola\r\n * @augments Conic\r\n * @constructor\r\n * @type JXG.Curve\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point,array_JXG.Point,array_JXG.Point,array} point1,point2,point3 Parent elements can be three elements either of type {@link JXG.Point} or array of\r\n * numbers describing the coordinates of a point. In the latter case the point will be constructed automatically as a fixed invisible point.\r\n * @param {JXG.Point,array_JXG.Point,array_number,function} point1,point2,number Parent elements can be two elements either of type {@link JXG.Point} or array of\r\n * numbers describing the coordinates of a point. The third parameter is a number/function which defines the length of the major axis\r\n * @param {Number} start (Optional) parameter of the curve start, default: -&pi;.\r\n * @param {Number} end (Optional) parameter for the curve end, default: &pi;.\r\n * @example\r\n * // Create an Hyperbola by three points\r\n * var A = board.create('point', [-1,4]);\r\n * var B = board.create('point', [-1,-4]);\r\n * var C = board.create('point', [1,1]);\r\n * var el = board.create('hyperbola',[A,B,C]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGcf99049d-a3fe-407f-b936-27d76550f8c4\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   (function(){\r\n *   var glex1_board = JXG.JSXGraph.initBoard('JXGcf99049d-a3fe-407f-b936-27d76550f8c4', {boundingbox:[-6,6,6,-6], keepaspectratio:true, showcopyright: false, shownavigation: false});\r\n *   var A = glex1_board.create('point', [-1,4]);\r\n *   var B = glex1_board.create('point', [-1,-4]);\r\n *   var C = glex1_board.create('point', [1,1]);\r\n *   var el = glex1_board.create('hyperbola',[A,B,C]);\r\n * })();\r\n * </script><pre>\r\n */\r\nJXG.createHyperbola = function (board, parents, attributes) {\r\n    var polarForm,\r\n        curve,\r\n        M,\r\n        C,\r\n        majorAxis,\r\n        i,\r\n        // focus 1 and focus 2\r\n        F = [],\r\n        attr_foci = Type.copyAttributes(attributes, board.options, \"conic\", 'foci'),\r\n        attr_center = Type.copyAttributes(attributes, board.options, \"conic\", 'center'),\r\n        attr_curve = Type.copyAttributes(attributes, board.options, 'conic');\r\n\r\n    // The foci and the third point are either points or coordinate arrays.\r\n    for (i = 0; i < 2; i++) {\r\n        // focus i given by coordinates\r\n        if (parents[i].length > 1) {\r\n            F[i] = board.create(\"point\", parents[i], attr_foci);\r\n            // focus i given by point\r\n        } else if (Type.isPoint(parents[i])) {\r\n            F[i] = board.select(parents[i]);\r\n            // given by function\r\n        } else if (Type.isFunction(parents[i]) && Type.isPoint(parents[i]())) {\r\n            F[i] = parents[i]();\r\n            // focus i given by point name\r\n        } else if (Type.isString(parents[i])) {\r\n            F[i] = board.select(parents[i]);\r\n        } else {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create Hyperbola with parent types '\" +\r\n                    typeof parents[0] +\r\n                    \"' and '\" +\r\n                    typeof parents[1] +\r\n                    \"'.\" +\r\n                    \"\\nPossible parent types: [point,point,point], [point,point,number|function]\"\r\n            );\r\n        }\r\n    }\r\n\r\n    // length of major axis\r\n    if (Type.isNumber(parents[2])) {\r\n        majorAxis = Type.createFunction(parents[2], board);\r\n    } else if (Type.isFunction(parents[2]) && Type.isNumber(parents[2]())) {\r\n        majorAxis = parents[2];\r\n    } else {\r\n        // point on ellipse\r\n        if (Type.isPoint(parents[2])) {\r\n            C = board.select(parents[2]);\r\n            // point on ellipse given by coordinates\r\n        } else if (parents[2].length > 1) {\r\n            C = board.create(\"point\", parents[2], attr_foci);\r\n            // given by function\r\n        } else if (Type.isFunction(parents[2]) && Type.isPoint(parents[2]())) {\r\n            C = parents[2]();\r\n            // focus i given by point name\r\n        } else if (Type.isString(parents[2])) {\r\n            C = board.select(parents[2]);\r\n        } else {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create Hyperbola with parent types '\" +\r\n                    typeof parents[0] +\r\n                    \"' and '\" +\r\n                    typeof parents[1] +\r\n                    \"' and '\" +\r\n                    typeof parents[2] +\r\n                    \"'.\" +\r\n                    \"\\nPossible parent types: [point,point,point], [point,point,number|function]\"\r\n            );\r\n        }\r\n        /** @ignore */\r\n        majorAxis = function () {\r\n            return C.Dist(F[0]) - C.Dist(F[1]);\r\n        };\r\n    }\r\n\r\n    // to\r\n    if (!Type.exists(parents[4])) {\r\n        parents[4] = 1.0001 * Math.PI;\r\n    }\r\n\r\n    // from\r\n    if (!Type.exists(parents[3])) {\r\n        parents[3] = -1.0001 * Math.PI;\r\n    }\r\n\r\n    M = board.create(\r\n        \"point\",\r\n        [\r\n            function () {\r\n                return (F[0].X() + F[1].X()) * 0.5;\r\n            },\r\n            function () {\r\n                return (F[0].Y() + F[1].Y()) * 0.5;\r\n            }\r\n        ],\r\n        attr_center\r\n    );\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    curve = board.create(\r\n        \"curve\",\r\n        [\r\n            function (x) {\r\n                return 0;\r\n            },\r\n            function (x) {\r\n                return 0;\r\n            },\r\n            parents[3],\r\n            parents[4]\r\n        ],\r\n        attr_curve\r\n    );\r\n\r\n    curve.majorAxis = majorAxis;\r\n\r\n    // Hyperbola is defined by (a*sec(t),b*tan(t)) and sec(t) = 1/cos(t)\r\n    /** @ignore */\r\n    polarForm = function (phi, suspendUpdate) {\r\n        var r, rr, ax, ay, bx, by, axbx, ayby, f;\r\n\r\n        if (!suspendUpdate) {\r\n            r = majorAxis();\r\n            rr = r * r;\r\n            ax = F[0].X();\r\n            ay = F[0].Y();\r\n            bx = F[1].X();\r\n            by = F[1].Y();\r\n            axbx = ax - bx;\r\n            ayby = ay - by;\r\n            f = (rr - ax * ax - ay * ay + bx * bx + by * by) / (2 * r);\r\n\r\n            curve.quadraticform = [\r\n                [f * f - bx * bx - by * by, (f * axbx) / r + bx, (f * ayby) / r + by],\r\n                [(f * axbx) / r + bx, (axbx * axbx) / rr - 1, (axbx * ayby) / rr],\r\n                [(f * ayby) / r + by, (axbx * ayby) / rr, (ayby * ayby) / rr - 1]\r\n            ];\r\n        }\r\n    };\r\n\r\n    /** @ignore */\r\n    curve.X = function (phi, suspendUpdate) {\r\n        var r = majorAxis(),\r\n            c = F[1].Dist(F[0]),\r\n            b = (0.5 * (c * c - r * r)) / (c * Math.cos(phi) + r),\r\n            beta = Math.atan2(F[1].Y() - F[0].Y(), F[1].X() - F[0].X());\r\n\r\n        if (!suspendUpdate) {\r\n            polarForm(phi, suspendUpdate);\r\n        }\r\n\r\n        return F[0].X() + Math.cos(beta + phi) * b;\r\n    };\r\n\r\n    /** @ignore */\r\n    curve.Y = function (phi, suspendUpdate) {\r\n        var r = majorAxis(),\r\n            c = F[1].Dist(F[0]),\r\n            b = (0.5 * (c * c - r * r)) / (c * Math.cos(phi) + r),\r\n            beta = Math.atan2(F[1].Y() - F[0].Y(), F[1].X() - F[0].X());\r\n\r\n        return F[0].Y() + Math.sin(beta + phi) * b;\r\n    };\r\n\r\n    curve.midpoint = curve.center = M;\r\n    curve.subs = {\r\n        center: curve.center\r\n    };\r\n    curve.inherits.push(curve.center, F[0], F[1]);\r\n    if (Type.isPoint(C)) {\r\n        curve.inherits.push(C);\r\n    }\r\n    curve.type = Const.OBJECT_TYPE_CONIC;\r\n\r\n    M.addChild(curve);\r\n    for (i = 0; i < 2; i++) {\r\n        if (Type.isPoint(F[i])) {\r\n            F[i].addChild(curve);\r\n        }\r\n    }\r\n    if (Type.isPoint(C)) {\r\n        C.addChild(curve);\r\n    }\r\n    curve.setParents(parents);\r\n\r\n    return curve;\r\n};\r\n\r\n/**\r\n * @class A parabola is a special conic section given by one point (the focus) and a line (the directrix).\r\n * @pseudo\r\n * @name Parabola\r\n * @augments Conic\r\n * @constructor\r\n * @type Object\r\n * @description JXG.Curve\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point,array_JXG.Line} point,line Parent elements are a point and a line or a pair of coordinates.\r\n * Optional parameters three and four are numbers which define the curve length (e.g. start/end). Default values are -pi and pi.\r\n * @example\r\n * // Create a parabola by a point C and a line l.\r\n * var A = board.create('point', [-1,4]);\r\n * var B = board.create('point', [-1,-4]);\r\n * var l = board.create('line', [A,B]);\r\n * var C = board.create('point', [1,1]);\r\n * var el = board.create('parabola',[C,l]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG524d1aae-217d-44d4-ac58-a19c7ab1de36\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function() {\r\n *   var glex1_board = JXG.JSXGraph.initBoard('JXG524d1aae-217d-44d4-ac58-a19c7ab1de36', {boundingbox:[-6,6,6,-6], keepaspectratio:true, showcopyright: false, shownavigation: false});\r\n *   var A = glex1_board.create('point', [-1,4]);\r\n *   var B = glex1_board.create('point', [-1,-4]);\r\n *   var l = glex1_board.create('line', [A,B]);\r\n *   var C = glex1_board.create('point', [1,1]);\r\n *   var el = glex1_board.create('parabola',[C,l]);\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * var par = board.create('parabola',[[3.25, 0], [[0.25, 1],[0.25, 0]]]);\r\n *\r\n * </pre><div id=\"JXG09252542-b77a-4990-a109-66ffb649a472\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG09252542-b77a-4990-a109-66ffb649a472',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var par = board.create('parabola',[[3.25, 0], [[0.25, 1],[0.25, 0]]]);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createParabola = function (board, parents, attributes) {\r\n    var polarForm,\r\n        curve,\r\n        M,\r\n        // focus\r\n        F1 = parents[0],\r\n        // directrix\r\n        l = parents[1],\r\n        attr_foci = Type.copyAttributes(attributes, board.options, \"conic\", 'foci'),\r\n        attr_center = Type.copyAttributes(attributes, board.options, \"conic\", 'center'),\r\n        attr_curve = Type.copyAttributes(attributes, board.options, 'conic'),\r\n        attr_line;\r\n\r\n    // focus 1 given by coordinates\r\n    if (parents[0].length > 1) {\r\n        F1 = board.create(\"point\", parents[0], attr_foci);\r\n        // focus 1 given by point\r\n    } else if (Type.isPoint(parents[0])) {\r\n        F1 = board.select(parents[0]);\r\n        // given by function\r\n    } else if (Type.isFunction(parents[0]) && Type.isPoint(parents[0]())) {\r\n        F1 = parents[0]();\r\n        // focus 1 given by point name\r\n    } else if (Type.isString(parents[0])) {\r\n        F1 = board.select(parents[0]);\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create Parabola with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [point,line]\"\r\n        );\r\n    }\r\n\r\n    // Create line if given as array of two points.\r\n    if (Type.isArray(l) && l.length === 2) {\r\n        attr_line = Type.copyAttributes(attributes, board.options, \"conic\", 'line');\r\n        l = board.create(\"line\", l, attr_line);\r\n    }\r\n\r\n    // to\r\n    if (!Type.exists(parents[3])) {\r\n        parents[3] = 2 * Math.PI;\r\n    }\r\n\r\n    // from\r\n    if (!Type.exists(parents[2])) {\r\n        parents[2] = 0;\r\n    }\r\n\r\n    M = board.create(\r\n        \"point\",\r\n        [\r\n            function () {\r\n                /*\r\n                var v = [0, l.stdform[1], l.stdform[2]];\r\n                v = Mat.crossProduct(v, F1.coords.usrCoords);\r\n                return Geometry.meetLineLine(v, l.stdform, 0, board).usrCoords;\r\n                */\r\n                return Geometry.projectPointToLine(F1, l, board).usrCoords;\r\n            }\r\n        ],\r\n        attr_center\r\n    );\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    curve = board.create(\r\n        \"curve\",\r\n        [\r\n            function (x) {\r\n                return 0;\r\n            },\r\n            function (x) {\r\n                return 0;\r\n            },\r\n            parents[2],\r\n            parents[3]\r\n        ],\r\n        attr_curve\r\n    );\r\n\r\n    curve.midpoint = curve.center = M;\r\n    curve.subs = {\r\n        center: curve.center\r\n    };\r\n    curve.inherits.push(curve.center);\r\n\r\n    /** @ignore */\r\n    polarForm = function (t, suspendUpdate) {\r\n        var a, b, c, ab, px, py;\r\n\r\n        if (!suspendUpdate) {\r\n            a = l.stdform[1];\r\n            b = l.stdform[2];\r\n            c = l.stdform[0];\r\n            ab = a * a + b * b;\r\n            px = F1.X();\r\n            py = F1.Y();\r\n\r\n            curve.quadraticform = [\r\n                [c * c - ab * (px * px + py * py), c * a + ab * px, c * b + ab * py],\r\n                [c * a + ab * px, -b * b, a * b],\r\n                [c * b + ab * py, a * b, -a * a]\r\n            ];\r\n        }\r\n    };\r\n\r\n    /** @ignore */\r\n    curve.X = function (phi, suspendUpdate) {\r\n        var a,\r\n            det,\r\n            beta = l.getAngle(),\r\n            d = Geometry.distPointLine(F1.coords.usrCoords, l.stdform),\r\n            A = l.point1.coords.usrCoords,\r\n            B = l.point2.coords.usrCoords,\r\n            M = F1.coords.usrCoords;\r\n\r\n        // Handle the case if one of the two defining points of the line is an ideal point\r\n        if (A[0] === 0) {\r\n            A = [1, B[1] + l.stdform[2], B[2] - l.stdform[1]];\r\n        } else if (B[0] === 0) {\r\n            B = [1, A[1] + l.stdform[2], A[2] - l.stdform[1]];\r\n        }\r\n        det = (B[1] - A[1]) * (M[2] - A[2]) - (B[2] - A[2]) * (M[1] - A[1]) >= 0 ? 1 : -1;\r\n        a = (det * d) / (1 - Math.sin(phi));\r\n\r\n        if (!suspendUpdate) {\r\n            polarForm(phi, suspendUpdate);\r\n        }\r\n\r\n        return F1.X() + Math.cos(phi + beta) * a;\r\n    };\r\n\r\n    /** @ignore */\r\n    curve.Y = function (phi, suspendUpdate) {\r\n        var a,\r\n            det,\r\n            beta = l.getAngle(),\r\n            d = Geometry.distPointLine(F1.coords.usrCoords, l.stdform),\r\n            A = l.point1.coords.usrCoords,\r\n            B = l.point2.coords.usrCoords,\r\n            M = F1.coords.usrCoords;\r\n\r\n        // Handle the case if one of the two defining points of the line is an ideal point\r\n        if (A[0] === 0) {\r\n            A = [1, B[1] + l.stdform[2], B[2] - l.stdform[1]];\r\n        } else if (B[0] === 0) {\r\n            B = [1, A[1] + l.stdform[2], A[2] - l.stdform[1]];\r\n        }\r\n        det = (B[1] - A[1]) * (M[2] - A[2]) - (B[2] - A[2]) * (M[1] - A[1]) >= 0 ? 1 : -1;\r\n        a = (det * d) / (1 - Math.sin(phi));\r\n\r\n        return F1.Y() + Math.sin(phi + beta) * a;\r\n    };\r\n\r\n    curve.type = Const.OBJECT_TYPE_CONIC;\r\n    M.addChild(curve);\r\n\r\n    if (Type.isPoint(F1)) {\r\n        F1.addChild(curve);\r\n        curve.inherits.push(F1);\r\n    }\r\n\r\n    l.addChild(curve);\r\n    curve.setParents(parents);\r\n\r\n    return curve;\r\n};\r\n\r\n/**\r\n *\r\n * @class Create a generic conic section either by five points or the coefficients of the general conic's equation.\r\n * If the conic section is defined by the coefficients of the equation\r\n * <p><i>Ax<sup>2</sup>+ Bxy+Cy<sup>2</sup> + Dx + Ey + F = 0</i></p>\r\n * then the parameters are as follows:\r\n * <pre>\r\n *     board.create('conic', [A, C, F, B/2, D/2, E/2]);\r\n * </pre>\r\n * @pseudo\r\n * @name Conic\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type JXG.Conic\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point,Array_JXG.Point,Array_JXG.Point,Array_JXG.Point,Array_JXG.Point,Array} a,b,c,d,e Parent elements are five points.\r\n * @param {Number_Number_Number_Number_Number_Number} a_00,a_11,a_22,a_01,a_02,a_12 6 numbers, i.e. A, C, F, B/2, D/2, E/2\r\n * @example\r\n * // Create a conic section through the points A, B, C, D, and E.\r\n *  var A = board.create('point', [1,5]);\r\n *  var B = board.create('point', [1,2]);\r\n *  var C = board.create('point', [2,0]);\r\n *  var D = board.create('point', [0,0]);\r\n *  var E = board.create('point', [-1,5]);\r\n *  var conic = board.create('conic',[A,B,C,D,E]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG2d79bd6a-db9b-423c-9cba-2497f0b06320\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function(){\r\n *   var glex1_board = JXG.JSXGraph.initBoard('JXG2d79bd6a-db9b-423c-9cba-2497f0b06320', {boundingbox:[-6,6,6,-6], keepaspectratio:true, showcopyright: false, shownavigation: false});\r\n *   var A = glex1_board.create('point', [1,5]);\r\n *   var B = glex1_board.create('point', [1,2]);\r\n *   var C = glex1_board.create('point', [2,0]);\r\n *   var D = glex1_board.create('point', [0,0]);\r\n *   var E = glex1_board.create('point', [-1,5]);\r\n *   var conic = glex1_board.create('conic',[A,B,C,D,E]);\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Parameters: A, C, F, B/2, D/2, E/2\r\n * var conic = board.create('conic', [1, 2, -4, 0, 0, 0]);\r\n *\r\n * </pre><div id=\"JXG8576a04a-52d8-4a7e-8d54-e32443910b97\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG8576a04a-52d8-4a7e-8d54-e32443910b97',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     // Parameters: A, C, F, B/2, D/2, E/2\r\n *     var conic = board.create('conic', [1, 2, -4, 0, 0, 0]);\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createConic = function (board, parents, attributes) {\r\n    var polarForm,\r\n        curve,\r\n        fitConic,\r\n        degconic,\r\n        sym,\r\n        eigen,\r\n        a,\r\n        b,\r\n        c,\r\n        c1,\r\n        c2,\r\n        i,\r\n        definingMat,\r\n        givenByPoints,\r\n        rotationMatrix = [\r\n            [1, 0, 0],\r\n            [0, 1, 0],\r\n            [0, 0, 1]\r\n        ],\r\n        M = [\r\n            [1, 0, 0],\r\n            [0, 1, 0],\r\n            [0, 0, 1]\r\n        ],\r\n        points = [],\r\n        p = [],\r\n        attr_point = Type.copyAttributes(attributes, board.options, \"conic\", 'point'),\r\n        attr_center = Type.copyAttributes(attributes, board.options, \"conic\", 'center'),\r\n        attr_curve = Type.copyAttributes(attributes, board.options, 'conic');\r\n\r\n    if (parents.length === 5) {\r\n        givenByPoints = true;\r\n    } else if (parents.length === 6) {\r\n        givenByPoints = false;\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create generic Conic with \" + parents.length + \" parameters.\"\r\n        );\r\n    }\r\n\r\n    if (givenByPoints) {\r\n        for (i = 0; i < 5; i++) {\r\n            // point i given by coordinates\r\n            if (parents[i].length > 1) {\r\n                points[i] = board.create(\"point\", parents[i], attr_point);\r\n                // point i given by point\r\n            } else if (Type.isPoint(parents[i])) {\r\n                points[i] = board.select(parents[i]);\r\n                // given by function\r\n            } else if (Type.isFunction(parents[i]) && Type.isPoint(parents[i]())) {\r\n                points[i] = parents[i]();\r\n                // point i given by point name\r\n            } else if (Type.isString(parents[i])) {\r\n                points[i] = board.select(parents[i]);\r\n            } else {\r\n                throw new Error(\r\n                    \"JSXGraph: Can't create Conic section with parent types '\" +\r\n                        typeof parents[i] +\r\n                        \"'.\" +\r\n                        \"\\nPossible parent types: [point,point,point,point,point], [a00,a11,a22,a01,a02,a12]\"\r\n                );\r\n            }\r\n        }\r\n    } else {\r\n        /* Usual notation (x,y,z):\r\n         *  [[A0,A3,A4],\r\n         *   [A3,A1,A5],\r\n         *   [A4,A5,A2]].\r\n         * Our notation (z,x,y):\r\n         *  [[A2, A4, A5],\r\n         *   [A4, A0, A3],\r\n         *   [A5, A3, A1]]\r\n         */\r\n        definingMat = [\r\n            [0, 0, 0],\r\n            [0, 0, 0],\r\n            [0, 0, 0]\r\n        ];\r\n        definingMat[0][0] = Type.isFunction(parents[2])\r\n            ? function () {\r\n                  return parents[2]();\r\n              }\r\n            : function () {\r\n                  return parents[2];\r\n              };\r\n        definingMat[0][1] = Type.isFunction(parents[4])\r\n            ? function () {\r\n                  return parents[4]();\r\n              }\r\n            : function () {\r\n                  return parents[4];\r\n              };\r\n        definingMat[0][2] = Type.isFunction(parents[5])\r\n            ? function () {\r\n                  return parents[5]();\r\n              }\r\n            : function () {\r\n                  return parents[5];\r\n              };\r\n        definingMat[1][1] = Type.isFunction(parents[0])\r\n            ? function () {\r\n                  return parents[0]();\r\n              }\r\n            : function () {\r\n                  return parents[0];\r\n              };\r\n        definingMat[1][2] = Type.isFunction(parents[3])\r\n            ? function () {\r\n                  return parents[3]();\r\n              }\r\n            : function () {\r\n                  return parents[3];\r\n              };\r\n        definingMat[2][2] = Type.isFunction(parents[1])\r\n            ? function () {\r\n                  return parents[1]();\r\n              }\r\n            : function () {\r\n                  return parents[1];\r\n              };\r\n    }\r\n\r\n    // sym(A) = A + A^t . Manipulates A in place.\r\n    sym = function (A) {\r\n        var i, j;\r\n        for (i = 0; i < 3; i++) {\r\n            for (j = i; j < 3; j++) {\r\n                A[i][j] += A[j][i];\r\n            }\r\n        }\r\n        for (i = 0; i < 3; i++) {\r\n            for (j = 0; j < i; j++) {\r\n                A[i][j] = A[j][i];\r\n            }\r\n        }\r\n        return A;\r\n    };\r\n\r\n    // degconic(v,w) = sym(v*w^t)\r\n    degconic = function (v, w) {\r\n        var i,\r\n            j,\r\n            mat = [\r\n                [0, 0, 0],\r\n                [0, 0, 0],\r\n                [0, 0, 0]\r\n            ];\r\n\r\n        for (i = 0; i < 3; i++) {\r\n            for (j = 0; j < 3; j++) {\r\n                mat[i][j] = v[i] * w[j];\r\n            }\r\n        }\r\n\r\n        return sym(mat);\r\n    };\r\n\r\n    // (p^t*B*p)*A-(p^t*A*p)*B\r\n    fitConic = function (A, B, p) {\r\n        var i,\r\n            j,\r\n            pBp,\r\n            pAp,\r\n            Mv,\r\n            mat = [\r\n                [0, 0, 0],\r\n                [0, 0, 0],\r\n                [0, 0, 0]\r\n            ];\r\n\r\n        Mv = Mat.matVecMult(B, p);\r\n        pBp = Mat.innerProduct(p, Mv);\r\n        Mv = Mat.matVecMult(A, p);\r\n        pAp = Mat.innerProduct(p, Mv);\r\n\r\n        for (i = 0; i < 3; i++) {\r\n            for (j = 0; j < 3; j++) {\r\n                mat[i][j] = pBp * A[i][j] - pAp * B[i][j];\r\n            }\r\n        }\r\n        return mat;\r\n    };\r\n\r\n    // Here, the defining functions for the curve are just dummy functions.\r\n    // In polarForm there is a reference to curve.quadraticform.\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    curve = board.create(\r\n        \"curve\",\r\n        [\r\n            function (x) {\r\n                return 0;\r\n            },\r\n            function (x) {\r\n                return 0;\r\n            },\r\n            0,\r\n            2 * Math.PI\r\n        ],\r\n        attr_curve\r\n    );\r\n\r\n    /** @ignore */\r\n    polarForm = function (phi, suspendUpdate) {\r\n        var i, j, v; // len,;\r\n\r\n        if (!suspendUpdate) {\r\n            if (givenByPoints) {\r\n                // Copy the point coordinate vectors\r\n                for (i = 0; i < 5; i++) {\r\n                    p[i] = points[i].coords.usrCoords;\r\n                }\r\n\r\n                // Compute the quadratic form\r\n                c1 = degconic(Mat.crossProduct(p[0], p[1]), Mat.crossProduct(p[2], p[3]));\r\n                c2 = degconic(Mat.crossProduct(p[0], p[2]), Mat.crossProduct(p[1], p[3]));\r\n                M = fitConic(c1, c2, p[4]);\r\n            } else {\r\n                for (i = 0; i < 3; i++) {\r\n                    for (j = i; j < 3; j++) {\r\n                        M[i][j] = definingMat[i][j]();\r\n                        if (j > i) {\r\n                            M[j][i] = M[i][j];\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Here is the reference back to the curve.\r\n            curve.quadraticform = M;\r\n\r\n            // Compute Eigenvalues and Eigenvectors\r\n            eigen = Numerics.Jacobi(M);\r\n\r\n            // Scale the Eigenvalues such that the first Eigenvalue is positive\r\n            if (eigen[0][0][0] < 0) {\r\n                eigen[0][0][0] *= -1;\r\n                eigen[0][1][1] *= -1;\r\n                eigen[0][2][2] *= -1;\r\n            }\r\n\r\n            // Normalize the Eigenvectors\r\n            // for (i = 0; i < 3; i++) {\r\n            //     // len = Mat.hypot(eigen[1][0][i], eigen[1][1][i], eigen[1][2][i])\r\n            //     for (j = 0; j < 3; j++) {\r\n            //         len += eigen[1][j][i] * eigen[1][j][i];\r\n            //     }\r\n            //     len = Math.sqrt(len);\r\n            //     /*for (j = 0; j < 3; j++) {\r\n            //             //eigen[1][j][i] /= len;\r\n            //         }*/\r\n            // }\r\n            rotationMatrix = eigen[1];\r\n            c = Math.sqrt(Math.abs(eigen[0][0][0]));\r\n            a = Math.sqrt(Math.abs(eigen[0][1][1]));\r\n            b = Math.sqrt(Math.abs(eigen[0][2][2]));\r\n        }\r\n\r\n        // The degenerate cases with eigen[0][i][i]==0 are not handled correct yet.\r\n        if (eigen[0][1][1] <= 0.0 && eigen[0][2][2] <= 0.0) {\r\n            v = Mat.matVecMult(rotationMatrix, [1 / c, Math.cos(phi) / a, Math.sin(phi) / b]);\r\n        } else if (eigen[0][1][1] <= 0.0 && eigen[0][2][2] > 0.0) {\r\n            v = Mat.matVecMult(rotationMatrix, [Math.cos(phi) / c, 1 / a, Math.sin(phi) / b]);\r\n        } else if (eigen[0][2][2] < 0.0) {\r\n            v = Mat.matVecMult(rotationMatrix, [Math.sin(phi) / c, Math.cos(phi) / a, 1 / b]);\r\n        }\r\n\r\n        if (Type.exists(v)) {\r\n            // Normalize\r\n            v[1] /= v[0];\r\n            v[2] /= v[0];\r\n            v[0] = 1.0;\r\n        } else {\r\n            v = [1, NaN, NaN];\r\n        }\r\n\r\n        return v;\r\n    };\r\n\r\n    /** @ignore */\r\n    curve.X = function (phi, suspendUpdate) {\r\n        return polarForm(phi, suspendUpdate)[1];\r\n    };\r\n\r\n    /** @ignore */\r\n    curve.Y = function (phi, suspendUpdate) {\r\n        return polarForm(phi, suspendUpdate)[2];\r\n    };\r\n\r\n    // Center coordinates see https://en.wikipedia.org/wiki/Matrix_representation_of_conic_sections\r\n    curve.midpoint = board.create(\r\n        \"point\",\r\n        [\r\n            function () {\r\n                var m = curve.quadraticform;\r\n\r\n                return [\r\n                    m[1][1] * m[2][2] - m[1][2] * m[1][2],\r\n                    m[1][2] * m[0][2] - m[2][2] * m[0][1],\r\n                    m[0][1] * m[1][2] - m[1][1] * m[0][2]\r\n                ];\r\n            }\r\n        ],\r\n        attr_center\r\n    );\r\n\r\n    curve.type = Const.OBJECT_TYPE_CONIC;\r\n    curve.center = curve.midpoint;\r\n    curve.subs = {\r\n        center: curve.center\r\n    };\r\n    curve.inherits.push(curve.center);\r\n    curve.inherits = curve.inherits.concat(points);\r\n\r\n    if (givenByPoints) {\r\n        for (i = 0; i < 5; i++) {\r\n            if (Type.isPoint(points[i])) {\r\n                points[i].addChild(curve);\r\n            }\r\n        }\r\n        curve.setParents(parents);\r\n    }\r\n    curve.addChild(curve.center);\r\n\r\n    return curve;\r\n};\r\n\r\nJXG.registerElement(\"ellipse\", JXG.createEllipse);\r\nJXG.registerElement(\"hyperbola\", JXG.createHyperbola);\r\nJXG.registerElement(\"parabola\", JXG.createParabola);\r\nJXG.registerElement(\"conic\", JXG.createConic);\r\n\r\n// export default {\r\n//     createEllipse: JXG.createEllipse,\r\n//     createHyperbola: JXG.createHyperbola,\r\n//     createParabola: JXG.createParabola,\r\n//     createConic: JXG.createConic\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG:true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"./constants.js\";\r\nimport Coords from \"./coords.js\";\r\nimport Statistics from \"../math/statistics.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport GeometryElement from \"./element.js\";\r\n\r\n/**\r\n * Creates a new instance of JXG.Polygon.\r\n * @class Polygon stores all style and functional properties that are required\r\n * to draw and to interactact with a polygon.\r\n * @constructor\r\n * @augments JXG.GeometryElement\r\n * @param {JXG.Board} board Reference to the board the polygon is to be drawn on.\r\n * @param {Array} vertices Unique identifiers for the points defining the polygon.\r\n * Last point must be first point. Otherwise, the first point will be added at the list.\r\n * @param {Object} attributes An object which contains properties as given in {@link JXG.Options.elements}\r\n * and {@link JXG.Options.polygon}.\r\n */\r\nJXG.Polygon = function (board, vertices, attributes) {\r\n    this.constructor(board, attributes, Const.OBJECT_TYPE_POLYGON, Const.OBJECT_CLASS_AREA);\r\n\r\n    var i, l, len, j, p,\r\n        attr_line = Type.copyAttributes(attributes, board.options, \"polygon\", 'borders');\r\n\r\n    this.withLines = attributes.withlines;\r\n    this.attr_line = attr_line;\r\n\r\n    /**\r\n     * References to the points defining the polygon. The last vertex is the same as the first vertex.\r\n     * Compared to the 3D {@link JXG.Polygon3D#vertices}, it contains one point more, i.e. for a quadrangle\r\n     * 'vertices' contains five points, the last one being\r\n     * a copy of the first one. In a 3D quadrangle, 'vertices' will contain four points.\r\n     * @type Array\r\n     */\r\n    this.vertices = [];\r\n    for (i = 0; i < vertices.length; i++) {\r\n        this.vertices[i] = this.board.select(vertices[i]);\r\n\r\n        // The _is_new flag is replaced by _is_new_pol.\r\n        // Otherwise, the polygon would disappear if the last border element\r\n        // is removed (and the point has been provided by coordinates)\r\n        if (this.vertices[i]._is_new) {\r\n            delete this.vertices[i]._is_new;\r\n            this.vertices[i]._is_new_pol = true;\r\n        }\r\n    }\r\n\r\n    // Close the polygon\r\n    if (\r\n        this.vertices.length > 0 &&\r\n        this.vertices[this.vertices.length - 1].id !== this.vertices[0].id\r\n    ) {\r\n        this.vertices.push(this.vertices[0]);\r\n    }\r\n\r\n    /**\r\n     * References to the border lines (edges) of the polygon.\r\n     * @type Array\r\n     */\r\n    this.borders = [];\r\n\r\n    if (this.withLines) {\r\n        len = this.vertices.length - 1;\r\n        for (j = 0; j < len; j++) {\r\n            // This sets the \"correct\" labels for the first triangle of a construction.\r\n            i = (j + 1) % len;\r\n            attr_line.id = attr_line.ids && attr_line.ids[i];\r\n            attr_line.name = attr_line.names && attr_line.names[i];\r\n            attr_line.strokecolor =\r\n                (Type.isArray(attr_line.colors) &&\r\n                    attr_line.colors[i % attr_line.colors.length]) ||\r\n                attr_line.strokecolor;\r\n            attr_line.visible = Type.exists(attributes.borders.visible)\r\n                ? attributes.borders.visible\r\n                : attributes.visible;\r\n\r\n            if (attr_line.strokecolor === false) {\r\n                attr_line.strokecolor = 'none';\r\n            }\r\n\r\n            l = board.create(\"segment\", [this.vertices[i], this.vertices[i + 1]], attr_line);\r\n            l.dump = false;\r\n            this.borders[i] = l;\r\n            l.parentPolygon = this;\r\n            this.addChild(l);\r\n        }\r\n    }\r\n\r\n    this.inherits.push(this.vertices, this.borders);\r\n\r\n    // Register polygon at board\r\n    // This needs to be done BEFORE the points get this polygon added in their descendants list\r\n    this.id = this.board.setId(this, 'Py');\r\n\r\n    // Add dependencies: either\r\n    // - add polygon as child to an existing point\r\n    // or\r\n    // - add  points (supplied as coordinate arrays by the user and created by Type.providePoints) as children to the polygon\r\n    for (i = 0; i < this.vertices.length - 1; i++) {\r\n        p = this.board.select(this.vertices[i]);\r\n        if (Type.exists(p._is_new_pol)) {\r\n            this.addChild(p);\r\n            delete p._is_new_pol;\r\n        } else {\r\n            p.addChild(this);\r\n        }\r\n    }\r\n\r\n    this.board.renderer.drawPolygon(this);\r\n    this.board.finalizeAdding(this);\r\n\r\n    this.createGradient();\r\n    this.elType = 'polygon';\r\n\r\n    // create label\r\n    this.createLabel();\r\n\r\n    this.methodMap = JXG.deepCopy(this.methodMap, {\r\n        borders: \"borders\",\r\n        vertices: \"vertices\",\r\n        A: \"Area\",\r\n        Area: \"Area\",\r\n        Perimeter: \"Perimeter\",\r\n        L: \"Perimeter\",\r\n        boundingBox: \"bounds\",\r\n        BoundingBox: \"bounds\",\r\n        addPoints: \"addPoints\",\r\n        insertPoints: \"insertPoints\",\r\n        removePoints: \"removePoints\",\r\n        Intersect: \"intersect\"\r\n    });\r\n};\r\n\r\nJXG.Polygon.prototype = new GeometryElement();\r\n\r\nJXG.extend(\r\n    JXG.Polygon.prototype,\r\n    /** @lends JXG.Polygon.prototype */ {\r\n        /**\r\n         * Wrapper for JXG.Math.Geometry.pnpoly.\r\n         *\r\n         * @param {Number} x_in x-coordinate (screen or user coordinates)\r\n         * @param {Number} y_in y-coordinate (screen or user coordinates)\r\n         * @param {Number} coord_type (Optional) the type of coordinates used here.\r\n         *   Possible values are <b>JXG.COORDS_BY_USER</b> and <b>JXG.COORDS_BY_SCREEN</b>.\r\n         *   Default value is JXG.COORDS_BY_SCREEN\r\n         *\r\n         * @returns {Boolean} if (x_in, y_in) is inside of the polygon.\r\n         * @see JXG.Math.Geometry#pnpoly\r\n         *\r\n         * @example\r\n         * var pol = board.create('polygon', [[-1,2], [2,2], [-1,4]]);\r\n         * var p = board.create('point', [4, 3]);\r\n         * var txt = board.create('text', [-1, 0.5, function() {\r\n         *   return 'Point A is inside of the polygon = ' +\r\n         *     pol.pnpoly(p.X(), p.Y(), JXG.COORDS_BY_USER);\r\n         * }]);\r\n         *\r\n         * </pre><div id=\"JXG7f96aec7-4e3d-4ffc-a3f5-d3f967b6691c\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG7f96aec7-4e3d-4ffc-a3f5-d3f967b6691c',\r\n         *             {boundingbox: [-2, 5, 5,-2], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var pol = board.create('polygon', [[-1,2], [2,2], [-1,4]]);\r\n         *     var p = board.create('point', [4, 3]);\r\n         *     var txt = board.create('text', [-1, 0.5, function() {\r\n         *     \t\treturn 'Point A is inside of the polygon = ' + pol.pnpoly(p.X(), p.Y(), JXG.COORDS_BY_USER);\r\n         *     }]);\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        pnpoly: function (x_in, y_in, coord_type) {\r\n            return Geometry.pnpoly(x_in, y_in, this.vertices, coord_type, this.board);\r\n        },\r\n\r\n        /**\r\n         * Checks whether (x,y) is near the polygon.\r\n         * @param {Number} x Coordinate in x direction, screen coordinates.\r\n         * @param {Number} y Coordinate in y direction, screen coordinates.\r\n         * @returns {Boolean} Returns true, if (x,y) is inside or at the boundary the polygon, otherwise false.\r\n         */\r\n        hasPoint: function (x, y) {\r\n            var i, len;\r\n\r\n            if (this.evalVisProp('hasinnerpoints')) {\r\n                // All points of the polygon trigger hasPoint: inner and boundary points\r\n                if (this.pnpoly(x, y)) {\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            // Only boundary points trigger hasPoint\r\n            // We additionally test the boundary also in case hasInnerPoints.\r\n            // Since even if the above test has failed, the strokewidth may be large and (x, y) may\r\n            // be inside of hasPoint() of a vertices.\r\n            len = this.borders.length;\r\n            for (i = 0; i < len; i++) {\r\n                if (this.borders[i].hasPoint(x, y)) {\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Uses the boards renderer to update the polygon.\r\n         */\r\n        updateRenderer: function () {\r\n            var i, len;\r\n\r\n            if (!this.needsUpdate) {\r\n                return this;\r\n            }\r\n\r\n            if (this.visPropCalc.visible) {\r\n                len = this.vertices.length - ((this.elType === 'polygonalchain') ? 0 : 1);\r\n                this.isReal = true;\r\n                for (i = 0; i < len; ++i) {\r\n                    if (!this.vertices[i].isReal) {\r\n                        this.isReal = false;\r\n                        break;\r\n                    }\r\n                }\r\n\r\n                if (!this.isReal) {\r\n                    this.updateVisibility(false);\r\n\r\n                    for (i in this.childElements) {\r\n                        if (this.childElements.hasOwnProperty(i)) {\r\n                            // All child elements are hidden.\r\n                            // This may be weakened to all borders and only vertices with with visible:'inherit'\r\n                            this.childElements[i].setDisplayRendNode(false);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (this.visPropCalc.visible) {\r\n                this.board.renderer.updatePolygon(this);\r\n            }\r\n\r\n            /* Update the label if visible. */\r\n            if (this.hasLabel &&\r\n                this.visPropCalc.visible &&\r\n                this.label &&\r\n                this.label.visPropCalc.visible &&\r\n                this.isReal\r\n            ) {\r\n                this.label.update();\r\n                this.board.renderer.updateText(this.label);\r\n            }\r\n\r\n            // Update rendNode display\r\n            this.setDisplayRendNode();\r\n\r\n            this.needsUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * return TextAnchor\r\n         */\r\n        getTextAnchor: function () {\r\n            var a, b, x, y, i;\r\n\r\n            if (this.vertices.length === 0) {\r\n                return new Coords(Const.COORDS_BY_USER, [1, 0, 0], this.board);\r\n            }\r\n\r\n            a = this.vertices[0].X();\r\n            b = this.vertices[0].Y();\r\n            x = a;\r\n            y = b;\r\n            for (i = 0; i < this.vertices.length; i++) {\r\n                if (this.vertices[i].X() < a) {\r\n                    a = this.vertices[i].X();\r\n                }\r\n\r\n                if (this.vertices[i].X() > x) {\r\n                    x = this.vertices[i].X();\r\n                }\r\n\r\n                if (this.vertices[i].Y() > b) {\r\n                    b = this.vertices[i].Y();\r\n                }\r\n\r\n                if (this.vertices[i].Y() < y) {\r\n                    y = this.vertices[i].Y();\r\n                }\r\n            }\r\n\r\n            return new Coords(Const.COORDS_BY_USER, [(a + x) * 0.5, (b + y) * 0.5], this.board);\r\n        },\r\n\r\n        getLabelAnchor: JXG.shortcut(JXG.Polygon.prototype, 'getTextAnchor'),\r\n\r\n        // documented in geometry element\r\n        cloneToBackground: function () {\r\n            var er,\r\n                copy = Type.getCloneObject(this);\r\n\r\n            copy.vertices = this.vertices;\r\n            er = this.board.renderer.enhancedRendering;\r\n            this.board.renderer.enhancedRendering = true;\r\n            this.board.renderer.drawPolygon(copy);\r\n            this.board.renderer.enhancedRendering = er;\r\n            this.traces[copy.id] = copy.rendNode;\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Hide the polygon including its border lines. It will still exist but not visible on the board.\r\n         * @param {Boolean} [borderless=false] If set to true, the polygon is treated as a polygon without\r\n         * borders, i.e. the borders will not be hidden.\r\n         */\r\n        hideElement: function (borderless) {\r\n            var i;\r\n\r\n            JXG.deprecated(\"Element.hideElement()\", \"Element.setDisplayRendNode()\");\r\n\r\n            this.visPropCalc.visible = false;\r\n            this.board.renderer.display(this, false);\r\n\r\n            if (!borderless) {\r\n                for (i = 0; i < this.borders.length; i++) {\r\n                    this.borders[i].hideElement();\r\n                }\r\n            }\r\n\r\n            if (this.hasLabel && Type.exists(this.label)) {\r\n                this.label.hiddenByParent = true;\r\n                if (this.label.visPropCalc.visible) {\r\n                    this.label.hideElement();\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Make the element visible.\r\n         * @param {Boolean} [borderless=false] If set to true, the polygon is treated as a polygon without\r\n         * borders, i.e. the borders will not be shown.\r\n         */\r\n        showElement: function (borderless) {\r\n            var i;\r\n\r\n            JXG.deprecated(\"Element.showElement()\", \"Element.setDisplayRendNode()\");\r\n\r\n            this.visPropCalc.visible = true;\r\n            this.board.renderer.display(this, true);\r\n\r\n            if (!borderless) {\r\n                for (i = 0; i < this.borders.length; i++) {\r\n                    this.borders[i].showElement().updateRenderer();\r\n                }\r\n            }\r\n\r\n            if (Type.exists(this.label) && this.hasLabel && this.label.hiddenByParent) {\r\n                this.label.hiddenByParent = false;\r\n                if (!this.label.visPropCalc.visible) {\r\n                    this.label.showElement().updateRenderer();\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Area of (not self-intersecting) polygon\r\n         * @returns {Number} Area of (not self-intersecting) polygon\r\n         */\r\n        Area: function () {\r\n            return Math.abs(Geometry.signedPolygon(this.vertices, true));\r\n        },\r\n\r\n        /**\r\n         * Perimeter of polygon. For a polygonal chain, this method returns its length.\r\n         *\r\n         * @returns {Number} Perimeter of polygon in user units.\r\n         * @see JXG.Polygon#L\r\n         *\r\n         * @example\r\n         * var p = [[0.0, 2.0], [2.0, 1.0], [4.0, 6.0], [1.0, 3.0]];\r\n         *\r\n         * var pol = board.create('polygon', p, {hasInnerPoints: true});\r\n         * var t = board.create('text', [5, 5, function() { return pol.Perimeter(); }]);\r\n         * </pre><div class=\"jxgbox\" id=\"JXGb10b734d-89fc-4b9d-b4a7-e3f0c1c6bf77\" style=\"width: 400px; height: 400px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *  (function () {\r\n         *   var board = JXG.JSXGraph.initBoard('JXGb10b734d-89fc-4b9d-b4a7-e3f0c1c6bf77', {boundingbox: [-1, 9, 9, -1], axis: false, showcopyright: false, shownavigation: false}),\r\n         *       p = [[0.0, 2.0], [2.0, 1.0], [4.0, 6.0], [1.0, 4.0]],\r\n         *       cc1 = board.create('polygon', p, {hasInnerPoints: true}),\r\n         *       t = board.create('text', [5, 5, function() { return cc1.Perimeter(); }]);\r\n         *  })();\r\n         * </script><pre>\r\n         *\r\n         */\r\n        Perimeter: function () {\r\n            var i,\r\n                len = this.vertices.length,\r\n                val = 0.0;\r\n\r\n            for (i = 1; i < len; ++i) {\r\n                val += this.vertices[i].Dist(this.vertices[i - 1]);\r\n            }\r\n\r\n            return val;\r\n        },\r\n\r\n        /**\r\n         * Alias for Perimeter. For polygons, the perimeter is returned. For polygonal chains the length is returned.\r\n         *\r\n         * @returns Number\r\n         * @see JXG.Polygon#Perimeter\r\n         */\r\n        L: function() {\r\n            return this.Perimeter();\r\n        },\r\n\r\n        /**\r\n         * Bounding box of a polygon. The bounding box is an array of four numbers: the first two numbers\r\n         * determine the upper left corner, the last two numbers determine the lower right corner of the bounding box.\r\n         *\r\n         * The width and height of a polygon can then determined like this:\r\n         * @example\r\n         * var box = polygon.boundingBox();\r\n         * var width = box[2] - box[0];\r\n         * var height = box[1] - box[3];\r\n         *\r\n         * @returns {Array} Array containing four numbers: [minX, maxY, maxX, minY]\r\n         */\r\n        boundingBox: function () {\r\n            var box = [0, 0, 0, 0],\r\n                i,\r\n                v,\r\n                le = this.vertices.length - 1;\r\n\r\n            if (le === 0) {\r\n                return box;\r\n            }\r\n            box[0] = this.vertices[0].X();\r\n            box[2] = box[0];\r\n            box[1] = this.vertices[0].Y();\r\n            box[3] = box[1];\r\n\r\n            for (i = 1; i < le; ++i) {\r\n                v = this.vertices[i].X();\r\n                if (v < box[0]) {\r\n                    box[0] = v;\r\n                } else if (v > box[2]) {\r\n                    box[2] = v;\r\n                }\r\n\r\n                v = this.vertices[i].Y();\r\n                if (v > box[1]) {\r\n                    box[1] = v;\r\n                } else if (v < box[3]) {\r\n                    box[3] = v;\r\n                }\r\n            }\r\n\r\n            return box;\r\n        },\r\n\r\n        // Already documented in GeometryElement\r\n        bounds: function () {\r\n            return this.boundingBox();\r\n        },\r\n\r\n        /**\r\n         * This method removes the SVG or VML nodes of the lines and the filled area from the renderer, to remove\r\n         * the object completely you should use {@link JXG.Board#removeObject}.\r\n         *\r\n         * @private\r\n         */\r\n        remove: function () {\r\n            var i;\r\n\r\n            for (i = 0; i < this.borders.length; i++) {\r\n                this.board.removeObject(this.borders[i]);\r\n            }\r\n\r\n            GeometryElement.prototype.remove.call(this);\r\n        },\r\n\r\n        /**\r\n         * Finds the index to a given point reference.\r\n         * @param {JXG.Point} p Reference to an element of type {@link JXG.Point}\r\n         * @returns {Number} Index of the point or -1.\r\n         */\r\n        findPoint: function (p) {\r\n            var i;\r\n\r\n            if (!Type.isPoint(p)) {\r\n                return -1;\r\n            }\r\n\r\n            for (i = 0; i < this.vertices.length; i++) {\r\n                if (this.vertices[i].id === p.id) {\r\n                    return i;\r\n                }\r\n            }\r\n\r\n            return -1;\r\n        },\r\n\r\n        /**\r\n         * Add more points to the polygon. The new points will be inserted at the end.\r\n         * The attributes of new border segments are set to the same values\r\n         * as those used when the polygon was created.\r\n         * If new vertices are supplied by coordinates, the default attributes of polygon\r\n         * vertices are taken as their attributes. Therefore, the visual attributes of\r\n         * new vertices and borders may have to be adapted afterwards.\r\n         * @param {JXG.Point} p Arbitrary number of points or coordinate arrays\r\n         * @returns {JXG.Polygon} Reference to the polygon\r\n         * @example\r\n         * var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});\r\n         * var newPoint = board.create('point', [-1, -1]);\r\n         * var newPoint2 = board.create('point', [-1, -2]);\r\n         * pg.addPoints(newPoint, newPoint2, [1, -2]);\r\n         *\r\n         * </pre><div id=\"JXG70eb0fd2-d20f-4ba9-9ab6-0eac92aabfa5\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG70eb0fd2-d20f-4ba9-9ab6-0eac92aabfa5',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});\r\n         *     var newPoint = board.create('point', [-1, -1]);\r\n         *     var newPoint2 = board.create('point', [-1, -2]);\r\n         *     pg.addPoints(newPoint, newPoint2, [1, -2]);\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        addPoints: function (p) {\r\n            var idx,\r\n                args = Array.prototype.slice.call(arguments);\r\n\r\n            if (this.elType === 'polygonalchain') {\r\n                idx = this.vertices.length - 1;\r\n            } else {\r\n                idx = this.vertices.length - 2;\r\n            }\r\n            return this.insertPoints.apply(this, [idx].concat(args));\r\n        },\r\n\r\n        /**\r\n         * Insert points to the vertex list of the polygon after index <tt>idx</tt>.\r\n         * The attributes of new border segments are set to the same values\r\n         * as those used when the polygon was created.\r\n         * If new vertices are supplied by coordinates, the default attributes of polygon\r\n         * vertices are taken as their attributes. Therefore, the visual attributes of\r\n         * new vertices and borders may have to be adapted afterwards.\r\n         *\r\n         * @param {Number} idx The position after which the new vertices are inserted.\r\n         * Setting idx to -1 inserts the new points at the front, i.e. at position 0.\r\n         * @param {JXG.Point} p Arbitrary number of points or coordinate arrays to insert.\r\n         * @returns {JXG.Polygon} Reference to the polygon object\r\n         *\r\n         * @example\r\n         * var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});\r\n         * var newPoint = board.create('point', [-1, -1]);\r\n         * pg.insertPoints(0, newPoint, newPoint, [1, -2]);\r\n         *\r\n         * </pre><div id=\"JXG17b84b2a-a851-4e3f-824f-7f6a60f166ca\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG17b84b2a-a851-4e3f-824f-7f6a60f166ca',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var pg = board.create('polygon', [[1,2], [3,4], [-3,1]], {hasInnerPoints: true});\r\n         *     var newPoint = board.create('point', [-1, -1]);\r\n         *     pg.insertPoints(0, newPoint, newPoint, [1, -2]);\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        insertPoints: function (idx, p) {\r\n            var i, le, last, start, q;\r\n\r\n            if (arguments.length === 0) {\r\n                return this;\r\n            }\r\n\r\n            last = this.vertices.length - 1;\r\n            if (this.elType === 'polygon') {\r\n                last--;\r\n            }\r\n\r\n            // Wrong insertion index, get out of here\r\n            if (idx < -1 || idx > last) {\r\n                return this;\r\n            }\r\n\r\n            le = arguments.length - 1;\r\n            for (i = 1; i < le + 1; i++) {\r\n                q = Type.providePoints(this.board, [arguments[i]], {}, \"polygon\", [\r\n                    \"vertices\"\r\n                ])[0];\r\n                if (q._is_new) {\r\n                    // Add the point as child of the polygon, but not of the borders.\r\n                    this.addChild(q);\r\n                    delete q._is_new;\r\n                }\r\n                this.vertices.splice(idx + i, 0, q);\r\n            }\r\n\r\n            if (this.withLines) {\r\n                start = idx + 1;\r\n                if (this.elType === 'polygon') {\r\n                    if (idx < 0) {\r\n                        // Add point(s) in the front\r\n                        this.vertices[this.vertices.length - 1] = this.vertices[0];\r\n                        this.borders[this.borders.length - 1].point2 =\r\n                            this.vertices[this.vertices.length - 1];\r\n                    } else {\r\n                        // Insert point(s) (middle or end)\r\n                        this.borders[idx].point2 = this.vertices[start];\r\n                    }\r\n                } else {\r\n                    // Add point(s) in the front: do nothing\r\n                    // Else:\r\n                    if (idx >= 0) {\r\n                        if (idx < this.borders.length) {\r\n                            // Insert point(s) in the middle\r\n                            this.borders[idx].point2 = this.vertices[start];\r\n                        } else {\r\n                            // Add point at the end\r\n                            start = idx;\r\n                        }\r\n                    }\r\n                }\r\n                for (i = start; i < start + le; i++) {\r\n                    this.borders.splice(\r\n                        i,\r\n                        0,\r\n                        this.board.create(\r\n                            \"segment\",\r\n                            [this.vertices[i], this.vertices[i + 1]],\r\n                            this.attr_line\r\n                        )\r\n                    );\r\n                }\r\n            }\r\n            this.inherits = [];\r\n            this.inherits.push(this.vertices, this.borders);\r\n            this.board.update();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Removes given set of vertices from the polygon\r\n         * @param {JXG.Point} p Arbitrary number of vertices as {@link JXG.Point} elements or index numbers\r\n         * @returns {JXG.Polygon} Reference to the polygon\r\n         */\r\n        removePoints: function (p) {\r\n            var i, j, idx,\r\n                firstPoint,\r\n                nvertices = [],\r\n                nborders = [],\r\n                nidx = [],\r\n                partition = [];\r\n\r\n            // Partition:\r\n            // in order to keep the borders which could be recycled, we have to partition\r\n            // the set of removed points. I.e. if the points 1, 2, 5, 6, 7, 10 are removed,\r\n            // the partitions are\r\n            //       1-2, 5-7, 10-10\r\n            // this gives us the borders, that can be removed and the borders we have to create.\r\n\r\n            // In case of polygon: remove the last vertex from the list of vertices since\r\n            // it is identical to the first\r\n            if (this.elType === 'polygon') {\r\n                firstPoint = this.vertices.pop();\r\n            }\r\n\r\n            // Collect all valid parameters as indices in nidx\r\n            for (i = 0; i < arguments.length; i++) {\r\n                idx = arguments[i];\r\n                if (Type.isPoint(idx)) {\r\n                    idx = this.findPoint(idx);\r\n                }\r\n                if (\r\n                    Type.isNumber(idx) &&\r\n                    idx > -1 &&\r\n                    idx < this.vertices.length &&\r\n                    Type.indexOf(nidx, idx) === -1\r\n                ) {\r\n                    nidx.push(idx);\r\n                }\r\n            }\r\n\r\n            if (nidx.length === 0) {\r\n                // Wrong index, get out of here\r\n                if (this.elType === 'polygon') {\r\n                    this.vertices.push(firstPoint);\r\n                }\r\n                return this;\r\n            }\r\n\r\n            // Remove the polygon from each removed point's children\r\n            for (i = 0; i < nidx.length; i++) {\r\n                this.vertices[nidx[i]].removeChild(this);\r\n            }\r\n\r\n            // Sort the elements to be eliminated\r\n            nidx = nidx.sort();\r\n            nvertices = this.vertices.slice();\r\n            nborders = this.borders.slice();\r\n\r\n            // Initialize the partition with an array containing the last point to be removed\r\n            if (this.withLines) {\r\n                partition.push([nidx[nidx.length - 1]]);\r\n            }\r\n\r\n            // Run through all existing vertices and copy all remaining ones to nvertices,\r\n            // compute the partition\r\n            for (i = nidx.length - 1; i > -1; i--) {\r\n                nvertices[nidx[i]] = -1;\r\n\r\n                // Find gaps between the list of points to be removed.\r\n                // In this case a new partition is added.\r\n                if (this.withLines && nidx.length > 1 && nidx[i] - 1 > nidx[i - 1]) {\r\n                    partition[partition.length - 1][1] = nidx[i];\r\n                    partition.push([nidx[i - 1]]);\r\n                }\r\n            }\r\n\r\n            // Finalize the partition computation\r\n            if (this.withLines) {\r\n                partition[partition.length - 1][1] = nidx[0];\r\n            }\r\n\r\n            // Update vertices\r\n            this.vertices = [];\r\n            for (i = 0; i < nvertices.length; i++) {\r\n                if (Type.isPoint(nvertices[i])) {\r\n                    this.vertices.push(nvertices[i]);\r\n                }\r\n            }\r\n\r\n            // Close the polygon again\r\n            if (\r\n                this.elType === \"polygon\" &&\r\n                this.vertices.length > 1 &&\r\n                this.vertices[this.vertices.length - 1].id !== this.vertices[0].id\r\n            ) {\r\n                this.vertices.push(this.vertices[0]);\r\n            }\r\n\r\n            // Delete obsolete and create missing borders\r\n            if (this.withLines) {\r\n                for (i = 0; i < partition.length; i++) {\r\n                    for (j = partition[i][1] - 1; j < partition[i][0] + 1; j++) {\r\n                        // special cases\r\n                        if (j < 0) {\r\n                            if (this.elType === 'polygon') {\r\n                                // First vertex is removed, so the last border has to be removed, too\r\n                                this.board.removeObject(this.borders[nborders.length - 1]);\r\n                                nborders[nborders.length - 1] = -1;\r\n                            }\r\n                        } else if (j < nborders.length) {\r\n                            this.board.removeObject(this.borders[j]);\r\n                            nborders[j] = -1;\r\n                        }\r\n                    }\r\n\r\n                    // Only create the new segment if it's not the closing border.\r\n                    // The closing border is getting a special treatment at the end.\r\n                    if (partition[i][1] !== 0 && partition[i][0] !== nvertices.length - 1) {\r\n                        // nborders[partition[i][0] - 1] = this.board.create('segment', [\r\n                        //             nvertices[Math.max(partition[i][1] - 1, 0)],\r\n                        //             nvertices[Math.min(partition[i][0] + 1, this.vertices.length - 1)]\r\n                        //         ], this.attr_line);\r\n                        nborders[partition[i][0] - 1] = this.board.create(\r\n                            \"segment\",\r\n                            [nvertices[partition[i][1] - 1], nvertices[partition[i][0] + 1]],\r\n                            this.attr_line\r\n                        );\r\n                    }\r\n                }\r\n\r\n                this.borders = [];\r\n                for (i = 0; i < nborders.length; i++) {\r\n                    if (nborders[i] !== -1) {\r\n                        this.borders.push(nborders[i]);\r\n                    }\r\n                }\r\n\r\n                // if the first and/or the last vertex is removed, the closing border is created at the end.\r\n                if (\r\n                    this.elType === \"polygon\" &&\r\n                    this.vertices.length > 2 && // Avoid trivial case of polygon with 1 vertex\r\n                    (partition[0][1] === this.vertices.length - 1 ||\r\n                        partition[partition.length - 1][1] === 0)\r\n                ) {\r\n                    this.borders.push(\r\n                        this.board.create(\r\n                            \"segment\",\r\n                            [this.vertices[this.vertices.length - 2], this.vertices[0]],\r\n                            this.attr_line\r\n                        )\r\n                    );\r\n                }\r\n            }\r\n            this.inherits = [];\r\n            this.inherits.push(this.vertices, this.borders);\r\n\r\n            this.board.update();\r\n\r\n            return this;\r\n        },\r\n\r\n        // documented in element.js\r\n        getParents: function () {\r\n            this.setParents(this.vertices);\r\n            return this.parents;\r\n        },\r\n\r\n        getAttributes: function () {\r\n            var attr = GeometryElement.prototype.getAttributes.call(this),\r\n                i;\r\n\r\n            if (this.withLines) {\r\n                attr.lines = attr.lines || {};\r\n                attr.lines.ids = [];\r\n                attr.lines.colors = [];\r\n\r\n                for (i = 0; i < this.borders.length; i++) {\r\n                    attr.lines.ids.push(this.borders[i].id);\r\n                    attr.lines.colors.push(this.borders[i].visProp.strokecolor);\r\n                }\r\n            }\r\n\r\n            return attr;\r\n        },\r\n\r\n        snapToGrid: function () {\r\n            var i, force;\r\n\r\n            if (this.evalVisProp('snaptogrid')) {\r\n                force = true;\r\n            } else {\r\n                force = false;\r\n            }\r\n\r\n            for (i = 0; i < this.vertices.length; i++) {\r\n                this.vertices[i].handleSnapToGrid(force, true);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Moves the polygon by the difference of two coordinates.\r\n         * @param {Number} method The type of coordinates used here. Possible values are {@link JXG.COORDS_BY_USER} and {@link JXG.COORDS_BY_SCREEN}.\r\n         * @param {Array} coords coordinates in screen/user units\r\n         * @param {Array} oldcoords previous coordinates in screen/user units\r\n         * @returns {JXG.Polygon} this element\r\n         */\r\n        setPositionDirectly: function (method, coords, oldcoords) {\r\n            var dc,\r\n                t,\r\n                i,\r\n                len,\r\n                c = new Coords(method, coords, this.board),\r\n                oldc = new Coords(method, oldcoords, this.board);\r\n\r\n            len = this.vertices.length - 1;\r\n            for (i = 0; i < len; i++) {\r\n                if (!this.vertices[i].draggable()) {\r\n                    return this;\r\n                }\r\n            }\r\n\r\n            dc = Statistics.subtract(c.usrCoords, oldc.usrCoords);\r\n            t = this.board.create(\"transform\", dc.slice(1), { type: \"translate\" });\r\n            t.applyOnce(this.vertices.slice(0, -1));\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Algorithm by Sutherland and Hodgman to compute the intersection of two convex polygons.\r\n         * The polygon itself is the clipping polygon, it expects as parameter a polygon to be clipped.\r\n         * See <a href=\"https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm\">wikipedia entry</a>.\r\n         * Called by {@link JXG.Polygon#intersect}.\r\n         *\r\n         * @private\r\n         *\r\n         * @param {JXG.Polygon} polygon Polygon which will be clipped.\r\n         *\r\n         * @returns {Array} of (normalized homogeneous user) coordinates (i.e. [z, x, y], where z==1 in most cases,\r\n         *   representing the vertices of the intersection polygon.\r\n         *\r\n         */\r\n        sutherlandHodgman: function (polygon) {\r\n            // First the two polygons are sorted counter clockwise\r\n            var clip = JXG.Math.Geometry.sortVertices(this.vertices), // \"this\" is the clipping polygon\r\n                subject = JXG.Math.Geometry.sortVertices(polygon.vertices), // \"polygon\" is the subject polygon\r\n                lenClip = clip.length - 1,\r\n                lenSubject = subject.length - 1,\r\n                lenIn,\r\n                outputList = [],\r\n                inputList,\r\n                i,\r\n                j,\r\n                S,\r\n                E,\r\n                cross,\r\n                // Determines if the point c3 is right of the line through c1 and c2.\r\n                // Since the polygons are sorted counter clockwise, \"right of\" and therefore >= is needed here\r\n                isInside = function (c1, c2, c3) {\r\n                    return (\r\n                        (c2[1] - c1[1]) * (c3[2] - c1[2]) - (c2[2] - c1[2]) * (c3[1] - c1[1]) >=\r\n                        0\r\n                    );\r\n                };\r\n\r\n            for (i = 0; i < lenSubject; i++) {\r\n                outputList.push(subject[i]);\r\n            }\r\n\r\n            for (i = 0; i < lenClip; i++) {\r\n                inputList = outputList.slice(0);\r\n                lenIn = inputList.length;\r\n                outputList = [];\r\n\r\n                S = inputList[lenIn - 1];\r\n\r\n                for (j = 0; j < lenIn; j++) {\r\n                    E = inputList[j];\r\n                    if (isInside(clip[i], clip[i + 1], E)) {\r\n                        if (!isInside(clip[i], clip[i + 1], S)) {\r\n                            cross = JXG.Math.Geometry.meetSegmentSegment(\r\n                                S,\r\n                                E,\r\n                                clip[i],\r\n                                clip[i + 1]\r\n                            );\r\n                            cross[0][1] /= cross[0][0];\r\n                            cross[0][2] /= cross[0][0];\r\n                            cross[0][0] = 1;\r\n                            outputList.push(cross[0]);\r\n                        }\r\n                        outputList.push(E);\r\n                    } else if (isInside(clip[i], clip[i + 1], S)) {\r\n                        cross = JXG.Math.Geometry.meetSegmentSegment(\r\n                            S,\r\n                            E,\r\n                            clip[i],\r\n                            clip[i + 1]\r\n                        );\r\n                        cross[0][1] /= cross[0][0];\r\n                        cross[0][2] /= cross[0][0];\r\n                        cross[0][0] = 1;\r\n                        outputList.push(cross[0]);\r\n                    }\r\n                    S = E;\r\n                }\r\n            }\r\n\r\n            return outputList;\r\n        },\r\n\r\n        /**\r\n         * Generic method for the intersection of this polygon with another polygon.\r\n         * The parent object is the clipping polygon, it expects as parameter a polygon to be clipped.\r\n         * Both polygons have to be convex.\r\n         * Calls the algorithm by Sutherland, Hodgman, {@link JXG.Polygon#sutherlandHodgman}.\r\n         * <p>\r\n         * An alternative is to use the methods from {@link JXG.Math.Clip}, where the algorithm by Greiner and Hormann\r\n         * is used.\r\n         *\r\n         * @param {JXG.Polygon} polygon Polygon which will be clipped.\r\n         *\r\n         * @returns {Array} of (normalized homogeneous user) coordinates (i.e. [z, x, y], where z==1 in most cases,\r\n         *   representing the vertices of the intersection polygon.\r\n         *\r\n         * @example\r\n         *  // Static intersection of two polygons pol1 and pol2\r\n         *  var pol1 = board.create('polygon', [[-2, 3], [-4, -3], [2, 0], [4, 4]], {\r\n         *                name:'pol1', withLabel: true,\r\n         *                fillColor: 'yellow'\r\n         *             });\r\n         *  var pol2 = board.create('polygon', [[-2, -3], [-4, 1], [0, 4], [5, 1]], {\r\n         *                name:'pol2', withLabel: true\r\n         *             });\r\n         *\r\n         *  // Static version:\r\n         *  // the intersection polygon does not adapt to changes of pol1 or pol2.\r\n         *  var pol3 = board.create('polygon', pol1.intersect(pol2), {fillColor: 'blue'});\r\n         * </pre><div class=\"jxgbox\" id=\"JXGd1fe5ea9-309f-494a-af07-ee3d033acb7c\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *   (function() {\r\n         *       var board = JXG.JSXGraph.initBoard('JXGd1fe5ea9-309f-494a-af07-ee3d033acb7c', {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *       // Intersect two polygons pol1 and pol2\r\n         *       var pol1 = board.create('polygon', [[-2, 3], [-4, -3], [2, 0], [4, 4]], {\r\n         *                name:'pol1', withLabel: true,\r\n         *                fillColor: 'yellow'\r\n         *             });\r\n         *       var pol2 = board.create('polygon', [[-2, -3], [-4, 1], [0, 4], [5, 1]], {\r\n         *                name:'pol2', withLabel: true\r\n         *             });\r\n         *\r\n         *       // Static version: the intersection polygon does not adapt to changes of pol1 or pol2.\r\n         *       var pol3 = board.create('polygon', pol1.intersect(pol2), {fillColor: 'blue'});\r\n         *   })();\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         *  // Dynamic intersection of two polygons pol1 and pol2\r\n         *  var pol1 = board.create('polygon', [[-2, 3], [-4, -3], [2, 0], [4, 4]], {\r\n         *                name:'pol1', withLabel: true,\r\n         *                fillColor: 'yellow'\r\n         *             });\r\n         *  var pol2 = board.create('polygon', [[-2, -3], [-4, 1], [0, 4], [5, 1]], {\r\n         *                name:'pol2', withLabel: true\r\n         *             });\r\n         *\r\n         *  // Dynamic version:\r\n         *  // the intersection polygon does adapt to changes of pol1 or pol2.\r\n         *  // For this a curve element is used.\r\n         *  var curve = board.create('curve', [[],[]], {fillColor: 'blue', fillOpacity: 0.4});\r\n         *  curve.updateDataArray = function() {\r\n         *      var mat = JXG.Math.transpose(pol1.intersect(pol2));\r\n         *\r\n         *      if (mat.length == 3) {\r\n         *          this.dataX = mat[1];\r\n         *          this.dataY = mat[2];\r\n         *      } else {\r\n         *          this.dataX = [];\r\n         *          this.dataY = [];\r\n         *      }\r\n         *  };\r\n         *  board.update();\r\n         * </pre><div class=\"jxgbox\" id=\"JXGf870d516-ca1a-4140-8fe3-5d64fb42e5f2\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *   (function() {\r\n         *       var board = JXG.JSXGraph.initBoard('JXGf870d516-ca1a-4140-8fe3-5d64fb42e5f2', {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *       // Intersect two polygons pol1 and pol2\r\n         *       var pol1 = board.create('polygon', [[-2, 3], [-4, -3], [2, 0], [4, 4]], {\r\n         *                name:'pol1', withLabel: true,\r\n         *                fillColor: 'yellow'\r\n         *             });\r\n         *       var pol2 = board.create('polygon', [[-2, -3], [-4, 1], [0, 4], [5, 1]], {\r\n         *                name:'pol2', withLabel: true\r\n         *             });\r\n         *\r\n         *  // Dynamic version:\r\n         *  // the intersection polygon does  adapt to changes of pol1 or pol2.\r\n         *  // For this a curve element is used.\r\n         *    var curve = board.create('curve', [[],[]], {fillColor: 'blue', fillOpacity: 0.4});\r\n         *    curve.updateDataArray = function() {\r\n         *        var mat = JXG.Math.transpose(pol1.intersect(pol2));\r\n         *\r\n         *        if (mat.length == 3) {\r\n         *            this.dataX = mat[1];\r\n         *            this.dataY = mat[2];\r\n         *        } else {\r\n         *            this.dataX = [];\r\n         *            this.dataY = [];\r\n         *        }\r\n         *    };\r\n         *    board.update();\r\n         *   })();\r\n         * </script><pre>\r\n         *\r\n         */\r\n        intersect: function (polygon) {\r\n            return this.sutherlandHodgman(polygon);\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * @class A polygon is a plane figure made up of line segments (the borders) connected\r\n * to form a closed polygonal chain.\r\n * It is determined by\r\n * <ul>\r\n *    <li> a list of points or\r\n *    <li> a list of coordinate arrays or\r\n *    <li> a function returning a list of coordinate arrays.\r\n * </ul>\r\n * Each two consecutive points of the list define a line.\r\n * @pseudo\r\n * @constructor\r\n * @name Polygon\r\n * @type JXG.Polygon\r\n * @augments JXG.Polygon\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Array} vertices The polygon's vertices. If the first and the last vertex don't match the first one will be\r\n * added to the array by the creator. Here, two points match if they have the same 'id' attribute.\r\n *\r\n * Additionally, a polygon can be created by providing a polygon and a transformation (or an array of transformations).\r\n * The result is a polygon which is the transformation of the supplied polygon.\r\n *\r\n * @example\r\n * var p1 = board.create('point', [0.0, 2.0]);\r\n * var p2 = board.create('point', [2.0, 1.0]);\r\n * var p3 = board.create('point', [4.0, 6.0]);\r\n * var p4 = board.create('point', [1.0, 4.0]);\r\n *\r\n * var pol = board.create('polygon', [p1, p2, p3, p4]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG682069e9-9e2c-4f63-9b73-e26f8a2b2bb1\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *  (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG682069e9-9e2c-4f63-9b73-e26f8a2b2bb1', {boundingbox: [-1, 9, 9, -1], axis: false, showcopyright: false, shownavigation: false}),\r\n *       p1 = board.create('point', [0.0, 2.0]),\r\n *       p2 = board.create('point', [2.0, 1.0]),\r\n *       p3 = board.create('point', [4.0, 6.0]),\r\n *       p4 = board.create('point', [1.0, 4.0]),\r\n *       cc1 = board.create('polygon', [p1, p2, p3, p4]);\r\n *  })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * var p = [[0.0, 2.0], [2.0, 1.0], [4.0, 6.0], [1.0, 3.0]];\r\n *\r\n * var pol = board.create('polygon', p, {hasInnerPoints: true});\r\n * </pre><div class=\"jxgbox\" id=\"JXG9f9a5946-112a-4768-99ca-f30792bcdefb\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *  (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG9f9a5946-112a-4768-99ca-f30792bcdefb', {boundingbox: [-1, 9, 9, -1], axis: false, showcopyright: false, shownavigation: false}),\r\n *       p = [[0.0, 2.0], [2.0, 1.0], [4.0, 6.0], [1.0, 4.0]],\r\n *       cc1 = board.create('polygon', p, {hasInnerPoints: true});\r\n *  })();\r\n * </script><pre>\r\n *\r\n * @example\r\n *   var f1 = function() { return [0.0, 2.0]; },\r\n *       f2 = function() { return [2.0, 1.0]; },\r\n *       f3 = function() { return [4.0, 6.0]; },\r\n *       f4 = function() { return [1.0, 4.0]; },\r\n *       cc1 = board.create('polygon', [f1, f2, f3, f4]);\r\n *       board.update();\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXGceb09915-b783-44db-adff-7877ae3534c8\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *  (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXGceb09915-b783-44db-adff-7877ae3534c8', {boundingbox: [-1, 9, 9, -1], axis: false, showcopyright: false, shownavigation: false}),\r\n *       f1 = function() { return [0.0, 2.0]; },\r\n *       f2 = function() { return [2.0, 1.0]; },\r\n *       f3 = function() { return [4.0, 6.0]; },\r\n *       f4 = function() { return [1.0, 4.0]; },\r\n *       cc1 = board.create('polygon', [f1, f2, f3, f4]);\r\n *       board.update();\r\n *  })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * var t = board.create('transform', [2, 1.5], {type: 'scale'});\r\n * var a = board.create('point', [-3,-2], {name: 'a'});\r\n * var b = board.create('point', [-1,-4], {name: 'b'});\r\n * var c = board.create('point', [-2,-0.5], {name: 'c'});\r\n * var pol1 = board.create('polygon', [a,b,c], {vertices: {withLabel: false}});\r\n * var pol2 = board.create('polygon', [pol1, t], {vertices: {withLabel: true}});\r\n *\r\n * </pre><div id=\"JXG6530a69c-6339-11e8-9fb9-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG6530a69c-6339-11e8-9fb9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var t = board.create('transform', [2, 1.5], {type: 'scale'});\r\n *     var a = board.create('point', [-3,-2], {name: 'a'});\r\n *     var b = board.create('point', [-1,-4], {name: 'b'});\r\n *     var c = board.create('point', [-2,-0.5], {name: 'c'});\r\n *     var pol1 = board.create('polygon', [a,b,c], {vertices: {withLabel: false}});\r\n *     var pol2 = board.create('polygon', [pol1, t], {vertices: {withLabel: true}});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createPolygon = function (board, parents, attributes) {\r\n    var el, i, le, obj,\r\n        points = [],\r\n        attr,\r\n        attr_points,\r\n        is_transform = false;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'polygon');\r\n    obj = board.select(parents[0]);\r\n    if (obj === null) {\r\n        // This is necessary if the original polygon is defined in another board.\r\n        obj = parents[0];\r\n    }\r\n    if (\r\n        Type.isObject(obj) &&\r\n        obj.type === Const.OBJECT_TYPE_POLYGON &&\r\n        Type.isTransformationOrArray(parents[1])\r\n    ) {\r\n        is_transform = true;\r\n        le = obj.vertices.length - 1;\r\n        attr_points = Type.copyAttributes(attributes, board.options, \"polygon\", 'vertices');\r\n        for (i = 0; i < le; i++) {\r\n            if (attr_points.withlabel) {\r\n                attr_points.name =\r\n                    obj.vertices[i].name === \"\" ? \"\" : obj.vertices[i].name + \"'\";\r\n            }\r\n            points.push(board.create(\"point\", [obj.vertices[i], parents[1]], attr_points));\r\n        }\r\n    } else {\r\n        points = Type.providePoints(board, parents, attributes, \"polygon\", [\"vertices\"]);\r\n        if (points === false) {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create polygon / polygonalchain with parent types other than 'point' and 'coordinate arrays' or a function returning an array of coordinates. Alternatively, a polygon and a transformation can be supplied\"\r\n            );\r\n        }\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'polygon');\r\n    el = new JXG.Polygon(board, points, attr);\r\n    el.isDraggable = true;\r\n\r\n    // Put the points to their position\r\n    if (is_transform) {\r\n        el.prepareUpdate().update().updateVisibility().updateRenderer();\r\n        le = obj.vertices.length - 1;\r\n        for (i = 0; i < le; i++) {\r\n            points[i].prepareUpdate().update().updateVisibility().updateRenderer();\r\n        }\r\n    }\r\n\r\n    return el;\r\n};\r\n\r\n/**\r\n * @class A regular polygon is a polygon that is\r\n * direct equiangular (all angles are equal in measure) and equilateral (all sides have the same length).\r\n * It needs two points which define the base line and the number of vertices.\r\n * @pseudo\r\n * @description Constructs a regular polygon. It needs two points which define the base line and the number of vertices, or a set of points.\r\n * @constructor\r\n * @name RegularPolygon\r\n * @type Polygon\r\n * @augments Polygon\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_Number} p1,p2,n The constructed regular polygon has n vertices and the base line defined by p1 and p2.\r\n * @example\r\n * var p1 = board.create('point', [0.0, 2.0]);\r\n * var p2 = board.create('point', [2.0, 1.0]);\r\n *\r\n * var pol = board.create('regularpolygon', [p1, p2, 5]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG682069e9-9e2c-4f63-9b73-e26f8a2b2bb1\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *  (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG682069e9-9e2c-4f63-9b73-e26f8a2b2bb1', {boundingbox: [-1, 9, 9, -1], axis: false, showcopyright: false, shownavigation: false}),\r\n *       p1 = board.create('point', [0.0, 2.0]),\r\n *       p2 = board.create('point', [2.0, 1.0]),\r\n *       cc1 = board.create('regularpolygon', [p1, p2, 5]);\r\n *  })();\r\n * </script><pre>\r\n * @example\r\n * var p1 = board.create('point', [0.0, 2.0]);\r\n * var p2 = board.create('point', [4.0,4.0]);\r\n * var p3 = board.create('point', [2.0,0.0]);\r\n *\r\n * var pol = board.create('regularpolygon', [p1, p2, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG096a78b3-bd50-4bac-b958-3be5e7df17ed\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG096a78b3-bd50-4bac-b958-3be5e7df17ed', {boundingbox: [-1, 9, 9, -1], axis: false, showcopyright: false, shownavigation: false}),\r\n *       p1 = board.create('point', [0.0, 2.0]),\r\n *       p2 = board.create('point', [4.0, 4.0]),\r\n *       p3 = board.create('point', [2.0,0.0]),\r\n *       cc1 = board.create('regularpolygon', [p1, p2, p3]);\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n *         // Line of reflection\r\n *         var li = board.create('line', [1,1,1], {strokeColor: '#aaaaaa'});\r\n *         var reflect = board.create('transform', [li], {type: 'reflect'});\r\n *         var pol1 = board.create('polygon', [[-3,-2], [-1,-4], [-2,-0.5]]);\r\n *         var pol2 = board.create('polygon', [pol1, reflect]);\r\n *\r\n * </pre><div id=\"JXG58fc3078-d8d1-11e7-93b3-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG58fc3078-d8d1-11e7-93b3-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *             var li = board.create('line', [1,1,1], {strokeColor: '#aaaaaa'});\r\n *             var reflect = board.create('transform', [li], {type: 'reflect'});\r\n *             var pol1 = board.create('polygon', [[-3,-2], [-1,-4], [-2,-0.5]]);\r\n *             var pol2 = board.create('polygon', [pol1, reflect]);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createRegularPolygon = function (board, parents, attributes) {\r\n    var el, i, n,\r\n        p = [],\r\n        rot, len,\r\n        pointsExist,\r\n        attr;\r\n\r\n    len = parents.length;\r\n    n = parents[len - 1];\r\n\r\n    if (Type.isNumber(n) && (parents.length !== 3 || n < 3)) {\r\n        throw new Error(\r\n            \"JSXGraph: A regular polygon needs two point types and a number > 2 as input.\"\r\n        );\r\n    }\r\n\r\n    if (Type.isNumber(board.select(n))) {\r\n        // Regular polygon given by 2 points and a number\r\n        len--;\r\n        pointsExist = false;\r\n    } else {\r\n        // Regular polygon given by n points\r\n        n = len;\r\n        pointsExist = true;\r\n    }\r\n\r\n    p = Type.providePoints(board, parents.slice(0, len), attributes, \"regularpolygon\", [\r\n        \"vertices\"\r\n    ]);\r\n    if (p === false) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create regular polygon with parent types other than 'point' and 'coordinate arrays' or a function returning an array of coordinates\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, \"regularpolygon\", 'vertices');\r\n    for (i = 2; i < n; i++) {\r\n        rot = board.create(\"transform\", [Math.PI * (2 - (n - 2) / n), p[i - 1]], {\r\n            type: \"rotate\"\r\n        });\r\n        if (pointsExist) {\r\n            p[i].addTransform(p[i - 2], rot);\r\n            p[i].fullUpdate();\r\n        } else {\r\n            if (Type.isArray(attr.ids) && attr.ids.length >= n - 2) {\r\n                attr.id = attr.ids[i - 2];\r\n            }\r\n            p[i] = board.create(\"point\", [p[i - 2], rot], attr);\r\n            p[i].type = Const.OBJECT_TYPE_CAS;\r\n\r\n            // The next two lines of code are needed to make regular polygons draggable\r\n            // The new helper points are set to be draggable.\r\n            p[i].isDraggable = true;\r\n            p[i].visProp.fixed = false;\r\n        }\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'regularpolygon');\r\n    el = board.create(\"polygon\", p, attr);\r\n    el.elType = 'regularpolygon';\r\n\r\n    return el;\r\n};\r\n\r\n/**\r\n * @class  A polygonal chain is a connected series of line segments (borders).\r\n * It is determined by\r\n * <ul>\r\n *    <li> a list of points or\r\n *    <li> a list of coordinate arrays or\r\n *    <li> a function returning a list of coordinate arrays.\r\n * </ul>\r\n * Each two consecutive points of the list define a line.\r\n * In JSXGraph, a polygonal chain is simply realized as polygon without the last - closing - point.\r\n * This may lead to unexpected results. Polygonal chains can be distinguished from polygons by the attribute 'elType' which\r\n * is 'polygonalchain' for the first and 'polygon' for the latter.\r\n * @pseudo\r\n * @constructor\r\n * @name PolygonalChain\r\n * @type Polygon\r\n * @augments JXG.Polygon\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Array} vertices The polygon's vertices.\r\n *\r\n * Additionally, a polygonal chain can be created by providing a polygonal chain and a transformation (or an array of transformations).\r\n * The result is a polygonal chain which is the transformation of the supplied polygonal chain.\r\n *\r\n * @example\r\n *     var attr = {\r\n *             snapToGrid: true\r\n *         },\r\n *         p = [];\r\n *\r\n * \tp.push(board.create('point', [-4, 0], attr));\r\n * \tp.push(board.create('point', [-1, -3], attr));\r\n * \tp.push(board.create('point', [0, 2], attr));\r\n * \tp.push(board.create('point', [2, 1], attr));\r\n * \tp.push(board.create('point', [4, -2], attr));\r\n *\r\n *  var chain = board.create('polygonalchain', p, {borders: {strokeWidth: 3}});\r\n *\r\n * </pre><div id=\"JXG878f93d8-3e49-46cf-aca2-d3bb7d60c5ae\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG878f93d8-3e49-46cf-aca2-d3bb7d60c5ae',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *         var attr = {\r\n *                 snapToGrid: true\r\n *             },\r\n *             p = [];\r\n *\r\n *     \tp.push(board.create('point', [-4, 0], attr));\r\n *     \tp.push(board.create('point', [-1, -3], attr));\r\n *     \tp.push(board.create('point', [0, 2], attr));\r\n *     \tp.push(board.create('point', [2, 1], attr));\r\n *     \tp.push(board.create('point', [4, -2], attr));\r\n *\r\n *         var chain = board.create('polygonalchain', p, {borders: {strokeWidth: 3}});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createPolygonalChain = function (board, parents, attributes) {\r\n    var attr, el;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'polygonalchain');\r\n    el = board.create(\"polygon\", parents, attr);\r\n    el.elType = 'polygonalchain';\r\n\r\n    // A polygonal chain is not necessarily closed.\r\n    el.vertices.pop();\r\n    board.removeObject(el.borders[el.borders.length - 1]);\r\n    el.borders.pop();\r\n\r\n    return el;\r\n};\r\n\r\n/**\r\n * @class A quadrilateral polygon with parallel opposite sides.\r\n * @pseudo\r\n * @description Constructs a parallelogram. As input, three points or coordinate arrays are expected.\r\n * @constructor\r\n * @name Parallelogram\r\n * @type Polygon\r\n * @augments Polygon\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point,Array_JXG.Point,Array_JXG.Point,Array} p1,p2,p3 The parallelogram is a polygon through\r\n * the points [p1, p2, pp, p3], where pp is a parallelpoint, available as sub-object parallelogram.parallelPoint.\r\n *\r\n * @example\r\n * var p1 = board.create('point', [-3, -4]);\r\n * var p2 = board.create('point', [3, -1]);\r\n * var p3 = board.create('point', [-2, 0]);\r\n * var par = board.create('parallelogram', [p1, p2, p3], {\r\n *     hasInnerPoints: true,\r\n *     parallelpoint: {\r\n *         size: 6,\r\n *         face: '<<>>'\r\n *     }\r\n * });\r\n *\r\n * </pre><div id=\"JXG05ff162f-7cee-4fd2-bd90-3d9ee5b489cc\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG05ff162f-7cee-4fd2-bd90-3d9ee5b489cc',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p1 = board.create('point', [-3, -4]);\r\n *     var p2 = board.create('point', [3, -1]);\r\n *     var p3 = board.create('point', [-2, 0]);\r\n *     var par = board.create('parallelogram', [p1, p2, p3], {\r\n *         hasInnerPoints: true,\r\n *         parallelpoint: {\r\n *             size: 6,\r\n *             face: '<<>>'\r\n *         }\r\n *     });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n *\r\n */\r\nJXG.createParallelogram = function (board, parents, attributes) {\r\n    var el, pp,\r\n        points = [],\r\n        attr,\r\n        attr_pp;\r\n\r\n    points = Type.providePoints(board, parents, attributes, \"polygon\", [\"vertices\"]);\r\n    if (points === false || points.length < 3) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create parallelogram with parent types other than 'point' and 'coordinate arrays' or a function returning an array of coordinates.\"\r\n        );\r\n    }\r\n\r\n    attr_pp = Type.copyAttributes(attributes, board.options, \"parallelogram\", 'parallelpoint');\r\n    pp = board.create('parallelpoint', points, attr_pp);\r\n    attr = Type.copyAttributes(attributes, board.options, 'parallelogram');\r\n    el = board.create('polygon', [points[0], points[1], pp, points[2]], attr);\r\n\r\n    el.elType = 'parallelogram';\r\n\r\n    /**\r\n     * Parallel point which makes the quadrilateral a parallelogram. Can also be accessed with\r\n     * parallelogram.vertices[2].\r\n     * @name Parallelogram#parallelPoint\r\n     * @type {JXG.Point}\r\n     */\r\n    el.parallelPoint = pp;\r\n\r\n    el.isDraggable = true;\r\n    pp.isDraggable = true;\r\n    pp.visProp.fixed = false;\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"polygon\", JXG.createPolygon);\r\nJXG.registerElement(\"regularpolygon\", JXG.createRegularPolygon);\r\nJXG.registerElement(\"polygonalchain\", JXG.createPolygonalChain);\r\nJXG.registerElement(\"parallelogram\", JXG.createParallelogram);\r\n\r\nexport default JXG.Polygon;\r\n// export default {\r\n//     Polygon: JXG.Polygon,\r\n//     createPolygon: JXG.createPolygon,\r\n//     createRegularPolygon: JXG.createRegularPolygon\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview In this file the geometry element Curve is defined.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Clip from \"../math/clip.js\";\r\nimport Const from \"./constants.js\";\r\nimport Coords from \"./coords.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport GeometryElement from \"./element.js\";\r\nimport GeonextParser from \"../parser/geonext.js\";\r\nimport ImplicitPlot from \"../math/implicitplot.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Metapost from \"../math/metapost.js\";\r\nimport Numerics from \"../math/numerics.js\";\r\nimport Plot from \"../math/plot.js\";\r\nimport QDT from \"../math/qdt.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Curves are the common object for function graphs, parametric curves, polar curves, and data plots.\r\n * @class Creates a new curve object. Do not use this constructor to create a curve. Use {@link JXG.Board#create} with\r\n * type {@link Curve}, or {@link Functiongraph} instead.\r\n * @augments JXG.GeometryElement\r\n * @param {String|JXG.Board} board The board the new curve is drawn on.\r\n * @param {Array} parents defining terms An array with the function terms or the data points of the curve.\r\n * @param {Object} attributes Defines the visual appearance of the curve.\r\n * @see JXG.Board#generateName\r\n * @see JXG.Board#addCurve\r\n */\r\nJXG.Curve = function (board, parents, attributes) {\r\n    this.constructor(board, attributes, Const.OBJECT_TYPE_CURVE, Const.OBJECT_CLASS_CURVE);\r\n\r\n    this.points = [];\r\n    /**\r\n     * Number of points on curves. This value changes\r\n     * between numberPointsLow and numberPointsHigh.\r\n     * It is set in {@link JXG.Curve#updateCurve}.\r\n     */\r\n    this.numberPoints = this.evalVisProp('numberpointshigh');\r\n\r\n    this.bezierDegree = 1;\r\n\r\n    /**\r\n     * Array holding the x-coordinates of a data plot.\r\n     * This array can be updated during run time by overwriting\r\n     * the method {@link JXG.Curve#updateDataArray}.\r\n     * @type array\r\n     */\r\n    this.dataX = null;\r\n\r\n    /**\r\n     * Array holding the y-coordinates of a data plot.\r\n     * This array can be updated during run time by overwriting\r\n     * the method {@link JXG.Curve#updateDataArray}.\r\n     * @type array\r\n     */\r\n    this.dataY = null;\r\n\r\n    /**\r\n     * Array of ticks storing all the ticks on this curve. Do not set this field directly and use\r\n     * {@link JXG.Curve#addTicks} and {@link JXG.Curve#removeTicks} to add and remove ticks to and\r\n     * from the curve.\r\n     * @type Array\r\n     * @see JXG.Ticks\r\n     */\r\n    this.ticks = [];\r\n\r\n    /**\r\n     * Stores a quadtree if it is required. The quadtree is generated in the curve\r\n     * updates and can be used to speed up the hasPoint method.\r\n     * @type JXG.Math.Quadtree\r\n     */\r\n    this.qdt = null;\r\n\r\n    if (Type.exists(parents[0])) {\r\n        this.varname = parents[0];\r\n    } else {\r\n        this.varname = 'x';\r\n    }\r\n\r\n    // function graphs: \"x\"\r\n    this.xterm = parents[1];\r\n    // function graphs: e.g. \"x^2\"\r\n    this.yterm = parents[2];\r\n\r\n    // Converts GEONExT syntax into JavaScript syntax\r\n    this.generateTerm(this.varname, this.xterm, this.yterm, parents[3], parents[4]);\r\n    // First evaluation of the curve\r\n    this.updateCurve();\r\n\r\n    this.id = this.board.setId(this, 'G');\r\n    this.board.renderer.drawCurve(this);\r\n\r\n    this.board.finalizeAdding(this);\r\n\r\n    this.createGradient();\r\n    this.elType = 'curve';\r\n    this.createLabel();\r\n\r\n    if (Type.isString(this.xterm)) {\r\n        this.notifyParents(this.xterm);\r\n    }\r\n    if (Type.isString(this.yterm)) {\r\n        this.notifyParents(this.yterm);\r\n    }\r\n\r\n    this.methodMap = Type.deepCopy(this.methodMap, {\r\n        generateTerm: \"generateTerm\",\r\n        setTerm: \"generateTerm\",\r\n        move: \"moveTo\",\r\n        moveTo: \"moveTo\",\r\n        MinX: \"minX\",\r\n        MaxX: \"maxX\"\r\n    });\r\n};\r\n\r\nJXG.Curve.prototype = new GeometryElement();\r\n\r\nJXG.extend(\r\n    JXG.Curve.prototype,\r\n    /** @lends JXG.Curve.prototype */ {\r\n        /**\r\n         * Gives the default value of the left bound for the curve.\r\n         * May be overwritten in {@link JXG.Curve#generateTerm}.\r\n         * @returns {Number} Left bound for the curve.\r\n         */\r\n        minX: function () {\r\n            var leftCoords;\r\n\r\n            if (this.evalVisProp('curvetype') === 'polar') {\r\n                return 0;\r\n            }\r\n\r\n            leftCoords = new Coords(\r\n                Const.COORDS_BY_SCREEN,\r\n                [-this.board.canvasWidth * 0.1, 0],\r\n                this.board,\r\n                false\r\n            );\r\n            return leftCoords.usrCoords[1];\r\n        },\r\n\r\n        /**\r\n         * Gives the default value of the right bound for the curve.\r\n         * May be overwritten in {@link JXG.Curve#generateTerm}.\r\n         * @returns {Number} Right bound for the curve.\r\n         */\r\n        maxX: function () {\r\n            var rightCoords;\r\n\r\n            if (this.evalVisProp('curvetype') === 'polar') {\r\n                return 2 * Math.PI;\r\n            }\r\n            rightCoords = new Coords(\r\n                Const.COORDS_BY_SCREEN,\r\n                [this.board.canvasWidth * 1.1, 0],\r\n                this.board,\r\n                false\r\n            );\r\n\r\n            return rightCoords.usrCoords[1];\r\n        },\r\n\r\n        /**\r\n         * The parametric function which defines the x-coordinate of the curve.\r\n         * @param {Number} t A number between {@link JXG.Curve#minX} and {@link JXG.Curve#maxX}.\r\n         * @param {Boolean} suspendUpdate A boolean flag which is false for the\r\n         * first call of the function during a fresh plot of the curve and true\r\n         * for all subsequent calls of the function. This may be used to speed up the\r\n         * plotting of the curve, if the e.g. the curve depends on some input elements.\r\n         * @returns {Number} x-coordinate of the curve at t.\r\n         */\r\n        X: function (t) {\r\n            return NaN;\r\n        },\r\n\r\n        /**\r\n         * The parametric function which defines the y-coordinate of the curve.\r\n         * @param {Number} t A number between {@link JXG.Curve#minX} and {@link JXG.Curve#maxX}.\r\n         * @param {Boolean} suspendUpdate A boolean flag which is false for the\r\n         * first call of the function during a fresh plot of the curve and true\r\n         * for all subsequent calls of the function. This may be used to speed up the\r\n         * plotting of the curve, if the e.g. the curve depends on some input elements.\r\n         * @returns {Number} y-coordinate of the curve at t.\r\n         */\r\n        Y: function (t) {\r\n            return NaN;\r\n        },\r\n\r\n        /**\r\n         * Treat the curve as curve with homogeneous coordinates.\r\n         * @param {Number} t A number between {@link JXG.Curve#minX} and {@link JXG.Curve#maxX}.\r\n         * @returns {Number} Always 1.0\r\n         */\r\n        Z: function (t) {\r\n            return 1;\r\n        },\r\n\r\n        /**\r\n         * Return the homogeneous coordinates of the curve at t - including all transformations\r\n         * applied to the curve.\r\n         * @param {Number} t A number between {@link JXG.Curve#minX} and {@link JXG.Curve#maxX}.\r\n         * @returns {Array} [Z(t), X(t), Y(t)] plus transformations\r\n         */\r\n        Ft: function(t) {\r\n            var c = [this.Z(t), this.X(t), this.Y(t)],\r\n                len = this.transformations.length;\r\n\r\n            if (len > 0) {\r\n                c = Mat.matVecMult(this.transformMat, c);\r\n            }\r\n            c[1] /= c[0];\r\n            c[2] /= c[0];\r\n            c[0] /= c[0];\r\n\r\n            return c;\r\n        },\r\n\r\n        /**\r\n         * Checks whether (x,y) is near the curve.\r\n         * @param {Number} x Coordinate in x direction, screen coordinates.\r\n         * @param {Number} y Coordinate in y direction, screen coordinates.\r\n         * @param {Number} start Optional start index for search on data plots.\r\n         * @returns {Boolean} True if (x,y) is near the curve, False otherwise.\r\n         */\r\n        hasPoint: function (x, y, start) {\r\n            var t, c, i, tX, tY,\r\n                checkPoint, len, invMat, isIn,\r\n                res = [],\r\n                points,\r\n                qdt,\r\n                steps = this.evalVisProp('numberpointslow'),\r\n                d = (this.maxX() - this.minX()) / steps,\r\n                prec, type,\r\n                dist = Infinity,\r\n                ux2, uy2,\r\n                ev_ct,\r\n                mi, ma,\r\n                suspendUpdate = true;\r\n\r\n            if (Type.isObject(this.evalVisProp('precision'))) {\r\n                type = this.board._inputDevice;\r\n                prec = this.evalVisProp('precision.' + type);\r\n            } else {\r\n                // 'inherit'\r\n                prec = this.board.options.precision.hasPoint;\r\n            }\r\n\r\n            // From now on, x,y are usrCoords\r\n            checkPoint = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board, false);\r\n            x = checkPoint.usrCoords[1];\r\n            y = checkPoint.usrCoords[2];\r\n\r\n            // Handle inner points of the curve\r\n            if (this.bezierDegree === 1 && this.evalVisProp('hasinnerpoints')) {\r\n                isIn = Geometry.windingNumber([1, x, y], this.points, true);\r\n                if (isIn !== 0) {\r\n                    return true;\r\n                }\r\n            }\r\n\r\n            // We use usrCoords. Only in the final distance calculation\r\n            // screen coords are used\r\n            prec += this.evalVisProp('strokewidth') * 0.5;\r\n            prec *= prec; // We do not want to take sqrt\r\n            ux2 = this.board.unitX * this.board.unitX;\r\n            uy2 = this.board.unitY * this.board.unitY;\r\n\r\n            mi = this.minX();\r\n            ma = this.maxX();\r\n            if (Type.exists(this._visibleArea)) {\r\n                mi = this._visibleArea[0];\r\n                ma = this._visibleArea[1];\r\n                d = (ma - mi) / steps;\r\n            }\r\n\r\n            ev_ct = this.evalVisProp('curvetype');\r\n            if (ev_ct === \"parameter\" || ev_ct === 'polar') {\r\n                // Transform the mouse/touch coordinates\r\n                // back to the original position of the curve.\r\n                // This is needed, because we work with the function terms, not the points.\r\n                if (this.transformations.length > 0) {\r\n                    this.updateTransformMatrix();\r\n                    invMat = Mat.inverse(this.transformMat);\r\n                    c = Mat.matVecMult(invMat, [1, x, y]);\r\n                    x = c[1];\r\n                    y = c[2];\r\n                }\r\n\r\n                // Brute force search for a point on the curve close to the mouse pointer\r\n                for (i = 0, t = mi; i < steps; i++) {\r\n                    tX = this.X(t, suspendUpdate);\r\n                    tY = this.Y(t, suspendUpdate);\r\n\r\n                    dist = (x - tX) * (x - tX) * ux2 + (y - tY) * (y - tY) * uy2;\r\n\r\n                    if (dist <= prec) {\r\n                        return true;\r\n                    }\r\n\r\n                    t += d;\r\n                }\r\n            } else if (ev_ct === \"plot\" || ev_ct === 'functiongraph') {\r\n                // Here, we can ignore transformations of the curve,\r\n                // since we are working directly with the points.\r\n\r\n                if (!Type.exists(start) || start < 0) {\r\n                    start = 0;\r\n                }\r\n\r\n                if (\r\n                    Type.exists(this.qdt) &&\r\n                    this.evalVisProp('useqdt') &&\r\n                    this.bezierDegree !== 3\r\n                ) {\r\n                    qdt = this.qdt.query(new Coords(Const.COORDS_BY_USER, [x, y], this.board));\r\n                    points = qdt.points;\r\n                    len = points.length;\r\n                } else {\r\n                    points = this.points;\r\n                    len = this.numberPoints - 1;\r\n                }\r\n\r\n                for (i = start; i < len; i++) {\r\n                    if (this.bezierDegree === 3) {\r\n                        //res.push(Geometry.projectCoordsToBeziersegment([1, x, y], this, i));\r\n                        res = Geometry.projectCoordsToBeziersegment([1, x, y], this, i);\r\n                    } else {\r\n                        if (qdt) {\r\n                            if (points[i].prev) {\r\n                                res = Geometry.projectCoordsToSegment(\r\n                                    [1, x, y],\r\n                                    points[i].prev.usrCoords,\r\n                                    points[i].usrCoords\r\n                                );\r\n                            }\r\n\r\n                            // If the next point in the array is the same as the current points\r\n                            // next neighbor we don't have to project it onto that segment because\r\n                            // that will already be done in the next iteration of this loop.\r\n                            if (points[i].next && points[i + 1] !== points[i].next) {\r\n                                res = Geometry.projectCoordsToSegment(\r\n                                    [1, x, y],\r\n                                    points[i].usrCoords,\r\n                                    points[i].next.usrCoords\r\n                                );\r\n                            }\r\n                        } else {\r\n                            res = Geometry.projectCoordsToSegment(\r\n                                [1, x, y],\r\n                                points[i].usrCoords,\r\n                                points[i + 1].usrCoords\r\n                            );\r\n                        }\r\n                    }\r\n\r\n                    if (\r\n                        res[1] >= 0 &&\r\n                        res[1] <= 1 &&\r\n                        (x - res[0][1]) * (x - res[0][1]) * ux2 +\r\n                        (y - res[0][2]) * (y - res[0][2]) * uy2 <=\r\n                        prec\r\n                    ) {\r\n                        return true;\r\n                    }\r\n                }\r\n                return false;\r\n            }\r\n            return dist < prec;\r\n        },\r\n\r\n        /**\r\n         * Allocate points in the Coords array this.points\r\n         */\r\n        allocatePoints: function () {\r\n            var i, len;\r\n\r\n            len = this.numberPoints;\r\n\r\n            if (this.points.length < this.numberPoints) {\r\n                for (i = this.points.length; i < len; i++) {\r\n                    this.points[i] = new Coords(\r\n                        Const.COORDS_BY_USER,\r\n                        [0, 0],\r\n                        this.board,\r\n                        false\r\n                    );\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Generates points of the curve to be plotted.\r\n         * @returns {JXG.Curve} Reference to the curve object.\r\n         * @see JXG.Curve#updateCurve\r\n         */\r\n        update: function () {\r\n            if (this.needsUpdate) {\r\n                if (this.evalVisProp('trace')) {\r\n                    this.cloneToBackground(true);\r\n                }\r\n                this.updateCurve();\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Updates the visual contents of the curve.\r\n         * @returns {JXG.Curve} Reference to the curve object.\r\n         */\r\n        updateRenderer: function () {\r\n            //var wasReal;\r\n\r\n            if (!this.needsUpdate) {\r\n                return this;\r\n            }\r\n\r\n            if (this.visPropCalc.visible) {\r\n                // wasReal = this.isReal;\r\n\r\n                this.isReal = Plot.checkReal(this.points);\r\n\r\n                if (\r\n                    //wasReal &&\r\n                    !this.isReal\r\n                ) {\r\n                    this.updateVisibility(false);\r\n                }\r\n            }\r\n\r\n            if (this.visPropCalc.visible) {\r\n                this.board.renderer.updateCurve(this);\r\n            }\r\n\r\n            /* Update the label if visible. */\r\n            if (\r\n                this.hasLabel &&\r\n                this.visPropCalc.visible &&\r\n                this.label &&\r\n                this.label.visPropCalc.visible &&\r\n                this.isReal\r\n            ) {\r\n                this.label.update();\r\n                this.board.renderer.updateText(this.label);\r\n            }\r\n\r\n            // Update rendNode display\r\n            this.setDisplayRendNode();\r\n            // if (this.visPropCalc.visible !== this.visPropOld.visible) {\r\n            //     this.board.renderer.display(this, this.visPropCalc.visible);\r\n            //     this.visPropOld.visible = this.visPropCalc.visible;\r\n            //\r\n            //     if (this.hasLabel) {\r\n            //         this.board.renderer.display(this.label, this.label.visPropCalc.visible);\r\n            //     }\r\n            // }\r\n\r\n            this.needsUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * For dynamic dataplots updateCurve can be used to compute new entries\r\n         * for the arrays {@link JXG.Curve#dataX} and {@link JXG.Curve#dataY}. It\r\n         * is used in {@link JXG.Curve#updateCurve}. Default is an empty method, can\r\n         * be overwritten by the user.\r\n         *\r\n         *\r\n         * @example\r\n         * // This example overwrites the updateDataArray method.\r\n         * // There, new values for the arrays JXG.Curve.dataX and JXG.Curve.dataY\r\n         * // are computed from the value of the slider N\r\n         *\r\n         * var N = board.create('slider', [[0,1.5],[3,1.5],[1,3,40]], {name:'n',snapWidth:1});\r\n         * var circ = board.create('circle',[[4,-1.5],1],{strokeWidth:1, strokecolor:'black', strokeWidth:2,\r\n         * \t\tfillColor:'#0055ff13'});\r\n         *\r\n         * var c = board.create('curve', [[0],[0]],{strokecolor:'red', strokeWidth:2});\r\n         * c.updateDataArray = function() {\r\n         *         var r = 1, n = Math.floor(N.Value()),\r\n         *             x = [0], y = [0],\r\n         *             phi = Math.PI/n,\r\n         *             h = r*Math.cos(phi),\r\n         *             s = r*Math.sin(phi),\r\n         *             i, j,\r\n         *             px = 0, py = 0, sgn = 1,\r\n         *             d = 16,\r\n         *             dt = phi/d,\r\n         *             pt;\r\n         *\r\n         *         for (i = 0; i < n; i++) {\r\n         *             for (j = -d; j <= d; j++) {\r\n         *                 pt = dt*j;\r\n         *                 x.push(px + r*Math.sin(pt));\r\n         *                 y.push(sgn*r*Math.cos(pt) - (sgn-1)*h*0.5);\r\n         *             }\r\n         *             px += s;\r\n         *             sgn *= (-1);\r\n         *         }\r\n         *         x.push((n - 1)*s);\r\n         *         y.push(h + (sgn - 1)*h*0.5);\r\n         *         this.dataX = x;\r\n         *         this.dataY = y;\r\n         *     }\r\n         *\r\n         * var c2 = board.create('curve', [[0],[0]],{strokecolor:'red', strokeWidth:1});\r\n         * c2.updateDataArray = function() {\r\n         *         var r = 1, n = Math.floor(N.Value()),\r\n         *             px = circ.midpoint.X(), py = circ.midpoint.Y(),\r\n         *             x = [px], y = [py],\r\n         *             phi = Math.PI/n,\r\n         *             s = r*Math.sin(phi),\r\n         *             i, j,\r\n         *             d = 16,\r\n         *             dt = phi/d,\r\n         *             pt = Math.PI*0.5+phi;\r\n         *\r\n         *         for (i = 0; i < n; i++) {\r\n         *             for (j= -d; j <= d; j++) {\r\n         *                 x.push(px + r*Math.cos(pt));\r\n         *                 y.push(py + r*Math.sin(pt));\r\n         *                 pt -= dt;\r\n         *             }\r\n         *             x.push(px);\r\n         *             y.push(py);\r\n         *             pt += dt;\r\n         *         }\r\n         *         this.dataX = x;\r\n         *         this.dataY = y;\r\n         *     }\r\n         *     board.update();\r\n         *\r\n         * </pre><div id=\"JXG20bc7802-e69e-11e5-b1bf-901b0e1b8723\" class=\"jxgbox\" style=\"width: 600px; height: 400px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG20bc7802-e69e-11e5-b1bf-901b0e1b8723',\r\n         *             {boundingbox: [-1.5,2,8,-3], keepaspectratio: true, axis: true, showcopyright: false, shownavigation: false});\r\n         *             var N = board.create('slider', [[0,1.5],[3,1.5],[1,3,40]], {name:'n',snapWidth:1});\r\n         *             var circ = board.create('circle',[[4,-1.5],1],{strokeWidth:1, strokecolor:'black',\r\n         *             strokeWidth:2, fillColor:'#0055ff13'});\r\n         *\r\n         *             var c = board.create('curve', [[0],[0]],{strokecolor:'red', strokeWidth:2});\r\n         *             c.updateDataArray = function() {\r\n         *                     var r = 1, n = Math.floor(N.Value()),\r\n         *                         x = [0], y = [0],\r\n         *                         phi = Math.PI/n,\r\n         *                         h = r*Math.cos(phi),\r\n         *                         s = r*Math.sin(phi),\r\n         *                         i, j,\r\n         *                         px = 0, py = 0, sgn = 1,\r\n         *                         d = 16,\r\n         *                         dt = phi/d,\r\n         *                         pt;\r\n         *\r\n         *                     for (i=0;i<n;i++) {\r\n         *                         for (j=-d;j<=d;j++) {\r\n         *                             pt = dt*j;\r\n         *                             x.push(px+r*Math.sin(pt));\r\n         *                             y.push(sgn*r*Math.cos(pt)-(sgn-1)*h*0.5);\r\n         *                         }\r\n         *                         px += s;\r\n         *                         sgn *= (-1);\r\n         *                     }\r\n         *                     x.push((n-1)*s);\r\n         *                     y.push(h+(sgn-1)*h*0.5);\r\n         *                     this.dataX = x;\r\n         *                     this.dataY = y;\r\n         *                 }\r\n         *\r\n         *             var c2 = board.create('curve', [[0],[0]],{strokecolor:'red', strokeWidth:1});\r\n         *             c2.updateDataArray = function() {\r\n         *                     var r = 1, n = Math.floor(N.Value()),\r\n         *                         px = circ.midpoint.X(), py = circ.midpoint.Y(),\r\n         *                         x = [px], y = [py],\r\n         *                         phi = Math.PI/n,\r\n         *                         s = r*Math.sin(phi),\r\n         *                         i, j,\r\n         *                         d = 16,\r\n         *                         dt = phi/d,\r\n         *                         pt = Math.PI*0.5+phi;\r\n         *\r\n         *                     for (i=0;i<n;i++) {\r\n         *                         for (j=-d;j<=d;j++) {\r\n         *                             x.push(px+r*Math.cos(pt));\r\n         *                             y.push(py+r*Math.sin(pt));\r\n         *                             pt -= dt;\r\n         *                         }\r\n         *                         x.push(px);\r\n         *                         y.push(py);\r\n         *                         pt += dt;\r\n         *                     }\r\n         *                     this.dataX = x;\r\n         *                     this.dataY = y;\r\n         *                 }\r\n         *                 board.update();\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         * // This is an example which overwrites updateDataArray and produces\r\n         * // a Bezier curve of degree three.\r\n         * var A = board.create('point', [-3,3]);\r\n         * var B = board.create('point', [3,-2]);\r\n         * var line = board.create('segment', [A,B]);\r\n         *\r\n         * var height = 0.5; // height of the curly brace\r\n         *\r\n         * // Curly brace\r\n         * var crl = board.create('curve', [[0],[0]], {strokeWidth:1, strokeColor:'black'});\r\n         * crl.bezierDegree = 3;\r\n         * crl.updateDataArray = function() {\r\n         *     var d = [B.X()-A.X(), B.Y()-A.Y()],\r\n         *         dl = Math.sqrt(d[0]*d[0]+d[1]*d[1]),\r\n         *         mid = [(A.X()+B.X())*0.5, (A.Y()+B.Y())*0.5];\r\n         *\r\n         *     d[0] *= height/dl;\r\n         *     d[1] *= height/dl;\r\n         *\r\n         *     this.dataX = [ A.X(), A.X()-d[1], mid[0], mid[0]-d[1], mid[0], B.X()-d[1], B.X() ];\r\n         *     this.dataY = [ A.Y(), A.Y()+d[0], mid[1], mid[1]+d[0], mid[1], B.Y()+d[0], B.Y() ];\r\n         * };\r\n         *\r\n         * // Text\r\n         * var txt = board.create('text', [\r\n         *                     function() {\r\n         *                         var d = [B.X()-A.X(), B.Y()-A.Y()],\r\n         *                             dl = Math.sqrt(d[0]*d[0]+d[1]*d[1]),\r\n         *                             mid = (A.X()+B.X())*0.5;\r\n         *\r\n         *                         d[1] *= height/dl;\r\n         *                         return mid-d[1]+0.1;\r\n         *                     },\r\n         *                     function() {\r\n         *                         var d = [B.X()-A.X(), B.Y()-A.Y()],\r\n         *                             dl = Math.sqrt(d[0]*d[0]+d[1]*d[1]),\r\n         *                             mid = (A.Y()+B.Y())*0.5;\r\n         *\r\n         *                         d[0] *= height/dl;\r\n         *                         return mid+d[0]+0.1;\r\n         *                     },\r\n         *                     function() { return \"length=\" + JXG.toFixed(B.Dist(A), 2); }\r\n         *                 ]);\r\n         *\r\n         *\r\n         * board.update(); // This update is necessary to call updateDataArray the first time.\r\n         *\r\n         * </pre><div id=\"JXGa61a4d66-e69f-11e5-b1bf-901b0e1b8723\"  class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *      var board = JXG.JSXGraph.initBoard('JXGa61a4d66-e69f-11e5-b1bf-901b0e1b8723',\r\n         *             {boundingbox: [-4, 4, 4,-4], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var A = board.create('point', [-3,3]);\r\n         *     var B = board.create('point', [3,-2]);\r\n         *     var line = board.create('segment', [A,B]);\r\n         *\r\n         *     var height = 0.5; // height of the curly brace\r\n         *\r\n         *     // Curly brace\r\n         *     var crl = board.create('curve', [[0],[0]], {strokeWidth:1, strokeColor:'black'});\r\n         *     crl.bezierDegree = 3;\r\n         *     crl.updateDataArray = function() {\r\n         *         var d = [B.X()-A.X(), B.Y()-A.Y()],\r\n         *             dl = Math.sqrt(d[0]*d[0]+d[1]*d[1]),\r\n         *             mid = [(A.X()+B.X())*0.5, (A.Y()+B.Y())*0.5];\r\n         *\r\n         *         d[0] *= height/dl;\r\n         *         d[1] *= height/dl;\r\n         *\r\n         *         this.dataX = [ A.X(), A.X()-d[1], mid[0], mid[0]-d[1], mid[0], B.X()-d[1], B.X() ];\r\n         *         this.dataY = [ A.Y(), A.Y()+d[0], mid[1], mid[1]+d[0], mid[1], B.Y()+d[0], B.Y() ];\r\n         *     };\r\n         *\r\n         *     // Text\r\n         *     var txt = board.create('text', [\r\n         *                         function() {\r\n         *                             var d = [B.X()-A.X(), B.Y()-A.Y()],\r\n         *                                 dl = Math.sqrt(d[0]*d[0]+d[1]*d[1]),\r\n         *                                 mid = (A.X()+B.X())*0.5;\r\n         *\r\n         *                             d[1] *= height/dl;\r\n         *                             return mid-d[1]+0.1;\r\n         *                         },\r\n         *                         function() {\r\n         *                             var d = [B.X()-A.X(), B.Y()-A.Y()],\r\n         *                                 dl = Math.sqrt(d[0]*d[0]+d[1]*d[1]),\r\n         *                                 mid = (A.Y()+B.Y())*0.5;\r\n         *\r\n         *                             d[0] *= height/dl;\r\n         *                             return mid+d[0]+0.1;\r\n         *                         },\r\n         *                         function() { return \"length=\"+JXG.toFixed(B.Dist(A), 2); }\r\n         *                     ]);\r\n         *\r\n         *\r\n         *     board.update(); // This update is necessary to call updateDataArray the first time.\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         *\r\n         */\r\n        updateDataArray: function () {\r\n            // this used to return this, but we shouldn't rely on the user to implement it.\r\n        },\r\n\r\n        /**\r\n         * Computes the curve path\r\n         * @see JXG.Curve#update\r\n         * @returns {JXG.Curve} Reference to the curve object.\r\n         */\r\n        updateCurve: function () {\r\n            var i, len, mi, ma,\r\n                x, y,\r\n                version = this.visProp.plotversion,\r\n                //t1, t2, l1,\r\n                suspendUpdate = false;\r\n\r\n            this.updateTransformMatrix();\r\n            this.updateDataArray();\r\n            mi = this.minX();\r\n            ma = this.maxX();\r\n\r\n            if (Type.exists(this.dataX)) {\r\n                // Discrete data points, i.e. x-coordinates are given in an array\r\n                this.numberPoints = this.dataX.length;\r\n                len = this.numberPoints;\r\n\r\n                // It is possible, that the array length has increased.\r\n                this.allocatePoints();\r\n\r\n                for (i = 0; i < len; i++) {\r\n                    x = i;\r\n\r\n                    // y-coordinates are in an array\r\n                    if (Type.exists(this.dataY)) {\r\n                        y = i;\r\n                        // The last parameter prevents rounding in usr2screen().\r\n                        this.points[i].setCoordinates(\r\n                            Const.COORDS_BY_USER,\r\n                            [this.dataX[i], this.dataY[i]],\r\n                            false\r\n                        );\r\n                    } else {\r\n                        // discrete x data, continuous y data\r\n                        y = this.X(x);\r\n                        // The last parameter prevents rounding in usr2screen().\r\n                        this.points[i].setCoordinates(\r\n                            Const.COORDS_BY_USER,\r\n                            [this.dataX[i], this.Y(y, suspendUpdate)],\r\n                            false\r\n                        );\r\n                    }\r\n                    this.points[i]._t = i;\r\n\r\n                    // this.updateTransform(this.points[i]);\r\n                    suspendUpdate = true;\r\n                }\r\n\r\n            } else {\r\n                // Continuous x-data, i.e. given as a function\r\n                if (this.evalVisProp('doadvancedplot')) {\r\n                    // console.time('plot');\r\n\r\n                    if (version === 1 || this.evalVisProp('doadvancedplotold')) {\r\n                        Plot.updateParametricCurveOld(this, mi, ma);\r\n                    } else if (version === 2) {\r\n                        Plot.updateParametricCurve_v2(this, mi, ma);\r\n                    } else if (version === 3) {\r\n                        Plot.updateParametricCurve_v3(this, mi, ma);\r\n                    } else if (version === 4) {\r\n                        Plot.updateParametricCurve_v4(this, mi, ma);\r\n                    } else {\r\n                        Plot.updateParametricCurve_v2(this, mi, ma);\r\n                    }\r\n                    // console.timeEnd('plot');\r\n                } else {\r\n                    if (this.board.updateQuality === this.board.BOARD_QUALITY_HIGH) {\r\n                        this.numberPoints = this.evalVisProp('numberpointshigh');\r\n                    } else {\r\n                        this.numberPoints = this.evalVisProp('numberpointslow');\r\n                    }\r\n\r\n                    // It is possible, that the array length has increased.\r\n                    this.allocatePoints();\r\n                    Plot.updateParametricCurveNaive(this, mi, ma, this.numberPoints);\r\n                }\r\n                len = this.numberPoints;\r\n\r\n                if (\r\n                    this.evalVisProp('useqdt') &&\r\n                    this.board.updateQuality === this.board.BOARD_QUALITY_HIGH\r\n                ) {\r\n                    this.qdt = new QDT(this.board.getBoundingBox());\r\n                    for (i = 0; i < this.points.length; i++) {\r\n                        this.qdt.insert(this.points[i]);\r\n\r\n                        if (i > 0) {\r\n                            this.points[i].prev = this.points[i - 1];\r\n                        }\r\n\r\n                        if (i < len - 1) {\r\n                            this.points[i].next = this.points[i + 1];\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // for (i = 0; i < len; i++) {\r\n                //     this.updateTransform(this.points[i]);\r\n                // }\r\n            }\r\n\r\n            if (\r\n                this.evalVisProp('curvetype') !== \"plot\" &&\r\n                this.evalVisProp('rdpsmoothing')\r\n            ) {\r\n                // console.time('rdp');\r\n                this.points = Numerics.RamerDouglasPeucker(this.points, 0.2);\r\n                this.numberPoints = this.points.length;\r\n                // console.timeEnd('rdp');\r\n                // console.log(this.numberPoints);\r\n            }\r\n\r\n            len = this.numberPoints;\r\n            for (i = 0; i < len; i++) {\r\n                this.updateTransform(this.points[i]);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        updateTransformMatrix: function () {\r\n            var t,\r\n                i,\r\n                len = this.transformations.length;\r\n\r\n            this.transformMat = [\r\n                [1, 0, 0],\r\n                [0, 1, 0],\r\n                [0, 0, 1]\r\n            ];\r\n\r\n            for (i = 0; i < len; i++) {\r\n                t = this.transformations[i];\r\n                t.update();\r\n                this.transformMat = Mat.matMatMult(t.matrix, this.transformMat);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Applies the transformations of the curve to the given point <tt>p</tt>.\r\n         * Before using it, {@link JXG.Curve#updateTransformMatrix} has to be called.\r\n         * @param {JXG.Point} p\r\n         * @returns {JXG.Point} The given point.\r\n         */\r\n        updateTransform: function (p) {\r\n            var c,\r\n                len = this.transformations.length;\r\n\r\n            if (len > 0) {\r\n                c = Mat.matVecMult(this.transformMat, p.usrCoords);\r\n                p.setCoordinates(Const.COORDS_BY_USER, c, false, true);\r\n            }\r\n\r\n            return p;\r\n        },\r\n\r\n        /**\r\n         * Add transformations to this curve.\r\n         * @param {JXG.Transformation|Array} transform Either one {@link JXG.Transformation} or an array of {@link JXG.Transformation}s.\r\n         * @returns {JXG.Curve} Reference to the curve object.\r\n         */\r\n        addTransform: function (transform) {\r\n            var i,\r\n                list = Type.isArray(transform) ? transform : [transform],\r\n                len = list.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                this.transformations.push(list[i]);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Generate the method curve.X() in case curve.dataX is an array\r\n         * and generate the method curve.Y() in case curve.dataY is an array.\r\n         * @private\r\n         * @param {String} which Either 'X' or 'Y'\r\n         * @returns {function}\r\n         **/\r\n        interpolationFunctionFromArray: function (which) {\r\n            var data = \"data\" + which,\r\n                that = this;\r\n\r\n            return function (t, suspendedUpdate) {\r\n                var i,\r\n                    j,\r\n                    t0,\r\n                    t1,\r\n                    arr = that[data],\r\n                    len = arr.length,\r\n                    last,\r\n                    f = [];\r\n\r\n                if (isNaN(t)) {\r\n                    return NaN;\r\n                }\r\n\r\n                if (t < 0) {\r\n                    if (Type.isFunction(arr[0])) {\r\n                        return arr[0]();\r\n                    }\r\n\r\n                    return arr[0];\r\n                }\r\n\r\n                if (that.bezierDegree === 3) {\r\n                    last = (len - 1) / 3;\r\n\r\n                    if (t >= last) {\r\n                        if (Type.isFunction(arr[arr.length - 1])) {\r\n                            return arr[arr.length - 1]();\r\n                        }\r\n\r\n                        return arr[arr.length - 1];\r\n                    }\r\n\r\n                    i = Math.floor(t) * 3;\r\n                    t0 = t % 1;\r\n                    t1 = 1 - t0;\r\n\r\n                    for (j = 0; j < 4; j++) {\r\n                        if (Type.isFunction(arr[i + j])) {\r\n                            f[j] = arr[i + j]();\r\n                        } else {\r\n                            f[j] = arr[i + j];\r\n                        }\r\n                    }\r\n\r\n                    return (\r\n                        t1 * t1 * (t1 * f[0] + 3 * t0 * f[1]) +\r\n                        (3 * t1 * f[2] + t0 * f[3]) * t0 * t0\r\n                    );\r\n                }\r\n\r\n                if (t > len - 2) {\r\n                    i = len - 2;\r\n                } else {\r\n                    i = parseInt(Math.floor(t), 10);\r\n                }\r\n\r\n                if (i === t) {\r\n                    if (Type.isFunction(arr[i])) {\r\n                        return arr[i]();\r\n                    }\r\n                    return arr[i];\r\n                }\r\n\r\n                for (j = 0; j < 2; j++) {\r\n                    if (Type.isFunction(arr[i + j])) {\r\n                        f[j] = arr[i + j]();\r\n                    } else {\r\n                        f[j] = arr[i + j];\r\n                    }\r\n                }\r\n                return f[0] + (f[1] - f[0]) * (t - i);\r\n            };\r\n        },\r\n\r\n        /**\r\n         * Converts the JavaScript/JessieCode/GEONExT syntax of the defining function term into JavaScript.\r\n         * New methods X() and Y() for the Curve object are generated, further\r\n         * new methods for minX() and maxX().\r\n         * If mi or ma are not supplied, default functions are set.\r\n         *\r\n         * @param {String} varname Name of the parameter in xterm and yterm, e.g. 'x' or 't'\r\n         * @param {String|Number|Function|Array} xterm Term for the x coordinate. Can also be an array consisting of discrete values.\r\n         * @param {String|Number|Function|Array} yterm Term for the y coordinate. Can also be an array consisting of discrete values.\r\n         * @param {String|Number|Function} [mi] Lower bound on the parameter\r\n         * @param {String|Number|Function} [ma] Upper bound on the parameter\r\n         * @see JXG.GeonextParser.geonext2JS\r\n         */\r\n        generateTerm: function (varname, xterm, yterm, mi, ma) {\r\n            var fx, fy, mat;\r\n\r\n            // Generate the methods X() and Y()\r\n            if (Type.isArray(xterm)) {\r\n                // Discrete data\r\n                this.dataX = xterm;\r\n\r\n                this.numberPoints = this.dataX.length;\r\n                this.X = this.interpolationFunctionFromArray.apply(this, [\"X\"]);\r\n                this.visProp.curvetype = 'plot';\r\n                this.isDraggable = true;\r\n            } else {\r\n                // Continuous data\r\n                this.X = Type.createFunction(xterm, this.board, varname);\r\n                if (Type.isString(xterm)) {\r\n                    this.visProp.curvetype = 'functiongraph';\r\n                } else if (Type.isFunction(xterm) || Type.isNumber(xterm)) {\r\n                    this.visProp.curvetype = 'parameter';\r\n                }\r\n\r\n                this.isDraggable = true;\r\n            }\r\n\r\n            if (Type.isArray(yterm)) {\r\n                this.dataY = yterm;\r\n                this.Y = this.interpolationFunctionFromArray.apply(this, [\"Y\"]);\r\n            } else if (!Type.exists(yterm)) {\r\n                // Discrete data as an array of coordinate pairs,\r\n                // i.e. transposed input\r\n                mat = Mat.transpose(xterm);\r\n                this.dataX = mat[0];\r\n                this.dataY = mat[1];\r\n                this.numberPoints = this.dataX.length;\r\n                this.Y = this.interpolationFunctionFromArray.apply(this, [\"Y\"]);\r\n            } else {\r\n                this.Y = Type.createFunction(yterm, this.board, varname);\r\n            }\r\n\r\n            /**\r\n             * Polar form\r\n             * Input data is function xterm() and offset coordinates yterm\r\n             */\r\n            if (Type.isFunction(xterm) && Type.isArray(yterm)) {\r\n                // Xoffset, Yoffset\r\n                fx = Type.createFunction(yterm[0], this.board, \"\");\r\n                fy = Type.createFunction(yterm[1], this.board, \"\");\r\n\r\n                this.X = function (phi) {\r\n                    return xterm(phi) * Math.cos(phi) + fx();\r\n                };\r\n                this.X.deps = fx.deps;\r\n\r\n                this.Y = function (phi) {\r\n                    return xterm(phi) * Math.sin(phi) + fy();\r\n                };\r\n                this.Y.deps = fy.deps;\r\n\r\n                this.visProp.curvetype = 'polar';\r\n            }\r\n\r\n            // Set the upper and lower bounds for the parameter of the curve.\r\n            // If not defined, reset the bounds to the default values\r\n            // given in Curve.prototype.minX, Curve.prototype.maxX\r\n            if (Type.exists(mi)) {\r\n                this.minX = Type.createFunction(mi, this.board, \"\");\r\n            } else {\r\n                delete this.minX;\r\n            }\r\n            if (Type.exists(ma)) {\r\n                this.maxX = Type.createFunction(ma, this.board, \"\");\r\n            } else {\r\n                delete this.maxX;\r\n            }\r\n\r\n            this.addParentsFromJCFunctions([this.X, this.Y, this.minX, this.maxX]);\r\n        },\r\n\r\n        /**\r\n         * Finds dependencies in a given term and notifies the parents by adding the\r\n         * dependent object to the found objects child elements.\r\n         * @param {String} contentStr String containing dependencies for the given object.\r\n         */\r\n        notifyParents: function (contentStr) {\r\n            var fstr,\r\n                dep,\r\n                isJessieCode = false,\r\n                obj;\r\n\r\n            // Read dependencies found by the JessieCode parser\r\n            obj = { xterm: 1, yterm: 1 };\r\n            for (fstr in obj) {\r\n                if (\r\n                    obj.hasOwnProperty(fstr) &&\r\n                    this.hasOwnProperty(fstr) &&\r\n                    this[fstr].origin\r\n                ) {\r\n                    isJessieCode = true;\r\n                    for (dep in this[fstr].origin.deps) {\r\n                        if (this[fstr].origin.deps.hasOwnProperty(dep)) {\r\n                            this[fstr].origin.deps[dep].addChild(this);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (!isJessieCode) {\r\n                GeonextParser.findDependencies(this, contentStr, this.board);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Position a curve label according to the attributes \"position\" and distance.\r\n         * This function is also used for angle, arc and sector.\r\n         *\r\n         * @param {String} pos\r\n         * @param {Number} distance\r\n         * @returns {JXG.Coords}\r\n         */\r\n        getLabelPosition: function(pos, distance) {\r\n            var x, y, xy,\r\n                c, d, e,\r\n                lbda,\r\n                mi, ma, ar,\r\n                t, dx, dy,\r\n                dist = 1.5;\r\n\r\n            // Shrink domain if necessary\r\n            mi = this.minX();\r\n            ma = this.maxX();\r\n            ar = Numerics.findDomain(this.X, [mi, ma], null, false);\r\n            ar = Numerics.findDomain(this.Y, ar, null, false);\r\n            mi = Math.max(ar[0], ar[0]);\r\n            ma = Math.min(ar[1], ar[1]);\r\n\r\n            xy = Type.parsePosition(pos);\r\n            lbda = Type.parseNumber(xy.pos, ma - mi, 1);\r\n\r\n            if (xy.pos.indexOf('fr') < 0 &&\r\n                xy.pos.indexOf('%') < 0) {\r\n                // 'px' or numbers are not supported\r\n                lbda = 0;\r\n            }\r\n\r\n            t = mi + lbda;\r\n\r\n            x = this.X(t);\r\n            y = this.Y(t);\r\n            // If x or y are NaN, the label is set to the line\r\n            // between the first and last point.\r\n            if (isNaN(x + y)) {\r\n                lbda /= (ma - mi);\r\n                t = mi + lbda;\r\n                x = this.X(mi) + lbda * (this.X(ma) - this.X(mi));\r\n                y = this.Y(mi) + lbda * (this.Y(ma) - this.Y(mi));\r\n            }\r\n            c = (new Coords(Const.COORDS_BY_USER, [x, y], this.board)).scrCoords;\r\n\r\n            e = Mat.eps;\r\n            if (t < mi + e) {\r\n                dx = (this.X(t + e) - this.X(t)) / e;\r\n                dy = (this.Y(t + e) - this.Y(t)) / e;\r\n            } else if (t > ma - e) {\r\n                dx = (this.X(t) - this.X(t - e)) / e;\r\n                dy = (this.Y(t) - this.Y(t - e)) / e;\r\n            } else {\r\n                dx = 0.5 * (this.X(t + e) - this.X(t - e)) / e;\r\n                dy = 0.5 * (this.Y(t + e) - this.Y(t - e)) / e;\r\n            }\r\n            dx = isNaN(dx) ? 1. : dx;\r\n            dy = isNaN(dy) ? 1. : dy;\r\n            d = Mat.hypot(dx, dy);\r\n\r\n            if (xy.side === 'left') {\r\n                dy *= -1;\r\n            } else {\r\n                dx *= -1;\r\n            }\r\n\r\n            // Position left or right\r\n\r\n            if (Type.exists(this.label)) {\r\n                dist = 0.5 * distance / d;\r\n            }\r\n\r\n            x = c[1] + dy * this.label.size[0] * dist;\r\n            y = c[2] - dx * this.label.size[1] * dist;\r\n\r\n            return new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board);\r\n        },\r\n\r\n        // documented in geometryElement\r\n        getLabelAnchor: function () {\r\n            var x, y, pos,\r\n                // xy, lbda, e,\r\n                // t, dx, dy, d,\r\n                // dist = 1.5,\r\n                c,\r\n                ax = 0.05 * this.board.canvasWidth,\r\n                ay = 0.05 * this.board.canvasHeight,\r\n                bx = 0.95 * this.board.canvasWidth,\r\n                by = 0.95 * this.board.canvasHeight;\r\n\r\n            if (!Type.exists(this.label)) {\r\n                return new Coords(Const.COORDS_BY_SCREEN, [NaN, NaN], this.board);\r\n            }\r\n            pos = this.label.evalVisProp('position');\r\n            if (!Type.isString(pos)) {\r\n                return new Coords(Const.COORDS_BY_SCREEN, [NaN, NaN], this.board);\r\n            }\r\n\r\n            if (pos.indexOf('right') < 0 && pos.indexOf('left') < 0) {\r\n                switch (this.evalVisProp('label.position')) {\r\n                    case \"ulft\":\r\n                        x = ax;\r\n                        y = ay;\r\n                        break;\r\n                    case \"llft\":\r\n                        x = ax;\r\n                        y = by;\r\n                        break;\r\n                    case \"rt\":\r\n                        x = bx;\r\n                        y = 0.5 * by;\r\n                        break;\r\n                    case \"lrt\":\r\n                        x = bx;\r\n                        y = by;\r\n                        break;\r\n                    case \"urt\":\r\n                        x = bx;\r\n                        y = ay;\r\n                        break;\r\n                    case \"top\":\r\n                        x = 0.5 * bx;\r\n                        y = ay;\r\n                        break;\r\n                    case \"bot\":\r\n                        x = 0.5 * bx;\r\n                        y = by;\r\n                        break;\r\n                    default:\r\n                        // includes case 'lft'\r\n                        x = ax;\r\n                        y = 0.5 * by;\r\n                }\r\n            } else {\r\n                // New positioning\r\n                return this.getLabelPosition(pos, this.label.evalVisProp('distance'));\r\n                // xy = Type.parsePosition(pos);\r\n                // lbda = Type.parseNumber(xy.pos, this.maxX() - this.minX(), 1);\r\n\r\n                // if (xy.pos.indexOf('fr') < 0 &&\r\n                //     xy.pos.indexOf('%') < 0) {\r\n                //     // 'px' or numbers are not supported\r\n                //     lbda = 0;\r\n                // }\r\n\r\n                // t = this.minX() + lbda;\r\n                // x = this.X(t);\r\n                // y = this.Y(t);\r\n                // c = (new Coords(Const.COORDS_BY_USER, [x, y], this.board)).scrCoords;\r\n\r\n                // e = Mat.eps;\r\n                // if (t < this.minX() + e) {\r\n                //     dx = (this.X(t + e) - this.X(t)) / e;\r\n                //     dy = (this.Y(t + e) - this.Y(t)) / e;\r\n                // } else if (t > this.maxX() - e) {\r\n                //     dx = (this.X(t) - this.X(t - e)) / e;\r\n                //     dy = (this.Y(t) - this.Y(t - e)) / e;\r\n                // } else {\r\n                //     dx = 0.5 * (this.X(t + e) - this.X(t - e)) / e;\r\n                //     dy = 0.5 * (this.Y(t + e) - this.Y(t - e)) / e;\r\n                // }\r\n                // d = Mat.hypot(dx, dy);\r\n\r\n                // if (xy.side === 'left') {\r\n                //     dy *= -1;\r\n                // } else {\r\n                //     dx *= -1;\r\n                // }\r\n\r\n                // // Position left or right\r\n\r\n                // if (Type.exists(this.label)) {\r\n                //     dist = 0.5 * this.label.evalVisProp('distance') / d;\r\n                // }\r\n\r\n                // x = c[1] + dy * this.label.size[0] * dist;\r\n                // y = c[2] - dx * this.label.size[1] * dist;\r\n\r\n                // return new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board);\r\n\r\n            }\r\n            c = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board, false);\r\n            return Geometry.projectCoordsToCurve(\r\n                c.usrCoords[1], c.usrCoords[2], 0, this, this.board\r\n            )[0];\r\n        },\r\n\r\n        // documented in geometry element\r\n        cloneToBackground: function () {\r\n            var er,\r\n                copy = Type.getCloneObject(this);\r\n\r\n            copy.points = this.points.slice(0);\r\n            copy.bezierDegree = this.bezierDegree;\r\n            copy.numberPoints = this.numberPoints;\r\n\r\n            er = this.board.renderer.enhancedRendering;\r\n            this.board.renderer.enhancedRendering = true;\r\n            this.board.renderer.drawCurve(copy);\r\n            this.board.renderer.enhancedRendering = er;\r\n            this.traces[copy.id] = copy.rendNode;\r\n\r\n            return this;\r\n        },\r\n\r\n        // Already documented in GeometryElement\r\n        bounds: function () {\r\n            var minX = Infinity,\r\n                maxX = -Infinity,\r\n                minY = Infinity,\r\n                maxY = -Infinity,\r\n                l = this.points.length,\r\n                i,\r\n                bezier,\r\n                up;\r\n\r\n            if (this.bezierDegree === 3) {\r\n                // Add methods X(), Y()\r\n                for (i = 0; i < l; i++) {\r\n                    this.points[i].X = Type.bind(function () {\r\n                        return this.usrCoords[1];\r\n                    }, this.points[i]);\r\n                    this.points[i].Y = Type.bind(function () {\r\n                        return this.usrCoords[2];\r\n                    }, this.points[i]);\r\n                }\r\n                bezier = Numerics.bezier(this.points);\r\n                up = bezier[3]();\r\n                minX = Numerics.fminbr(\r\n                    function (t) {\r\n                        return bezier[0](t);\r\n                    },\r\n                    [0, up]\r\n                );\r\n                maxX = Numerics.fminbr(\r\n                    function (t) {\r\n                        return -bezier[0](t);\r\n                    },\r\n                    [0, up]\r\n                );\r\n                minY = Numerics.fminbr(\r\n                    function (t) {\r\n                        return bezier[1](t);\r\n                    },\r\n                    [0, up]\r\n                );\r\n                maxY = Numerics.fminbr(\r\n                    function (t) {\r\n                        return -bezier[1](t);\r\n                    },\r\n                    [0, up]\r\n                );\r\n\r\n                minX = bezier[0](minX);\r\n                maxX = bezier[0](maxX);\r\n                minY = bezier[1](minY);\r\n                maxY = bezier[1](maxY);\r\n                return [minX, maxY, maxX, minY];\r\n            }\r\n\r\n            // Linear segments\r\n            for (i = 0; i < l; i++) {\r\n                if (minX > this.points[i].usrCoords[1]) {\r\n                    minX = this.points[i].usrCoords[1];\r\n                }\r\n\r\n                if (maxX < this.points[i].usrCoords[1]) {\r\n                    maxX = this.points[i].usrCoords[1];\r\n                }\r\n\r\n                if (minY > this.points[i].usrCoords[2]) {\r\n                    minY = this.points[i].usrCoords[2];\r\n                }\r\n\r\n                if (maxY < this.points[i].usrCoords[2]) {\r\n                    maxY = this.points[i].usrCoords[2];\r\n                }\r\n            }\r\n\r\n            return [minX, maxY, maxX, minY];\r\n        },\r\n\r\n        // documented in element.js\r\n        getParents: function () {\r\n            var p = [this.xterm, this.yterm, this.minX(), this.maxX()];\r\n\r\n            if (this.parents.length !== 0) {\r\n                p = this.parents;\r\n            }\r\n\r\n            return p;\r\n        },\r\n\r\n        /**\r\n         * Shift the curve by the vector 'where'.\r\n         *\r\n         * @param {Array} where Array containing the x and y coordinate of the target location.\r\n         * @returns {JXG.Curve} Reference to itself.\r\n         */\r\n        moveTo: function (where) {\r\n            // TODO add animation\r\n            var delta = [],\r\n                p;\r\n            if (this.points.length > 0 && !this.evalVisProp('fixed')) {\r\n                p = this.points[0];\r\n                if (where.length === 3) {\r\n                    delta = [\r\n                        where[0] - p.usrCoords[0],\r\n                        where[1] - p.usrCoords[1],\r\n                        where[2] - p.usrCoords[2]\r\n                    ];\r\n                } else {\r\n                    delta = [where[0] - p.usrCoords[1], where[1] - p.usrCoords[2]];\r\n                }\r\n                this.setPosition(Const.COORDS_BY_USER, delta);\r\n                return this.board.update(this);\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * If the curve is the result of a transformation applied\r\n         * to a continuous curve, the glider projection has to be done\r\n         * on the original curve. Otherwise there will be problems\r\n         * when changing between high and low precision plotting,\r\n         * since there number of points changes.\r\n         *\r\n         * @private\r\n         * @returns {Array} [Boolean, curve]: Array contining 'true' if curve is result of a transformation,\r\n         *   and the source curve of the transformation.\r\n         */\r\n        getTransformationSource: function () {\r\n            var isTransformed, curve_org;\r\n            if (Type.exists(this._transformationSource)) {\r\n                curve_org = this._transformationSource;\r\n                if (\r\n                    curve_org.elementClass === Const.OBJECT_CLASS_CURVE //&&\r\n                    //curve_org.evalVisProp('curvetype') !== 'plot'\r\n                ) {\r\n                    isTransformed = true;\r\n                }\r\n            }\r\n            return [isTransformed, curve_org];\r\n        }\r\n\r\n        // See JXG.Math.Geometry.pnpoly\r\n        // pnpoly: function (x_in, y_in, coord_type) {\r\n        //     var i,\r\n        //         j,\r\n        //         len,\r\n        //         x,\r\n        //         y,\r\n        //         crds,\r\n        //         v = this.points,\r\n        //         isIn = false;\r\n\r\n        //     if (coord_type === Const.COORDS_BY_USER) {\r\n        //         crds = new Coords(Const.COORDS_BY_USER, [x_in, y_in], this.board);\r\n        //         x = crds.scrCoords[1];\r\n        //         y = crds.scrCoords[2];\r\n        //     } else {\r\n        //         x = x_in;\r\n        //         y = y_in;\r\n        //     }\r\n\r\n        //     len = this.points.length;\r\n        //     for (i = 0, j = len - 2; i < len - 1; j = i++) {\r\n        //         if (\r\n        //             v[i].scrCoords[2] > y !== v[j].scrCoords[2] > y &&\r\n        //             x <\r\n        //                 ((v[j].scrCoords[1] - v[i].scrCoords[1]) * (y - v[i].scrCoords[2])) /\r\n        //                     (v[j].scrCoords[2] - v[i].scrCoords[2]) +\r\n        //                     v[i].scrCoords[1]\r\n        //         ) {\r\n        //             isIn = !isIn;\r\n        //         }\r\n        //     }\r\n\r\n        //     return isIn;\r\n        // }\r\n    }\r\n);\r\n\r\n/**\r\n * @class  Curves can be defined by mappings or by discrete data sets.\r\n * In general, a curve is a mapping from R to R^2, where t maps to (x(t),y(t)). The graph is drawn for t in the interval [a,b].\r\n * <p>\r\n * The following types of curves can be plotted:\r\n * <ul>\r\n *  <li> parametric curves: t mapsto (x(t),y(t)), where x() and y() are univariate functions.\r\n *  <li> polar curves: curves commonly written with polar equations like spirals and cardioids.\r\n *  <li> data plots: plot line segments through a given list of coordinates.\r\n * </ul>\r\n * @pseudo\r\n * @name Curve\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type Object\r\n * @description JXG.Curve\r\n\r\n * @param {function,number_function,number_function,number_function,number}  x,y,a_,b_ Parent elements for Parametric Curves.\r\n *                     <p>\r\n *                     x describes the x-coordinate of the curve. It may be a function term in one variable, e.g. x(t).\r\n *                     In case of x being of type number, x(t) is set to  a constant function.\r\n *                     this function at the values of the array.\r\n *                     </p>\r\n *                     <p>\r\n *                     y describes the y-coordinate of the curve. In case of a number, y(t) is set to the constant function\r\n *                     returning this number.\r\n *                     </p>\r\n *                     <p>\r\n *                     Further parameters are an optional number or function for the left interval border a,\r\n *                     and an optional number or function for the right interval border b.\r\n *                     </p>\r\n *                     <p>\r\n *                     Default values are a=-10 and b=10.\r\n *                     </p>\r\n *\r\n * @param {array_array,function,number}\r\n *\r\n * @description x,y Parent elements for Data Plots.\r\n *                     <p>\r\n *                     x and y are arrays contining the x and y coordinates of the data points which are connected by\r\n *                     line segments. The individual entries of x and y may also be functions.\r\n *                     In case of x being an array the curve type is data plot, regardless of the second parameter and\r\n *                     if additionally the second parameter y is a function term the data plot evaluates.\r\n *                     </p>\r\n * @param {function_array,function,number_function,number_function,number}\r\n * @description r,offset_,a_,b_ Parent elements for Polar Curves.\r\n *                     <p>\r\n *                     The first parameter is a function term r(phi) describing the polar curve.\r\n *                     </p>\r\n *                     <p>\r\n *                     The second parameter is the offset of the curve. It has to be\r\n *                     an array containing numbers or functions describing the offset. Default value is the origin [0,0].\r\n *                     </p>\r\n *                     <p>\r\n *                     Further parameters are an optional number or function for the left interval border a,\r\n *                     and an optional number or function for the right interval border b.\r\n *                     </p>\r\n *                     <p>\r\n *                     Default values are a=-10 and b=10.\r\n *                     </p>\r\n * <p>\r\n * Additionally, a curve can be created by providing a curve and a transformation (or an array of transformations).\r\n * The result is a curve which is the transformation of the supplied curve.\r\n *\r\n * @see JXG.Curve\r\n * @example\r\n * // Parametric curve\r\n * // Create a curve of the form (t-sin(t), 1-cos(t), i.e.\r\n * // the cycloid curve.\r\n *   var graph = board.create('curve',\r\n *                        [function(t){ return t-Math.sin(t);},\r\n *                         function(t){ return 1-Math.cos(t);},\r\n *                         0, 2*Math.PI]\r\n *                     );\r\n * </pre><div class=\"jxgbox\" id=\"JXGaf9f818b-f3b6-4c4d-8c4c-e4a4078b726d\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var c1_board = JXG.JSXGraph.initBoard('JXGaf9f818b-f3b6-4c4d-8c4c-e4a4078b726d', {boundingbox: [-1, 5, 7, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var graph1 = c1_board.create('curve', [function(t){ return t-Math.sin(t);},function(t){ return 1-Math.cos(t);},0, 2*Math.PI]);\r\n * </script><pre>\r\n * @example\r\n * // Data plots\r\n * // Connect a set of points given by coordinates with dashed line segments.\r\n * // The x- and y-coordinates of the points are given in two separate\r\n * // arrays.\r\n *   var x = [0,1,2,3,4,5,6,7,8,9];\r\n *   var y = [9.2,1.3,7.2,-1.2,4.0,5.3,0.2,6.5,1.1,0.0];\r\n *   var graph = board.create('curve', [x,y], {dash:2});\r\n * </pre><div class=\"jxgbox\" id=\"JXG7dcbb00e-b6ff-481d-b4a8-887f5d8c6a83\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var c3_board = JXG.JSXGraph.initBoard('JXG7dcbb00e-b6ff-481d-b4a8-887f5d8c6a83', {boundingbox: [-1,10,10,-1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];\r\n *   var y = [9.2, 1.3, 7.2, -1.2, 4.0, 5.3, 0.2, 6.5, 1.1, 0.0];\r\n *   var graph3 = c3_board.create('curve', [x,y], {dash:2});\r\n * </script><pre>\r\n * @example\r\n * // Polar plot\r\n * // Create a curve with the equation r(phi)= a*(1+phi), i.e.\r\n * // a cardioid.\r\n *   var a = board.create('slider',[[0,2],[2,2],[0,1,2]]);\r\n *   var graph = board.create('curve',\r\n *                        [function(phi){ return a.Value()*(1-Math.cos(phi));},\r\n *                         [1,0],\r\n *                         0, 2*Math.PI],\r\n *                         {curveType: 'polar'}\r\n *                     );\r\n * </pre><div class=\"jxgbox\" id=\"JXGd0bc7a2a-8124-45ca-a6e7-142321a8f8c2\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var c2_board = JXG.JSXGraph.initBoard('JXGd0bc7a2a-8124-45ca-a6e7-142321a8f8c2', {boundingbox: [-3,3,3,-3], axis: true, showcopyright: false, shownavigation: false});\r\n *   var a = c2_board.create('slider',[[0,2],[2,2],[0,1,2]]);\r\n *   var graph2 = c2_board.create('curve', [function(phi){ return a.Value()*(1-Math.cos(phi));}, [1,0], 0, 2*Math.PI], {curveType: 'polar'});\r\n * </script><pre>\r\n *\r\n * @example\r\n *  // Draggable Bezier curve\r\n *  var col, p, c;\r\n *  col = 'blue';\r\n *  p = [];\r\n *  p.push(board.create('point',[-2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[1, 2.5 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[-1, -2.5 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, -2], {size: 5, strokeColor:col, fillColor:col}));\r\n *\r\n *  c = board.create('curve', JXG.Math.Numerics.bezier(p),\r\n *              {strokeColor:'red', name:\"curve\", strokeWidth:5, fixed: false}); // Draggable curve\r\n *  c.addParents(p);\r\n * </pre><div class=\"jxgbox\" id=\"JXG7bcc6280-f6eb-433e-8281-c837c3387849\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function(){\r\n *  var board, col, p, c;\r\n *  board = JXG.JSXGraph.initBoard('JXG7bcc6280-f6eb-433e-8281-c837c3387849', {boundingbox: [-3,3,3,-3], axis: true, showcopyright: false, shownavigation: false});\r\n *  col = 'blue';\r\n *  p = [];\r\n *  p.push(board.create('point',[-2, -1 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[1, 2.5 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[-1, -2.5 ], {size: 5, strokeColor:col, fillColor:col}));\r\n *  p.push(board.create('point',[2, -2], {size: 5, strokeColor:col, fillColor:col}));\r\n *\r\n *  c = board.create('curve', JXG.Math.Numerics.bezier(p),\r\n *              {strokeColor:'red', name:\"curve\", strokeWidth:5, fixed: false}); // Draggable curve\r\n *  c.addParents(p);\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n *         // The curve cu2 is the reflection of cu1 against line li\r\n *         var li = board.create('line', [1,1,1], {strokeColor: '#aaaaaa'});\r\n *         var reflect = board.create('transform', [li], {type: 'reflect'});\r\n *         var cu1 = board.create('curve', [[-1, -1, -0.5, -1, -1, -0.5], [-3, -2, -2, -2, -2.5, -2.5]]);\r\n *         var cu2 = board.create('curve', [cu1, reflect], {strokeColor: 'red'});\r\n *\r\n * </pre><div id=\"JXG866dc7a2-d448-11e7-93b3-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG866dc7a2-d448-11e7-93b3-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *             var li = board.create('line', [1,1,1], {strokeColor: '#aaaaaa'});\r\n *             var reflect = board.create('transform', [li], {type: 'reflect'});\r\n *             var cu1 = board.create('curve', [[-1, -1, -0.5, -1, -1, -0.5], [-3, -2, -2, -2, -2.5, -2.5]]);\r\n *             var cu2 = board.create('curve', [cu1, reflect], {strokeColor: 'red'});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n */\r\nJXG.createCurve = function (board, parents, attributes) {\r\n    var obj,\r\n        cu,\r\n        attr = Type.copyAttributes(attributes, board.options, 'curve');\r\n\r\n    obj = board.select(parents[0], true);\r\n    if (\r\n        Type.isTransformationOrArray(parents[1]) &&\r\n        Type.isObject(obj) &&\r\n        (obj.type === Const.OBJECT_TYPE_CURVE ||\r\n            obj.type === Const.OBJECT_TYPE_ANGLE ||\r\n            obj.type === Const.OBJECT_TYPE_ARC ||\r\n            obj.type === Const.OBJECT_TYPE_CONIC ||\r\n            obj.type === Const.OBJECT_TYPE_SECTOR)\r\n    ) {\r\n        if (obj.type === Const.OBJECT_TYPE_SECTOR) {\r\n            attr = Type.copyAttributes(attributes, board.options, 'sector');\r\n        } else if (obj.type === Const.OBJECT_TYPE_ARC) {\r\n            attr = Type.copyAttributes(attributes, board.options, 'arc');\r\n        } else if (obj.type === Const.OBJECT_TYPE_ANGLE) {\r\n            if (!Type.exists(attributes.withLabel)) {\r\n                attributes.withLabel = false;\r\n            }\r\n            attr = Type.copyAttributes(attributes, board.options, 'angle');\r\n        } else {\r\n            attr = Type.copyAttributes(attributes, board.options, 'curve');\r\n        }\r\n        attr = Type.copyAttributes(attr, board.options, 'curve');\r\n\r\n        cu = new JXG.Curve(board, [\"x\", [], []], attr);\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        cu.updateDataArray = function () {\r\n            var i,\r\n                le = obj.numberPoints;\r\n            this.bezierDegree = obj.bezierDegree;\r\n            this.dataX = [];\r\n            this.dataY = [];\r\n            for (i = 0; i < le; i++) {\r\n                this.dataX.push(obj.points[i].usrCoords[1]);\r\n                this.dataY.push(obj.points[i].usrCoords[2]);\r\n            }\r\n            return this;\r\n        };\r\n        cu.addTransform(parents[1]);\r\n        obj.addChild(cu);\r\n        cu.setParents([obj]);\r\n        cu._transformationSource = obj;\r\n\r\n        return cu;\r\n    }\r\n    attr = Type.copyAttributes(attributes, board.options, 'curve');\r\n    return new JXG.Curve(board, [\"x\"].concat(parents), attr);\r\n};\r\n\r\nJXG.registerElement(\"curve\", JXG.createCurve);\r\n\r\n/**\r\n * @class A functiongraph visualizes a map x &rarr; f(x).\r\n * The graph is displayed for x in the interval [a,b] and is a {@link Curve} element.\r\n * @pseudo\r\n * @name Functiongraph\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n * @param {function_number,function_number,function} f,a_,b_ Parent elements are a function term f(x) describing the function graph.\r\n *         <p>\r\n *         Further, an optional number or function for the left interval border a,\r\n *         and an optional number or function for the right interval border b.\r\n *         <p>\r\n *         Default values are a=-10 and b=10.\r\n * @see JXG.Curve\r\n * @example\r\n * // Create a function graph for f(x) = 0.5*x*x-2*x\r\n *   var graph = board.create('functiongraph',\r\n *                        [function(x){ return 0.5*x*x-2*x;}, -2, 4]\r\n *                     );\r\n * </pre><div class=\"jxgbox\" id=\"JXGefd432b5-23a3-4846-ac5b-b471e668b437\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var alex1_board = JXG.JSXGraph.initBoard('JXGefd432b5-23a3-4846-ac5b-b471e668b437', {boundingbox: [-3, 7, 5, -3], axis: true, showcopyright: false, shownavigation: false});\r\n *   var graph = alex1_board.create('functiongraph', [function(x){ return 0.5*x*x-2*x;}, -2, 4]);\r\n * </script><pre>\r\n * @example\r\n * // Create a function graph for f(x) = 0.5*x*x-2*x with variable interval\r\n *   var s = board.create('slider',[[0,4],[3,4],[-2,4,5]]);\r\n *   var graph = board.create('functiongraph',\r\n *                        [function(x){ return 0.5*x*x-2*x;},\r\n *                         -2,\r\n *                         function(){return s.Value();}]\r\n *                     );\r\n * </pre><div class=\"jxgbox\" id=\"JXG4a203a84-bde5-4371-ad56-44619690bb50\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var alex2_board = JXG.JSXGraph.initBoard('JXG4a203a84-bde5-4371-ad56-44619690bb50', {boundingbox: [-3, 7, 5, -3], axis: true, showcopyright: false, shownavigation: false});\r\n *   var s = alex2_board.create('slider',[[0,4],[3,4],[-2,4,5]]);\r\n *   var graph = alex2_board.create('functiongraph', [function(x){ return 0.5*x*x-2*x;}, -2, function(){return s.Value();}]);\r\n * </script><pre>\r\n */\r\nJXG.createFunctiongraph = function (board, parents, attributes) {\r\n    var attr,\r\n        par = [\"x\", \"x\"].concat(parents); // variable name and identity function for x-coordinate\r\n    // par = [\"x\", function(x) { return x; }].concat(parents);\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'functiongraph');\r\n    attr = Type.copyAttributes(attr, board.options, 'curve');\r\n    attr.curvetype = 'functiongraph';\r\n    return new JXG.Curve(board, par, attr);\r\n};\r\n\r\nJXG.registerElement(\"functiongraph\", JXG.createFunctiongraph);\r\nJXG.registerElement(\"plot\", JXG.createFunctiongraph);\r\n\r\n/**\r\n * @class The (natural) cubic spline curves (function graph) interpolating a set of points.\r\n * Create a dynamic spline interpolated curve given by sample points p_1 to p_n.\r\n * @pseudo\r\n * @name Spline\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n * @param {JXG.Board} board Reference to the board the spline is drawn on.\r\n * @param {Array} parents Array of points the spline interpolates. This can be\r\n *   <ul>\r\n *   <li> an array of JSXGraph points</li>\r\n *   <li> an array of coordinate pairs</li>\r\n *   <li> an array of functions returning coordinate pairs</li>\r\n *   <li> an array consisting of an array with x-coordinates and an array of y-coordinates</li>\r\n *   </ul>\r\n *   All individual entries of coordinates arrays may be numbers or functions returning numbers.\r\n * @param {Object} attributes Define color, width, ... of the spline\r\n * @returns {JXG.Curve} Returns reference to an object of type JXG.Curve.\r\n * @see JXG.Curve\r\n * @example\r\n *\r\n * var p = [];\r\n * p[0] = board.create('point', [-2,2], {size: 4, face: 'o'});\r\n * p[1] = board.create('point', [0,-1], {size: 4, face: 'o'});\r\n * p[2] = board.create('point', [2,0], {size: 4, face: 'o'});\r\n * p[3] = board.create('point', [4,1], {size: 4, face: 'o'});\r\n *\r\n * var c = board.create('spline', p, {strokeWidth:3});\r\n * </pre><div id=\"JXG6c197afc-e482-11e5-b1bf-901b0e1b8723\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG6c197afc-e482-11e5-b1bf-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *\r\n *     var p = [];\r\n *     p[0] = board.create('point', [-2,2], {size: 4, face: 'o'});\r\n *     p[1] = board.create('point', [0,-1], {size: 4, face: 'o'});\r\n *     p[2] = board.create('point', [2,0], {size: 4, face: 'o'});\r\n *     p[3] = board.create('point', [4,1], {size: 4, face: 'o'});\r\n *\r\n *     var c = board.create('spline', p, {strokeWidth:3});\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createSpline = function (board, parents, attributes) {\r\n    var el, funcs, ret;\r\n\r\n    funcs = function () {\r\n        var D,\r\n            x = [],\r\n            y = [];\r\n\r\n        return [\r\n            function (t, suspended) {\r\n                // Function term\r\n                var i, j, c;\r\n\r\n                if (!suspended) {\r\n                    x = [];\r\n                    y = [];\r\n\r\n                    // given as [x[], y[]]\r\n                    if (\r\n                        parents.length === 2 &&\r\n                        Type.isArray(parents[0]) &&\r\n                        Type.isArray(parents[1]) &&\r\n                        parents[0].length === parents[1].length\r\n                    ) {\r\n                        for (i = 0; i < parents[0].length; i++) {\r\n                            if (Type.isFunction(parents[0][i])) {\r\n                                x.push(parents[0][i]());\r\n                            } else {\r\n                                x.push(parents[0][i]);\r\n                            }\r\n\r\n                            if (Type.isFunction(parents[1][i])) {\r\n                                y.push(parents[1][i]());\r\n                            } else {\r\n                                y.push(parents[1][i]);\r\n                            }\r\n                        }\r\n                    } else {\r\n                        for (i = 0; i < parents.length; i++) {\r\n                            if (Type.isPoint(parents[i])) {\r\n                                x.push(parents[i].X());\r\n                                y.push(parents[i].Y());\r\n                                // given as [[x1,y1], [x2, y2], ...]\r\n                            } else if (Type.isArray(parents[i]) && parents[i].length === 2) {\r\n                                for (j = 0; j < parents.length; j++) {\r\n                                    if (Type.isFunction(parents[j][0])) {\r\n                                        x.push(parents[j][0]());\r\n                                    } else {\r\n                                        x.push(parents[j][0]);\r\n                                    }\r\n\r\n                                    if (Type.isFunction(parents[j][1])) {\r\n                                        y.push(parents[j][1]());\r\n                                    } else {\r\n                                        y.push(parents[j][1]);\r\n                                    }\r\n                                }\r\n                            } else if (\r\n                                Type.isFunction(parents[i]) &&\r\n                                parents[i]().length === 2\r\n                            ) {\r\n                                c = parents[i]();\r\n                                x.push(c[0]);\r\n                                y.push(c[1]);\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                    // The array D has only to be calculated when the position of one or more sample points\r\n                    // changes. Otherwise D is always the same for all points on the spline.\r\n                    D = Numerics.splineDef(x, y);\r\n                }\r\n\r\n                return Numerics.splineEval(t, x, y, D);\r\n            },\r\n            // minX()\r\n            function () {\r\n                return x[0];\r\n            },\r\n            //maxX()\r\n            function () {\r\n                return x[x.length - 1];\r\n            }\r\n        ];\r\n    };\r\n\r\n    attributes = Type.copyAttributes(attributes, board.options, 'curve');\r\n    attributes.curvetype = 'functiongraph';\r\n    ret = funcs();\r\n    el = new JXG.Curve(board, [\"x\", \"x\", ret[0], ret[1], ret[2]], attributes);\r\n    el.setParents(parents);\r\n    el.elType = 'spline';\r\n\r\n    return el;\r\n};\r\n\r\n/**\r\n * Register the element type spline at JSXGraph\r\n * @private\r\n */\r\nJXG.registerElement(\"spline\", JXG.createSpline);\r\n\r\n/**\r\n * @class Cardinal spline curve through a given data set.\r\n * Create a dynamic cardinal spline interpolated curve given by sample points p_1 to p_n.\r\n * @pseudo\r\n * @name Cardinalspline\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n * @param {Array} points Points array defining the cardinal spline. This can be\r\n *   <ul>\r\n *   <li> an array of JSXGraph points</li>\r\n *   <li> an array of coordinate pairs</li>\r\n *   <li> an array of functions returning coordinate pairs</li>\r\n *   <li> an array consisting of an array with x-coordinates and an array of y-coordinates</li>\r\n *   </ul>\r\n *   All individual entries of coordinates arrays may be numbers or functions returning numbers.\r\n * @param {function,Number} tau Tension parameter\r\n * @param {String} [type='uniform'] Type of the cardinal spline, may be 'uniform' (default) or 'centripetal'\r\n * @see JXG.Curve\r\n * @example\r\n * //Create a cardinal spline out of an array of JXG points with adjustable tension\r\n *\r\n * //Create array of points\r\n * var p = [];\r\n * p.push(board.create('point',[0,0]));\r\n * p.push(board.create('point',[1,4]));\r\n * p.push(board.create('point',[4,5]));\r\n * p.push(board.create('point',[2,3]));\r\n * p.push(board.create('point',[3,0]));\r\n *\r\n * // tension\r\n * var tau = board.create('slider', [[-4,-5],[2,-5],[0.001,0.5,1]], {name:'tau'});\r\n * var c = board.create('cardinalspline', [p, function(){ return tau.Value();}], {strokeWidth:3});\r\n *\r\n * </pre><div id=\"JXG1537cb69-4d45-43aa-8fc3-c6d4f98b4cdd\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG1537cb69-4d45-43aa-8fc3-c6d4f98b4cdd',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     //Create a cardinal spline out of an array of JXG points with adjustable tension\r\n *\r\n *     //Create array of points\r\n *     var p = [];\r\n *     p.push(board.create('point',[0,0]));\r\n *     p.push(board.create('point',[1,4]));\r\n *     p.push(board.create('point',[4,5]));\r\n *     p.push(board.create('point',[2,3]));\r\n *     p.push(board.create('point',[3,0]));\r\n *\r\n *     // tension\r\n *     var tau = board.create('slider', [[-4,-5],[2,-5],[0.001,0.5,1]], {name:'tau'});\r\n *     var c = board.create('cardinalspline', [p, function(){ return tau.Value();}], {strokeWidth:3});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createCardinalSpline = function (board, parents, attributes) {\r\n    var el,\r\n        getPointLike,\r\n        points,\r\n        tau,\r\n        type,\r\n        p,\r\n        q,\r\n        i,\r\n        le,\r\n        splineArr,\r\n        errStr = \"\\nPossible parent types: [points:array, tau:number|function, type:string]\";\r\n\r\n    if (!Type.exists(parents[0]) || !Type.isArray(parents[0])) {\r\n        throw new Error(\r\n            \"JSXGraph: JXG.createCardinalSpline: argument 1 'points' has to be array of points or coordinate pairs\" +\r\n            errStr\r\n        );\r\n    }\r\n    if (\r\n        !Type.exists(parents[1]) ||\r\n        (!Type.isNumber(parents[1]) && !Type.isFunction(parents[1]))\r\n    ) {\r\n        throw new Error(\r\n            \"JSXGraph: JXG.createCardinalSpline: argument 2 'tau' has to be number between [0,1] or function'\" +\r\n            errStr\r\n        );\r\n    }\r\n    if (!Type.exists(parents[2]) || !Type.isString(parents[2])) {\r\n        type = 'uniform';\r\n        // throw new Error(\r\n        //     \"JSXGraph: JXG.createCardinalSpline: argument 3 'type' has to be string 'uniform' or 'centripetal'\" +\r\n        //     errStr\r\n        // );\r\n    } else {\r\n        type = parents[2];\r\n    }\r\n\r\n    attributes = Type.copyAttributes(attributes, board.options, 'curve');\r\n    attributes = Type.copyAttributes(attributes, board.options, 'cardinalspline');\r\n    attributes.curvetype = 'parameter';\r\n\r\n    p = parents[0];\r\n    q = [];\r\n\r\n    // Given as [x[], y[]]\r\n    if (\r\n        !attributes.isarrayofcoordinates &&\r\n        p.length === 2 &&\r\n        Type.isArray(p[0]) &&\r\n        Type.isArray(p[1]) &&\r\n        p[0].length === p[1].length\r\n    ) {\r\n        for (i = 0; i < p[0].length; i++) {\r\n            q[i] = [];\r\n            if (Type.isFunction(p[0][i])) {\r\n                q[i].push(p[0][i]());\r\n            } else {\r\n                q[i].push(p[0][i]);\r\n            }\r\n\r\n            if (Type.isFunction(p[1][i])) {\r\n                q[i].push(p[1][i]());\r\n            } else {\r\n                q[i].push(p[1][i]);\r\n            }\r\n        }\r\n    } else {\r\n        // given as [[x0, y0], [x1, y1], point, ...]\r\n        for (i = 0; i < p.length; i++) {\r\n            if (Type.isString(p[i])) {\r\n                q.push(board.select(p[i]));\r\n            } else if (Type.isPoint(p[i])) {\r\n                q.push(p[i]);\r\n                // given as [[x0,y0], [x1, y2], ...]\r\n            } else if (Type.isArray(p[i]) && p[i].length === 2) {\r\n                q[i] = [];\r\n                if (Type.isFunction(p[i][0])) {\r\n                    q[i].push(p[i][0]());\r\n                } else {\r\n                    q[i].push(p[i][0]);\r\n                }\r\n\r\n                if (Type.isFunction(p[i][1])) {\r\n                    q[i].push(p[i][1]());\r\n                } else {\r\n                    q[i].push(p[i][1]);\r\n                }\r\n            } else if (Type.isFunction(p[i]) && p[i]().length === 2) {\r\n                q.push(parents[i]());\r\n            }\r\n        }\r\n    }\r\n\r\n    if (attributes.createpoints === true) {\r\n        points = Type.providePoints(board, q, attributes, \"cardinalspline\", [\"points\"]);\r\n    } else {\r\n        points = [];\r\n\r\n        /**\r\n         * @ignore\r\n         */\r\n        getPointLike = function (ii) {\r\n            return {\r\n                X: function () {\r\n                    return q[ii][0];\r\n                },\r\n                Y: function () {\r\n                    return q[ii][1];\r\n                },\r\n                Dist: function (p) {\r\n                    var dx = this.X() - p.X(),\r\n                        dy = this.Y() - p.Y();\r\n\r\n                    return Mat.hypot(dx, dy);\r\n                }\r\n            };\r\n        };\r\n\r\n        for (i = 0; i < q.length; i++) {\r\n            if (Type.isPoint(q[i])) {\r\n                points.push(q[i]);\r\n            } else {\r\n                points.push(getPointLike(i));\r\n            }\r\n        }\r\n    }\r\n\r\n    tau = parents[1];\r\n    // type = parents[2];\r\n\r\n    splineArr = [\"x\"].concat(Numerics.CardinalSpline(points, tau, type));\r\n\r\n    el = new JXG.Curve(board, splineArr, attributes);\r\n    le = points.length;\r\n    el.setParents(points);\r\n    for (i = 0; i < le; i++) {\r\n        p = points[i];\r\n        if (Type.isPoint(p)) {\r\n            if (Type.exists(p._is_new)) {\r\n                el.addChild(p);\r\n                delete p._is_new;\r\n            } else {\r\n                p.addChild(el);\r\n            }\r\n        }\r\n    }\r\n    el.elType = 'cardinalspline';\r\n\r\n    return el;\r\n};\r\n\r\n/**\r\n * Register the element type cardinalspline at JSXGraph\r\n * @private\r\n */\r\nJXG.registerElement(\"cardinalspline\", JXG.createCardinalSpline);\r\n\r\n/**\r\n * @class Interpolate data points by the spline curve from Metapost (by Donald Knuth and John Hobby).\r\n * Create a dynamic metapost spline interpolated curve given by sample points p_1 to p_n.\r\n * @pseudo\r\n * @name Metapostspline\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n * @param {JXG.Board} board Reference to the board the metapost spline is drawn on.\r\n * @param {Array} parents Array with two entries.\r\n * <p>\r\n *   First entry: Array of points the spline interpolates. This can be\r\n *   <ul>\r\n *   <li> an array of JSXGraph points</li>\r\n *   <li> an object of coordinate pairs</li>\r\n *   <li> an array of functions returning coordinate pairs</li>\r\n *   <li> an array consisting of an array with x-coordinates and an array of y-coordinates</li>\r\n *   </ul>\r\n *   All individual entries of coordinates arrays may be numbers or functions returning numbers.\r\n *   <p>\r\n *   Second entry: JavaScript object containing the control values like tension, direction, curl.\r\n * @param {Object} attributes Define color, width, ... of the metapost spline\r\n * @returns {JXG.Curve} Returns reference to an object of type JXG.Curve.\r\n * @see JXG.Curve\r\n * @example\r\n *     var po = [],\r\n *         attr = {\r\n *             size: 5,\r\n *             color: 'red'\r\n *         },\r\n *         controls;\r\n *\r\n *     var tension = board.create('slider', [[-3, 6], [3, 6], [0, 1, 20]], {name: 'tension'});\r\n *     var curl = board.create('slider', [[-3, 5], [3, 5], [0, 1, 30]], {name: 'curl A, D'});\r\n *     var dir = board.create('slider', [[-3, 4], [3, 4], [-180, 0, 180]], {name: 'direction B'});\r\n *\r\n *     po.push(board.create('point', [-3, -3]));\r\n *     po.push(board.create('point', [0, -3]));\r\n *     po.push(board.create('point', [4, -5]));\r\n *     po.push(board.create('point', [6, -2]));\r\n *\r\n *     var controls = {\r\n *         tension: function() {return tension.Value(); },\r\n *         direction: { 1: function() {return dir.Value(); } },\r\n *         curl: { 0: function() {return curl.Value(); },\r\n *                 3: function() {return curl.Value(); }\r\n *             },\r\n *         isClosed: false\r\n *     };\r\n *\r\n *     // Plot a metapost curve\r\n *     var cu = board.create('metapostspline', [po, controls], {strokeColor: 'blue', strokeWidth: 2});\r\n *\r\n *\r\n * </pre><div id=\"JXGb8c6ffed-7419-41a3-9e55-3754b2327ae9\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGb8c6ffed-7419-41a3-9e55-3754b2327ae9',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *         var po = [],\r\n *             attr = {\r\n *                 size: 5,\r\n *                 color: 'red'\r\n *             },\r\n *             controls;\r\n *\r\n *         var tension = board.create('slider', [[-3, 6], [3, 6], [0, 1, 20]], {name: 'tension'});\r\n *         var curl = board.create('slider', [[-3, 5], [3, 5], [0, 1, 30]], {name: 'curl A, D'});\r\n *         var dir = board.create('slider', [[-3, 4], [3, 4], [-180, 0, 180]], {name: 'direction B'});\r\n *\r\n *         po.push(board.create('point', [-3, -3]));\r\n *         po.push(board.create('point', [0, -3]));\r\n *         po.push(board.create('point', [4, -5]));\r\n *         po.push(board.create('point', [6, -2]));\r\n *\r\n *         var controls = {\r\n *             tension: function() {return tension.Value(); },\r\n *             direction: { 1: function() {return dir.Value(); } },\r\n *             curl: { 0: function() {return curl.Value(); },\r\n *                     3: function() {return curl.Value(); }\r\n *                 },\r\n *             isClosed: false\r\n *         };\r\n *\r\n *         // Plot a metapost curve\r\n *         var cu = board.create('metapostspline', [po, controls], {strokeColor: 'blue', strokeWidth: 2});\r\n *\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createMetapostSpline = function (board, parents, attributes) {\r\n    var el,\r\n        getPointLike,\r\n        points,\r\n        controls,\r\n        p,\r\n        q,\r\n        i,\r\n        le,\r\n        errStr = \"\\nPossible parent types: [points:array, controls:object\";\r\n\r\n    if (!Type.exists(parents[0]) || !Type.isArray(parents[0])) {\r\n        throw new Error(\r\n            \"JSXGraph: JXG.createMetapostSpline: argument 1 'points' has to be array of points or coordinate pairs\" +\r\n            errStr\r\n        );\r\n    }\r\n    if (!Type.exists(parents[1]) || !Type.isObject(parents[1])) {\r\n        throw new Error(\r\n            \"JSXGraph: JXG.createMetapostSpline: argument 2 'controls' has to be a JavaScript object'\" +\r\n            errStr\r\n        );\r\n    }\r\n\r\n    attributes = Type.copyAttributes(attributes, board.options, 'curve');\r\n    attributes = Type.copyAttributes(attributes, board.options, 'metapostspline');\r\n    attributes.curvetype = 'parameter';\r\n\r\n    p = parents[0];\r\n    q = [];\r\n\r\n    // given as [x[], y[]]\r\n    if (\r\n        !attributes.isarrayofcoordinates &&\r\n        p.length === 2 &&\r\n        Type.isArray(p[0]) &&\r\n        Type.isArray(p[1]) &&\r\n        p[0].length === p[1].length\r\n    ) {\r\n        for (i = 0; i < p[0].length; i++) {\r\n            q[i] = [];\r\n            if (Type.isFunction(p[0][i])) {\r\n                q[i].push(p[0][i]());\r\n            } else {\r\n                q[i].push(p[0][i]);\r\n            }\r\n\r\n            if (Type.isFunction(p[1][i])) {\r\n                q[i].push(p[1][i]());\r\n            } else {\r\n                q[i].push(p[1][i]);\r\n            }\r\n        }\r\n    } else {\r\n        // given as [[x0, y0], [x1, y1], point, ...]\r\n        for (i = 0; i < p.length; i++) {\r\n            if (Type.isString(p[i])) {\r\n                q.push(board.select(p[i]));\r\n            } else if (Type.isPoint(p[i])) {\r\n                q.push(p[i]);\r\n                // given as [[x0,y0], [x1, y2], ...]\r\n            } else if (Type.isArray(p[i]) && p[i].length === 2) {\r\n                q[i] = [];\r\n                if (Type.isFunction(p[i][0])) {\r\n                    q[i].push(p[i][0]());\r\n                } else {\r\n                    q[i].push(p[i][0]);\r\n                }\r\n\r\n                if (Type.isFunction(p[i][1])) {\r\n                    q[i].push(p[i][1]());\r\n                } else {\r\n                    q[i].push(p[i][1]);\r\n                }\r\n            } else if (Type.isFunction(p[i]) && p[i]().length === 2) {\r\n                q.push(parents[i]());\r\n            }\r\n        }\r\n    }\r\n\r\n    if (attributes.createpoints === true) {\r\n        points = Type.providePoints(board, q, attributes, 'metapostspline', ['points']);\r\n    } else {\r\n        points = [];\r\n\r\n        /**\r\n         * @ignore\r\n         */\r\n        getPointLike = function (ii) {\r\n            return {\r\n                X: function () {\r\n                    return q[ii][0];\r\n                },\r\n                Y: function () {\r\n                    return q[ii][1];\r\n                }\r\n            };\r\n        };\r\n\r\n        for (i = 0; i < q.length; i++) {\r\n            if (Type.isPoint(q[i])) {\r\n                points.push(q[i]);\r\n            } else {\r\n                points.push(getPointLike);\r\n            }\r\n        }\r\n    }\r\n\r\n    controls = parents[1];\r\n\r\n    el = new JXG.Curve(board, [\"t\", [], [], 0, p.length - 1], attributes);\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    el.updateDataArray = function () {\r\n        var res,\r\n            i,\r\n            len = points.length,\r\n            p = [];\r\n\r\n        for (i = 0; i < len; i++) {\r\n            p.push([points[i].X(), points[i].Y()]);\r\n        }\r\n\r\n        res = Metapost.curve(p, controls);\r\n        this.dataX = res[0];\r\n        this.dataY = res[1];\r\n    };\r\n    el.bezierDegree = 3;\r\n\r\n    le = points.length;\r\n    el.setParents(points);\r\n    for (i = 0; i < le; i++) {\r\n        if (Type.isPoint(points[i])) {\r\n            points[i].addChild(el);\r\n        }\r\n    }\r\n    el.elType = 'metapostspline';\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"metapostspline\", JXG.createMetapostSpline);\r\n\r\n/**\r\n * @class Visualize the Riemann sum which is an approximation of an integral by a finite sum.\r\n * It is realized as a special curve.\r\n * The returned element has the method Value() which returns the sum of the areas of the bars.\r\n * <p>\r\n * In case of type \"simpson\" and \"trapezoidal\", the horizontal line approximating the function value\r\n * is replaced by a parabola or a secant. IN case of \"simpson\",\r\n * the parabola is approximated visually by a polygonal chain of fixed step width.\r\n *\r\n * @pseudo\r\n * @name Riemannsum\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type Curve\r\n * @param {function,array_number,function_string,function_function,number_function,number} f,n,type_,a_,b_ Parent elements of Riemannsum are a\r\n *         Either a function term f(x) describing the function graph which is filled by the Riemann bars, or\r\n *         an array consisting of two functions and the area between is filled by the Riemann bars.\r\n *         <p>\r\n *         n determines the number of bars, it is either a fixed number or a function.\r\n *         <p>\r\n *         type is a string or function returning one of the values:  'left', 'right', 'middle', 'lower', 'upper', 'random', 'simpson', or 'trapezoidal'.\r\n *         Default value is 'left'. \"simpson\" is Simpson's 1/3 rule.\r\n *         <p>\r\n *         Further parameters are an optional number or function for the left interval border a,\r\n *         and an optional number or function for the right interval border b.\r\n *         <p>\r\n *         Default values are a=-10 and b=10.\r\n * @see JXG.Curve\r\n * @example\r\n * // Create Riemann sums for f(x) = 0.5*x*x-2*x.\r\n *   var s = board.create('slider',[[0,4],[3,4],[0,4,10]],{snapWidth:1});\r\n *   var f = function(x) { return 0.5*x*x-2*x; };\r\n *   var r = board.create('riemannsum',\r\n *               [f, function(){return s.Value();}, 'upper', -2, 5],\r\n *               {fillOpacity:0.4}\r\n *               );\r\n *   var g = board.create('functiongraph',[f, -2, 5]);\r\n *   var t = board.create('text',[-2,-2, function(){ return 'Sum=' + JXG.toFixed(r.Value(), 4); }]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG940f40cc-2015-420d-9191-c5d83de988cf\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function(){\r\n *   var board = JXG.JSXGraph.initBoard('JXG940f40cc-2015-420d-9191-c5d83de988cf', {boundingbox: [-3, 7, 5, -3], axis: true, showcopyright: false, shownavigation: false});\r\n *   var f = function(x) { return 0.5*x*x-2*x; };\r\n *   var s = board.create('slider',[[0,4],[3,4],[0,4,10]],{snapWidth:1});\r\n *   var r = board.create('riemannsum', [f, function(){return s.Value();}, 'upper', -2, 5], {fillOpacity:0.4});\r\n *   var g = board.create('functiongraph', [f, -2, 5]);\r\n *   var t = board.create('text',[-2,-2, function(){ return 'Sum=' + JXG.toFixed(r.Value(), 4); }]);\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n *   // Riemann sum between two functions\r\n *   var s = board.create('slider',[[0,4],[3,4],[0,4,10]],{snapWidth:1});\r\n *   var g = function(x) { return 0.5*x*x-2*x; };\r\n *   var f = function(x) { return -x*(x-4); };\r\n *   var r = board.create('riemannsum',\r\n *               [[g,f], function(){return s.Value();}, 'lower', 0, 4],\r\n *               {fillOpacity:0.4}\r\n *               );\r\n *   var f = board.create('functiongraph',[f, -2, 5]);\r\n *   var g = board.create('functiongraph',[g, -2, 5]);\r\n *   var t = board.create('text',[-2,-2, function(){ return 'Sum=' + JXG.toFixed(r.Value(), 4); }]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGf9a7ba38-b50f-4a32-a873-2f3bf9caee79\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function(){\r\n *   var board = JXG.JSXGraph.initBoard('JXGf9a7ba38-b50f-4a32-a873-2f3bf9caee79', {boundingbox: [-3, 7, 5, -3], axis: true, showcopyright: false, shownavigation: false});\r\n *   var s = board.create('slider',[[0,4],[3,4],[0,4,10]],{snapWidth:1});\r\n *   var g = function(x) { return 0.5*x*x-2*x; };\r\n *   var f = function(x) { return -x*(x-4); };\r\n *   var r = board.create('riemannsum',\r\n *               [[g,f], function(){return s.Value();}, 'lower', 0, 4],\r\n *               {fillOpacity:0.4}\r\n *               );\r\n *   var f = board.create('functiongraph',[f, -2, 5]);\r\n *   var g = board.create('functiongraph',[g, -2, 5]);\r\n *   var t = board.create('text',[-2,-2, function(){ return 'Sum=' + JXG.toFixed(r.Value(), 4); }]);\r\n * })();\r\n * </script><pre>\r\n */\r\nJXG.createRiemannsum = function (board, parents, attributes) {\r\n    var n, type, f, par, c, attr;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'riemannsum');\r\n    attr.curvetype = 'plot';\r\n\r\n    f = parents[0];\r\n    n = Type.createFunction(parents[1], board, \"\");\r\n\r\n    if (!Type.exists(n)) {\r\n        throw new Error(\r\n            \"JSXGraph: JXG.createRiemannsum: argument '2' n has to be number or function.\" +\r\n            \"\\nPossible parent types: [function,n:number|function,type,start:number|function,end:number|function]\"\r\n        );\r\n    }\r\n\r\n    if (typeof parents[2] === 'string') {\r\n        parents[2] = '\\'' + parents[2] + '\\'';\r\n    }\r\n\r\n    type = Type.createFunction(parents[2], board, \"\");\r\n    if (!Type.exists(type)) {\r\n        throw new Error(\r\n            \"JSXGraph: JXG.createRiemannsum: argument 3 'type' has to be string or function.\" +\r\n            \"\\nPossible parent types: [function,n:number|function,type,start:number|function,end:number|function]\"\r\n        );\r\n    }\r\n\r\n    par = [[0], [0]].concat(parents.slice(3));\r\n\r\n    c = board.create(\"curve\", par, attr);\r\n\r\n    c.sum = 0.0;\r\n    /**\r\n     * Returns the value of the Riemann sum, i.e. the sum of the (signed) areas of the rectangles.\r\n     * @name Value\r\n     * @memberOf Riemannsum.prototype\r\n     * @function\r\n     * @returns {Number} value of Riemann sum.\r\n     */\r\n    c.Value = function () {\r\n        return this.sum;\r\n    };\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    c.updateDataArray = function () {\r\n        var u = Numerics.riemann(f, n(), type(), this.minX(), this.maxX());\r\n        this.dataX = u[0];\r\n        this.dataY = u[1];\r\n\r\n        // Update \"Riemann sum\"\r\n        this.sum = u[2];\r\n    };\r\n\r\n    c.addParentsFromJCFunctions([n, type]);\r\n\r\n    return c;\r\n};\r\n\r\nJXG.registerElement(\"riemannsum\", JXG.createRiemannsum);\r\n\r\n/**\r\n * @class A trace curve is simple locus curve showing the orbit of a point that depends on a glider point.\r\n * @pseudo\r\n * @name Tracecurve\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type Object\r\n * @descript JXG.Curve\r\n * @param {Point} Parent elements of Tracecurve are a\r\n *         glider point and a point whose locus is traced.\r\n * @param {point}\r\n * @see JXG.Curve\r\n * @example\r\n * // Create trace curve.\r\n * var c1 = board.create('circle',[[0, 0], [2, 0]]),\r\n * p1 = board.create('point',[-3, 1]),\r\n * g1 = board.create('glider',[2, 1, c1]),\r\n * s1 = board.create('segment',[g1, p1]),\r\n * p2 = board.create('midpoint',[s1]),\r\n * curve = board.create('tracecurve', [g1, p2]);\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXG5749fb7d-04fc-44d2-973e-45c1951e29ad\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var tc1_board = JXG.JSXGraph.initBoard('JXG5749fb7d-04fc-44d2-973e-45c1951e29ad', {boundingbox: [-4, 4, 4, -4], axis: false, showcopyright: false, shownavigation: false});\r\n *   var c1 = tc1_board.create('circle',[[0, 0], [2, 0]]),\r\n *       p1 = tc1_board.create('point',[-3, 1]),\r\n *       g1 = tc1_board.create('glider',[2, 1, c1]),\r\n *       s1 = tc1_board.create('segment',[g1, p1]),\r\n *       p2 = tc1_board.create('midpoint',[s1]),\r\n *       curve = tc1_board.create('tracecurve', [g1, p2]);\r\n * </script><pre>\r\n */\r\nJXG.createTracecurve = function (board, parents, attributes) {\r\n    var c, glider, tracepoint, attr;\r\n\r\n    if (parents.length !== 2) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create trace curve with given parent'\" +\r\n            \"\\nPossible parent types: [glider, point]\"\r\n        );\r\n    }\r\n\r\n    glider = board.select(parents[0]);\r\n    tracepoint = board.select(parents[1]);\r\n\r\n    if (glider.type !== Const.OBJECT_TYPE_GLIDER || !Type.isPoint(tracepoint)) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create trace curve with parent types '\" +\r\n            typeof parents[0] +\r\n            \"' and '\" +\r\n            typeof parents[1] +\r\n            \"'.\" +\r\n            \"\\nPossible parent types: [glider, point]\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'tracecurve');\r\n    attr.curvetype = 'plot';\r\n    c = board.create(\"curve\", [[0], [0]], attr);\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    c.updateDataArray = function () {\r\n        var i, step, t, el, pEl, x, y, from,\r\n            savetrace,\r\n            le = this.visProp.numberpoints,\r\n            savePos = glider.position,\r\n            slideObj = glider.slideObject,\r\n            mi = slideObj.minX(),\r\n            ma = slideObj.maxX();\r\n\r\n        // set step width\r\n        step = (ma - mi) / le;\r\n        this.dataX = [];\r\n        this.dataY = [];\r\n\r\n        /*\r\n         * For gliders on circles and lines a closed curve is computed.\r\n         * For gliders on curves the curve is not closed.\r\n         */\r\n        if (slideObj.elementClass !== Const.OBJECT_CLASS_CURVE) {\r\n            le++;\r\n        }\r\n\r\n        // Loop over all steps\r\n        for (i = 0; i < le; i++) {\r\n            t = mi + i * step;\r\n            x = slideObj.X(t) / slideObj.Z(t);\r\n            y = slideObj.Y(t) / slideObj.Z(t);\r\n\r\n            // Position the glider\r\n            glider.setPositionDirectly(Const.COORDS_BY_USER, [x, y]);\r\n            from = false;\r\n\r\n            // Update all elements from the glider up to the trace element\r\n            for (el in this.board.objects) {\r\n                if (this.board.objects.hasOwnProperty(el)) {\r\n                    pEl = this.board.objects[el];\r\n\r\n                    if (pEl === glider) {\r\n                        from = true;\r\n                    }\r\n\r\n                    if (from && pEl.needsRegularUpdate) {\r\n                        // Save the trace mode of the element\r\n                        savetrace = pEl.visProp.trace;\r\n                        pEl.visProp.trace = false;\r\n                        pEl.needsUpdate = true;\r\n                        pEl.update(true);\r\n\r\n                        // Restore the trace mode\r\n                        pEl.visProp.trace = savetrace;\r\n                        if (pEl === tracepoint) {\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            // Store the position of the trace point\r\n            this.dataX[i] = tracepoint.X();\r\n            this.dataY[i] = tracepoint.Y();\r\n        }\r\n\r\n        // Restore the original position of the glider\r\n        glider.position = savePos;\r\n        from = false;\r\n\r\n        // Update all elements from the glider to the trace point\r\n        for (el in this.board.objects) {\r\n            if (this.board.objects.hasOwnProperty(el)) {\r\n                pEl = this.board.objects[el];\r\n                if (pEl === glider) {\r\n                    from = true;\r\n                }\r\n\r\n                if (from && pEl.needsRegularUpdate) {\r\n                    savetrace = pEl.visProp.trace;\r\n                    pEl.visProp.trace = false;\r\n                    pEl.needsUpdate = true;\r\n                    pEl.update(true);\r\n                    pEl.visProp.trace = savetrace;\r\n\r\n                    if (pEl === tracepoint) {\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    };\r\n\r\n    return c;\r\n};\r\n\r\nJXG.registerElement(\"tracecurve\", JXG.createTracecurve);\r\n\r\n/**\r\n     * @class A step function is a function graph that is piecewise constant.\r\n     *\r\n     * In case the data points should be updated after creation time,\r\n     * they can be accessed by curve.xterm and curve.yterm.\r\n     * @pseudo\r\n     * @name Stepfunction\r\n     * @augments JXG.Curve\r\n     * @constructor\r\n     * @type Curve\r\n     * @description JXG.Curve\r\n     * @param {Array|Function} Parent1 elements of Stepfunction are two arrays containing the coordinates.\r\n     * @param {Array|Function} Parent2\r\n     * @see JXG.Curve\r\n     * @example\r\n     * // Create step function.\r\n     var curve = board.create('stepfunction', [[0,1,2,3,4,5], [1,3,0,2,2,1]]);\r\n\r\n     * </pre><div class=\"jxgbox\" id=\"JXG32342ec9-ad17-4339-8a97-ff23dc34f51a\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *   var sf1_board = JXG.JSXGraph.initBoard('JXG32342ec9-ad17-4339-8a97-ff23dc34f51a', {boundingbox: [-1, 5, 6, -2], axis: true, showcopyright: false, shownavigation: false});\r\n     *   var curve = sf1_board.create('stepfunction', [[0,1,2,3,4,5], [1,3,0,2,2,1]]);\r\n     * </script><pre>\r\n     */\r\nJXG.createStepfunction = function (board, parents, attributes) {\r\n    var c, attr;\r\n    if (parents.length !== 2) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create step function with given parent'\" +\r\n            \"\\nPossible parent types: [array, array|function]\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'stepfunction');\r\n    c = board.create(\"curve\", parents, attr);\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    c.updateDataArray = function () {\r\n        var i,\r\n            j = 0,\r\n            len = this.xterm.length;\r\n\r\n        this.dataX = [];\r\n        this.dataY = [];\r\n\r\n        if (len === 0) {\r\n            return;\r\n        }\r\n\r\n        this.dataX[j] = this.xterm[0];\r\n        this.dataY[j] = this.yterm[0];\r\n        ++j;\r\n\r\n        for (i = 1; i < len; ++i) {\r\n            this.dataX[j] = this.xterm[i];\r\n            this.dataY[j] = this.dataY[j - 1];\r\n            ++j;\r\n            this.dataX[j] = this.xterm[i];\r\n            this.dataY[j] = this.yterm[i];\r\n            ++j;\r\n        }\r\n    };\r\n\r\n    return c;\r\n};\r\n\r\nJXG.registerElement(\"stepfunction\", JXG.createStepfunction);\r\n\r\n/**\r\n * @class A curve visualizing the function graph of the (numerical) derivative of a given curve.\r\n *\r\n * @pseudo\r\n * @name Derivative\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n * @param {JXG.Curve} Parent Curve for which the derivative is generated.\r\n * @see JXG.Curve\r\n * @example\r\n * var cu = board.create('cardinalspline', [[[-3,0], [-1,2], [0,1], [2,0], [3,1]], 0.5, 'centripetal'], {createPoints: false});\r\n * var d = board.create('derivative', [cu], {dash: 2});\r\n *\r\n * </pre><div id=\"JXGb9600738-1656-11e8-8184-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGb9600738-1656-11e8-8184-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var cu = board.create('cardinalspline', [[[-3,0], [-1,2], [0,1], [2,0], [3,1]], 0.5, 'centripetal'], {createPoints: false});\r\n *     var d = board.create('derivative', [cu], {dash: 2});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createDerivative = function (board, parents, attributes) {\r\n    var c, curve, dx, dy, attr;\r\n\r\n    if (parents.length !== 1 && parents[0].class !== Const.OBJECT_CLASS_CURVE) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create derivative curve with given parent'\" +\r\n            \"\\nPossible parent types: [curve]\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'curve');\r\n\r\n    curve = parents[0];\r\n    dx = Numerics.D(curve.X);\r\n    dy = Numerics.D(curve.Y);\r\n\r\n    c = board.create(\r\n        \"curve\",\r\n        [\r\n            function (t) {\r\n                return curve.X(t);\r\n            },\r\n            function (t) {\r\n                return dy(t) / dx(t);\r\n            },\r\n            curve.minX(),\r\n            curve.maxX()\r\n        ],\r\n        attr\r\n    );\r\n\r\n    c.setParents(curve);\r\n\r\n    return c;\r\n};\r\n\r\nJXG.registerElement(\"derivative\", JXG.createDerivative);\r\n\r\n/**\r\n * @class The path forming the intersection of two closed path elements.\r\n * The elements may be of type curve, circle, polygon, inequality.\r\n * If one element is a curve, it has to be closed.\r\n * The resulting element is of type curve.\r\n * @pseudo\r\n * @name CurveIntersection\r\n * @param {JXG.Curve|JXG.Polygon|JXG.Circle} curve1 First element which is intersected\r\n * @param {JXG.Curve|JXG.Polygon|JXG.Circle} curve2 Second element which is intersected\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n *\r\n * @example\r\n * var f = board.create('functiongraph', ['cos(x)']);\r\n * var ineq = board.create('inequality', [f], {inverse: true, fillOpacity: 0.1});\r\n * var circ = board.create('circle', [[0,0], 4]);\r\n * var clip = board.create('curveintersection', [ineq, circ], {fillColor: 'yellow', fillOpacity: 0.6});\r\n *\r\n * </pre><div id=\"JXGe2948257-8835-4276-9164-8acccb48e8d4\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGe2948257-8835-4276-9164-8acccb48e8d4',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var f = board.create('functiongraph', ['cos(x)']);\r\n *     var ineq = board.create('inequality', [f], {inverse: true, fillOpacity: 0.1});\r\n *     var circ = board.create('circle', [[0,0], 4]);\r\n *     var clip = board.create('curveintersection', [ineq, circ], {fillColor: 'yellow', fillOpacity: 0.6});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createCurveIntersection = function (board, parents, attributes) {\r\n    var c;\r\n\r\n    if (parents.length !== 2) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create curve intersection with given parent'\" +\r\n            \"\\nPossible parent types: [array, array|function]\"\r\n        );\r\n    }\r\n\r\n    c = board.create(\"curve\", [[], []], attributes);\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    c.updateDataArray = function () {\r\n        var a = Clip.intersection(parents[0], parents[1], this.board);\r\n        this.dataX = a[0];\r\n        this.dataY = a[1];\r\n    };\r\n    return c;\r\n};\r\n\r\n/**\r\n * @class The path forming the union of two closed path elements.\r\n * The elements may be of type curve, circle, polygon, inequality.\r\n * If one element is a curve, it has to be closed.\r\n * The resulting element is of type curve.\r\n * @pseudo\r\n * @name CurveUnion\r\n * @param {JXG.Curve|JXG.Polygon|JXG.Circle} curve1 First element defining the union\r\n * @param {JXG.Curve|JXG.Polygon|JXG.Circle} curve2 Second element defining the union\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n *\r\n * @example\r\n * var f = board.create('functiongraph', ['cos(x)']);\r\n * var ineq = board.create('inequality', [f], {inverse: true, fillOpacity: 0.1});\r\n * var circ = board.create('circle', [[0,0], 4]);\r\n * var clip = board.create('curveunion', [ineq, circ], {fillColor: 'yellow', fillOpacity: 0.6});\r\n *\r\n * </pre><div id=\"JXGe2948257-8835-4276-9164-8acccb48e8d4\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGe2948257-8835-4276-9164-8acccb48e8d4',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var f = board.create('functiongraph', ['cos(x)']);\r\n *     var ineq = board.create('inequality', [f], {inverse: true, fillOpacity: 0.1});\r\n *     var circ = board.create('circle', [[0,0], 4]);\r\n *     var clip = board.create('curveunion', [ineq, circ], {fillColor: 'yellow', fillOpacity: 0.6});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createCurveUnion = function (board, parents, attributes) {\r\n    var c;\r\n\r\n    if (parents.length !== 2) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create curve union with given parent'\" +\r\n            \"\\nPossible parent types: [array, array|function]\"\r\n        );\r\n    }\r\n\r\n    c = board.create(\"curve\", [[], []], attributes);\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    c.updateDataArray = function () {\r\n        var a = Clip.union(parents[0], parents[1], this.board);\r\n        this.dataX = a[0];\r\n        this.dataY = a[1];\r\n    };\r\n    return c;\r\n};\r\n\r\n/**\r\n * @class The path forming the difference of two closed path elements.\r\n * The elements may be of type curve, circle, polygon, inequality.\r\n * If one element is a curve, it has to be closed.\r\n * The resulting element is of type curve.\r\n * @pseudo\r\n * @name CurveDifference\r\n * @param {JXG.Curve|JXG.Polygon|JXG.Circle} curve1 First element from which the second element is \"subtracted\"\r\n * @param {JXG.Curve|JXG.Polygon|JXG.Circle} curve2 Second element which is subtracted from the first element\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n *\r\n * @example\r\n * var f = board.create('functiongraph', ['cos(x)']);\r\n * var ineq = board.create('inequality', [f], {inverse: true, fillOpacity: 0.1});\r\n * var circ = board.create('circle', [[0,0], 4]);\r\n * var clip = board.create('curvedifference', [ineq, circ], {fillColor: 'yellow', fillOpacity: 0.6});\r\n *\r\n * </pre><div id=\"JXGe2948257-8835-4276-9164-8acccb48e8d4\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGe2948257-8835-4276-9164-8acccb48e8d4',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var f = board.create('functiongraph', ['cos(x)']);\r\n *     var ineq = board.create('inequality', [f], {inverse: true, fillOpacity: 0.1});\r\n *     var circ = board.create('circle', [[0,0], 4]);\r\n *     var clip = board.create('curvedifference', [ineq, circ], {fillColor: 'yellow', fillOpacity: 0.6});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createCurveDifference = function (board, parents, attributes) {\r\n    var c;\r\n\r\n    if (parents.length !== 2) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create curve difference with given parent'\" +\r\n            \"\\nPossible parent types: [array, array|function]\"\r\n        );\r\n    }\r\n\r\n    c = board.create(\"curve\", [[], []], attributes);\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    c.updateDataArray = function () {\r\n        var a = Clip.difference(parents[0], parents[1], this.board);\r\n        this.dataX = a[0];\r\n        this.dataY = a[1];\r\n    };\r\n    return c;\r\n};\r\n\r\nJXG.registerElement(\"curvedifference\", JXG.createCurveDifference);\r\nJXG.registerElement(\"curveintersection\", JXG.createCurveIntersection);\r\nJXG.registerElement(\"curveunion\", JXG.createCurveUnion);\r\n\r\n// /**\r\n//  * @class Concat of two path elements, in general neither is a closed path. The parent elements have to be curves, too.\r\n//  * The resulting element is of type curve. The curve points are simply concatenated.\r\n//  * @pseudo\r\n//  * @name CurveConcat\r\n//  * @param {JXG.Curve} curve1 First curve element.\r\n//  * @param {JXG.Curve} curve2 Second curve element.\r\n//  * @augments JXG.Curve\r\n//  * @constructor\r\n//  * @type JXG.Curve\r\n//  */\r\n// JXG.createCurveConcat = function (board, parents, attributes) {\r\n//     var c;\r\n\r\n//     if (parents.length !== 2) {\r\n//         throw new Error(\r\n//             \"JSXGraph: Can't create curve difference with given parent'\" +\r\n//                 \"\\nPossible parent types: [array, array|function]\"\r\n//         );\r\n//     }\r\n\r\n//     c = board.create(\"curve\", [[], []], attributes);\r\n//     /**\r\n//      * @class\r\n//      * @ignore\r\n//      */\r\n//     c.updateCurve = function () {\r\n//         this.points = parents[0].points.concat(\r\n//                 [new JXG.Coords(Const.COORDS_BY_USER, [NaN, NaN], this.board)]\r\n//             ).concat(parents[1].points);\r\n//         this.numberPoints = this.points.length;\r\n//         return this;\r\n//     };\r\n\r\n//     return c;\r\n// };\r\n\r\n// JXG.registerElement(\"curveconcat\", JXG.createCurveConcat);\r\n\r\n/**\r\n * @class Vertical or horizontal box plot curve to present numerical data through their quartiles.\r\n * The direction of the box plot is controlled by the attribute \"dir\".\r\n * @pseudo\r\n * @name Boxplot\r\n * @param {Array} quantiles Array containing at least five quantiles. The elements can be of type number, function or string.\r\n * @param {Number|Function} axis Axis position of the box plot\r\n * @param {Number|Function} width Width of the rectangle part of the box plot. The width of the first and 4th quantile\r\n * is relative to this width and can be controlled by the attribute \"smallWidth\".\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n *\r\n * @example\r\n * var Q = [ -1, 2, 3, 3.5, 5 ];\r\n *\r\n * var b = board.create('boxplot', [Q, 2, 4], {strokeWidth: 3});\r\n *\r\n * </pre><div id=\"JXG13eb23a1-a641-41a2-be11-8e03e400a947\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG13eb23a1-a641-41a2-be11-8e03e400a947',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var Q = [ -1, 2, 3, 3.5, 5 ];\r\n *     var b = board.create('boxplot', [Q, 2, 4], {strokeWidth: 3});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var Q = [ -1, 2, 3, 3.5, 5 ];\r\n * var b = board.create('boxplot', [Q, 3, 4], {dir: 'horizontal', smallWidth: 0.25, color:'red'});\r\n *\r\n * </pre><div id=\"JXG0deb9cb2-84bc-470d-a6db-8be9a5694813\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG0deb9cb2-84bc-470d-a6db-8be9a5694813',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var Q = [ -1, 2, 3, 3.5, 5 ];\r\n *     var b = board.create('boxplot', [Q, 3, 4], {dir: 'horizontal', smallWidth: 0.25, color:'red'});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var data = [57, 57, 57, 58, 63, 66, 66, 67, 67, 68, 69, 70, 70, 70, 70, 72, 73, 75, 75, 76, 76, 78, 79, 81];\r\n * var Q = [];\r\n *\r\n * Q[0] = JXG.Math.Statistics.min(data);\r\n * Q = Q.concat(JXG.Math.Statistics.percentile(data, [25, 50, 75]));\r\n * Q[4] = JXG.Math.Statistics.max(data);\r\n *\r\n * var b = board.create('boxplot', [Q, 0, 3]);\r\n *\r\n * </pre><div id=\"JXGef079e76-ae99-41e4-af29-1d07d83bf85a\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGef079e76-ae99-41e4-af29-1d07d83bf85a',\r\n *             {boundingbox: [-5,90,5,30], axis: true, showcopyright: false, shownavigation: false});\r\n *     var data = [57, 57, 57, 58, 63, 66, 66, 67, 67, 68, 69, 70, 70, 70, 70, 72, 73, 75, 75, 76, 76, 78, 79, 81];\r\n *     var Q = [];\r\n *\r\n *     Q[0] = JXG.Math.Statistics.min(data);\r\n *     Q = Q.concat(JXG.Math.Statistics.percentile(data, [25, 50, 75]));\r\n *     Q[4] = JXG.Math.Statistics.max(data);\r\n *\r\n *     var b = board.create('boxplot', [Q, 0, 3]);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var mi = board.create('glider', [0, -1, board.defaultAxes.y]);\r\n * var ma = board.create('glider', [0, 5, board.defaultAxes.y]);\r\n * var Q = [function() { return mi.Y(); }, 2, 3, 3.5, function() { return ma.Y(); }];\r\n *\r\n * var b = board.create('boxplot', [Q, 0, 2]);\r\n *\r\n * </pre><div id=\"JXG3b3225da-52f0-42fe-8396-be9016bf289b\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG3b3225da-52f0-42fe-8396-be9016bf289b',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var mi = board.create('glider', [0, -1, board.defaultAxes.y]);\r\n *     var ma = board.create('glider', [0, 5, board.defaultAxes.y]);\r\n *     var Q = [function() { return mi.Y(); }, 2, 3, 3.5, function() { return ma.Y(); }];\r\n *\r\n *     var b = board.create('boxplot', [Q, 0, 2]);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createBoxPlot = function (board, parents, attributes) {\r\n    var box, i, len,\r\n        attr = Type.copyAttributes(attributes, board.options, 'boxplot');\r\n\r\n    if (parents.length !== 3) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create box plot with given parent'\" +\r\n            \"\\nPossible parent types: [array, number|function, number|function] containing quantiles, axis, width\"\r\n        );\r\n    }\r\n    if (parents[0].length < 5) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create box plot with given parent[0]'\" +\r\n            \"\\nparent[0] has to contain at least 5 quantiles.\"\r\n        );\r\n    }\r\n    box = board.create(\"curve\", [[], []], attr);\r\n\r\n    len = parents[0].length; // Quantiles\r\n    box.Q = [];\r\n    for (i = 0; i < len; i++) {\r\n        box.Q[i] = Type.createFunction(parents[0][i], board);\r\n    }\r\n    box.x = Type.createFunction(parents[1], board);\r\n    box.w = Type.createFunction(parents[2], board);\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    box.updateDataArray = function () {\r\n        var v1, v2, l1, l2, r1, r2, w2, dir, x;\r\n\r\n        w2 = this.evalVisProp('smallwidth');\r\n        dir = this.evalVisProp('dir');\r\n        x = this.x();\r\n        l1 = x - this.w() * 0.5;\r\n        l2 = x - this.w() * 0.5 * w2;\r\n        r1 = x + this.w() * 0.5;\r\n        r2 = x + this.w() * 0.5 * w2;\r\n        v1 = [x, l2, r2, x, x, l1, l1, r1, r1, x, NaN, l1, r1, NaN, x, x, l2, r2, x];\r\n        v2 = [\r\n            this.Q[0](),\r\n            this.Q[0](),\r\n            this.Q[0](),\r\n            this.Q[0](),\r\n            this.Q[1](),\r\n            this.Q[1](),\r\n            this.Q[3](),\r\n            this.Q[3](),\r\n            this.Q[1](),\r\n            this.Q[1](),\r\n            NaN,\r\n            this.Q[2](),\r\n            this.Q[2](),\r\n            NaN,\r\n            this.Q[3](),\r\n            this.Q[4](),\r\n            this.Q[4](),\r\n            this.Q[4](),\r\n            this.Q[4]()\r\n        ];\r\n        if (dir === 'vertical') {\r\n            this.dataX = v1;\r\n            this.dataY = v2;\r\n        } else {\r\n            this.dataX = v2;\r\n            this.dataY = v1;\r\n        }\r\n    };\r\n\r\n    box.addParentsFromJCFunctions([box.Q, box.x, box.w]);\r\n\r\n    return box;\r\n};\r\n\r\nJXG.registerElement(\"boxplot\", JXG.createBoxPlot);\r\n\r\n/**\r\n * @class An implicit curve is a plane curve defined by an implicit equation\r\n * relating two coordinate variables, commonly <i>x</i> and <i>y</i>.\r\n * For example, the unit circle is defined by the implicit equation\r\n * x<sup>2</sup> + y<sup>2</sup> = 1.\r\n * In general, every implicit curve is defined by an equation of the form\r\n * <i>f(x, y) = 0</i>\r\n * for some function <i>f</i> of two variables. (<a href=\"https://en.wikipedia.org/wiki/Implicit_curve\">Wikipedia</a>)\r\n * <p>\r\n * The partial derivatives for <i>f</i> are optional. If not given, numerical\r\n * derivatives are used instead. This is good enough for most practical use cases.\r\n * But if supplied, both partial derivatives must be supplied.\r\n * <p>\r\n * The most effective attributes to tinker with if the implicit curve algorithm fails are\r\n * {@link ImplicitCurve#resolution_outer},\r\n * {@link ImplicitCurve#resolution_inner},\r\n * {@link ImplicitCurve#alpha_0},\r\n * {@link ImplicitCurve#h_initial},\r\n * {@link ImplicitCurve#h_max}, and\r\n * {@link ImplicitCurve#qdt_box}.\r\n *\r\n * @pseudo\r\n * @name ImplicitCurve\r\n * @param {Function|String} f Function of two variables for the left side of the equation <i>f(x,y)=0</i>.\r\n * If f is supplied as string, it has to use the variables 'x' and 'y'.\r\n * @param {Function|String} [dfx=null] Optional partial derivative in respect to the first variable\r\n * If dfx is supplied as string, it has to use the variables 'x' and 'y'.\r\n * @param {Function|String} [dfy=null] Optional partial derivative in respect to the second variable\r\n * If dfy is supplied as string, it has to use the variables 'x' and 'y'.\r\n * @param {Array|Function} [rangex=boundingbox] Optional array of length 2\r\n * of the form [x_min, x_max] setting the domain of the x coordinate of the implicit curve.\r\n * If not supplied, the board's boundingbox (+ the attribute 'margin') is taken.\r\n * @param {Array|Function} [rangey=boundingbox] Optional array of length 2\r\n * of the form [y_min, y_max] setting the domain of the y coordinate of the implicit curve.\r\n * If not supplied, the board's boundingbox (+ the attribute 'margin') is taken.\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n *\r\n * @example\r\n *   var f, c;\r\n *   f = (x, y) => 1 / 16 * x ** 2 + y ** 2 - 1;\r\n *   c = board.create('implicitcurve', [f], {\r\n *       strokeWidth: 3,\r\n *       strokeColor: JXG.palette.red,\r\n *       strokeOpacity: 0.8\r\n *   });\r\n *\r\n * </pre><div id=\"JXGa6e86701-1a82-48d0-b007-3a3d32075076\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGa6e86701-1a82-48d0-b007-3a3d32075076',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *             var f, c;\r\n *             f = (x, y) => 1 / 16 * x ** 2 + y ** 2 - 1;\r\n *             c = board.create('implicitcurve', [f], {\r\n *                 strokeWidth: 3,\r\n *                 strokeColor: JXG.palette.red,\r\n *                 strokeOpacity: 0.8\r\n *             });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *  var a, c, f;\r\n *  a = board.create('slider', [[-3, 6], [3, 6], [-3, 1, 3]], {\r\n *      name: 'a', stepWidth: 0.1\r\n *  });\r\n *  f = (x, y) => x ** 2 - 2 * x * y - 2 * x + (a.Value() + 1) * y ** 2 + (4 * a.Value() + 2) * y + 4 * a.Value() - 3;\r\n *  c = board.create('implicitcurve', [f], {\r\n *      strokeWidth: 3,\r\n *      strokeColor: JXG.palette.red,\r\n *      strokeOpacity: 0.8,\r\n *      resolution_outer: 20,\r\n *      resolution_inner: 20\r\n *  });\r\n *\r\n * </pre><div id=\"JXG0b133a54-9509-4a65-9722-9c5145e23b40\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG0b133a54-9509-4a65-9722-9c5145e23b40',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *             var a, c, f;\r\n *             a = board.create('slider', [[-3, 6], [3, 6], [-3, 1, 3]], {\r\n *                 name: 'a', stepWidth: 0.1\r\n *             });\r\n *             f = (x, y) => x ** 2 - 2 * x * y - 2 * x + (a.Value() + 1) * y ** 2 + (4 * a.Value() + 2) * y + 4 * a.Value() - 3;\r\n *             c = board.create('implicitcurve', [f], {\r\n *                 strokeWidth: 3,\r\n *                 strokeColor: JXG.palette.red,\r\n *                 strokeOpacity: 0.8,\r\n *                 resolution_outer: 20,\r\n *                 resolution_inner: 20\r\n *             });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *  var c = board.create('implicitcurve', ['abs(x * y) - 3'], {\r\n *      strokeWidth: 3,\r\n *      strokeColor: JXG.palette.red,\r\n *      strokeOpacity: 0.8\r\n *  });\r\n *\r\n * </pre><div id=\"JXG02802981-0abb-446b-86ea-ee588f02ed1a\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG02802981-0abb-446b-86ea-ee588f02ed1a',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *             var c = board.create('implicitcurve', ['abs(x * y) - 3'], {\r\n *                 strokeWidth: 3,\r\n *                 strokeColor: JXG.palette.red,\r\n *                 strokeOpacity: 0.8\r\n *             });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var niveauline = [];\r\n * niveauline = [0.5, 1, 1.5, 2];\r\n * for (let i = 0; i < niveauline.length; i++) {\r\n *     board.create(\"implicitcurve\", [\r\n *         (x, y) => x ** .5 * y ** .5 - niveauline[i],\r\n           [0.25, 3], [0.5, 4] // Domain\r\n *     ], {\r\n *         strokeWidth: 2,\r\n *         strokeColor: JXG.palette.red,\r\n *         strokeOpacity: (1 + i) / niveauline.length,\r\n *         needsRegularUpdate: false\r\n *     });\r\n * }\r\n *\r\n * </pre><div id=\"JXGccee9aab-6dd9-4a79-827d-3164f70cc6a1\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGccee9aab-6dd9-4a79-827d-3164f70cc6a1',\r\n *             {boundingbox: [-1, 5, 5,-1], axis: true, showcopyright: false, shownavigation: false});\r\n *         var niveauline = [];\r\n *         niveauline = [0.5, 1, 1.5, 2];\r\n *         for (let i = 0; i < niveauline.length; i++) {\r\n *             board.create(\"implicitcurve\", [\r\n *                 (x, y) => x ** .5 * y ** .5 - niveauline[i],\r\n *                 [0.25, 3], [0.5, 4]\r\n *             ], {\r\n *                 strokeWidth: 2,\r\n *                 strokeColor: JXG.palette.red,\r\n *                 strokeOpacity: (1 + i) / niveauline.length,\r\n *                 needsRegularUpdate: false\r\n *             });\r\n *         }\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createImplicitCurve = function (board, parents, attributes) {\r\n    var c, attr;\r\n\r\n    if ([1, 3, 5].indexOf(parents.length) < 0) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create curve implicitCurve with given parent'\" +\r\n            \"\\nPossible parent types: [f], [f, rangex, rangey], [f, dfx, dfy] or [f, dfx, dfy, rangex, rangey]\" +\r\n            \"\\nwith functions f, dfx, dfy and arrays of length 2 rangex, rangey.\"\r\n        );\r\n    }\r\n\r\n    // if (parents.length === 3) {\r\n    //     if (!Type.isArray(parents[1]) && !Type.isArray(parents[2])) {\r\n    //         throw new Error(\r\n    //             \"JSXGraph: Can't create curve implicitCurve with given parent'\" +\r\n    //             \"\\nPossible parent types: [f], [f, rangex, rangey], [f, dfx, dfy] or [f, dfx, dfy, rangex, rangey]\" +\r\n    //             \"\\nwith functions f, dfx, dfy and arrays of length 2 rangex, rangey.\"\r\n    //         );\r\n    //     }\r\n    // }\r\n    // if (parents.length === 5) {\r\n    //     if (!Type.isArray(parents[3]) && !Type.isArray(parents[4])) {\r\n    //         throw new Error(\r\n    //             \"JSXGraph: Can't create curve implicitCurve with given parent'\" +\r\n    //             \"\\nPossible parent types: [f], [f, rangex, rangey], [f, dfx, dfy] or [f, dfx, dfy, rangex, rangey]\" +\r\n    //             \"\\nwith functions f, dfx, dfy and arrays of length 2 rangex, rangey.\"\r\n    //         );\r\n    //     }\r\n    // }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'implicitcurve');\r\n    c = board.create(\"curve\", [[], []], attr);\r\n\r\n    /**\r\n     * Function of two variables for the left side of the equation <i>f(x,y)=0</i>.\r\n     *\r\n     * @name f\r\n     * @memberOf ImplicitCurve.prototype\r\n     * @function\r\n     * @returns {Number}\r\n     */\r\n    c.f = Type.createFunction(parents[0], board, 'x, y');\r\n\r\n    /**\r\n     * Partial derivative in the first variable of\r\n     * the left side of the equation <i>f(x,y)=0</i>.\r\n     * If null, then numerical derivative is used.\r\n     *\r\n     * @name dfx\r\n     * @memberOf ImplicitCurve.prototype\r\n     * @function\r\n     * @returns {Number}\r\n     */\r\n    if (parents.length === 5 || Type.isString(parents[1]) || Type.isFunction(parents[1])) {\r\n        c.dfx = Type.createFunction(parents[1], board, 'x, y');\r\n    } else {\r\n        c.dfx = null;\r\n    }\r\n\r\n    /**\r\n     * Partial derivative in the second variable of\r\n     * the left side of the equation <i>f(x,y)=0</i>.\r\n     * If null, then numerical derivative is used.\r\n     *\r\n     * @name dfy\r\n     * @memberOf ImplicitCurve.prototype\r\n     * @function\r\n     * @returns {Number}\r\n     */\r\n    if (parents.length === 5 || Type.isString(parents[2]) || Type.isFunction(parents[2])) {\r\n        c.dfy = Type.createFunction(parents[2], board, 'x, y');\r\n    } else {\r\n        c.dfy = null;\r\n    }\r\n\r\n    /**\r\n     * Defines a domain for searching f(x,y)=0. Default is null, meaning\r\n     * the bounding box of the board is used.\r\n     * Using domain, visProp.margin is ignored.\r\n     * @name domain\r\n     * @memberOf ImplicitCurve.prototype\r\n     * @param {Array} of length 4 defining the domain used to compute the implict curve.\r\n     * Syntax: [x_min, y_max, x_max, y_min]\r\n     */\r\n    // c.domain = board.getBoundingBox();\r\n    c.domain = null;\r\n    if (parents.length === 5) {\r\n        c.domain = [parents[3], parents[4]];\r\n        //     [Math.min(parents[3][0], parents[3][1]), Math.max(parents[3][0], parents[3][1])],\r\n        //     [Math.min(parents[4][0], parents[4][1]), Math.max(parents[4][0], parents[4][1])]\r\n        // ];\r\n    } else if (parents.length === 3) {\r\n        c.domain = [parents[1], parents[2]];\r\n        //     [Math.min(parents[1][0], parents[1][1]), Math.max(parents[1][0], parents[1][1])],\r\n        //     [Math.min(parents[2][0], parents[2][1]), Math.max(parents[2][0], parents[2][1])]\r\n        // ];\r\n    }\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    c.updateDataArray = function () {\r\n        var bbox, rx, ry,\r\n            ip, cfg,\r\n            ret = [],\r\n            mgn;\r\n\r\n        if (this.domain === null) {\r\n            mgn = this.evalVisProp('margin');\r\n            bbox = this.board.getBoundingBox();\r\n            bbox[0] -= mgn;\r\n            bbox[1] += mgn;\r\n            bbox[2] += mgn;\r\n            bbox[3] -= mgn;\r\n        } else {\r\n            rx = Type.evaluate(this.domain[0]);\r\n            ry = Type.evaluate(this.domain[1]);\r\n            bbox = [\r\n                Math.min(rx[0], rx[1]),\r\n                Math.max(ry[0], ry[1]),\r\n                Math.max(rx[0], rx[1]),\r\n                Math.min(ry[0], ry[1])\r\n                // rx[0], ry[1], rx[1], ry[0]\r\n            ];\r\n        }\r\n\r\n        cfg = {\r\n            resolution_out: Math.max(0.01, this.evalVisProp('resolution_outer')),\r\n            resolution_in: Math.max(0.01, this.evalVisProp('resolution_inner')),\r\n            max_steps: this.evalVisProp('max_steps'),\r\n            alpha_0: this.evalVisProp('alpha_0'),\r\n            tol_u0: this.evalVisProp('tol_u0'),\r\n            tol_newton: this.evalVisProp('tol_newton'),\r\n            tol_cusp: this.evalVisProp('tol_cusp'),\r\n            tol_progress: this.evalVisProp('tol_progress'),\r\n            qdt_box: this.evalVisProp('qdt_box'),\r\n            kappa_0: this.evalVisProp('kappa_0'),\r\n            delta_0: this.evalVisProp('delta_0'),\r\n            h_initial: this.evalVisProp('h_initial'),\r\n            h_critical: this.evalVisProp('h_critical'),\r\n            h_max: this.evalVisProp('h_max'),\r\n            loop_dist: this.evalVisProp('loop_dist'),\r\n            loop_dir: this.evalVisProp('loop_dir'),\r\n            loop_detection: this.evalVisProp('loop_detection'),\r\n            unitX: this.board.unitX,\r\n            unitY: this.board.unitY\r\n        };\r\n        this.dataX = [];\r\n        this.dataY = [];\r\n\r\n        // console.time(\"implicit plot\");\r\n        ip = new ImplicitPlot(bbox, cfg, this.f, this.dfx, this.dfy);\r\n        this.qdt = ip.qdt;\r\n\r\n        ret = ip.plot();\r\n        // console.timeEnd(\"implicit plot\");\r\n\r\n        this.dataX = ret[0];\r\n        this.dataY = ret[1];\r\n    };\r\n\r\n    c.elType = 'implicitcurve';\r\n\r\n    return c;\r\n};\r\n\r\nJXG.registerElement(\"implicitcurve\", JXG.createImplicitCurve);\r\n\r\n\r\nexport default JXG.Curve;\r\n\r\n// export default {\r\n//     Curve: JXG.Curve,\r\n//     createCardinalSpline: JXG.createCardinalSpline,\r\n//     createCurve: JXG.createCurve,\r\n//     createCurveDifference: JXG.createCurveDifference,\r\n//     createCurveIntersection: JXG.createCurveIntersection,\r\n//     createCurveUnion: JXG.createCurveUnion,\r\n//     createDerivative: JXG.createDerivative,\r\n//     createFunctiongraph: JXG.createFunctiongraph,\r\n//     createMetapostSpline: JXG.createMetapostSpline,\r\n//     createPlot: JXG.createFunctiongraph,\r\n//     createSpline: JXG.createSpline,\r\n//     createRiemannsum: JXG.createRiemannsum,\r\n//     createStepfunction: JXG.createStepfunction,\r\n//     createTracecurve: JXG.createTracecurve\r\n// };\r\n\r\n// const Curve = JXG.Curve;\r\n// export { Curve as default, Curve};\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview In this file the geometry object Arc is defined. Arc stores all\r\n * style and functional properties that are required to draw an arc on a board.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Coords from \"../base/coords.js\";\r\nimport Circle from \"../base/circle.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Const from \"../base/constants.js\";\r\n\r\n/**\r\n * @class An arc is a partial circumference line of a circle.\r\n * It is defined by a center, one point that\r\n * defines the radius, and a third point that defines the angle of the arc.\r\n * <p>\r\n * As a curve the arc has curve length 6.\r\n * @pseudo\r\n * @name Arc\r\n * @augments Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 The result will be an arc of a circle around p1 through p2. The arc is drawn\r\n * counter-clockwise from p2 to p3.\r\n * @example\r\n * // Create an arc out of three free points\r\n * var p1 = board.create('point', [2.0, 2.0]);\r\n * var p2 = board.create('point', [1.0, 0.5]);\r\n * var p3 = board.create('point', [3.5, 1.0]);\r\n *\r\n * var a = board.create('arc', [p1, p2, p3]);\r\n * board.create('text',[1,6,function(){return 'arclength: '+Math.round(a.Value()*100)/100}])\r\n * </pre><div class=\"jxgbox\" id=\"JXG114ef584-4a5e-4686-8392-c97501befb5b\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG114ef584-4a5e-4686-8392-c97501befb5b', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),\r\n *       p1 = board.create('point', [2.0, 2.0]),\r\n *       p2 = board.create('point', [1.0, 0.5]),\r\n *       p3 = board.create('point', [3.5, 1.0]),\r\n *\r\n *       a = board.create('arc', [p1, p2, p3]);\r\n *       board.create('text',[1,6,function(){return 'arclength: '+Math.round(a.Value()*100)/100}])\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * var t = board.create('transform', [2, 1.5], {type: 'scale'});\r\n * var a1 = board.create('arc', [[1, 1], [0, 1], [1, 0]], {strokeColor: 'red'});\r\n * var a2 = board.create('curve', [a1, t], {strokeColor: 'red'});\r\n *\r\n * </pre><div id=\"JXG1949da46-6339-11e8-9fb9-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG1949da46-6339-11e8-9fb9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var t = board.create('transform', [2, 1.5], {type: 'scale'});\r\n *     var a1 = board.create('arc', [[1, 1], [0, 1], [1, 0]], {strokeColor: 'red'});\r\n *     var a2 = board.create('curve', [a1, t], {strokeColor: 'red'});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createArc = function (board, parents, attributes) {\r\n    var el, attr, points;\r\n\r\n    // attributes.radiusPoint = {visible: false};\r\n    points = Type.providePoints(board, parents, attributes, \"arc\", [\r\n        \"center\",\r\n        \"radiuspoint\",\r\n        \"anglepoint\"\r\n    ]);\r\n    if (points === false || points.length < 3) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create Arc with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"' and '\" +\r\n                typeof parents[2] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [point,point,point], [arc, transformation]\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'arc');\r\n    el = board.create(\"curve\", [[0], [0], 0, 4], attr);\r\n\r\n    el.elType = 'arc';\r\n    el.setParents(points);\r\n\r\n    /**\r\n     * documented in JXG.GeometryElement\r\n     * @ignore\r\n     */\r\n    el.type = Const.OBJECT_TYPE_ARC;\r\n\r\n    /**\r\n     * Center of the arc.\r\n     * @memberOf Arc.prototype\r\n     * @name center\r\n     * @type JXG.Point\r\n     */\r\n    el.center = points[0];\r\n\r\n    /**\r\n     * Point defining the arc's radius.\r\n     * @memberOf Arc.prototype\r\n     * @name radiuspoint\r\n     * @type JXG.Point\r\n     */\r\n    el.radiuspoint = points[1];\r\n    el.point2 = el.radiuspoint;\r\n\r\n    /**\r\n     * The point defining the arc's angle.\r\n     * @memberOf Arc.prototype\r\n     * @name anglepoint\r\n     * @type JXG.Point\r\n     */\r\n    el.anglepoint = points[2];\r\n    el.point3 = el.anglepoint;\r\n\r\n    // Add arc as child to defining points\r\n    // or vice versa if the points are provided as coordinates\r\n    if (Type.exists(el.center._is_new)) {\r\n        el.addChild(el.center);\r\n        delete el.center._is_new;\r\n    } else {\r\n        el.center.addChild(el);\r\n    }\r\n    if (Type.exists(el.radiuspoint._is_new)) {\r\n        el.addChild(el.radiuspoint);\r\n        delete el.radiuspoint._is_new;\r\n    } else {\r\n        el.radiuspoint.addChild(el);\r\n    }\r\n    if (Type.exists(el.anglepoint._is_new)) {\r\n        el.addChild(el.anglepoint);\r\n        delete el.anglepoint._is_new;\r\n    } else {\r\n        el.anglepoint.addChild(el);\r\n    }\r\n\r\n    // This attribute is necessary for circumCircleArcs\r\n    el.useDirection = attr.usedirection; // This makes the attribute immutable\r\n\r\n    // documented in JXG.Curve\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    el.updateDataArray = function () {\r\n        var ar, phi, det,\r\n            p0c, p1c, p2c,\r\n            sgn = 1,\r\n            A = this.radiuspoint,\r\n            B = this.center,\r\n            C = this.anglepoint,\r\n            ev_s = this.evalVisProp('selection');\r\n\r\n        phi = Geometry.rad(A, B, C);\r\n        if ((ev_s === \"minor\" && phi > Math.PI) || (ev_s === \"major\" && phi < Math.PI)) {\r\n            sgn = -1;\r\n        }\r\n\r\n        // This is true for circumCircleArcs. In that case there is\r\n        // a fourth parent element: [center, point1, point3, point2]\r\n        if (this.useDirection) {\r\n            p0c = points[1].coords.usrCoords;\r\n            p1c = points[3].coords.usrCoords;\r\n            p2c = points[2].coords.usrCoords;\r\n            det = (p0c[1] - p2c[1]) * (p0c[2] - p1c[2]) - (p0c[2] - p2c[2]) * (p0c[1] - p1c[1]);\r\n\r\n            if (det < 0) {\r\n                this.radiuspoint = points[1];\r\n                this.anglepoint = points[2];\r\n            } else {\r\n                this.radiuspoint = points[2];\r\n                this.anglepoint = points[1];\r\n            }\r\n        }\r\n\r\n        A = A.coords.usrCoords;\r\n        B = B.coords.usrCoords;\r\n        C = C.coords.usrCoords;\r\n\r\n        ar = Geometry.bezierArc(A, B, C, false, sgn);\r\n\r\n        this.dataX = ar[0];\r\n        this.dataY = ar[1];\r\n\r\n        this.bezierDegree = 3;\r\n\r\n        this.updateStdform();\r\n        this.updateQuadraticform();\r\n    };\r\n\r\n    /**\r\n     * Determines the arc's current radius. I.e. the distance between {@link Arc#center} and {@link Arc#radiuspoint}.\r\n     * @memberOf Arc.prototype\r\n     * @name Radius\r\n     * @function\r\n     * @returns {Number} The arc's radius\r\n     */\r\n    el.Radius = function () {\r\n        return this.radiuspoint.Dist(this.center);\r\n    };\r\n\r\n    /**\r\n     * @deprecated Use {@link Arc#Radius}\r\n     * @memberOf Arc.prototype\r\n     * @name getRadius\r\n     * @function\r\n     * @returns {Number}\r\n     */\r\n    el.getRadius = function () {\r\n        JXG.deprecated(\"Arc.getRadius()\", \"Arc.Radius()\");\r\n        return this.Radius();\r\n    };\r\n\r\n    /**\r\n     * Returns the length of the arc or the value of the angle spanned by the arc.\r\n     * @memberOf Arc.prototype\r\n     * @name Value\r\n     * @function\r\n     * @param {String} [unit='length'] Unit of the returned values. Possible units are\r\n     * <ul>\r\n     * <li> 'length' (default): length of the arc line\r\n     * <li> 'radians': angle spanned by the arc in radians\r\n     * <li> 'degrees': angle spanned by the arc in degrees\r\n     * <li> 'semicircle': angle spanned by the arc in radians as a multiple of &pi;, e.g. if the angle is 1.5&pi;, 1.5 will be returned.\r\n     * <li> 'circle': angle spanned by the arc in radians as a multiple of 2&pi;\r\n     * </ul>\r\n     * It is sufficient to supply the first three characters of the unit, e.g. 'len'.\r\n     * @param {Number} [rad=undefined] Value of angle which can be used instead of the generic one.\r\n     * @returns {Number} The arc length or the angle value in various units.\r\n     */\r\n    el.Value = function (unit, rad) {\r\n        var val;\r\n\r\n        rad = rad || Geometry.rad(this.radiuspoint, this.center, this.anglepoint);\r\n\r\n        unit = unit || 'length';\r\n        unit = unit.toLocaleLowerCase();\r\n        if (unit === '' || unit.indexOf('len') === 0) {\r\n            val = rad * this.Radius();\r\n        } else if (unit.indexOf('rad') === 0) {\r\n            val = rad;\r\n        } else if (unit.indexOf('deg') === 0) {\r\n            val = rad * 180 / Math.PI;\r\n        } else if (unit.indexOf('sem') === 0) {\r\n            val = rad / Math.PI;\r\n        } else if (unit.indexOf('cir') === 0) {\r\n            val = rad * 0.5 / Math.PI;\r\n        }\r\n\r\n        return val;\r\n    };\r\n\r\n    /**\r\n     * Arc length.\r\n     * @memberOf Arc.prototype\r\n     * @name L\r\n     * @returns {Number} Length of the arc.\r\n     * @see Arc#Value\r\n     */\r\n    el.L = function() {\r\n        return this.Value('length');\r\n    };\r\n\r\n    // documented in geometry element\r\n    el.hasPoint = function (x, y) {\r\n        var dist,\r\n            checkPoint,\r\n            has,\r\n            invMat,\r\n            c,\r\n            prec,\r\n            type,\r\n            r = this.Radius();\r\n\r\n        if (this.evalVisProp('hasinnerpoints')) {\r\n            return this.hasPointSector(x, y);\r\n        }\r\n\r\n        if (Type.isObject(this.evalVisProp('precision'))) {\r\n            type = this.board._inputDevice;\r\n            prec = this.evalVisProp('precision.' + type);\r\n        } else {\r\n            // 'inherit'\r\n            prec = this.board.options.precision.hasPoint;\r\n        }\r\n        prec /= Math.min(Math.abs(this.board.unitX), Math.abs(this.board.unitY));\r\n        checkPoint = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board);\r\n\r\n        if (this.transformations.length > 0) {\r\n            // Transform the mouse/touch coordinates\r\n            // back to the original position of the curve.\r\n            this.updateTransformMatrix();\r\n            invMat = Mat.inverse(this.transformMat);\r\n            c = Mat.matVecMult(invMat, checkPoint.usrCoords);\r\n            checkPoint = new Coords(Const.COORDS_BY_USER, c, this.board);\r\n        }\r\n\r\n        dist = this.center.coords.distance(Const.COORDS_BY_USER, checkPoint);\r\n        has = Math.abs(dist - r) < prec;\r\n\r\n        /**\r\n         * At that point we know that the user has touched the circle line.\r\n         * Now, we have to check, if the user has hit the arc path.\r\n         */\r\n        if (has) {\r\n            has = Geometry.coordsOnArc(this, checkPoint);\r\n        }\r\n        return has;\r\n    };\r\n\r\n    /**\r\n     * Checks whether (x,y) is within the sector defined by the arc.\r\n     * @memberOf Arc.prototype\r\n     * @name hasPointSector\r\n     * @function\r\n     * @param {Number} x Coordinate in x direction, screen coordinates.\r\n     * @param {Number} y Coordinate in y direction, screen coordinates.\r\n     * @returns {Boolean} True if (x,y) is within the sector defined by the arc, False otherwise.\r\n     */\r\n    el.hasPointSector = function (x, y) {\r\n        var checkPoint = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board),\r\n            r = this.Radius(),\r\n            dist = this.center.coords.distance(Const.COORDS_BY_USER, checkPoint),\r\n            has = dist < r;\r\n\r\n        if (has) {\r\n            has = Geometry.coordsOnArc(this, checkPoint);\r\n        }\r\n        return has;\r\n    };\r\n\r\n    // documented in geometry element\r\n    el.getTextAnchor = function () {\r\n        return this.center.coords;\r\n    };\r\n\r\n    // documented in geometry element\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    el.getLabelAnchor = function () {\r\n        var coords,\r\n            vec, vecx, vecy,\r\n            len,\r\n            pos = this.label.evalVisProp('position'),\r\n            angle = Geometry.rad(this.radiuspoint, this.center, this.anglepoint),\r\n            dx = 10 / this.board.unitX,\r\n            dy = 10 / this.board.unitY,\r\n            p2c = this.point2.coords.usrCoords,\r\n            pmc = this.center.coords.usrCoords,\r\n            bxminusax = p2c[1] - pmc[1],\r\n            byminusay = p2c[2] - pmc[2],\r\n            ev_s = this.evalVisProp('selection'),\r\n            l_vp = this.label ? this.label.visProp : this.visProp.label;\r\n\r\n        // If this is uncommented, the angle label can not be dragged\r\n        //if (Type.exists(this.label)) {\r\n        //    this.label.relativeCoords = new Coords(Const.COORDS_BY_SCREEN, [0, 0], this.board);\r\n        //}\r\n\r\n        if (\r\n            !Type.isString(pos) ||\r\n            (pos.indexOf('right') < 0 && pos.indexOf('left') < 0)\r\n        ) {\r\n\r\n            if ((ev_s === \"minor\" && angle > Math.PI) || (ev_s === \"major\" && angle < Math.PI)) {\r\n                angle = -(2 * Math.PI - angle);\r\n            }\r\n\r\n            coords = new Coords(\r\n                Const.COORDS_BY_USER,\r\n                [\r\n                    pmc[1] + Math.cos(angle * 0.5) * bxminusax - Math.sin(angle * 0.5) * byminusay,\r\n                    pmc[2] + Math.sin(angle * 0.5) * bxminusax + Math.cos(angle * 0.5) * byminusay\r\n                ],\r\n                this.board\r\n            );\r\n\r\n            vecx = coords.usrCoords[1] - pmc[1];\r\n            vecy = coords.usrCoords[2] - pmc[2];\r\n\r\n            len = Mat.hypot(vecx, vecy);\r\n            vecx = (vecx * (len + dx)) / len;\r\n            vecy = (vecy * (len + dy)) / len;\r\n            vec = [pmc[1] + vecx, pmc[2] + vecy];\r\n\r\n            l_vp.position = Geometry.calcLabelQuadrant(Geometry.rad([1, 0], [0, 0], vec));\r\n\r\n            return new Coords(Const.COORDS_BY_USER, vec, this.board);\r\n        } else {\r\n            return this.getLabelPosition(pos, this.label.evalVisProp('distance'));\r\n        }\r\n\r\n    };\r\n\r\n    // documentation in jxg.circle\r\n    el.updateQuadraticform = Circle.prototype.updateQuadraticform;\r\n\r\n    // documentation in jxg.circle\r\n    el.updateStdform = Circle.prototype.updateStdform;\r\n\r\n    el.methodMap = JXG.deepCopy(el.methodMap, {\r\n        getRadius: \"getRadius\",\r\n        radius: \"Radius\",\r\n        Radius: \"Radius\",\r\n        center: \"center\",\r\n        radiuspoint: \"radiuspoint\",\r\n        anglepoint: \"anglepoint\",\r\n        Value: \"Value\",\r\n        L: \"L\"\r\n    });\r\n\r\n    el.prepareUpdate().update();\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"arc\", JXG.createArc);\r\n\r\n/**\r\n * @class A semicircle is a special arc defined by two points. The arc hits both points.\r\n * @pseudo\r\n * @name Semicircle\r\n * @augments Arc\r\n * @constructor\r\n * @type Arc\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point} p1,p2 The result will be a composition of an arc drawn clockwise from <tt>p1</tt> and\r\n * <tt>p2</tt> and the midpoint of <tt>p1</tt> and <tt>p2</tt>.\r\n * @example\r\n * // Create an arc out of three free points\r\n * var p1 = board.create('point', [4.5, 2.0]);\r\n * var p2 = board.create('point', [1.0, 0.5]);\r\n *\r\n * var a = board.create('semicircle', [p1, p2]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG5385d349-75d7-4078-b732-9ae808db1b0e\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG5385d349-75d7-4078-b732-9ae808db1b0e', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),\r\n *       p1 = board.create('point', [4.5, 2.0]),\r\n *       p2 = board.create('point', [1.0, 0.5]),\r\n *\r\n *       sc = board.create('semicircle', [p1, p2]);\r\n * })();\r\n * </script><pre>\r\n */\r\nJXG.createSemicircle = function (board, parents, attributes) {\r\n    var el, mp, attr, points;\r\n\r\n    // we need 2 points\r\n    points = Type.providePoints(board, parents, attributes, 'point');\r\n    if (points === false || points.length !== 2) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create Semicircle with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [point,point]\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, \"semicircle\", 'center');\r\n    mp = board.create(\"midpoint\", points, attr);\r\n    mp.dump = false;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'semicircle');\r\n    el = board.create(\"arc\", [mp, points[1], points[0]], attr);\r\n    el.elType = 'semicircle';\r\n    el.setParents([points[0].id, points[1].id]);\r\n    el.subs = {\r\n        midpoint: mp\r\n    };\r\n    el.inherits.push(mp);\r\n\r\n    /**\r\n     * The midpoint of the two defining points.\r\n     * @memberOf Semicircle.prototype\r\n     * @name midpoint\r\n     * @type Midpoint\r\n     */\r\n    el.midpoint = el.center = mp;\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"semicircle\", JXG.createSemicircle);\r\n\r\n/**\r\n * @class A partial circum circle through three points.\r\n * @pseudo\r\n * @name CircumcircleArc\r\n * @augments Arc\r\n * @constructor\r\n * @type Arc\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 The result will be a composition of an arc of the circumcircle of\r\n * <tt>p1</tt>, <tt>p2</tt>, and <tt>p3</tt> and the midpoint of the circumcircle of the three points. The arc is drawn\r\n * counter-clockwise from <tt>p1</tt> over <tt>p2</tt> to <tt>p3</tt>.\r\n * @example\r\n * // Create a circum circle arc out of three free points\r\n * var p1 = board.create('point', [2.0, 2.0]);\r\n * var p2 = board.create('point', [1.0, 0.5]);\r\n * var p3 = board.create('point', [3.5, 1.0]);\r\n *\r\n * var a = board.create('circumcirclearc', [p1, p2, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG87125fd4-823a-41c1-88ef-d1a1369504e3\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG87125fd4-823a-41c1-88ef-d1a1369504e3', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),\r\n *       p1 = board.create('point', [2.0, 2.0]),\r\n *       p2 = board.create('point', [1.0, 0.5]),\r\n *       p3 = board.create('point', [3.5, 1.0]),\r\n *\r\n *       cca = board.create('circumcirclearc', [p1, p2, p3]);\r\n * })();\r\n * </script><pre>\r\n */\r\nJXG.createCircumcircleArc = function (board, parents, attributes) {\r\n    var el, mp, attr, points;\r\n\r\n    // We need three points\r\n    points = Type.providePoints(board, parents, attributes, 'point');\r\n    if (points === false || points.length !== 3) {\r\n        throw new Error(\r\n            \"JSXGraph: create Circumcircle Arc with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"' and '\" +\r\n                typeof parents[2] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [point,point,point]\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, \"circumcirclearc\", 'center');\r\n    mp = board.create(\"circumcenter\", points, attr);\r\n    mp.dump = false;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'circumcirclearc');\r\n    attr.usedirection = true;\r\n    el = board.create(\"arc\", [mp, points[0], points[2], points[1]], attr);\r\n\r\n    el.elType = 'circumcirclearc';\r\n    el.setParents([points[0].id, points[1].id, points[2].id]);\r\n    el.subs = {\r\n        center: mp\r\n    };\r\n    el.inherits.push(mp);\r\n\r\n    /**\r\n     * The midpoint of the circumcircle of the three points defining the circumcircle arc.\r\n     * @memberOf CircumcircleArc.prototype\r\n     * @name center\r\n     * @type Circumcenter\r\n     */\r\n    el.center = mp;\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"circumcirclearc\", JXG.createCircumcircleArc);\r\n\r\n/**\r\n * @class A minor arc given by three points is that part of the circumference of a circle having\r\n * measure at most 180 degrees (pi radians). It is defined by a center, one point that\r\n * defines the radius, and a third point that defines the angle of the arc.\r\n * @pseudo\r\n * @name MinorArc\r\n * @augments Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 . Minor arc is an arc of a circle around p1 having measure less than or equal to\r\n * 180 degrees (pi radians) and starts at p2. The radius is determined by p2, the angle by p3.\r\n * @example\r\n * // Create an arc out of three free points\r\n * var p1 = board.create('point', [2.0, 2.0]);\r\n * var p2 = board.create('point', [1.0, 0.5]);\r\n * var p3 = board.create('point', [3.5, 1.0]);\r\n *\r\n * var a = board.create('arc', [p1, p2, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG64ba7ca2-8728-45f3-96e5-3c7a4414de2f\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG64ba7ca2-8728-45f3-96e5-3c7a4414de2f', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),\r\n *       p1 = board.create('point', [2.0, 2.0]),\r\n *       p2 = board.create('point', [1.0, 0.5]),\r\n *       p3 = board.create('point', [3.5, 1.0]),\r\n *\r\n *       a = board.create('minorarc', [p1, p2, p3]);\r\n * })();\r\n * </script><pre>\r\n */\r\n\r\nJXG.createMinorArc = function (board, parents, attributes) {\r\n    attributes.selection = 'minor';\r\n    return JXG.createArc(board, parents, attributes);\r\n};\r\n\r\nJXG.registerElement(\"minorarc\", JXG.createMinorArc);\r\n\r\n/**\r\n * @class A major arc given by three points is that part of the circumference of a circle having\r\n * measure at least 180 degrees (pi radians). It is defined by a center, one point that\r\n * defines the radius, and a third point that defines the angle of the arc.\r\n * @pseudo\r\n * @name MajorArc\r\n * @augments Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 . Major arc is an arc of a circle around p1 having measure greater than or equal to\r\n * 180 degrees (pi radians) and starts at p2. The radius is determined by p2, the angle by p3.\r\n * @example\r\n * // Create an arc out of three free points\r\n * var p1 = board.create('point', [2.0, 2.0]);\r\n * var p2 = board.create('point', [1.0, 0.5]);\r\n * var p3 = board.create('point', [3.5, 1.0]);\r\n *\r\n * var a = board.create('majorarc', [p1, p2, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG17a10d38-5629-40a4-b150-f41806edee9f\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG17a10d38-5629-40a4-b150-f41806edee9f', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),\r\n *       p1 = board.create('point', [2.0, 2.0]),\r\n *       p2 = board.create('point', [1.0, 0.5]),\r\n *       p3 = board.create('point', [3.5, 1.0]),\r\n *\r\n *       a = board.create('majorarc', [p1, p2, p3]);\r\n * })();\r\n * </script><pre>\r\n */\r\nJXG.createMajorArc = function (board, parents, attributes) {\r\n    attributes.selection = 'major';\r\n    return JXG.createArc(board, parents, attributes);\r\n};\r\n\r\nJXG.registerElement(\"majorarc\", JXG.createMajorArc);\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Statistics from \"../math/statistics.js\";\r\nimport Coords from \"../base/coords.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * @class A circular sector is a subarea of the area enclosed by a circle. It is enclosed by two radii and an arc.\r\n * <p>\r\n * The sector as curve consists of two legs and an arc. The curve length is 6. That means, a point with coordinates\r\n * [sector.X(t), sector.Y(t)] is on\r\n * <ul>\r\n * <li> leg 1 if t is between 0 and 1,\r\n * <li> the arc if t is between 1 and 5,\r\n * <li> leg 2 if t is between 5 and 6.\r\n * </ul>\r\n * @pseudo\r\n * @name Sector\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n *\r\n * First possibility of input parameters are:\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 A sector is defined by three points: The sector's center <tt>p1</tt>,\r\n * a second point <tt>p2</tt> defining the radius and a third point <tt>p3</tt> defining the angle of the sector. The\r\n * Sector is always drawn counter clockwise from <tt>p2</tt> to <tt>p3</tt>.\r\n * <p>\r\n * In this case, the sector will have an arc as sub-object.\r\n * <p>\r\n * Second possibility of input parameters are:\r\n * @param {JXG.Line_JXG.Line_array,number_array,number_number,function} line, line2, coords1 or direction1, coords2 or direction2, radius The sector is defined by two lines.\r\n * The two legs which define the sector are given by two coordinates arrays which are projected initially to the two lines or by\r\n * two directions (+/- 1). If the two lines are parallel, two of the defining points on different lines have to coincide.\r\n * This will be the center of the sector.\r\n * The last parameter is the radius of the sector.\r\n * <p>In this case, the sector will <b>not</b> have an arc as sub-object.\r\n *\r\n * @example\r\n * // Create a sector out of three free points\r\n * var p1 = board.create('point', [1.5, 5.0]),\r\n *     p2 = board.create('point', [1.0, 0.5]),\r\n *     p3 = board.create('point', [5.0, 3.0]),\r\n *\r\n *     a = board.create('sector', [p1, p2, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG49f59123-f013-4681-bfd9-338b89893156\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG49f59123-f013-4681-bfd9-338b89893156', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),\r\n *     p1 = board.create('point', [1.5, 5.0]),\r\n *     p2 = board.create('point', [1.0, 0.5]),\r\n *     p3 = board.create('point', [5.0, 3.0]),\r\n *\r\n *     a = board.create('sector', [p1, p2, p3]);\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Create a sector out of two lines, two directions and a radius\r\n * var p1 = board.create('point', [-1, 4]),\r\n *  p2 = board.create('point', [4, 1]),\r\n *  q1 = board.create('point', [-2, -3]),\r\n *  q2 = board.create('point', [4,3]),\r\n *\r\n *  li1 = board.create('line', [p1,p2], {strokeColor:'black', lastArrow:true}),\r\n *  li2 = board.create('line', [q1,q2], {lastArrow:true}),\r\n *\r\n *  sec1 = board.create('sector', [li1, li2, [5.5, 0], [4, 3], 3]),\r\n *  sec2 = board.create('sector', [li1, li2, 1, -1, 4]);\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXGbb9e2809-9895-4ff1-adfa-c9c71d50aa53\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXGbb9e2809-9895-4ff1-adfa-c9c71d50aa53', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),\r\n *     p1 = board.create('point', [-1, 4]),\r\n *     p2 = board.create('point', [4, 1]),\r\n *     q1 = board.create('point', [-2, -3]),\r\n *     q2 = board.create('point', [4,3]),\r\n *\r\n *     li1 = board.create('line', [p1,p2], {strokeColor:'black', lastArrow:true}),\r\n *     li2 = board.create('line', [q1,q2], {lastArrow:true}),\r\n *\r\n *     sec1 = board.create('sector', [li1, li2, [5.5, 0], [4, 3], 3]),\r\n *     sec2 = board.create('sector', [li1, li2, 1, -1, 4]);\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * var t = board.create('transform', [2, 1.5], {type: 'scale'});\r\n * var s1 = board.create('sector', [[-3.5,-3], [-3.5, -2], [-3.5,-4]], {\r\n *                 anglePoint: {visible:true}, center: {visible: true}, radiusPoint: {visible: true},\r\n *                 fillColor: 'yellow', strokeColor: 'black'});\r\n * var s2 = board.create('curve', [s1, t], {fillColor: 'yellow', strokeColor: 'black'});\r\n *\r\n * </pre><div id=\"JXG2e70ee14-6339-11e8-9fb9-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG2e70ee14-6339-11e8-9fb9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var t = board.create('transform', [2, 1.5], {type: 'scale'});\r\n *     var s1 = board.create('sector', [[-3.5,-3], [-3.5, -2], [-3.5,-4]], {\r\n *                     anglePoint: {visible:true}, center: {visible: true}, radiusPoint: {visible: true},\r\n *                     fillColor: 'yellow', strokeColor: 'black'});\r\n *     var s2 = board.create('curve', [s1, t], {fillColor: 'yellow', strokeColor: 'black'});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var A = board.create('point', [3, -2]),\r\n *     B = board.create('point', [-2, -2]),\r\n *     C = board.create('point', [0, 4]);\r\n *\r\n * var angle = board.create('sector', [B, A, C], {\r\n *         strokeWidth: 0,\r\n *         arc: {\r\n *         \tvisible: true,\r\n *         \tstrokeWidth: 3,\r\n *           lastArrow: {size: 4},\r\n *           firstArrow: {size: 4}\r\n *         }\r\n *       });\r\n * //angle.arc.setAttribute({firstArrow: false});\r\n * angle.arc.setAttribute({lastArrow: false});\r\n *\r\n * </pre><div id=\"JXGca37b99e-1510-49fa-ac9e-efd60e956104\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGca37b99e-1510-49fa-ac9e-efd60e956104',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var A = board.create('point', [3, -2]),\r\n *         B = board.create('point', [-2, -2]),\r\n *         C = board.create('point', [0, 4]);\r\n *\r\n *     var angle = board.create('sector', [B, A, C], {\r\n *             strokeWidth: 0,\r\n *             arc: {\r\n *             \tvisible: true,\r\n *             \tstrokeWidth: 3,\r\n *               lastArrow: {size: 4},\r\n *               firstArrow: {size: 4}\r\n *             }\r\n *           });\r\n *     //angle.arc.setAttribute({firstArrow: false});\r\n *     angle.arc.setAttribute({lastArrow: false});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n *\r\n */\r\nJXG.createSector = function (board, parents, attributes) {\r\n    var el,\r\n        attr,\r\n        i,\r\n        eps = 1.0e-14,\r\n        type = \"invalid\",\r\n        s, v,\r\n        attrPoints = [\"center\", \"radiusPoint\", \"anglePoint\"],\r\n        points;\r\n\r\n    // Three points?\r\n    if (\r\n        parents[0].elementClass === Const.OBJECT_CLASS_LINE &&\r\n        parents[1].elementClass === Const.OBJECT_CLASS_LINE &&\r\n        (Type.isArray(parents[2]) || Type.isNumber(parents[2])) &&\r\n        (Type.isArray(parents[3]) || Type.isNumber(parents[3])) &&\r\n        (Type.isNumber(parents[4]) || Type.isFunction(parents[4]) || Type.isString(parents[4]))\r\n    ) {\r\n        type = '2lines';\r\n    } else {\r\n        points = Type.providePoints(board, parents, attributes, \"sector\", attrPoints);\r\n        if (points === false) {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create Sector with parent types '\" +\r\n                    typeof parents[0] +\r\n                    \"' and '\" +\r\n                    typeof parents[1] +\r\n                    \"' and '\" +\r\n                    typeof parents[2] +\r\n                    \"'.\"\r\n            );\r\n        }\r\n        type = '3points';\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'sector');\r\n    // The curve length is 6: 0-1: leg 1, 1-5: arc, 5-6: leg 2\r\n    el = board.create(\"curve\", [[0], [0], 0, 6], attr);\r\n    el.type = Const.OBJECT_TYPE_SECTOR;\r\n    el.elType = 'sector';\r\n\r\n    /**\r\n     * Sets radius if the attribute `radius` has value 'auto'.\r\n     * Sets a radius between 20 and 50 points, depending on the distance\r\n     * between the center and the radius point.\r\n     * This function is used in {@link Angle}.\r\n     *\r\n     * @name autoRadius\r\n     * @memberof Sector.prototype\r\n     * @function\r\n     * @returns {Number} returns a radius value in user coordinates.\r\n     * @private\r\n     */\r\n    el.autoRadius = function () {\r\n        var r1 = 20 / el.board.unitX, // 20px\r\n            r2 = Infinity,\r\n            r3 = 50 / el.board.unitX; // 50px\r\n\r\n        if (Type.isPoint(el.center)) {\r\n            // This does not work for 2-lines sectors / angles\r\n            r2 = el.center.Dist(el.point2) * 0.3333;\r\n        }\r\n\r\n        return Math.max(r1, Math.min(r2, r3));\r\n    };\r\n\r\n    if (type === '2lines') {\r\n        /**\r\n         * @ignore\r\n         */\r\n        el.Radius = function () {\r\n            var r = Type.evaluate(parents[4]);\r\n            if (r === 'auto') {\r\n                return this.autoRadius();\r\n            }\r\n            return r;\r\n        };\r\n\r\n        el.line1 = board.select(parents[0]);\r\n        el.line2 = board.select(parents[1]);\r\n\r\n        el.line1.addChild(el);\r\n        el.line2.addChild(el);\r\n        el.setParents(parents);\r\n\r\n        el.point1 = { visProp: {} };\r\n        el.point2 = { visProp: {} };\r\n        el.point3 = { visProp: {} };\r\n\r\n        // Intersection point, just used locally for direction1 and  direction2\r\n        s = Geometry.meetLineLine(el.line1.stdform, el.line2.stdform, 0, board);\r\n        if (Geometry.distance(s.usrCoords, [0, 0, 0], 3) < eps) {\r\n            // Parallel lines\r\n            if (\r\n                el.line1.point1.Dist(el.line2.point1) < eps ||\r\n                el.line1.point1.Dist(el.line2.point2) < eps\r\n            ) {\r\n                s = el.line1.point1.coords;\r\n            } else if (\r\n                el.line1.point2.Dist(el.line2.point1) < eps ||\r\n                el.line1.point2.Dist(el.line2.point1) < eps\r\n            ) {\r\n                s = el.line1.point2.coords;\r\n            } else {\r\n                console.log(\r\n                    \"JSXGraph warning: Can't create Sector from parallel lines with no common defining point.\"\r\n                );\r\n            }\r\n        }\r\n\r\n        if (Type.isArray(parents[2])) {\r\n            /* project p1 to l1 */\r\n            if (parents[2].length === 2) {\r\n                parents[2] = [1].concat(parents[2]);\r\n            }\r\n            /*\r\n                v = [0, el.line1.stdform[1], el.line1.stdform[2]];\r\n                v = Mat.crossProduct(v, parents[2]);\r\n                v = Geometry.meetLineLine(v, el.line1.stdform, 0, board);\r\n                */\r\n            v = Geometry.projectPointToLine(\r\n                { coords: { usrCoords: parents[2] } },\r\n                el.line1,\r\n                board\r\n            );\r\n            v = Statistics.subtract(v.usrCoords, s.usrCoords);\r\n            el.direction1 =\r\n                Mat.innerProduct(v, [0, el.line1.stdform[2], -el.line1.stdform[1]], 3) >= 0\r\n                    ? +1\r\n                    : -1;\r\n        } else {\r\n            el.direction1 = parents[2] >= 0 ? 1 : -1;\r\n        }\r\n\r\n        if (Type.isArray(parents[3])) {\r\n            /* project p2 to l2 */\r\n            if (parents[3].length === 2) {\r\n                parents[3] = [1].concat(parents[3]);\r\n            }\r\n            /*\r\n                v = [0, el.line2.stdform[1], el.line2.stdform[2]];\r\n                v = Mat.crossProduct(v, parents[3]);\r\n                v = Geometry.meetLineLine(v, el.line2.stdform, 0, board);\r\n                */\r\n            v = Geometry.projectPointToLine(\r\n                { coords: { usrCoords: parents[3] } },\r\n                el.line2,\r\n                board\r\n            );\r\n            v = Statistics.subtract(v.usrCoords, s.usrCoords);\r\n            el.direction2 =\r\n                Mat.innerProduct(v, [0, el.line2.stdform[2], -el.line2.stdform[1]], 3) >= 0\r\n                    ? +1\r\n                    : -1;\r\n        } else {\r\n            el.direction2 = parents[3] >= 0 ? 1 : -1;\r\n        }\r\n\r\n        el.methodMap = JXG.deepCopy(el.methodMap, {\r\n            arc: \"arc\",\r\n            center: \"center\",\r\n            line1: \"line1\",\r\n            line2: \"line2\"\r\n        });\r\n\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        el.updateDataArray = function () {\r\n            var r,\r\n                l1, l2,\r\n                eps = 1.0e-14,\r\n                A = [0, 0, 0],\r\n                B = [0, 0, 0],\r\n                C = [0, 0, 0],\r\n                ar;\r\n\r\n            l1 = this.line1;\r\n            l2 = this.line2;\r\n\r\n            // Intersection point of the lines\r\n            B = Mat.crossProduct(l1.stdform, l2.stdform);\r\n            if (Geometry.distance(B, [0, 0, 0], 3) < eps) {\r\n                // Parallel lines\r\n                if (\r\n                    l1.point1.Dist(l2.point1) < eps ||\r\n                    l1.point1.Dist(l2.point2) < eps\r\n                ) {\r\n                    B = l1.point1.coords.usrCoords;\r\n                } else if (\r\n                    l1.point2.Dist(l2.point1) < eps ||\r\n                    l1.point2.Dist(l2.point1) < eps\r\n                ) {\r\n                    B = l1.point2.coords.usrCoords;\r\n                } else {\r\n                }\r\n            }\r\n\r\n            if (Math.abs(B[0]) > eps) {\r\n                B[1] /= B[0];\r\n                B[2] /= B[0];\r\n                B[0] /= B[0];\r\n            }\r\n            // First point\r\n            r = this.direction1 * this.Radius();\r\n            A = Statistics.add(B, [0, r * l1.stdform[2], -r * l1.stdform[1]]);\r\n\r\n            // Second point\r\n            r = this.direction2 * this.Radius();\r\n            C = Statistics.add(B, [0, r * l2.stdform[2], -r * l2.stdform[1]]);\r\n\r\n            this.point2.coords = new Coords(Const.COORDS_BY_USER, A, el.board);\r\n            this.point1.coords = new Coords(Const.COORDS_BY_USER, B, el.board);\r\n            this.point3.coords = new Coords(Const.COORDS_BY_USER, C, el.board);\r\n\r\n            if (\r\n                Math.abs(A[0]) < Mat.eps ||\r\n                Math.abs(B[0]) < Mat.eps ||\r\n                Math.abs(C[0]) < Mat.eps\r\n            ) {\r\n                this.dataX = [NaN];\r\n                this.dataY = [NaN];\r\n                return;\r\n            }\r\n\r\n            ar = Geometry.bezierArc(A, B, C, true, 1);\r\n\r\n            this.dataX = ar[0];\r\n            this.dataY = ar[1];\r\n\r\n            this.bezierDegree = 3;\r\n        };\r\n\r\n        // Arc does not work yet, since point1, point2 and point3 are\r\n        // virtual points.\r\n        //\r\n        // attr = Type.copyAttributes(attributes, board.options, 'arc');\r\n        // attr = Type.copyAttributes(attr, board.options, \"sector\", 'arc');\r\n        // attr.withlabel = false;\r\n        // attr.name += \"_arc\";\r\n        // // el.arc = board.create(\"arc\", [el.point1, el.point2, el.point3], attr);\r\n        // // The arc's radius is always the radius of sector.\r\n        // // This is important for angles.\r\n        // el.updateDataArray();\r\n        // el.arc = board.create(\"arc\", [\r\n        //     function() {\r\n        //         return el.point1.coords.usrCoords;\r\n        //     }, // Center\r\n        //     function() {\r\n        //         var d = el.point2.coords.distance(Const.COORDS_BY_USER, el.point1.coords);\r\n        //         if (d === 0) {\r\n        //             return [el.point1.coords.usrCoords[1], el.point1.coords.usrCoords[2]];\r\n        //         }\r\n        //         return [\r\n        //             el.point1.coords.usrCoords[1] + el.Radius() * (el.point2.coords.usrCoords[1] - el.point1.coords.usrCoords[1]) / d,\r\n        //             el.point1.coords.usrCoords[2] + el.Radius() * (el.point2.coords.usrCoords[2] - el.point1.coords.usrCoords[2]) / d\r\n        //         ];\r\n        //     },\r\n        //     function() {\r\n        //         return el.point3.coords.usrCoords;\r\n        //     }, // Center\r\n        // ], attr);\r\n        // el.addChild(el.arc);\r\n\r\n        // end '2lines'\r\n    } else if (type === '3points') {\r\n        /**\r\n         * Midpoint of the sector.\r\n         * @memberOf Sector.prototype\r\n         * @name point1\r\n         * @type JXG.Point\r\n         */\r\n        el.point1 = points[0];\r\n\r\n        /**\r\n         * This point together with {@link Sector#point1} defines the radius.\r\n         * @memberOf Sector.prototype\r\n         * @name point2\r\n         * @type JXG.Point\r\n         */\r\n        el.point2 = points[1];\r\n\r\n        /**\r\n         * Defines the sector's angle.\r\n         * @memberOf Sector.prototype\r\n         * @name point3\r\n         * @type JXG.Point\r\n         */\r\n        el.point3 = points[2];\r\n\r\n        /* Add arc as child to defining points */\r\n        for (i = 0; i < 3; i++) {\r\n            if (Type.exists(points[i]._is_new)) {\r\n                el.addChild(points[i]);\r\n                delete points[i]._is_new;\r\n            } else {\r\n                points[i].addChild(el);\r\n            }\r\n        }\r\n\r\n        // useDirection is necessary for circumCircleSectors\r\n        el.useDirection = attributes.usedirection; // this makes the attribute immutable\r\n        el.setParents(points);\r\n\r\n        /**\r\n         * Defines the sectors orientation in case of circumCircleSectors.\r\n         * @memberOf Sector.prototype\r\n         * @name point4\r\n         * @type JXG.Point\r\n         */\r\n        if (Type.exists(points[3])) {\r\n            el.point4 = points[3];\r\n            el.point4.addChild(el);\r\n        }\r\n\r\n        el.methodMap = JXG.deepCopy(el.methodMap, {\r\n            arc: \"arc\",\r\n            center: \"center\",\r\n            radiuspoint: \"radiuspoint\",\r\n            anglepoint: \"anglepoint\"\r\n        });\r\n\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        el.updateDataArray = function () {\r\n            var ar, det,\r\n                p0c, p1c, p2c,\r\n                A = this.point2,\r\n                B = this.point1,\r\n                C = this.point3,\r\n                phi,\r\n                sgn = 1,\r\n                vp_s = this.evalVisProp('selection');\r\n\r\n            if (!A.isReal || !B.isReal || !C.isReal) {\r\n                this.dataX = [NaN];\r\n                this.dataY = [NaN];\r\n                return;\r\n            }\r\n\r\n            phi = Geometry.rad(A, B, C);\r\n            if ((vp_s === \"minor\" && phi > Math.PI) || (vp_s === \"major\" && phi < Math.PI)) {\r\n                sgn = -1;\r\n            }\r\n\r\n            // This is true for circumCircleSectors. In that case there is\r\n            // a fourth parent element: [midpoint, point1, point3, point2]\r\n            if (this.useDirection && Type.exists(this.point4)) {\r\n                p0c = this.point2.coords.usrCoords;\r\n                p1c = this.point4.coords.usrCoords;\r\n                p2c = this.point3.coords.usrCoords;\r\n                det =\r\n                    (p0c[1] - p2c[1]) * (p0c[2] - p1c[2]) -\r\n                    (p0c[2] - p2c[2]) * (p0c[1] - p1c[1]);\r\n\r\n                if (det >= 0.0) {\r\n                    C = this.point2;\r\n                    A = this.point3;\r\n                }\r\n            }\r\n\r\n            A = A.coords.usrCoords;\r\n            B = B.coords.usrCoords;\r\n            C = C.coords.usrCoords;\r\n\r\n            ar = Geometry.bezierArc(A, B, C, true, sgn);\r\n\r\n            this.dataX = ar[0];\r\n            this.dataY = ar[1];\r\n            this.bezierDegree = 3;\r\n        };\r\n\r\n        /**\r\n         * Returns the radius of the sector.\r\n         * @memberOf Sector.prototype\r\n         * @name Radius\r\n         * @function\r\n         * @returns {Number} The distance between {@link Sector#point1} and {@link Sector#point2}.\r\n         */\r\n        el.Radius = function () {\r\n            return this.point2.Dist(this.point1);\r\n        };\r\n    } // end '3points'\r\n\r\n    el.center = el.point1;\r\n    el.radiuspoint = el.point2;\r\n    el.anglepoint = el.point3;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'arc');\r\n    attr = Type.copyAttributes(attr, board.options, \"sector\", 'arc');\r\n    attr.withlabel = false;\r\n    // Minor or major arc:\r\n    attr.selection = el.visProp.selection;\r\n    attr.name += \"_arc\";\r\n\r\n    if (type === '2lines') {\r\n        el.updateDataArray();\r\n        el.arc = board.create(\"arc\", [\r\n            function() {\r\n                return el.point1.coords.usrCoords;\r\n            }, // Center\r\n            function() {\r\n                var d = el.point2.coords.distance(Const.COORDS_BY_USER, el.point1.coords);\r\n                if (d === 0) {\r\n                    return [el.point1.coords.usrCoords[1], el.point1.coords.usrCoords[2]];\r\n                }\r\n                return [\r\n                    el.point1.coords.usrCoords[1] + el.Radius() * (el.point2.coords.usrCoords[1] - el.point1.coords.usrCoords[1]) / d,\r\n                    el.point1.coords.usrCoords[2] + el.Radius() * (el.point2.coords.usrCoords[2] - el.point1.coords.usrCoords[2]) / d\r\n                ];\r\n            },\r\n            function() {\r\n                return el.point3.coords.usrCoords;\r\n            } // Center\r\n        ], attr);\r\n    } else {\r\n        // The arc's radius is always the radius of sector.\r\n        // This is important for angles.\r\n        el.arc = board.create(\"arc\", [\r\n            el.point1, // Center\r\n            function() {\r\n                var d = el.point2.Dist(el.point1);\r\n                if (d === 0) {\r\n                    return [el.point1.X(), el.point1.Y()];\r\n                }\r\n                return [\r\n                    el.point1.X() + el.Radius() * (el.point2.X() - el.point1.X()) / d,\r\n                    el.point1.Y() + el.Radius() * (el.point2.Y() - el.point1.Y()) / d\r\n                ];\r\n            },\r\n            el.point3\r\n        ], attr);\r\n    }\r\n    el.addChild(el.arc);\r\n\r\n    // Default hasPoint method. Documented in geometry element\r\n    el.hasPointCurve = function (x, y) {\r\n        var angle,\r\n            alpha,\r\n            beta,\r\n            prec,\r\n            type,\r\n            checkPoint = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board),\r\n            r = this.Radius(),\r\n            dist = this.center.coords.distance(Const.COORDS_BY_USER, checkPoint),\r\n            has,\r\n            vp_s = this.evalVisProp('selection');\r\n\r\n        if (Type.isObject(this.evalVisProp('precision'))) {\r\n            type = this.board._inputDevice;\r\n            prec = this.evalVisProp('precision.' + type);\r\n        } else {\r\n            // 'inherit'\r\n            prec = this.board.options.precision.hasPoint;\r\n        }\r\n        prec /= Math.min(Math.abs(this.board.unitX), Math.abs(this.board.unitY));\r\n        has = Math.abs(dist - r) < prec;\r\n        if (has) {\r\n            angle = Geometry.rad(this.point2, this.center, checkPoint.usrCoords.slice(1));\r\n            alpha = 0;\r\n            beta = Geometry.rad(this.point2, this.center, this.point3);\r\n\r\n            if ((vp_s === \"minor\" && beta > Math.PI) || (vp_s === \"major\" && beta < Math.PI)) {\r\n                alpha = beta;\r\n                beta = 2 * Math.PI;\r\n            }\r\n\r\n            if (angle < alpha || angle > beta) {\r\n                has = false;\r\n            }\r\n        }\r\n\r\n        return has;\r\n    };\r\n\r\n    /**\r\n     * Checks whether (x,y) is within the area defined by the sector.\r\n     * @memberOf Sector.prototype\r\n     * @name hasPointSector\r\n     * @function\r\n     * @param {Number} x Coordinate in x direction, screen coordinates.\r\n     * @param {Number} y Coordinate in y direction, screen coordinates.\r\n     * @returns {Boolean} True if (x,y) is within the sector defined by the arc, False otherwise.\r\n     */\r\n    el.hasPointSector = function (x, y) {\r\n        var angle,\r\n            checkPoint = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board),\r\n            r = this.Radius(),\r\n            dist = this.point1.coords.distance(Const.COORDS_BY_USER, checkPoint),\r\n            alpha,\r\n            beta,\r\n            has = dist < r,\r\n            vp_s = this.evalVisProp('selection');\r\n\r\n        if (has) {\r\n            angle = Geometry.rad(this.radiuspoint, this.center, checkPoint.usrCoords.slice(1));\r\n            alpha = 0.0;\r\n            beta = Geometry.rad(this.radiuspoint, this.center, this.anglepoint);\r\n\r\n            if ((vp_s === \"minor\" && beta > Math.PI) || (vp_s === \"major\" && beta < Math.PI)) {\r\n                alpha = beta;\r\n                beta = 2 * Math.PI;\r\n            }\r\n            //if (angle > Geometry.rad(this.point2, this.point1, this.point3)) {\r\n            if (angle < alpha || angle > beta) {\r\n                has = false;\r\n            }\r\n        }\r\n        return has;\r\n    };\r\n\r\n    el.hasPoint = function (x, y) {\r\n        if (\r\n            this.evalVisProp('highlightonsector') ||\r\n            this.evalVisProp('hasinnerpoints')\r\n        ) {\r\n            return this.hasPointSector(x, y);\r\n        }\r\n\r\n        return this.hasPointCurve(x, y);\r\n    };\r\n\r\n    // documented in GeometryElement\r\n    el.getTextAnchor = function () {\r\n        return this.point1.coords;\r\n    };\r\n\r\n    // documented in GeometryElement\r\n    // this method is very similar to arc.getLabelAnchor()\r\n    // there are some additions in the arc version though, mainly concerning\r\n    // \"major\" and \"minor\" arcs. but maybe these methods can be merged.\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    el.getLabelAnchor = function () {\r\n        var coords,\r\n            vec, vecx, vecy,\r\n            len,\r\n            pos = this.label.evalVisProp('position'),\r\n            angle = Geometry.rad(this.point2, this.point1, this.point3),\r\n            dx = 13 / this.board.unitX,\r\n            dy = 13 / this.board.unitY,\r\n            p2c = this.point2.coords.usrCoords,\r\n            pmc = this.point1.coords.usrCoords,\r\n            bxminusax = p2c[1] - pmc[1],\r\n            byminusay = p2c[2] - pmc[2],\r\n            vp_s = this.evalVisProp('selection'),\r\n            l_vp = this.label ? this.label.visProp : this.visProp.label;\r\n\r\n        // If this is uncommented, the angle label can not be dragged\r\n        //if (Type.exists(this.label)) {\r\n        //    this.label.relativeCoords = new Coords(Const.COORDS_BY_SCREEN, [0, 0], this.board);\r\n        //}\r\n\r\n        if (\r\n            !Type.isString(pos) ||\r\n            (pos.indexOf('right') < 0 && pos.indexOf('left') < 0)\r\n        ) {\r\n\r\n            if ((vp_s === \"minor\" && angle > Math.PI) || (vp_s === \"major\" && angle < Math.PI)) {\r\n                angle = -(2 * Math.PI - angle);\r\n            }\r\n\r\n            coords = new Coords(\r\n                Const.COORDS_BY_USER,\r\n                [\r\n                    pmc[1] + Math.cos(angle * 0.5) * bxminusax - Math.sin(angle * 0.5) * byminusay,\r\n                    pmc[2] + Math.sin(angle * 0.5) * bxminusax + Math.cos(angle * 0.5) * byminusay\r\n                ],\r\n                this.board\r\n            );\r\n\r\n            vecx = coords.usrCoords[1] - pmc[1];\r\n            vecy = coords.usrCoords[2] - pmc[2];\r\n\r\n            len = Mat.hypot(vecx, vecy);\r\n            vecx = (vecx * (len + dx)) / len;\r\n            vecy = (vecy * (len + dy)) / len;\r\n            vec = [pmc[1] + vecx, pmc[2] + vecy];\r\n\r\n            l_vp.position = Geometry.calcLabelQuadrant(Geometry.rad([1, 0], [0, 0], vec));\r\n\r\n            return new Coords(Const.COORDS_BY_USER, vec, this.board);\r\n        } else {\r\n            return this.getLabelPosition(pos, this.label.evalVisProp('distance'));\r\n        }\r\n    };\r\n\r\n    /**\r\n     * Overwrite the Radius method of the sector.\r\n     * Used in {@link GeometryElement#setAttribute}.\r\n     * @memberOf Sector.prototype\r\n     * @name setRadius\r\n     * @param {Number|Function} value New radius.\r\n     * @function\r\n     */\r\n    el.setRadius = function (val) {\r\n        var res,\r\n            e = Type.evaluate(val);\r\n\r\n        if (val === 'auto' || e === 'auto') {\r\n            res = 'auto';\r\n        } else if (Type.isNumber(val)) {\r\n            res = 'number';\r\n        } else if (Type.isFunction(val) && !Type.isString(e)) {\r\n            res = 'function';\r\n        } else {\r\n            res = 'undefined';\r\n        }\r\n        if (res !== 'undefined') {\r\n            this.visProp.radius = val;\r\n        }\r\n\r\n        /**\r\n         * @ignore\r\n         */\r\n        el.Radius = function () {\r\n            var r = Type.evaluate(val);\r\n            if (r === 'auto') {\r\n                return this.autoRadius();\r\n            }\r\n            return r;\r\n        };\r\n    };\r\n\r\n    /**\r\n     * @deprecated\r\n     * @ignore\r\n     */\r\n    el.getRadius = function () {\r\n        JXG.deprecated(\"Sector.getRadius()\", \"Sector.Radius()\");\r\n        return this.Radius();\r\n    };\r\n\r\n    /**\r\n     * Length of the sector's arc or the angle in various units, see {@link Arc#Value}.\r\n     * @memberOf Sector.prototype\r\n     * @name Value\r\n     * @function\r\n     * @param {String} unit\r\n     * @returns {Number} The arc length or the angle value in various units.\r\n     * @see Arc#Value\r\n     */\r\n    el.Value = function(unit) {\r\n        return this.arc.Value(unit);\r\n    };\r\n\r\n    /**\r\n     * Arc length.\r\n     * @memberOf Sector.prototype\r\n     * @name L\r\n     * @returns {Number} Length of the sector's arc.\r\n     * @function\r\n     * @see Arc#L\r\n     */\r\n    el.L = function() {\r\n        return this.arc.L();\r\n    };\r\n\r\n    /**\r\n     * Area of the sector.\r\n     * @memberOf Sector.prototype\r\n     * @name Area\r\n     * @function\r\n     * @returns {Number} The area of the sector.\r\n     */\r\n    el.Area = function () {\r\n        var r = this.Radius();\r\n\r\n        return 0.5 * r * r * this.Value('radians');\r\n    };\r\n\r\n    /**\r\n     * Sector perimeter, i.e. arc length plus 2 * radius.\r\n     * @memberOf Sector.prototype\r\n     * @name Perimeter\r\n     * @function\r\n     * @returns {Number} Perimeter of sector.\r\n     */\r\n    el.Perimeter = function () {\r\n        return this.L() + 2 * this.Radius();\r\n    };\r\n\r\n    if (type === '3points') {\r\n        /**\r\n         * Moves the sector by the difference of two coordinates.\r\n         * @memberOf Sector.prototype\r\n         * @name setPositionDirectly\r\n         * @function\r\n         * @param {Number} method The type of coordinates used here. Possible values are {@link JXG.COORDS_BY_USER} and {@link JXG.COORDS_BY_SCREEN}.\r\n         * @param {Array} coords coordinates in screen/user units\r\n         * @param {Array} oldcoords previous coordinates in screen/user units\r\n         * @returns {JXG.Curve} this element\r\n         * @private\r\n         */\r\n        el.setPositionDirectly = function (method, coords, oldcoords) {\r\n            var dc, t,\r\n                c = new Coords(method, coords, this.board),\r\n                oldc = new Coords(method, oldcoords, this.board);\r\n\r\n            if (!el.point1.draggable() || !el.point2.draggable() || !el.point3.draggable()) {\r\n                return this;\r\n            }\r\n\r\n            dc = Statistics.subtract(c.usrCoords, oldc.usrCoords);\r\n            t = this.board.create(\"transform\", dc.slice(1), { type: \"translate\" });\r\n            t.applyOnce([el.point1, el.point2, el.point3]);\r\n\r\n            return this;\r\n        };\r\n    }\r\n\r\n    el.methodMap = JXG.deepCopy(el.methodMap, {\r\n        radius: \"Radius\",\r\n        Radius: \"Radius\",\r\n        getRadius: \"Radius\",\r\n        setRadius: \"setRadius\",\r\n        Value: \"Value\",\r\n        L: \"L\",\r\n        Area: \"Area\",\r\n        Perimeter: \"Perimeter\"\r\n    });\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"sector\", JXG.createSector);\r\n\r\n/**\r\n * @class A sector whose arc is a circum circle arc through three points.\r\n * A circumcircle sector is different from a {@link Sector} mostly in the way the parent elements are interpreted.\r\n * At first, the circum center is determined from the three given points.\r\n * Then the sector is drawn from <tt>p1</tt> through\r\n * <tt>p2</tt> to <tt>p3</tt>.\r\n * @pseudo\r\n * @name CircumcircleSector\r\n * @augments Sector\r\n * @constructor\r\n * @type Sector\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p1 A circumcircle sector is defined by the circumcircle which is determined\r\n * by these three given points. The circumcircle sector is always drawn from <tt>p1</tt> through <tt>p2</tt> to <tt>p3</tt>.\r\n * @example\r\n * // Create an arc out of three free points\r\n * var p1 = board.create('point', [1.5, 5.0]),\r\n *     p2 = board.create('point', [1.0, 0.5]),\r\n *     p3 = board.create('point', [5.0, 3.0]),\r\n *\r\n *     a = board.create('circumcirclesector', [p1, p2, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG695cf0d6-6d7a-4d4d-bfc9-34c6aa28cd04\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG695cf0d6-6d7a-4d4d-bfc9-34c6aa28cd04', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),\r\n *     p1 = board.create('point', [1.5, 5.0]),\r\n *     p2 = board.create('point', [1.0, 0.5]),\r\n *     p3 = board.create('point', [5.0, 3.0]),\r\n *\r\n *     a = board.create('circumcirclesector', [p1, p2, p3]);\r\n * })();\r\n * </script><pre>\r\n */\r\nJXG.createCircumcircleSector = function (board, parents, attributes) {\r\n    var el, mp, attr, points;\r\n\r\n    points = Type.providePoints(board, parents, attributes, 'point');\r\n    if (points === false) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create circumcircle sector with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"' and '\" +\r\n                typeof parents[2] +\r\n                \"'.\"\r\n        );\r\n    }\r\n\r\n    mp = board.create(\"circumcenter\", points.slice(0, 3), attr);\r\n    mp.dump = false;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'circumcirclesector');\r\n    el = board.create(\"sector\", [mp, points[0], points[2], points[1]], attr);\r\n\r\n    el.elType = 'circumcirclesector';\r\n    el.setParents(points);\r\n\r\n    /**\r\n     * Center of the circumcirclesector\r\n     * @memberOf CircumcircleSector.prototype\r\n     * @name center\r\n     * @type Circumcenter\r\n     */\r\n    el.center = mp;\r\n    el.subs = {\r\n        center: mp\r\n    };\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"circumcirclesector\", JXG.createCircumcircleSector);\r\n\r\n/**\r\n * @class A minor sector is a sector of a circle having measure at most\r\n * 180 degrees (pi radians). It is defined by a center, one point that\r\n * defines the radius, and a third point that defines the angle of the sector.\r\n * @pseudo\r\n * @name MinorSector\r\n * @augments Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 . Minor sector is a sector of a circle around p1 having measure less than or equal to\r\n * 180 degrees (pi radians) and starts at p2. The radius is determined by p2, the angle by p3.\r\n * @example\r\n * // Create sector out of three free points\r\n * var p1 = board.create('point', [2.0, 2.0]);\r\n * var p2 = board.create('point', [1.0, 0.5]);\r\n * var p3 = board.create('point', [3.5, 1.0]);\r\n *\r\n * var a = board.create('minorsector', [p1, p2, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGaf27ddcc-265f-428f-90dd-d31ace945800\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXGaf27ddcc-265f-428f-90dd-d31ace945800', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),\r\n *       p1 = board.create('point', [2.0, 2.0]),\r\n *       p2 = board.create('point', [1.0, 0.5]),\r\n *       p3 = board.create('point', [3.5, 1.0]),\r\n *\r\n *       a = board.create('minorsector', [p1, p2, p3]);\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * var A = board.create('point', [3, -2]),\r\n *     B = board.create('point', [-2, -2]),\r\n *     C = board.create('point', [0, 4]);\r\n *\r\n * var angle = board.create('minorsector', [B, A, C], {\r\n *         strokeWidth: 0,\r\n *         arc: {\r\n *         \tvisible: true,\r\n *         \tstrokeWidth: 3,\r\n *           lastArrow: {size: 4},\r\n *           firstArrow: {size: 4}\r\n *         }\r\n *       });\r\n * //angle.arc.setAttribute({firstArrow: false});\r\n * angle.arc.setAttribute({lastArrow: false});\r\n *\r\n *\r\n * </pre><div id=\"JXGdddf3c8f-4b0c-4268-8171-8fcd30e71f60\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGdddf3c8f-4b0c-4268-8171-8fcd30e71f60',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var A = board.create('point', [3, -2]),\r\n *         B = board.create('point', [-2, -2]),\r\n *         C = board.create('point', [0, 4]);\r\n *\r\n *     var angle = board.create('minorsector', [B, A, C], {\r\n *             strokeWidth: 0,\r\n *             arc: {\r\n *             \tvisible: true,\r\n *             \tstrokeWidth: 3,\r\n *               lastArrow: {size: 4},\r\n *               firstArrow: {size: 4}\r\n *             }\r\n *           });\r\n *     //angle.arc.setAttribute({firstArrow: false});\r\n *     angle.arc.setAttribute({lastArrow: false});\r\n *\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createMinorSector = function (board, parents, attributes) {\r\n    attributes.selection = 'minor';\r\n    return JXG.createSector(board, parents, attributes);\r\n};\r\n\r\nJXG.registerElement(\"minorsector\", JXG.createMinorSector);\r\n\r\n/**\r\n * @class A major sector is a sector of a circle having measure at least\r\n * 180 degrees (pi radians). It is defined by a center, one point that\r\n * defines the radius, and a third point that defines the angle of the sector.\r\n * @pseudo\r\n * @name MajorSector\r\n * @augments Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 . Major sector is a sector of a circle around p1 having measure greater than or equal to\r\n * 180 degrees (pi radians) and starts at p2. The radius is determined by p2, the angle by p3.\r\n * @example\r\n * // Create an arc out of three free points\r\n * var p1 = board.create('point', [2.0, 2.0]);\r\n * var p2 = board.create('point', [1.0, 0.5]);\r\n * var p3 = board.create('point', [3.5, 1.0]);\r\n *\r\n * var a = board.create('majorsector', [p1, p2, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG83c6561f-7561-4047-b98d-036248a00932\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG83c6561f-7561-4047-b98d-036248a00932', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),\r\n *       p1 = board.create('point', [2.0, 2.0]),\r\n *       p2 = board.create('point', [1.0, 0.5]),\r\n *       p3 = board.create('point', [3.5, 1.0]),\r\n *\r\n *       a = board.create('majorsector', [p1, p2, p3]);\r\n * })();\r\n * </script><pre>\r\n */\r\nJXG.createMajorSector = function (board, parents, attributes) {\r\n    attributes.selection = 'major';\r\n    return JXG.createSector(board, parents, attributes);\r\n};\r\n\r\nJXG.registerElement(\"majorsector\", JXG.createMajorSector);\r\n\r\n/**\r\n * @class Angle sector defined by three points or two lines.\r\n * Visually it is just a {@link Sector}\r\n * element with a radius not defined by the parent elements but by an attribute <tt>radius</tt>. As opposed to the sector,\r\n * an angle has two angle points and no radius point.\r\n * Sector is displayed if type==\"sector\".\r\n * If type==\"square\", instead of a sector a parallelogram is displayed.\r\n * In case of type==\"auto\", a square is displayed if the angle is near orthogonal. The precision\r\n * to decide if an angle is orthogonal is determined by the attribute\r\n * {@link Angle#orthoSensitivity}.\r\n * <p>\r\n * If no name is provided the angle label is automatically set to a lower greek letter. If no label should be displayed use\r\n * the attribute <tt>withLabel:false</tt> or set the name attribute to the empty string.\r\n *\r\n * @pseudo\r\n * @name Angle\r\n * @augments Sector\r\n * @constructor\r\n * @type Sector\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * First possibility of input parameters are:\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p1 An angle is always drawn counterclockwise from <tt>p1</tt> to\r\n * <tt>p3</tt> around <tt>p2</tt>.\r\n *\r\n * Second possibility of input parameters are:\r\n * @param {JXG.Line_JXG.Line_array|number_array|number} line, line2, coords1 or direction1, coords2 or direction2, radius The angle is defined by two lines.\r\n * The two legs which define the angle are given by two coordinate arrays.\r\n * The points given by these coordinate arrays are projected initially (i.e. only once) onto the two lines.\r\n * The other possibility is to supply directions (+/- 1).\r\n *\r\n * @example\r\n * // Create an angle out of three free points\r\n * var p1 = board.create('point', [5.0, 3.0]),\r\n *     p2 = board.create('point', [1.0, 0.5]),\r\n *     p3 = board.create('point', [1.5, 5.0]),\r\n *\r\n *     a = board.create('angle', [p1, p2, p3]),\r\n *     t = board.create('text', [4, 4, function() { return JXG.toFixed(a.Value(), 2); }]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGa34151f9-bb26-480a-8d6e-9b8cbf789ae5\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXGa34151f9-bb26-480a-8d6e-9b8cbf789ae5', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),\r\n *     p1 = board.create('point', [5.0, 3.0]),\r\n *     p2 = board.create('point', [1.0, 0.5]),\r\n *     p3 = board.create('point', [1.5, 5.0]),\r\n *\r\n *     a = board.create('angle', [p1, p2, p3]),\r\n *     t = board.create('text', [4, 4, function() { return JXG.toFixed(a.Value(), 2); }]);\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Create an angle out of two lines and two directions\r\n * var p1 = board.create('point', [-1, 4]),\r\n *  p2 = board.create('point', [4, 1]),\r\n *  q1 = board.create('point', [-2, -3]),\r\n *  q2 = board.create('point', [4,3]),\r\n *\r\n *  li1 = board.create('line', [p1,p2], {strokeColor:'black', lastArrow:true}),\r\n *  li2 = board.create('line', [q1,q2], {lastArrow:true}),\r\n *\r\n *  a1 = board.create('angle', [li1, li2, [5.5, 0], [4, 3]], { radius:1 }),\r\n *  a2 = board.create('angle', [li1, li2, 1, -1], { radius:2 });\r\n *\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXG3a667ddd-63dc-4594-b5f1-afac969b371f\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG3a667ddd-63dc-4594-b5f1-afac969b371f', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),\r\n *     p1 = board.create('point', [-1, 4]),\r\n *     p2 = board.create('point', [4, 1]),\r\n *     q1 = board.create('point', [-2, -3]),\r\n *     q2 = board.create('point', [4,3]),\r\n *\r\n *     li1 = board.create('line', [p1,p2], {strokeColor:'black', lastArrow:true}),\r\n *     li2 = board.create('line', [q1,q2], {lastArrow:true}),\r\n *\r\n *     a1 = board.create('angle', [li1, li2, [5.5, 0], [4, 3]], { radius:1 }),\r\n *     a2 = board.create('angle', [li1, li2, 1, -1], { radius:2 });\r\n * })();\r\n * </script><pre>\r\n *\r\n *\r\n * @example\r\n * // Display the angle value instead of the name\r\n * var p1 = board.create('point', [0,2]);\r\n * var p2 = board.create('point', [0,0]);\r\n * var p3 = board.create('point', [-2,0.2]);\r\n *\r\n * var a = board.create('angle', [p1, p2, p3], {\r\n * \t radius: 1,\r\n *   name: function() {\r\n *   \treturn JXG.Math.Geometry.trueAngle(p1, p2, p3).toFixed(1) + '°';\r\n *   }});\r\n *\r\n * </pre><div id=\"JXGc813f601-8dd3-4030-9892-25c6d8671512\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGc813f601-8dd3-4030-9892-25c6d8671512',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *\r\n *     var p1 = board.create('point', [0,2]);\r\n *     var p2 = board.create('point', [0,0]);\r\n *     var p3 = board.create('point', [-2,0.2]);\r\n *\r\n *     var a = board.create('angle', [p1, p2, p3], {\r\n *     \tradius: 1,\r\n *       name: function() {\r\n *       \treturn JXG.Math.Geometry.trueAngle(p1, p2, p3).toFixed(1) + '°';\r\n *       }});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n *\r\n * @example\r\n * // Apply a transformation to an angle.\r\n * var t = board.create('transform', [2, 1.5], {type: 'scale'});\r\n * var an1 = board.create('angle', [[-4,3.9], [-3, 4], [-3, 3]]);\r\n * var an2 = board.create('curve', [an1, t]);\r\n *\r\n * </pre><div id=\"JXG4c8d9ed8-6339-11e8-9fb9-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG4c8d9ed8-6339-11e8-9fb9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var t = board.create('transform', [2, 1.5], {type: 'scale'});\r\n *     var an1 = board.create('angle', [[-4,3.9], [-3, 4], [-3, 3]]);\r\n *     var an2 = board.create('curve', [an1, t]);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createAngle = function (board, parents, attributes) {\r\n    var el,\r\n        radius, attr, attrsub,\r\n        i, points,\r\n        type = 'invalid';\r\n\r\n    // Two lines or three points?\r\n    if (\r\n        parents[0].elementClass === Const.OBJECT_CLASS_LINE &&\r\n        parents[1].elementClass === Const.OBJECT_CLASS_LINE &&\r\n        (Type.isArray(parents[2]) || Type.isNumber(parents[2])) &&\r\n        (Type.isArray(parents[3]) || Type.isNumber(parents[3]))\r\n    ) {\r\n        type = '2lines';\r\n    } else {\r\n        attr = {\r\n            name: ''\r\n        };\r\n        points = Type.providePoints(board, parents, attr, 'point');\r\n        if (points === false) {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create angle with parent types '\" +\r\n                    typeof parents[0] +\r\n                    \"' and '\" +\r\n                    typeof parents[1] +\r\n                    \"' and '\" +\r\n                    typeof parents[2] +\r\n                    \"'.\"\r\n            );\r\n        }\r\n        type = '3points';\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'angle');\r\n\r\n    //  If empty, create a new name\r\n    if (!Type.exists(attr.name) /*|| attr.name === \"\"*/) {\r\n        attr.name = board.generateName({ type: Const.OBJECT_TYPE_ANGLE });\r\n    }\r\n\r\n    if (Type.exists(attr.radius)) {\r\n        radius = attr.radius;\r\n    } else {\r\n        radius = 0;\r\n    }\r\n\r\n    board.suspendUpdate(); // Necessary for immediate availability of radius.\r\n    if (type === '2lines') {\r\n        // Angle defined by two lines\r\n        parents.push(radius);\r\n        el = board.create(\"sector\", parents, attr);\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        el.updateDataArraySector = el.updateDataArray;\r\n\r\n        // TODO\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        el.setAngle = function (val) {};\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        el.free = function (val) {};\r\n    } else {\r\n        // Angle defined by three points\r\n        el = board.create(\"sector\", [points[1], points[0], points[2]], attr);\r\n        el.arc.visProp.priv = true;\r\n\r\n        /**\r\n         * The point defining the radius of the angle element.\r\n         * Alias for {@link Sector#radiuspoint}.\r\n         * @type JXG.Point\r\n         * @name point\r\n         * @memberOf Angle.prototype\r\n         *\r\n         */\r\n        el.point = el.point2 = el.radiuspoint = points[0];\r\n\r\n        /**\r\n         * Helper point for angles of type 'square'.\r\n         * @type JXG.Point\r\n         * @name pointsquare\r\n         * @memberOf Angle.prototype\r\n         */\r\n        el.pointsquare = el.point3 = el.anglepoint = points[2];\r\n\r\n        /**\r\n         * @ignore\r\n         */\r\n        el.Radius = function () {\r\n            // Set the angle radius, also @see @link Sector#autoRadius\r\n            var r = Type.evaluate(radius);\r\n            if (r === 'auto') {\r\n                return el.autoRadius();\r\n            }\r\n            return r;\r\n        };\r\n\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        el.updateDataArraySector = function () {\r\n            var A = this.point2,\r\n                B = this.point1,\r\n                C = this.point3,\r\n                r = this.Radius(),\r\n                d = B.Dist(A),\r\n                ar,\r\n                phi,\r\n                sgn = 1,\r\n                vp_s = this.evalVisProp('selection');\r\n\r\n            phi = Geometry.rad(A, B, C);\r\n            if ((vp_s === \"minor\" && phi > Math.PI) || (vp_s === \"major\" && phi < Math.PI)) {\r\n                sgn = -1;\r\n            }\r\n\r\n            A = A.coords.usrCoords;\r\n            B = B.coords.usrCoords;\r\n            C = C.coords.usrCoords;\r\n\r\n            A = [1, B[1] + ((A[1] - B[1]) * r) / d, B[2] + ((A[2] - B[2]) * r) / d];\r\n            C = [1, B[1] + ((C[1] - B[1]) * r) / d, B[2] + ((C[2] - B[2]) * r) / d];\r\n\r\n            ar = Geometry.bezierArc(A, B, C, true, sgn);\r\n\r\n            this.dataX = ar[0];\r\n            this.dataY = ar[1];\r\n            this.bezierDegree = 3;\r\n        };\r\n\r\n        /**\r\n         * Set an angle to a prescribed value given in radians.\r\n         * This is only possible if the third point of the angle, i.e.\r\n         * the anglepoint is a free point.\r\n         * Removing the constraint again is done by calling \"angle.free()\".\r\n         *\r\n         * Changing the angle requires to call the method \"free()\":\r\n         *\r\n         * <pre>\r\n         * angle.setAngle(Math.PI / 6);\r\n         * // ...\r\n         * angle.free().setAngle(Math.PI / 4);\r\n         * </pre>\r\n         *\r\n         * @name setAngle\r\n         * @memberof Angle.prototype\r\n         * @function\r\n         * @param {Number|Function} val Number or Function which returns the size of the angle in Radians\r\n         * @returns {Object} Pointer to the angle element..\r\n         * @see Angle#free\r\n         *\r\n         * @example\r\n         * var p1, p2, p3, c, a, s;\r\n         *\r\n         * p1 = board.create('point',[0,0]);\r\n         * p2 = board.create('point',[5,0]);\r\n         * p3 = board.create('point',[0,5]);\r\n         *\r\n         * c1 = board.create('circle',[p1, p2]);\r\n         *\r\n         * a = board.create('angle',[p2, p1, p3], {radius:3});\r\n         *\r\n         * a.setAngle(function() {\r\n         *     return Math.PI / 3;\r\n         * });\r\n         * board.update();\r\n         *\r\n         * </pre><div id=\"JXG987c-394f-11e6-af4a-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG987c-394f-11e6-af4a-901b0e1b8723',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var p1, p2, p3, c, a, s;\r\n         *\r\n         *     p1 = board.create('point',[0,0]);\r\n         *     p2 = board.create('point',[5,0]);\r\n         *     p3 = board.create('point',[0,5]);\r\n         *\r\n         *     c1 = board.create('circle',[p1, p2]);\r\n         *\r\n         *     a = board.create('angle',[p2, p1, p3], {radius: 3});\r\n         *\r\n         *     a.setAngle(function() {\r\n         *         return Math.PI / 3;\r\n         *     });\r\n         *     board.update();\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         * var p1, p2, p3, c, a, s;\r\n         *\r\n         * p1 = board.create('point',[0,0]);\r\n         * p2 = board.create('point',[5,0]);\r\n         * p3 = board.create('point',[0,5]);\r\n         *\r\n         * c1 = board.create('circle',[p1, p2]);\r\n         *\r\n         * a = board.create('angle',[p2, p1, p3], {radius:3});\r\n         * s = board.create('slider',[[-2,1], [2,1], [0, Math.PI*0.5, 2*Math.PI]]);\r\n         *\r\n         * a.setAngle(function() {\r\n         *     return s.Value();\r\n         * });\r\n         * board.update();\r\n         *\r\n         * </pre><div id=\"JXG99957b1c-394f-11e6-af4a-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG99957b1c-394f-11e6-af4a-901b0e1b8723',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var p1, p2, p3, c, a, s;\r\n         *\r\n         *     p1 = board.create('point',[0,0]);\r\n         *     p2 = board.create('point',[5,0]);\r\n         *     p3 = board.create('point',[0,5]);\r\n         *\r\n         *     c1 = board.create('circle',[p1, p2]);\r\n         *\r\n         *     a = board.create('angle',[p2, p1, p3], {radius: 3});\r\n         *     s = board.create('slider',[[-2,1], [2,1], [0, Math.PI*0.5, 2*Math.PI]]);\r\n         *\r\n         *     a.setAngle(function() {\r\n         *         return s.Value();\r\n         *     });\r\n         *     board.update();\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        el.setAngle = function (val) {\r\n            var t1, t2,\r\n                val2,\r\n                p = this.anglepoint,\r\n                q = this.radiuspoint;\r\n\r\n            if (p.draggable()) {\r\n                t1 = this.board.create(\"transform\", [val, this.center], {\r\n                    type: \"rotate\"\r\n                });\r\n                p.addTransform(q, t1);\r\n                // Immediately apply the transformation.\r\n                // This prevents that jumping elements can be watched.\r\n                t1.update();\r\n                p.moveTo(Mat.matVecMult(t1.matrix, q.coords.usrCoords));\r\n\r\n                if (Type.isFunction(val)) {\r\n                    /**\r\n                     * @ignore\r\n                     */\r\n                    val2 = function () {\r\n                        return Math.PI * 2 - val();\r\n                    };\r\n                } else {\r\n                    /**\r\n                     * @ignore\r\n                     */\r\n                    val2 = function () {\r\n                        return Math.PI * 2 - val;\r\n                    };\r\n                }\r\n                t2 = this.board.create(\"transform\", [val2, this.center], {\r\n                    type: \"rotate\"\r\n                });\r\n                p.coords.on(\"update\", function () {\r\n                    t2.update();\r\n                    // q.moveTo(Mat.matVecMult(t2.matrix, p.coords.usrCoords));\r\n                    q.setPositionDirectly(Const.COORDS_BY_USER, Mat.matVecMult(t2.matrix, p.coords.usrCoords));\r\n                });\r\n\r\n                p.setParents(q);\r\n\r\n                this.hasFixedAngle = true;\r\n            }\r\n            return this;\r\n        };\r\n\r\n        /**\r\n         * Frees an angle from a prescribed value. This is only relevant if the angle size has been set by\r\n         * \"setAngle()\" previously. The anglepoint is set to a free point.\r\n         * @name free\r\n         * @function\r\n         * @memberof Angle.prototype\r\n         * @returns {Object} Pointer to the angle element..\r\n         * @see Angle#setAngle\r\n         */\r\n        el.free = function () {\r\n            var p = this.anglepoint;\r\n\r\n            if (p.transformations.length > 0) {\r\n                p.transformations.pop();\r\n                p.isDraggable = true;\r\n                p.parents = [];\r\n\r\n                p.coords.off('update');\r\n            }\r\n\r\n            this.hasFixedAngle = false;\r\n\r\n            return this;\r\n        };\r\n\r\n        el.setParents(points); // Important: This overwrites the parents order in underlying sector\r\n    } // end '3points'\r\n\r\n    // GEONExT compatible labels.\r\n    if (Type.exists(el.visProp.text)) {\r\n        el.label.setText(el.evalVisProp('text'));\r\n    }\r\n\r\n    el.elType = 'angle';\r\n    el.type = Const.OBJECT_TYPE_ANGLE;\r\n    el.subs = {};\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    el.updateDataArraySquare = function () {\r\n        var A, B, C,\r\n            d1, d2, v, l1, l2,\r\n            r = this.Radius();\r\n\r\n        if (type === '2lines') {\r\n            // This is necessary to update this.point1, this.point2, this.point3.\r\n            this.updateDataArraySector();\r\n        }\r\n\r\n        A = this.point2;\r\n        B = this.point1;\r\n        C = this.point3;\r\n\r\n        A = A.coords.usrCoords;\r\n        B = B.coords.usrCoords;\r\n        C = C.coords.usrCoords;\r\n\r\n        d1 = Geometry.distance(A, B, 3);\r\n        d2 = Geometry.distance(C, B, 3);\r\n\r\n        // In case of type=='2lines' this is redundant, because r == d1 == d2\r\n        A = [1, B[1] + ((A[1] - B[1]) * r) / d1, B[2] + ((A[2] - B[2]) * r) / d1];\r\n        C = [1, B[1] + ((C[1] - B[1]) * r) / d2, B[2] + ((C[2] - B[2]) * r) / d2];\r\n\r\n        v = Mat.crossProduct(C, B);\r\n        l1 = [-A[1] * v[1] - A[2] * v[2], A[0] * v[1], A[0] * v[2]];\r\n        v = Mat.crossProduct(A, B);\r\n        l2 = [-C[1] * v[1] - C[2] * v[2], C[0] * v[1], C[0] * v[2]];\r\n\r\n        v = Mat.crossProduct(l1, l2);\r\n        v[1] /= v[0];\r\n        v[2] /= v[0];\r\n\r\n        this.dataX = [B[1], A[1], v[1], C[1], B[1]];\r\n        this.dataY = [B[2], A[2], v[2], C[2], B[2]];\r\n\r\n        this.bezierDegree = 1;\r\n    };\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    el.updateDataArrayNone = function () {\r\n        this.dataX = [NaN];\r\n        this.dataY = [NaN];\r\n        this.bezierDegree = 1;\r\n    };\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    el.updateDataArray = function () {\r\n        var type = this.evalVisProp('type'),\r\n            deg = Geometry.trueAngle(this.point2, this.point1, this.point3),\r\n            vp_s = this.evalVisProp('selection');\r\n\r\n        if ((vp_s === \"minor\" && deg > 180.0) || (vp_s === \"major\" && deg < 180.0)) {\r\n            deg = 360.0 - deg;\r\n        }\r\n\r\n        if (Math.abs(deg - 90.0) < this.evalVisProp('orthosensitivity') + Mat.eps) {\r\n            type = this.evalVisProp('orthotype');\r\n        }\r\n\r\n        if (type === 'none') {\r\n            this.updateDataArrayNone();\r\n            this.maxX = function() { return 0; };\r\n        } else if (type === 'square') {\r\n            this.updateDataArraySquare();\r\n            this.maxX = function() { return 4; };\r\n        } else if (type === 'sector') {\r\n            this.updateDataArraySector();\r\n            this.maxX = function() { return 6; };\r\n        } else if (type === 'sectordot') {\r\n            this.updateDataArraySector();\r\n            this.maxX = function() { return 6; };\r\n            if (!this.dot.visProp.visible) {\r\n                this.dot.setAttribute({ visible: true });\r\n            }\r\n        }\r\n\r\n        if (!this.visProp.visible || (type !== \"sectordot\" && this.dot.visProp.visible)) {\r\n            this.dot.setAttribute({ visible: false });\r\n        }\r\n    };\r\n\r\n    attrsub = Type.copyAttributes(attributes, board.options, \"angle\", 'dot');\r\n    /**\r\n     * Indicates a right angle. Invisible by default, use <tt>dot.visible: true</tt> to show.\r\n     * Though this dot indicates a right angle, it can be visible even if the angle is not a right\r\n     * one.\r\n     * @type JXG.Point\r\n     * @name dot\r\n     * @memberOf Angle.prototype\r\n     */\r\n    el.dot = board.create(\r\n        \"point\",\r\n        [\r\n            function () {\r\n                var A, B, r, d, a2, co, si, mat, vp_s;\r\n\r\n                if (Type.exists(el.dot) && !el.dot.visProp.visible) {\r\n                    return [0, 0];\r\n                }\r\n\r\n                A = el.point2.coords.usrCoords;\r\n                B = el.point1.coords.usrCoords;\r\n                r = el.Radius();\r\n                d = Geometry.distance(A, B, 3);\r\n                a2 = Geometry.rad(el.point2, el.point1, el.point3);\r\n\r\n                vp_s = el.evalVisProp('selection');\r\n                if ((vp_s === \"minor\" && a2 > Math.PI) || (vp_s === \"major\" && a2 < Math.PI)) {\r\n                    a2 = -(2 * Math.PI - a2);\r\n                }\r\n                a2 *= 0.5;\r\n\r\n                co = Math.cos(a2);\r\n                si = Math.sin(a2);\r\n\r\n                A = [1, B[1] + ((A[1] - B[1]) * r) / d, B[2] + ((A[2] - B[2]) * r) / d];\r\n\r\n                mat = [\r\n                    [1, 0, 0],\r\n                    [B[1] - 0.5 * B[1] * co + 0.5 * B[2] * si, co * 0.5, -si * 0.5],\r\n                    [B[2] - 0.5 * B[1] * si - 0.5 * B[2] * co, si * 0.5, co * 0.5]\r\n                ];\r\n                return Mat.matVecMult(mat, A);\r\n            }\r\n        ],\r\n        attrsub\r\n    );\r\n\r\n    el.dot.dump = false;\r\n    el.subs.dot = el.dot;\r\n\r\n    if (type === '2lines') {\r\n        for (i = 0; i < 2; i++) {\r\n            board.select(parents[i]).addChild(el.dot);\r\n        }\r\n    } else {\r\n        for (i = 0; i < 3; i++) {\r\n            board.select(points[i]).addChild(el.dot);\r\n        }\r\n    }\r\n    board.unsuspendUpdate();\r\n\r\n    /**\r\n     * Returns the value of the angle.\r\n     * @memberOf Angle.prototype\r\n     * @name Value\r\n     * @function\r\n     * @param {String} [unit='length'] Unit of the returned values. Possible units are\r\n     * <ul>\r\n     * <li> 'radians' (default): angle value in radians\r\n     * <li> 'degrees': angle value in degrees\r\n     * <li> 'semicircle': angle value in radians as a multiple of &pi;, e.g. if the angle is 1.5&pi;, 1.5 will be returned.\r\n     * <li> 'circle': angle value in radians as a multiple of 2&pi;\r\n     * <li> 'length': length of the arc line of the angle\r\n     * </ul>\r\n     * It is sufficient to supply the first three characters of the unit, e.g. 'len'.\r\n     * @returns {Number} angle value in various units.\r\n     * @see Sector#L\r\n     * @see Arc#Value\r\n     * @example\r\n     * var A, B, C, ang,\r\n     *     r = 0.5;\r\n     * A = board.create(\"point\", [3, 0]);\r\n     * B = board.create(\"point\", [0, 0]);\r\n     * C = board.create(\"point\", [2, 2]);\r\n     * ang = board.create(\"angle\", [A, B, C], {radius: r});\r\n     *\r\n     * console.log(ang.Value());\r\n     * // Output Math.PI * 0.25\r\n     *\r\n     * console.log(ang.Value('radian'));\r\n     * // Output Math.PI * 0.25\r\n     *\r\n     * console.log(ang.Value('degree');\r\n     * // Output 45\r\n     *\r\n     * console.log(ang.Value('semicircle'));\r\n     * // Output 0.25\r\n     *\r\n     * console.log(ang.Value('circle'));\r\n     * // Output 0.125\r\n     *\r\n     * console.log(ang.Value('length'));\r\n     * // Output r * Math.PI * 0.25\r\n     *\r\n     * console.log(ang.L());\r\n     * // Output r * Math.PI * 0.25\r\n     *\r\n     */\r\n    el.Value = function(unit) {\r\n        unit = unit || 'radians';\r\n        if (unit === '') {\r\n            unit = 'radians';\r\n        }\r\n        return el.arc.Value(unit);\r\n    };\r\n\r\n\r\n    // documented in GeometryElement\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    el.getLabelAnchor = function () {\r\n        var vec,\r\n            dx = 12,\r\n            A, B, r, d, a2, co, si, mat,\r\n            vp_s = el.evalVisProp('selection'),\r\n            l_vp = this.label ? this.label.visProp : this.visProp.label,\r\n            pos = (this.label) ?\r\n                    this.label.evalVisProp('position') : this.evalVisProp('label.position');\r\n\r\n        // If this is uncommented, the angle label can not be dragged\r\n        //if (Type.exists(this.label)) {\r\n        //    this.label.relativeCoords = new Coords(Const.COORDS_BY_SCREEN, [0, 0], this.board);\r\n        //}\r\n\r\n        if (\r\n            !Type.isString(pos) ||\r\n            (pos.indexOf('right') < 0 && pos.indexOf('left') < 0)\r\n        ) {\r\n\r\n            if (Type.exists(this.label) && Type.exists(this.label.visProp.fontsize)) {\r\n                dx = this.label.evalVisProp('fontsize');\r\n            }\r\n            dx /= this.board.unitX;\r\n\r\n            A = el.point2.coords.usrCoords;\r\n            B = el.point1.coords.usrCoords;\r\n            r = el.Radius();\r\n            d = Geometry.distance(A, B, 3);\r\n            a2 = Geometry.rad(el.point2, el.point1, el.point3);\r\n            if ((vp_s === \"minor\" && a2 > Math.PI) || (vp_s === \"major\" && a2 < Math.PI)) {\r\n                a2 = -(2 * Math.PI - a2);\r\n            }\r\n            a2 *= 0.5;\r\n            co = Math.cos(a2);\r\n            si = Math.sin(a2);\r\n\r\n            A = [1, B[1] + ((A[1] - B[1]) * r) / d, B[2] + ((A[2] - B[2]) * r) / d];\r\n\r\n            mat = [\r\n                [1, 0, 0],\r\n                [B[1] - 0.5 * B[1] * co + 0.5 * B[2] * si, co * 0.5, -si * 0.5],\r\n                [B[2] - 0.5 * B[1] * si - 0.5 * B[2] * co, si * 0.5, co * 0.5]\r\n            ];\r\n            vec = Mat.matVecMult(mat, A);\r\n            vec[1] /= vec[0];\r\n            vec[2] /= vec[0];\r\n            vec[0] /= vec[0];\r\n\r\n            d = Geometry.distance(vec, B, 3);\r\n            vec = [\r\n                vec[0],\r\n                B[1] + ((vec[1] - B[1]) * (r + dx)) / d,\r\n                B[2] + ((vec[2] - B[2]) * (r + dx)) / d\r\n            ];\r\n\r\n            l_vp.position = Geometry.calcLabelQuadrant(Geometry.rad([1, 0], [0, 0], vec));\r\n\r\n            return new Coords(Const.COORDS_BY_USER, vec, this.board);\r\n        } else {\r\n            return this.getLabelPosition(pos, this.label.evalVisProp('distance'));\r\n        }\r\n    };\r\n\r\n    el.methodMap = Type.deepCopy(el.methodMap, {\r\n        setAngle: \"setAngle\",\r\n        Value: \"Value\",\r\n        free: \"free\"\r\n    });\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"angle\", JXG.createAngle);\r\n\r\n/**\r\n * @class A non-reflex angle is the instance of an angle that is at most 180°.\r\n * It is defined by a center, one point that\r\n * defines the radius, and a third point that defines the angle of the sector.\r\n * @pseudo\r\n * @name NonReflexAngle\r\n * @augments Angle\r\n * @constructor\r\n * @type Sector\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 . Minor sector is a sector of a circle around p1 having measure less than or equal to\r\n * 180 degrees (pi radians) and starts at p2. The radius is determined by p2, the angle by p3.\r\n * @example\r\n * // Create a non-reflex angle out of three free points\r\n * var p1 = board.create('point', [5.0, 3.0]),\r\n *     p2 = board.create('point', [1.0, 0.5]),\r\n *     p3 = board.create('point', [1.5, 5.0]),\r\n *\r\n *     a = board.create('nonreflexangle', [p1, p2, p3], {radius: 2}),\r\n *     t = board.create('text', [4, 4, function() { return JXG.toFixed(a.Value(), 2); }]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGd0ab6d6b-63a7-48b2-8749-b02bb5e744f9\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXGd0ab6d6b-63a7-48b2-8749-b02bb5e744f9', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),\r\n *     p1 = board.create('point', [5.0, 3.0]),\r\n *     p2 = board.create('point', [1.0, 0.5]),\r\n *     p3 = board.create('point', [1.5, 5.0]),\r\n *\r\n *     a = board.create('nonreflexangle', [p1, p2, p3], {radius: 2}),\r\n *     t = board.create('text', [4, 4, function() { return JXG.toFixed(a.Value(), 2); }]);\r\n * })();\r\n * </script><pre>\r\n */\r\nJXG.createNonreflexAngle = function (board, parents, attributes) {\r\n    var el;\r\n\r\n    attributes.selection = 'minor';\r\n    attributes = Type.copyAttributes(attributes, board.options, 'nonreflexangle');\r\n    el = JXG.createAngle(board, parents, attributes);\r\n\r\n    // Documented in createAngle\r\n    el.Value = function (unit) {\r\n        var rad = Geometry.rad(this.point2, this.point1, this.point3);\r\n        unit = unit || 'radians';\r\n        if (unit === '') {\r\n            unit = 'radians';\r\n        }\r\n        rad = (rad < Math.PI) ? rad : 2.0 * Math.PI - rad;\r\n\r\n        return this.arc.Value(unit, rad);\r\n    };\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"nonreflexangle\", JXG.createNonreflexAngle);\r\n\r\n/**\r\n * @class A reflex angle is the instance of an angle that is larger than 180°.\r\n * It is defined by a center, one point that\r\n * defines the radius, and a third point that defines the angle of the sector.\r\n * @pseudo\r\n * @name ReflexAngle\r\n * @augments Angle\r\n * @constructor\r\n * @type Sector\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 . Minor sector is a sector of a circle around p1 having measure less than or equal to\r\n * 180 degrees (pi radians) and starts at p2. The radius is determined by p2, the angle by p3.\r\n * @example\r\n * // Create a non-reflex angle out of three free points\r\n * var p1 = board.create('point', [5.0, 3.0]),\r\n *     p2 = board.create('point', [1.0, 0.5]),\r\n *     p3 = board.create('point', [1.5, 5.0]),\r\n *\r\n *     a = board.create('reflexangle', [p1, p2, p3], {radius: 2}),\r\n *     t = board.create('text', [4, 4, function() { return JXG.toFixed(a.Value(), 2); }]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGf2a577f2-553d-4f9f-a895-2d6d4b8c60e8\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n * var board = JXG.JSXGraph.initBoard('JXGf2a577f2-553d-4f9f-a895-2d6d4b8c60e8', {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false}),\r\n *     p1 = board.create('point', [5.0, 3.0]),\r\n *     p2 = board.create('point', [1.0, 0.5]),\r\n *     p3 = board.create('point', [1.5, 5.0]),\r\n *\r\n *     a = board.create('reflexangle', [p1, p2, p3], {radius: 2}),\r\n *     t = board.create('text', [4, 4, function() { return JXG.toFixed(a.Value(), 2); }]);\r\n * })();\r\n * </script><pre>\r\n */\r\nJXG.createReflexAngle = function (board, parents, attributes) {\r\n    var el;\r\n\r\n    attributes.selection = 'major';\r\n    attributes = Type.copyAttributes(attributes, board.options, 'reflexangle');\r\n    el = JXG.createAngle(board, parents, attributes);\r\n\r\n    // Documented in createAngle\r\n    el.Value = function (unit) {\r\n        var rad = Geometry.rad(this.point2, this.point1, this.point3);\r\n        unit = unit || 'radians';\r\n        if (unit === '') {\r\n            unit = 'radians';\r\n        }\r\n        rad = (rad >= Math.PI) ? rad : 2.0 * Math.PI - rad;\r\n\r\n        return this.arc.Value(unit, rad);\r\n    };\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"reflexangle\", JXG.createReflexAngle);\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview This file contains our composition elements, i.e. these elements are mostly put together\r\n * from one or more {@link JXG.GeometryElement} but with a special meaning. E.g. the midpoint element is contained here\r\n * and this is just a {@link JXG.Point} with coordinates dependent from two other points. Currently in this file the\r\n * following compositions can be found: <ul>\r\n *   <li>{@link Arrowparallel} (currently private)</li>\r\n *   <li>{@link Bisector}</li>\r\n *   <li>{@link Msector}</li>\r\n *   <li>{@link Circumcircle}</li>\r\n *   <li>{@link Circumcirclemidpoint}</li>\r\n *   <li>{@link Integral}</li>\r\n *   <li>{@link Midpoint}</li>\r\n *   <li>{@link Mirrorpoint}</li>\r\n *   <li>{@link Normal}</li>\r\n *   <li>{@link Orthogonalprojection}</li>\r\n *   <li>{@link Parallel}</li>\r\n *   <li>{@link Perpendicular}</li>\r\n *   <li>{@link Perpendicularpoint}</li>\r\n *   <li>{@link Perpendicularsegment}</li>\r\n *   <li>{@link Reflection}</li></ul>\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Numerics from \"../math/numerics.js\";\r\nimport Coords from \"../base/coords.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Const from \"../base/constants.js\";\r\n// import Point from \"../base/point.js\";\r\n// import Line from \"../base/line.js\";\r\n// import Circle from \"../base/circle.js\";\r\n// import Transform from \"../base/transformation.js\";\r\nimport Composition from \"../base/composition.js\";\r\n// import Curve from \"../base/curve.js\";\r\n// import Polygon from \"../base/polygon.js\";\r\n\r\n/**\r\n * @class A point that is the orthogonal projection of a point onto a line.\r\n * @pseudo\r\n * @description An orthogonal projection is given by a point and a line. It is determined by projecting the given point\r\n * orthogonal onto the given line.\r\n * @constructor\r\n * @name Orthogonalprojection\r\n * @type JXG.Point\r\n * @augments JXG.Point\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Line_JXG.Point} p,l The constructed point is the orthogonal projection of p onto l.\r\n * @example\r\n * var p1 = board.create('point', [0.0, 4.0]);\r\n * var p2 = board.create('point', [6.0, 1.0]);\r\n * var l1 = board.create('line', [p1, p2]);\r\n * var p3 = board.create('point', [3.0, 3.0]);\r\n *\r\n * var pp1 = board.create('orthogonalprojection', [p3, l1]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG7708b215-39fa-41b6-b972-19d73d77d791\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var ppex1_board = JXG.JSXGraph.initBoard('JXG7708b215-39fa-41b6-b972-19d73d77d791', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var ppex1_p1 = ppex1_board.create('point', [0.0, 4.0]);\r\n *   var ppex1_p2 = ppex1_board.create('point', [6.0, 1.0]);\r\n *   var ppex1_l1 = ppex1_board.create('line', [ppex1_p1, ppex1_p2]);\r\n *   var ppex1_p3 = ppex1_board.create('point', [3.0, 3.0]);\r\n *   var ppex1_pp1 = ppex1_board.create('orthogonalprojection', [ppex1_p3, ppex1_l1]);\r\n * </script><pre>\r\n */\r\nJXG.createOrthogonalProjection = function (board, parents, attributes) {\r\n    var l, p, t, attr;\r\n\r\n    parents[0] = board.select(parents[0]);\r\n    parents[1] = board.select(parents[1]);\r\n\r\n    if (\r\n        Type.isPointType(board, parents[0]) &&\r\n        parents[1].elementClass === Const.OBJECT_CLASS_LINE\r\n    ) {\r\n        p = Type.providePoints(board, [parents[0]], attributes, 'point')[0];\r\n        l = parents[1];\r\n    } else if (\r\n        Type.isPointType(board, parents[1]) &&\r\n        parents[0].elementClass === Const.OBJECT_CLASS_LINE\r\n    ) {\r\n        p = Type.providePoints(board, [parents[1]], attributes, 'point')[0];\r\n        l = parents[0];\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create perpendicular point with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [point,line]\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'orthogonalprojection');\r\n\r\n    /**\r\n     * @type JXG.Element\r\n     * @ignore\r\n     */\r\n    t = board.create(\r\n        \"point\",\r\n        [\r\n            function () {\r\n                return Geometry.projectPointToLine(p, l, board);\r\n            }\r\n        ],\r\n        attr\r\n    );\r\n\r\n    if (Type.exists(p._is_new)) {\r\n        t.addChild(p);\r\n        delete p._is_new;\r\n    } else {\r\n        p.addChild(t);\r\n    }\r\n    l.addChild(t);\r\n\r\n    t.elType = 'orthogonalprojection';\r\n    t.setParents([p.id, t.id]);\r\n\r\n    t.update();\r\n\r\n    /**\r\n     * Used to generate a polynomial for the orthogonal projection\r\n     * @name Orthogonalprojection#generatePolynomial\r\n     * @returns {Array} An array containing the generated polynomial.\r\n     * @private\r\n     * @function\r\n     * @ignore\r\n     */\r\n    t.generatePolynomial = function () {\r\n        /*\r\n         *  Perpendicular takes point P and line L and creates point T and line M:\r\n         *\r\n         *                          | M\r\n         *                          |\r\n         *                          x P (p1,p2)\r\n         *                          |\r\n         *                          |\r\n         *  L                       |\r\n         *  ----------x-------------x------------------------x--------\r\n         *            A (a1,a2)     |T (t1,t2)               B (b1,b2)\r\n         *                          |\r\n         *                          |\r\n         *\r\n         * So we have two conditions:\r\n         *\r\n         *   (a)  AT  || TB          (collinearity condition)\r\n         *   (b)  PT _|_ AB          (orthogonality condition)\r\n         *\r\n         *      a2-t2       t2-b2\r\n         *     -------  =  -------           (1)\r\n         *      a1-t1       t1-b1\r\n         *\r\n         *      p2-t2         a1-b1\r\n         *     -------  =  - -------         (2)\r\n         *      p1-t1         a2-b2\r\n         *\r\n         * Multiplying (1) and (2) with denominators and simplifying gives\r\n         *\r\n         *    a2t1 - a2b1 + t2b1 - a1t2 + a1b2 - t1b2 = 0                  (1')\r\n         *\r\n         *    p2a2 - p2b2 - t2a2 + t2b2 + p1a1 - p1b1 - t1a1 + t1b1 = 0    (2')\r\n         *\r\n         */\r\n\r\n        var a1 = l.point1.symbolic.x,\r\n            a2 = l.point1.symbolic.y,\r\n            b1 = l.point2.symbolic.x,\r\n            b2 = l.point2.symbolic.y,\r\n            p1 = p.symbolic.x,\r\n            p2 = p.symbolic.y,\r\n            t1 = t.symbolic.x,\r\n            t2 = t.symbolic.y,\r\n            poly1 = \"(\" + a2 + \")*(\" + t1 + \")-(\" + a2 + \")*(\" + b1 + \")+(\" + t2 + \")*(\" + b1 + \")-(\" + a1 + \")*(\" + t2 + \")+(\" + a1 + \")*(\" +\r\n                b2 + \")-(\" + t1 + \")*(\" + b2 + \")\",\r\n            poly2 = \"(\" + p2 + \")*(\" + a2 + \")-(\" + p2 + \")*(\" + b2 + \")-(\" + t2 + \")*(\" + a2 + \")+(\" + t2 + \")*(\" + b2 + \")+(\" + p1 + \")*(\" +\r\n                a1 + \")-(\" + p1 + \")*(\" + b1 + \")-(\" + t1 + \")*(\" + a1 + \")+(\" + t1 + \")*(\" + b1 + \")\";\r\n\r\n        return [poly1, poly2];\r\n    };\r\n\r\n    return t;\r\n};\r\n\r\n/**\r\n\r\n     * @class A perpendicular is a line orthogonal to a given line, through a given point not on the line,\r\n     * @pseudo\r\n     * @description  A perpendicular is a composition of two elements: a line and a point. The line is orthogonal\r\n     * to a given line and contains a given point.\r\n     * @name Perpendicular\r\n     * @constructor\r\n     * @type JXG.Line\r\n     * @augments Segment\r\n     * @returns A {@link JXG.Line} object through the given point that is orthogonal to the given line.\r\n     * @throws {Error} If the elements cannot be constructed with the given parent objects an exception is thrown.\r\n     * @param {JXG.Line_JXG.Point} l,p The perpendicular line will be orthogonal to l and\r\n     * will contain p.\r\n     * @example\r\n     * // Create a perpendicular\r\n     * var p1 = board.create('point', [0.0, 2.0]);\r\n     * var p2 = board.create('point', [2.0, 1.0]);\r\n     * var l1 = board.create('line', [p1, p2]);\r\n     *\r\n     * var p3 = board.create('point', [3.0, 3.0]);\r\n     * var perp1 = board.create('perpendicular', [l1, p3]);\r\n     * </pre><div class=\"jxgbox\" id=\"JXGd5b78842-7b27-4d37-b608-d02519e6cd03\" style=\"width: 400px; height: 400px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *   var pex1_board = JXG.JSXGraph.initBoard('JXGd5b78842-7b27-4d37-b608-d02519e6cd03', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n     *   var pex1_p1 = pex1_board.create('point', [0.0, 2.0]);\r\n     *   var pex1_p2 = pex1_board.create('point', [2.0, 1.0]);\r\n     *   var pex1_l1 = pex1_board.create('line', [pex1_p1, pex1_p2]);\r\n     *   var pex1_p3 = pex1_board.create('point', [3.0, 3.0]);\r\n     *   var pex1_perp1 = pex1_board.create('perpendicular', [pex1_l1, pex1_p3]);\r\n     * </script><pre>\r\n     */\r\nJXG.createPerpendicular = function (board, parents, attributes) {\r\n    var p, l, pd, attr;\r\n\r\n    parents[0] = board.select(parents[0]);\r\n    parents[1] = board.select(parents[1]);\r\n\r\n    if (\r\n        Type.isPointType(board, parents[0]) &&\r\n        parents[1].elementClass === Const.OBJECT_CLASS_LINE\r\n    ) {\r\n        l = parents[1];\r\n        p = Type.providePoints(board, [parents[0]], attributes, 'point')[0];\r\n    } else if (\r\n        Type.isPointType(board, parents[1]) &&\r\n        parents[0].elementClass === Const.OBJECT_CLASS_LINE\r\n    ) {\r\n        l = parents[0];\r\n        p = Type.providePoints(board, [parents[1]], attributes, 'point')[0];\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create perpendicular with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [line,point]\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'perpendicular');\r\n    pd = JXG.createLine(\r\n        board,\r\n        [\r\n            function () {\r\n                return l.stdform[2] * p.X() - l.stdform[1] * p.Y();\r\n            },\r\n            function () {\r\n                return -l.stdform[2] * p.Z();\r\n            },\r\n            function () {\r\n                return l.stdform[1] * p.Z();\r\n            }\r\n        ],\r\n        attr\r\n    );\r\n\r\n    pd.elType = 'perpendicular';\r\n    pd.setParents([l.id, p.id]);\r\n\r\n    if (Type.exists(p._is_new)) {\r\n        pd.addChild(p);\r\n        delete p._is_new;\r\n    } else {\r\n        p.addChild(pd);\r\n    }\r\n    l.addChild(pd);\r\n\r\n    return pd;\r\n};\r\n\r\n/**\r\n * @class Orthogonal projection of a point onto a line.\r\n * @pseudo\r\n * @description A perpendicular point is given by a point and a line. It is determined by projecting the given point\r\n * orthogonal onto the given line. This element should be used in GEONExTReader only. All other applications should\r\n * use orthogonal projection {@link Orthogonalprojection}.\r\n * @constructor\r\n * @name PerpendicularPoint\r\n * @type JXG.Point\r\n * @augments JXG.Point\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Line_JXG.Point} p,l The constructed point is the orthogonal projection of p onto l.\r\n * @example\r\n * var p1 = board.create('point', [0.0, 4.0]);\r\n * var p2 = board.create('point', [6.0, 1.0]);\r\n * var l1 = board.create('line', [p1, p2]);\r\n * var p3 = board.create('point', [3.0, 3.0]);\r\n *\r\n * var pp1 = board.create('perpendicularpoint', [p3, l1]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGded148c9-3536-44c0-ab81-1bb8fa48f3f4\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var ppex1_board = JXG.JSXGraph.initBoard('JXGded148c9-3536-44c0-ab81-1bb8fa48f3f4', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var ppex1_p1 = ppex1_board.create('point', [0.0, 4.0]);\r\n *   var ppex1_p2 = ppex1_board.create('point', [6.0, 1.0]);\r\n *   var ppex1_l1 = ppex1_board.create('line', [ppex1_p1, ppex1_p2]);\r\n *   var ppex1_p3 = ppex1_board.create('point', [3.0, 3.0]);\r\n *   var ppex1_pp1 = ppex1_board.create('perpendicularpoint', [ppex1_p3, ppex1_l1]);\r\n * </script><pre>\r\n */\r\nJXG.createPerpendicularPoint = function (board, parents, attributes) {\r\n    var l, p, t;\r\n\r\n    parents[0] = board.select(parents[0]);\r\n    parents[1] = board.select(parents[1]);\r\n    if (\r\n        Type.isPointType(board, parents[0]) &&\r\n        parents[1].elementClass === Const.OBJECT_CLASS_LINE\r\n    ) {\r\n        p = Type.providePoints(board, [parents[0]], attributes, 'point')[0];\r\n        l = parents[1];\r\n    } else if (\r\n        Type.isPointType(board, parents[1]) &&\r\n        parents[0].elementClass === Const.OBJECT_CLASS_LINE\r\n    ) {\r\n        p = Type.providePoints(board, [parents[1]], attributes, 'point')[0];\r\n        l = parents[0];\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create perpendicular point with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [point,line]\"\r\n        );\r\n    }\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    t = board.create(\r\n        \"point\",\r\n        [\r\n            function () {\r\n                return Geometry.perpendicular(l, p, board)[0];\r\n            }\r\n        ],\r\n        attributes\r\n    );\r\n\r\n    if (Type.exists(p._is_new)) {\r\n        t.addChild(p);\r\n        delete p._is_new;\r\n    } else {\r\n        p.addChild(t);\r\n    }\r\n    l.addChild(t);\r\n\r\n    t.elType = 'perpendicularpoint';\r\n    t.setParents([p.id, l.id]);\r\n\r\n    t.update();\r\n\r\n    /**\r\n     * Used to generate a polynomial for the perpendicular point\r\n     * @name PerpendicularPoint#generatePolynomial\r\n     * @returns {Array} An array containing the generated polynomial.\r\n     * @private\r\n     * @function\r\n     * @ignore\r\n     */\r\n    t.generatePolynomial = function () {\r\n        /*\r\n         *  Perpendicular takes point P and line L and creates point T and line M:\r\n         *\r\n         *                          | M\r\n         *                          |\r\n         *                          x P (p1,p2)\r\n         *                          |\r\n         *                          |\r\n         *  L                       |\r\n         *  ----------x-------------x------------------------x--------\r\n         *            A (a1,a2)     |T (t1,t2)               B (b1,b2)\r\n         *                          |\r\n         *                          |\r\n         *\r\n         * So we have two conditions:\r\n         *\r\n         *   (a)  AT  || TB          (collinearity condition)\r\n         *   (b)  PT _|_ AB          (orthogonality condition)\r\n         *\r\n         *      a2-t2       t2-b2\r\n         *     -------  =  -------           (1)\r\n         *      a1-t1       t1-b1\r\n         *\r\n         *      p2-t2         a1-b1\r\n         *     -------  =  - -------         (2)\r\n         *      p1-t1         a2-b2\r\n         *\r\n         * Multiplying (1) and (2) with denominators and simplifying gives\r\n         *\r\n         *    a2t1 - a2b1 + t2b1 - a1t2 + a1b2 - t1b2 = 0                  (1')\r\n         *\r\n         *    p2a2 - p2b2 - t2a2 + t2b2 + p1a1 - p1b1 - t1a1 + t1b1 = 0    (2')\r\n         *\r\n         */\r\n        var a1 = l.point1.symbolic.x,\r\n            a2 = l.point1.symbolic.y,\r\n            b1 = l.point2.symbolic.x,\r\n            b2 = l.point2.symbolic.y,\r\n            p1 = p.symbolic.x,\r\n            p2 = p.symbolic.y,\r\n            t1 = t.symbolic.x,\r\n            t2 = t.symbolic.y,\r\n            poly1 = \"(\" + a2 + \")*(\" + t1 + \")-(\" + a2 + \")*(\" + b1 + \")+(\" + t2 + \")*(\" + b1 + \")-(\" + a1 + \")*(\" + t2 + \")+(\" + a1 + \")*(\" + b2 + \")-(\" + t1 +\r\n                \")*(\" + b2 + \")\",\r\n            poly2 = \"(\" + p2 + \")*(\" + a2 + \")-(\" + p2 + \")*(\" + b2 + \")-(\" + t2 + \")*(\" + a2 + \")+(\" + t2 + \")*(\" + b2 + \")+(\" + p1 + \")*(\" + a1 + \")-(\" + p1 +\r\n                \")*(\" + b1 + \")-(\" + t1 + \")*(\" + a1 + \")+(\" + t1 + \")*(\" + b1 + \")\";\r\n\r\n        return [poly1, poly2];\r\n    };\r\n\r\n    return t;\r\n};\r\n\r\n/**\r\n * @class A line segment orthogonal to a given line, through a given point not on the line,\r\n * @pseudo\r\n * @description  A perpendicular is a composition of two elements: a line segment and a point. The line segment is orthogonal\r\n * to a given line and contains a given point and meets the given line in the perpendicular point.\r\n * @name PerpendicularSegment\r\n * @constructor\r\n * @type JXG.Line\r\n * @augments Segment\r\n * @returns An array containing two elements: A {@link JXG.Line} object in the first component and a\r\n * {@link JXG.Point} element in the second component. The line segment is orthogonal to the given line and meets it\r\n * in the returned point.\r\n * @throws {Error} If the elements cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Line_JXG.Point} l,p The perpendicular line will be orthogonal to l and\r\n * will contain p. The perpendicular point is the intersection point of the two lines.\r\n * @example\r\n * // Create a perpendicular\r\n * var p1 = board.create('point', [0.0, 2.0]);\r\n * var p2 = board.create('point', [2.0, 1.0]);\r\n * var l1 = board.create('line', [p1, p2]);\r\n *\r\n * var p3 = board.create('point', [3.0, 3.0]);\r\n * var perp1 = board.create('perpendicularsegment', [l1, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG037a6eb2-781d-4b71-b286-763619a63f22\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var pex1_board = JXG.JSXGraph.initBoard('JXG037a6eb2-781d-4b71-b286-763619a63f22', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var pex1_p1 = pex1_board.create('point', [0.0, 2.0]);\r\n *   var pex1_p2 = pex1_board.create('point', [2.0, 1.0]);\r\n *   var pex1_l1 = pex1_board.create('line', [pex1_p1, pex1_p2]);\r\n *   var pex1_p3 = pex1_board.create('point', [3.0, 3.0]);\r\n *   var pex1_perp1 = pex1_board.create('perpendicularsegment', [pex1_l1, pex1_p3]);\r\n * </script><pre>\r\n */\r\nJXG.createPerpendicularSegment = function (board, parents, attributes) {\r\n    var p, l, pd, t, attr;\r\n\r\n    parents[0] = board.select(parents[0]);\r\n    parents[1] = board.select(parents[1]);\r\n    if (\r\n        Type.isPointType(board, parents[0]) &&\r\n        parents[1].elementClass === Const.OBJECT_CLASS_LINE\r\n    ) {\r\n        l = parents[1];\r\n        p = Type.providePoints(board, [parents[0]], attributes, 'point')[0];\r\n    } else if (\r\n        Type.isPointType(board, parents[1]) &&\r\n        parents[0].elementClass === Const.OBJECT_CLASS_LINE\r\n    ) {\r\n        l = parents[0];\r\n        p = Type.providePoints(board, [parents[1]], attributes, 'point')[0];\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create perpendicular with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [line,point]\"\r\n        );\r\n    }\r\n    attr = Type.copyAttributes(attributes, board.options, \"perpendicularsegment\", 'point');\r\n    t = JXG.createPerpendicularPoint(board, [l, p], attr);\r\n    t.dump = false;\r\n\r\n    if (!Type.exists(attributes.layer)) {\r\n        attributes.layer = board.options.layer.line;\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'perpendicularsegment');\r\n    pd = JXG.createLine(\r\n        board,\r\n        [\r\n            function () {\r\n                return Geometry.perpendicular(l, p, board)[1] ? [t, p] : [p, t];\r\n            }\r\n        ],\r\n        attr\r\n    );\r\n\r\n    /**\r\n     * Helper point\r\n     * @memberOf PerpendicularSegment.prototype\r\n     * @type PerpendicularPoint\r\n     * @name point\r\n     */\r\n    pd.point = t;\r\n\r\n    if (Type.exists(p._is_new)) {\r\n        pd.addChild(p);\r\n        delete p._is_new;\r\n    } else {\r\n        p.addChild(pd);\r\n    }\r\n    l.addChild(pd);\r\n\r\n    pd.elType = 'perpendicularsegment';\r\n    pd.setParents([p.id, l.id]);\r\n    pd.subs = {\r\n        point: t\r\n    };\r\n    pd.inherits.push(t);\r\n\r\n    return pd;\r\n};\r\n\r\n/**\r\n * @class Midpoint of two points.\r\n * @pseudo\r\n * @description A midpoint is given by two points. It is collinear to the given points and the distance\r\n * is the same to each of the given points, i.e. it is in the middle of the given points.\r\n * @constructor\r\n * @name Midpoint\r\n * @type JXG.Point\r\n * @augments JXG.Point\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point} p1,p2 The constructed point will be in the middle of p1 and p2.\r\n * @param {JXG.Line} l The midpoint will be in the middle of {@link JXG.Line#point1} and {@link JXG.Line#point2} of\r\n * the given line l.\r\n * @example\r\n * // Create base elements: 2 points and 1 line\r\n * var p1 = board.create('point', [0.0, 2.0]);\r\n * var p2 = board.create('point', [2.0, 1.0]);\r\n * var l1 = board.create('segment', [[0.0, 3.0], [3.0, 3.0]]);\r\n *\r\n * var mp1 = board.create('midpoint', [p1, p2]);\r\n * var mp2 = board.create('midpoint', [l1]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG7927ef86-24ae-40cc-afb0-91ff61dd0de7\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var mpex1_board = JXG.JSXGraph.initBoard('JXG7927ef86-24ae-40cc-afb0-91ff61dd0de7', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var mpex1_p1 = mpex1_board.create('point', [0.0, 2.0]);\r\n *   var mpex1_p2 = mpex1_board.create('point', [2.0, 1.0]);\r\n *   var mpex1_l1 = mpex1_board.create('segment', [[0.0, 3.0], [3.0, 3.0]]);\r\n *   var mpex1_mp1 = mpex1_board.create('midpoint', [mpex1_p1, mpex1_p2]);\r\n *   var mpex1_mp2 = mpex1_board.create('midpoint', [mpex1_l1]);\r\n * </script><pre>\r\n */\r\nJXG.createMidpoint = function (board, parents, attributes) {\r\n    var a, b, el, i, attr;\r\n\r\n    for (i = 0; i < parents.length; ++i) {\r\n        parents[i] = board.select(parents[i]);\r\n    }\r\n    if (\r\n        parents.length === 2 &&\r\n        Type.isPointType(board, parents[0]) &&\r\n        Type.isPointType(board, parents[1])\r\n    ) {\r\n        parents = Type.providePoints(board, parents, attributes, 'point');\r\n        a = parents[0];\r\n        b = parents[1];\r\n    } else if (parents.length === 1 && parents[0].elementClass === Const.OBJECT_CLASS_LINE) {\r\n        a = parents[0].point1;\r\n        b = parents[0].point2;\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create midpoint.\" +\r\n                \"\\nPossible parent types: [point,point], [line]\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'midpoint');\r\n    /**\r\n     * @type JXG.Element\r\n     * @ignore\r\n     */\r\n    el = board.create(\r\n        \"point\",\r\n        [\r\n            function () {\r\n                var x = a.coords.usrCoords[1] + b.coords.usrCoords[1];\r\n                if (\r\n                    isNaN(x) ||\r\n                    Math.abs(a.coords.usrCoords[0]) < Mat.eps ||\r\n                    Math.abs(b.coords.usrCoords[0]) < Mat.eps\r\n                ) {\r\n                    return NaN;\r\n                }\r\n\r\n                return x * 0.5;\r\n            },\r\n            function () {\r\n                var y = a.coords.usrCoords[2] + b.coords.usrCoords[2];\r\n                if (\r\n                    isNaN(y) ||\r\n                    Math.abs(a.coords.usrCoords[0]) < Mat.eps ||\r\n                    Math.abs(b.coords.usrCoords[0]) < Mat.eps\r\n                ) {\r\n                    return NaN;\r\n                }\r\n\r\n                return y * 0.5;\r\n            }\r\n        ],\r\n        attr\r\n    );\r\n    if (Type.exists(a._is_new)) {\r\n        el.addChild(a);\r\n        delete a._is_new;\r\n    } else {\r\n        a.addChild(el);\r\n    }\r\n    if (Type.exists(b._is_new)) {\r\n        el.addChild(b);\r\n        delete b._is_new;\r\n    } else {\r\n        b.addChild(el);\r\n    }\r\n\r\n    el.elType = 'midpoint';\r\n    el.setParents([a.id, b.id]);\r\n\r\n    el.prepareUpdate().update();\r\n\r\n    /**\r\n     * Used to generate a polynomial for the midpoint.\r\n     * @name Midpoint#generatePolynomial\r\n     * @returns {Array} An array containing the generated polynomial.\r\n     * @private\r\n     * @function\r\n     * @ignore\r\n     */\r\n    el.generatePolynomial = function () {\r\n        /*\r\n         *  Midpoint takes two point A and B or line L (with points P and Q) and creates point T:\r\n         *\r\n         *  L (not necessarily)\r\n         *  ----------x------------------x------------------x--------\r\n         *            A (a1,a2)          T (t1,t2)          B (b1,b2)\r\n         *\r\n         * So we have two conditions:\r\n         *\r\n         *   (a)   AT  ||  TB           (collinearity condition)\r\n         *   (b)  [AT] == [TB]          (equidistant condition)\r\n         *\r\n         *      a2-t2       t2-b2\r\n         *     -------  =  -------                                         (1)\r\n         *      a1-t1       t1-b1\r\n         *\r\n         *     (a1 - t1)^2 + (a2 - t2)^2 = (b1 - t1)^2 + (b2 - t2)^2       (2)\r\n         *\r\n         *\r\n         * Multiplying (1) with denominators and simplifying (1) and (2) gives\r\n         *\r\n         *    a2t1 - a2b1 + t2b1 - a1t2 + a1b2 - t1b2 = 0                      (1')\r\n         *\r\n         *    a1^2 - 2a1t1 + a2^2 - 2a2t2 - b1^2 + 2b1t1 - b2^2 + 2b2t2 = 0    (2')\r\n         *\r\n         */\r\n        var a1 = a.symbolic.x,\r\n            a2 = a.symbolic.y,\r\n            b1 = b.symbolic.x,\r\n            b2 = b.symbolic.y,\r\n            t1 = el.symbolic.x,\r\n            t2 = el.symbolic.y,\r\n            poly1 = \"(\" + a2 + \")*(\" + t1 + \")-(\" + a2 + \")*(\" + b1 + \")+(\" + t2 + \")*(\" + b1 + \")-(\" + a1 + \")*(\" + t2 + \")+(\" + a1 + \")*(\" + b2 +\r\n                \")-(\" + t1 + \")*(\" + b2 + \")\",\r\n            poly2 = \"(\" + a1 + \")^2 - 2*(\" + a1 + \")*(\" + t1 + \")+(\" + a2 + \")^2-2*(\" + a2 + \")*(\" + t2 + \")-(\" + b1 + \")^2+2*(\" + b1 + \")*(\" + t1 +\r\n                \")-(\" + b2 + \")^2+2*(\" + b2 + \")*(\" + t2 + \")\";\r\n\r\n        return [poly1, poly2];\r\n    };\r\n\r\n    return el;\r\n};\r\n\r\n/**\r\n * @class Given three point, a parallel point is the point such that the four points form a parallelogram.\r\n * @pseudo\r\n * @description A parallel point is given by three points. Taking the Euclidean vector from the first to the\r\n * second point, the parallel point is determined by adding that vector to the third point.\r\n * The line determined by the first two points is parallel to the line determined by the third point and the constructed point.\r\n * @constructor\r\n * @name Parallelpoint\r\n * @type JXG.Point\r\n * @augments JXG.Point\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 Taking the Euclidean vector <tt>v=p2-p1</tt> the parallel point is determined by\r\n * <tt>p4 = p3+v</tt>\r\n * @param {JXG.Line_JXG.Point} l,p The resulting point will together with p specify a line which is parallel to l.\r\n * @example\r\n * var p1 = board.create('point', [0.0, 2.0]);\r\n * var p2 = board.create('point', [2.0, 1.0]);\r\n * var p3 = board.create('point', [3.0, 3.0]);\r\n *\r\n * var pp1 = board.create('parallelpoint', [p1, p2, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG488c4be9-274f-40f0-a469-c5f70abe1f0e\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var ppex1_board = JXG.JSXGraph.initBoard('JXG488c4be9-274f-40f0-a469-c5f70abe1f0e', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var ppex1_p1 = ppex1_board.create('point', [0.0, 2.0]);\r\n *   var ppex1_p2 = ppex1_board.create('point', [2.0, 1.0]);\r\n *   var ppex1_p3 = ppex1_board.create('point', [3.0, 3.0]);\r\n *   var ppex1_pp1 = ppex1_board.create('parallelpoint', [ppex1_p1, ppex1_p2, ppex1_p3]);\r\n * </script><pre>\r\n */\r\nJXG.createParallelPoint = function (board, parents, attributes) {\r\n    var a, b, c, p, i, attr;\r\n\r\n    for (i = 0; i < parents.length; ++i) {\r\n        parents[i] = board.select(parents[i]);\r\n    }\r\n    if (\r\n        parents.length === 3 &&\r\n        Type.isPointType(board, parents[0]) &&\r\n        Type.isPointType(board, parents[1]) &&\r\n        Type.isPointType(board, parents[2])\r\n    ) {\r\n        parents = Type.providePoints(board, parents, attributes, 'point');\r\n        a = parents[0];\r\n        b = parents[1];\r\n        c = parents[2];\r\n    } else if (\r\n        Type.isPointType(board, parents[0]) &&\r\n        parents[1].elementClass === Const.OBJECT_CLASS_LINE\r\n    ) {\r\n        c = Type.providePoints(board, [parents[0]], attributes, 'point')[0];\r\n        a = parents[1].point1;\r\n        b = parents[1].point2;\r\n    } else if (\r\n        Type.isPointType(board, parents[1]) &&\r\n        parents[0].elementClass === Const.OBJECT_CLASS_LINE\r\n    ) {\r\n        c = Type.providePoints(board, [parents[1]], attributes, 'point')[0];\r\n        a = parents[0].point1;\r\n        b = parents[0].point2;\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create parallel point with parent types '\" +\r\n                typeof parents[0] +\r\n                \"', '\" +\r\n                typeof parents[1] +\r\n                \"' and '\" +\r\n                typeof parents[2] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [line,point], [point,point,point]\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'parallelpoint');\r\n    /**\r\n     * @type {JXG.Element}\r\n     * @ignore\r\n     */\r\n    p = board.create(\r\n        \"point\",\r\n        [\r\n            function () {\r\n                return c.coords.usrCoords[1] + b.coords.usrCoords[1] - a.coords.usrCoords[1];\r\n            },\r\n            function () {\r\n                return c.coords.usrCoords[2] + b.coords.usrCoords[2] - a.coords.usrCoords[2];\r\n            }\r\n        ],\r\n        attr\r\n    );\r\n\r\n    // required for algorithms requiring dependencies between elements\r\n    if (Type.exists(a._is_new)) {\r\n        p.addChild(a);\r\n        delete a._is_new;\r\n    } else {\r\n        a.addChild(p);\r\n    }\r\n    if (Type.exists(b._is_new)) {\r\n        p.addChild(b);\r\n        delete b._is_new;\r\n    } else {\r\n        b.addChild(p);\r\n    }\r\n    if (Type.exists(c._is_new)) {\r\n        p.addChild(c);\r\n        delete c._is_new;\r\n    } else {\r\n        c.addChild(p);\r\n    }\r\n\r\n    p.elType = 'parallelpoint';\r\n    p.setParents([a.id, b.id, c.id]);\r\n\r\n    // required to set the coordinates because functions are considered as constraints. hence, the coordinates get set first after an update.\r\n    // can be removed if the above issue is resolved.\r\n    p.prepareUpdate().update();\r\n\r\n    /**\r\n     * @function\r\n     * @ignore\r\n     */\r\n    p.generatePolynomial = function () {\r\n        /*\r\n         *  Parallelpoint takes three points A, B and C or line L (with points B and C) and creates point T:\r\n         *\r\n         *\r\n         *                     C (c1,c2)                             T (t1,t2)\r\n         *                      x                                     x\r\n         *                     /                                     /\r\n         *                    /                                     /\r\n         *                   /                                     /\r\n         *                  /                                     /\r\n         *                 /                                     /\r\n         *                /                                     /\r\n         *               /                                     /\r\n         *              /                                     /\r\n         *  L (opt)    /                                     /\r\n         *  ----------x-------------------------------------x--------\r\n         *            A (a1,a2)                             B (b1,b2)\r\n         *\r\n         * So we have two conditions:\r\n         *\r\n         *   (a)   CT  ||  AB           (collinearity condition I)\r\n         *   (b)   BT  ||  AC           (collinearity condition II)\r\n         *\r\n         * The corresponding equations are\r\n         *\r\n         *    (b2 - a2)(t1 - c1) - (t2 - c2)(b1 - a1) = 0         (1)\r\n         *    (t2 - b2)(a1 - c1) - (t1 - b1)(a2 - c2) = 0         (2)\r\n         *\r\n         * Simplifying (1) and (2) gives\r\n         *\r\n         *    b2t1 - b2c1 - a2t1 + a2c1 - t2b1 + t2a1 + c2b1 - c2a1 = 0      (1')\r\n         *    t2a1 - t2c1 - b2a1 + b2c1 - t1a2 + t1c2 + b1a2 - b1c2 = 0      (2')\r\n         *\r\n         */\r\n        var a1 = a.symbolic.x,\r\n            a2 = a.symbolic.y,\r\n            b1 = b.symbolic.x,\r\n            b2 = b.symbolic.y,\r\n            c1 = c.symbolic.x,\r\n            c2 = c.symbolic.y,\r\n            t1 = p.symbolic.x,\r\n            t2 = p.symbolic.y,\r\n            poly1 = \"(\" + b2 + \")*(\" + t1 + \")-(\" + b2 + \")*(\" + c1 + \")-(\" + a2 + \")*(\" + t1 + \")+(\" + a2 + \")*(\" + c1 + \")-(\" + t2 + \")*(\" + b1 + \")+(\" + t2 + \")*(\" +\r\n                a1 + \")+(\" + c2 + \")*(\" + b1 + \")-(\" + c2 + \")*(\" + a1 + \")\",\r\n            poly2 = \"(\" + t2 + \")*(\" + a1 + \")-(\" + t2 + \")*(\" + c1 + \")-(\" + b2 + \")*(\" + a1 + \")+(\" + b2 + \")*(\" + c1 + \")-(\" + t1 + \")*(\" + a2 + \")+(\" + t1 + \")*(\" +\r\n                c2 + \")+(\" + b1 + \")*(\" + a2 + \")-(\" + b1 + \")*(\" + c2 + \")\";\r\n\r\n        return [poly1, poly2];\r\n    };\r\n\r\n    return p;\r\n};\r\n\r\n/**\r\n * @class A parallel is a line through a given point, parallel to a given line.\r\n * <p>\r\n * If original line is given as a JSXGraph line object, the resulting parallel line will be defined by the given point and an\r\n * infinitely far away point (an ideal point). That means, the line can not be shortened to a segment.\r\n * <p>\r\n * If the original line is given as two points, the resulting parallel line can be shortened to a a segment.\r\n * @pseudo\r\n * @name Parallel\r\n * @augments Line\r\n * @constructor\r\n * @type JXG.Line\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Line_JXG.Point} l,p The constructed line contains p and has the same slope as l. Alternative parameters are p1, p2, p: The\r\n * constructed line contains p and has the same slope as the line through p1 and p2.\r\n * @example\r\n * // Create a parallel\r\n * var p1 = board.create('point', [0.0, 2.0]);\r\n * var p2 = board.create('point', [2.0, 1.0]);\r\n * var l1 = board.create('line', [p1, p2]);\r\n *\r\n * var p3 = board.create('point', [3.0, 3.0]);\r\n * var pl1 = board.create('parallel', [l1, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG24e54f9e-5c4e-4afb-9228-0ef27a59d627\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var plex1_board = JXG.JSXGraph.initBoard('JXG24e54f9e-5c4e-4afb-9228-0ef27a59d627', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var plex1_p1 = plex1_board.create('point', [0.0, 2.0]);\r\n *   var plex1_p2 = plex1_board.create('point', [2.0, 1.0]);\r\n *   var plex1_l1 = plex1_board.create('line', [plex1_p1, plex1_p2]);\r\n *   var plex1_p3 = plex1_board.create('point', [3.0, 3.0]);\r\n *   var plex1_pl1 = plex1_board.create('parallel', [plex1_l1, plex1_p3]);\r\n * </script><pre>\r\n * @example\r\n * var p1, p2, p3, l1, pl1;\r\n *\r\n * p1 = board.create('point', [0.0, 2.0]);\r\n * p2 = board.create('point', [2.0, 1.0]);\r\n * l1 = board.create('line', [p1, p2]);\r\n *\r\n * p3 = board.create('point', [1.0, 3.0]);\r\n * pl1 = board.create('parallel', [p1, p2, p3], {straightFirst: false, straightLast: false});\r\n *\r\n * </pre><div id=\"JXGd643305d-20c3-4a88-91f9-8d0c4448594f\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGd643305d-20c3-4a88-91f9-8d0c4448594f',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p1, p2, p3, l1, pl1;\r\n *\r\n *     p1 = board.create('point', [0.0, 2.0]);\r\n *     p2 = board.create('point', [2.0, 1.0]);\r\n *     l1 = board.create('line', [p1, p2]);\r\n *\r\n *     p3 = board.create('point', [1.0, 3.0]);\r\n *     pl1 = board.create('parallel', [p1, p2, p3], {straightFirst: false, straightLast: false});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createParallel = function (board, parents, attributes) {\r\n    var p,\r\n        pp,\r\n        pl,\r\n        li,\r\n        i,\r\n        attr,\r\n        ty = 1;\r\n\r\n    for (i = 0; i < parents.length; ++i) {\r\n        parents[i] = board.select(parents[i]);\r\n    }\r\n    p = null;\r\n    if (parents.length === 3) {\r\n        // Line / segment through point parents[2] which is parallel to line through parents[0] and parents[1]\r\n        parents = Type.providePoints(board, parents, attributes, 'point');\r\n        p = parents[2];\r\n        ty = 0;\r\n    } else if (Type.isPointType(board, parents[0])) {\r\n        // Parallel to line parents[1] through point parents[0]\r\n        p = Type.providePoints(board, [parents[0]], attributes, 'point')[0];\r\n        /** @ignore */\r\n        li = function () {\r\n            return parents[1].stdform;\r\n        };\r\n    } else if (Type.isPointType(board, parents[1])) {\r\n        // Parallel to line parents[0] through point parents[1]\r\n        p = Type.providePoints(board, [parents[1]], attributes, 'point')[0];\r\n        /** @ignore */\r\n        li = function () {\r\n            return parents[0].stdform;\r\n        };\r\n    }\r\n\r\n    if (!Type.exists(attributes.layer)) {\r\n        attributes.layer = board.options.layer.line;\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, \"parallel\", 'point');\r\n    if (ty === 1) {\r\n        // Line is given by line element. The parallel line is\r\n        // constructed as line through an ideal point.\r\n        pp = board.create(\r\n            \"point\",\r\n            [\r\n                function () {\r\n                    return Mat.crossProduct([1, 0, 0], li());\r\n                }\r\n            ],\r\n            attr\r\n        );\r\n    } else {\r\n        // Line is given by two points. The parallel line is\r\n        // constructed as line through two finite point.\r\n        pp = board.create(\"parallelpoint\", parents, attr);\r\n    }\r\n    pp.isDraggable = true;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'parallel');\r\n    // line creator also calls addChild\r\n    pl = board.create(\"line\", [p, pp], attr);\r\n\r\n    pl.elType = 'parallel';\r\n    pl.subs = {\r\n        point: pp\r\n    };\r\n\r\n    pl.inherits.push(pp);\r\n    pl.setParents([parents[0].id, parents[1].id]);\r\n    if (parents.length === 3) {\r\n        pl.addParents(parents[2].id);\r\n    }\r\n\r\n    // p.addChild(pl);\r\n\r\n    /**\r\n     * Helper point used to create the parallel line. This point lies on the line at infinity, hence it's not visible,\r\n     * not even with visible set to <tt>true</tt>. Creating another line through this point would make that other line\r\n     * parallel to the create parallel.\r\n     * @memberOf Parallel.prototype\r\n     * @name point\r\n     * @type JXG.Point\r\n     */\r\n    pl.point = pp;\r\n\r\n    return pl;\r\n};\r\n\r\n/**\r\n * @class A segment with an arrow head attached thath is parallel to a given segment.\r\n * The segment is given by its defining two points, the arrow starts at a given point.\r\n * <p>\r\n * @pseudo\r\n * @constructor\r\n * @name Arrowparallel\r\n * @type Parallel\r\n * @augments Parallel\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 The constructed arrow contains p3 and has the same slope as the line through p1 and p2.\r\n * @example\r\n * // Create a parallel\r\n * var p1 = board.create('point', [0.0, 2.0]);\r\n * var p2 = board.create('point', [2.0, 1.0]);\r\n * var l1 = board.create('segment', [p1, p2]);\r\n *\r\n * var p3 = board.create('point', [3.0, 3.0]);\r\n * var pl1 = board.create('arrowparallel', [p1, p2, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGeeacdf99-036f-4e83-aeb6-f7388423e369\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var plex1_board = JXG.JSXGraph.initBoard('JXGeeacdf99-036f-4e83-aeb6-f7388423e369', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var plex1_p1 = plex1_board.create('point', [0.0, 2.0]);\r\n *   var plex1_p2 = plex1_board.create('point', [2.0, 1.0]);\r\n *   var plex1_l1 = plex1_board.create('segment', [plex1_p1, plex1_p2]);\r\n *   var plex1_p3 = plex1_board.create('point', [3.0, 3.0]);\r\n *   var plex1_pl1 = plex1_board.create('arrowparallel', [plex1_p1, plex1_p2, plex1_p3]);\r\n * })();\r\n * </script><pre>\r\n */\r\nJXG.createArrowParallel = function (board, parents, attributes) {\r\n    var p, attr;\r\n\r\n    /* parallel arrow point polynomials are done in createParallelPoint */\r\n    try {\r\n        attr = Type.copyAttributes(attributes, board.options, 'arrowparallel');\r\n\r\n        if (attr.lastArrow === false) {\r\n            // An arrow has to have an arrow head.\r\n            attr.lastArrow = true;\r\n        }\r\n        p = JXG.createParallel(board, parents, attr).setAttribute({\r\n            straightFirst: false,\r\n            straightLast: false\r\n        });\r\n        p.type = Const.OBJECT_TYPE_VECTOR;\r\n        p.elType = 'arrowparallel';\r\n\r\n        // parents are set in createParallel\r\n\r\n        return p;\r\n    } catch (e) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create arrowparallel with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [line,point], [point,point,point]\"\r\n        );\r\n    }\r\n};\r\n\r\n/**\r\n * @class A bisector is a line which divides an angle into two equal angles. It is given by three points A, B, and\r\n * C and divides the angle ABC into two equal sized parts.\r\n * @pseudo\r\n * @constructor\r\n * @name Bisector\r\n * @type JXG.Line\r\n * @augments JXG.Line\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 The angle described by <tt>p1</tt>, <tt>p2</tt> and <tt>p3</tt> will\r\n * be divided into two equal angles.\r\n * @example\r\n * var p1 = board.create('point', [6.0, 4.0]);\r\n * var p2 = board.create('point', [3.0, 2.0]);\r\n * var p3 = board.create('point', [1.0, 7.0]);\r\n *\r\n * var bi1 = board.create('bisector', [p1, p2, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG0d58cea8-b06a-407c-b27c-0908f508f5a4\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG0d58cea8-b06a-407c-b27c-0908f508f5a4', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var p1 = board.create('point', [6.0, 4.0]);\r\n *   var p2 = board.create('point', [3.0, 2.0]);\r\n *   var p3 = board.create('point', [1.0, 7.0]);\r\n *   var bi1 = board.create('bisector', [p1, p2, p3]);\r\n * })();\r\n * </script><pre>\r\n */\r\nJXG.createBisector = function (board, parents, attributes) {\r\n    var p, l, i, attr;\r\n\r\n    parents = Type.providePoints(board, parents, attributes, 'point');\r\n    if (Type.isPoint(parents[0]) && Type.isPoint(parents[1]) && Type.isPoint(parents[2])) {\r\n        // hidden and fixed helper\r\n        attr = Type.copyAttributes(attributes, board.options, \"bisector\", 'point');\r\n        attr.snapToGrid = false;\r\n\r\n        p = board.create(\r\n            \"point\",\r\n            [\r\n                function () {\r\n                    return Geometry.angleBisector(parents[0], parents[1], parents[2], board);\r\n                }\r\n            ],\r\n            attr\r\n        );\r\n        p.dump = false;\r\n\r\n        for (i = 0; i < 3; i++) {\r\n            // required for algorithm requiring dependencies between elements\r\n            if (Type.exists(parents[i]._is_new)) {\r\n                p.addChild(parents[i]);\r\n                delete parents[i]._is_new;\r\n            } else {\r\n                parents[i].addChild(p);\r\n            }\r\n        }\r\n\r\n        if (!Type.exists(attributes.layer)) {\r\n            attributes.layer = board.options.layer.line;\r\n        }\r\n\r\n        attr = Type.copyAttributes(attributes, board.options, 'bisector');\r\n        l = JXG.createLine(board, [parents[1], p], attr);\r\n\r\n        /**\r\n         * Helper point\r\n         * @memberOf Bisector.prototype\r\n         * @type Point\r\n         * @name point\r\n         */\r\n        l.point = p;\r\n\r\n        l.elType = 'bisector';\r\n        l.setParents(parents);\r\n        l.subs = {\r\n            point: p\r\n        };\r\n        l.inherits.push(p);\r\n\r\n        return l;\r\n    }\r\n\r\n    throw new Error(\r\n        \"JSXGraph: Can't create angle bisector with parent types '\" +\r\n            typeof parents[0] +\r\n            \"' and '\" +\r\n            typeof parents[1] +\r\n            \"'.\" +\r\n            \"\\nPossible parent types: [point,point,point]\"\r\n    );\r\n};\r\n\r\n/**\r\n * @class Bisector lines are similar to {@link Bisector} but take two lines as parent elements. The resulting element is\r\n * a composition of two lines.\r\n * @pseudo\r\n * @constructor\r\n * @name Bisectorlines\r\n * @type JXG.Composition\r\n * @augments JXG.Composition\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Line_JXG.Line} l1,l2 The four angles described by the lines <tt>l1</tt> and <tt>l2</tt> will each\r\n * be divided into two equal angles.\r\n * @example\r\n * var p1 = board.create('point', [6.0, 4.0]);\r\n * var p2 = board.create('point', [3.0, 2.0]);\r\n * var p3 = board.create('point', [1.0, 7.0]);\r\n * var p4 = board.create('point', [3.0, 0.0]);\r\n * var l1 = board.create('line', [p1, p2]);\r\n * var l2 = board.create('line', [p3, p4]);\r\n *\r\n * var bi1 = board.create('bisectorlines', [l1, l2]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG3121ff67-44f0-4dda-bb10-9cda0b80bf18\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG3121ff67-44f0-4dda-bb10-9cda0b80bf18', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var p1 = board.create('point', [6.0, 4.0]);\r\n *   var p2 = board.create('point', [3.0, 2.0]);\r\n *   var p3 = board.create('point', [1.0, 7.0]);\r\n *   var p4 = board.create('point', [3.0, 0.0]);\r\n *   var l1 = board.create('line', [p1, p2]);\r\n *   var l2 = board.create('line', [p3, p4]);\r\n *   var bi1 = board.create('bisectorlines', [l1, l2]);\r\n * })();\r\n * </script><pre>\r\n */\r\nJXG.createAngularBisectorsOfTwoLines = function (board, parents, attributes) {\r\n    // The angular bisectors of two line [c1,a1,b1] and [c2,a2,b2] are determined by the equation:\r\n    // (a1*x+b1*y+c1*z)/sqrt(a1^2+b1^2) = +/- (a2*x+b2*y+c2*z)/sqrt(a2^2+b2^2)\r\n\r\n    var g1,\r\n        g2,\r\n        attr,\r\n        ret,\r\n        l1 = board.select(parents[0]),\r\n        l2 = board.select(parents[1]);\r\n\r\n    if (\r\n        l1.elementClass !== Const.OBJECT_CLASS_LINE ||\r\n        l2.elementClass !== Const.OBJECT_CLASS_LINE\r\n    ) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create angle bisectors of two lines with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [line,line]\"\r\n        );\r\n    }\r\n\r\n    if (!Type.exists(attributes.layer)) {\r\n        attributes.layer = board.options.layer.line;\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, \"bisectorlines\", 'line1');\r\n    g1 = board.create(\r\n        \"line\",\r\n        [\r\n            function () {\r\n                var d1 = Mat.hypot(l1.stdform[1], l1.stdform[2]),\r\n                    d2 = Mat.hypot(l2.stdform[1], l2.stdform[2]);\r\n\r\n                return l1.stdform[0] / d1 - l2.stdform[0] / d2;\r\n            },\r\n            function () {\r\n                var d1 = Mat.hypot(l1.stdform[1], l1.stdform[2]),\r\n                    d2 = Mat.hypot(l2.stdform[1], l2.stdform[2]);\r\n\r\n                return l1.stdform[1] / d1 - l2.stdform[1] / d2;\r\n            },\r\n            function () {\r\n                var d1 = Mat.hypot(l1.stdform[1], l1.stdform[2]),\r\n                    d2 = Mat.hypot(l2.stdform[1], l2.stdform[2]);\r\n\r\n                return l1.stdform[2] / d1 - l2.stdform[2] / d2;\r\n            }\r\n        ],\r\n        attr\r\n    );\r\n\r\n    if (!Type.exists(attributes.layer)) {\r\n        attributes.layer = board.options.layer.line;\r\n    }\r\n    attr = Type.copyAttributes(attributes, board.options, \"bisectorlines\", 'line2');\r\n    g2 = board.create(\r\n        \"line\",\r\n        [\r\n            function () {\r\n                var d1 = Mat.hypot(l1.stdform[1], l1.stdform[2]),\r\n                    d2 = Mat.hypot(l2.stdform[1], l2.stdform[2]);\r\n\r\n                return l1.stdform[0] / d1 + l2.stdform[0] / d2;\r\n            },\r\n            function () {\r\n                var d1 = Mat.hypot(l1.stdform[1], l1.stdform[2]),\r\n                    d2 = Mat.hypot(l2.stdform[1], l2.stdform[2]);\r\n\r\n                return l1.stdform[1] / d1 + l2.stdform[1] / d2;\r\n            },\r\n            function () {\r\n                var d1 = Mat.hypot(l1.stdform[1], l1.stdform[2]),\r\n                    d2 = Mat.hypot(l2.stdform[1], l2.stdform[2]);\r\n\r\n                return l1.stdform[2] / d1 + l2.stdform[2] / d2;\r\n            }\r\n        ],\r\n        attr\r\n    );\r\n\r\n    // documentation\r\n    /**\r\n     * First line.\r\n     * @memberOf Bisectorlines.prototype\r\n     * @name line1\r\n     * @type Line\r\n     */\r\n\r\n    /**\r\n     * Second line.\r\n     * @memberOf Bisectorlines.prototype\r\n     * @name line2\r\n     * @type Line\r\n     */\r\n\r\n    ret = new Composition({ line1: g1, line2: g2 });\r\n\r\n    g1.dump = false;\r\n    g2.dump = false;\r\n\r\n    ret.elType = 'bisectorlines';\r\n    ret.setParents([l1.id, l2.id]);\r\n    ret.subs = {\r\n        line1: g1,\r\n        line2: g2\r\n    };\r\n    // ret.inherits.push(g1, g2);\r\n\r\n    return ret;\r\n};\r\n\r\n// /**\r\n//  * @class An m-sector is a line which divides an angle into two angles. It is given by three points A, B, and\r\n//  * C and a real number m, and divides an angle into two angles, an angle with amplitude m and an angle with\r\n//  * amplitude (1-m)\r\n//  * @pseudo\r\n//  * @constructor\r\n//  * @name Msector\r\n//  * @type JXG.Line\r\n//  * @augments JXG.Line\r\n//  * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n//  * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 The angle described by <tt>p1</tt>, <tt>p2</tt> and <tt>p3</tt> will\r\n//  * be divided into two angles according to the value of <tt>m</tt>.\r\n//  * @example\r\n//  * var p1 = board.create('point', [6.0, 4.0]);\r\n//  * var p2 = board.create('point', [3.0, 2.0]);\r\n//  * var p3 = board.create('point', [1.0, 7.0]);\r\n//  *\r\n//  * var bi1 = board.create('msector', [p1, p2, p3], 1/5);\r\n//  * </pre><div id=\"JXG0d58cea8-b06a-407c-b27c-0908f508f5a4\" style=\"width: 400px; height: 400px;\"></div>\r\n//  * <script type=\"text/javascript\">\r\n//  * (function () {\r\n//  *   var board = JXG.JSXGraph.initBoard('JXG0d58cea8-b06a-407c-b27c-0908f508f5a4', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n//  *   var p1 = board.create('point', [6.0, 4.0]);\r\n//  *   var p2 = board.create('point', [3.0, 2.0]);\r\n//  *   var p3 = board.create('point', [1.0, 7.0]);\r\n//  *   var bi1 = board.create('msector', [p1, p2, p3], 1/5);\r\n//  * })();\r\n//  * </script><pre>\r\n//  */\r\n// JXG.createMsector = function (board, parents, attributes) {\r\n//     var p, l, i, attr;\r\n\r\n//     if (parents[0].elementClass === Const.OBJECT_CLASS_POINT &&\r\n//             parents[1].elementClass === Const.OBJECT_CLASS_POINT &&\r\n//             parents[2].elementClass === Const.OBJECT_CLASS_POINT) {\r\n//         // hidden and fixed helper\r\n//         attr = Type.copyAttributes(attributes, board.options, 'msector', 'point');\r\n//         p = board.create('point', [\r\n//             function () {\r\n//                 return Geometry.angleMsector(parents[0], parents[1], parents[2], parents[3], board);\r\n//             }\r\n//         ], attr);\r\n//         p.dump = false;\r\n\r\n//         for (i = 0; i < 3; i++) {\r\n//             // required for algorithm requiring dependencies between elements\r\n//             parents[i].addChild(p);\r\n//         }\r\n\r\n//         if (!Type.exists(attributes.layer)) {\r\n//             attributes.layer = board.options.layer.line;\r\n//         }\r\n\r\n//         attr = Type.copyAttributes(attributes, board.options, 'msector');\r\n//         l = JXG.createLine(board, [parents[1], p], attr);\r\n\r\n//         /**\r\n//          * Helper point\r\n//          * @memberOf Msector.prototype\r\n//          * @type Point\r\n//          * @name point\r\n//          */\r\n//         l.point = p;\r\n\r\n//         l.elType = 'msector';\r\n//         l.parents = [parents[0].id, parents[1].id, parents[2].id];\r\n//         l.subs = {\r\n//             point: p\r\n//         };\r\n//         l.inherits.push(p);\r\n\r\n//         return l;\r\n//     }\r\n\r\n//     throw new Error(\"JSXGraph: Can't create angle msector with parent types '\" +\r\n//         (typeof parents[0]) + \"' and '\" + (typeof parents[1]) + \"'.\" +\r\n//         \"\\nPossible parent types: [point,point,point,Number]\");\r\n// };\r\n\r\n/**\r\n * @class Constructs the center of a {@link Circumcircle} without creating the circle.\r\n * Like the circumcircle the circumcenter is constructed by providing three points.\r\n * @pseudo\r\n * @description A circumcenter is given by three points which are all lying on the circle with the\r\n * constructed circumcenter as the midpoint.\r\n * @constructor\r\n * @name Circumcenter\r\n * @type JXG.Point\r\n * @augments JXG.Point\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 The constructed point is the midpoint of the circle determined\r\n * by p1, p2, and p3.\r\n * @example\r\n * var p1 = board.create('point', [0.0, 2.0]);\r\n * var p2 = board.create('point', [2.0, 1.0]);\r\n * var p3 = board.create('point', [3.0, 3.0]);\r\n *\r\n * var cc1 = board.create('circumcenter', [p1, p2, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGe8a40f95-bf30-4eb4-88a8-f4d5495261fd\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var ccmex1_board = JXG.JSXGraph.initBoard('JXGe8a40f95-bf30-4eb4-88a8-f4d5495261fd', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var ccmex1_p1 = ccmex1_board.create('point', [0.0, 2.0]);\r\n *   var ccmex1_p2 = ccmex1_board.create('point', [6.0, 1.0]);\r\n *   var ccmex1_p3 = ccmex1_board.create('point', [3.0, 7.0]);\r\n *   var ccmex1_cc1 = ccmex1_board.create('circumcenter', [ccmex1_p1, ccmex1_p2, ccmex1_p3]);\r\n * </script><pre>\r\n */\r\nJXG.createCircumcenter = function (board, parents, attributes) {\r\n    var p, i, a, b, c;\r\n\r\n    parents = Type.providePoints(board, parents, attributes, 'point');\r\n    if (Type.isPoint(parents[0]) && Type.isPoint(parents[1]) && Type.isPoint(parents[2])) {\r\n        a = parents[0];\r\n        b = parents[1];\r\n        c = parents[2];\r\n\r\n        p = JXG.createPoint(\r\n            board,\r\n            [\r\n                function () {\r\n                    return Geometry.circumcenter(a, b, c, board);\r\n                }\r\n            ],\r\n            attributes\r\n        );\r\n\r\n        for (i = 0; i < 3; i++) {\r\n            if (Type.exists(parents[i]._is_new)) {\r\n                p.addChild(parents[i]);\r\n                delete parents[i]._is_new;\r\n            } else {\r\n                parents[i].addChild(p);\r\n            }\r\n        }\r\n\r\n        p.elType = 'circumcenter';\r\n        p.setParents(parents);\r\n\r\n        p.generatePolynomial = function () {\r\n            /*\r\n             *  CircumcircleMidpoint takes three points A, B and C  and creates point M, which is the circumcenter of A, B, and C.\r\n             *\r\n             *\r\n             * So we have two conditions:\r\n             *\r\n             *   (a)   CT  ==  AT           (distance condition I)\r\n             *   (b)   BT  ==  AT           (distance condition II)\r\n             *\r\n             */\r\n            var a1 = a.symbolic.x,\r\n                a2 = a.symbolic.y,\r\n                b1 = b.symbolic.x,\r\n                b2 = b.symbolic.y,\r\n                c1 = c.symbolic.x,\r\n                c2 = c.symbolic.y,\r\n                t1 = p.symbolic.x,\r\n                t2 = p.symbolic.y,\r\n                poly1 = [\"((\", t1, \")-(\", a1, \"))^2+((\", t2, \")-(\", a2, \"))^2-((\", t1, \")-(\", b1, \"))^2-((\", t2, \")-(\", b2, \"))^2\"].join(\"\"),\r\n                poly2 = [\"((\", t1, \")-(\", a1, \"))^2+((\", t2, \")-(\", a2, \"))^2-((\", t1, \")-(\", c1, \"))^2-((\", t2, \")-(\", c2, \"))^2\"].join(\"\");\r\n\r\n            return [poly1, poly2];\r\n        };\r\n\r\n        return p;\r\n    }\r\n\r\n    throw new Error(\r\n        \"JSXGraph: Can't create circumcircle midpoint with parent types '\" +\r\n            typeof parents[0] +\r\n            \"', '\" +\r\n            typeof parents[1] +\r\n            \"' and '\" +\r\n            typeof parents[2] +\r\n            \"'.\" +\r\n            \"\\nPossible parent types: [point,point,point]\"\r\n    );\r\n};\r\n\r\n/**\r\n * @class The center of the incircle of the triangle described by the three given points (without\r\n * constructing the circle).\r\n * {@link https://mathworld.wolfram.com/Incenter.html}\r\n * @pseudo\r\n * @constructor\r\n * @name Incenter\r\n * @type JXG.Point\r\n * @augments JXG.Point\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 The constructed point is the incenter of the triangle described\r\n * by p1, p2, and p3.\r\n * @example\r\n * var p1 = board.create('point', [0.0, 2.0]);\r\n * var p2 = board.create('point', [2.0, 1.0]);\r\n * var p3 = board.create('point', [3.0, 3.0]);\r\n *\r\n * var ic1 = board.create('incenter', [p1, p2, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGe8a40f95-bf30-4eb4-88a8-a2d5495261fd\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var icmex1_board = JXG.JSXGraph.initBoard('JXGe8a40f95-bf30-4eb4-88a8-a2d5495261fd', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var icmex1_p1 = icmex1_board.create('point', [0.0, 2.0]);\r\n *   var icmex1_p2 = icmex1_board.create('point', [6.0, 1.0]);\r\n *   var icmex1_p3 = icmex1_board.create('point', [3.0, 7.0]);\r\n *   var icmex1_ic1 = icmex1_board.create('incenter', [icmex1_p1, icmex1_p2, icmex1_p3]);\r\n * </script><pre>\r\n */\r\nJXG.createIncenter = function (board, parents, attributes) {\r\n    var p, A, B, C, i;\r\n\r\n    parents = Type.providePoints(board, parents, attributes, 'point');\r\n    if (\r\n        parents.length >= 3 &&\r\n        Type.isPoint(parents[0]) &&\r\n        Type.isPoint(parents[1]) &&\r\n        Type.isPoint(parents[2])\r\n    ) {\r\n        A = parents[0];\r\n        B = parents[1];\r\n        C = parents[2];\r\n\r\n        p = board.create(\r\n            \"point\",\r\n            [\r\n                function () {\r\n                    var a, b, c;\r\n\r\n                    a = Mat.hypot(B.X() - C.X(), B.Y() - C.Y());\r\n                    b = Mat.hypot(A.X() - C.X(), A.Y() - C.Y());\r\n                    c = Mat.hypot(B.X() - A.X(), B.Y() - A.Y());\r\n\r\n                    return new Coords(\r\n                        Const.COORDS_BY_USER,\r\n                        [\r\n                            (a * A.X() + b * B.X() + c * C.X()) / (a + b + c),\r\n                            (a * A.Y() + b * B.Y() + c * C.Y()) / (a + b + c)\r\n                        ],\r\n                        board\r\n                    );\r\n                }\r\n            ],\r\n            attributes\r\n        );\r\n\r\n        for (i = 0; i < 3; i++) {\r\n            if (Type.exists(parents[i]._is_new)) {\r\n                p.addChild(parents[i]);\r\n                delete parents[i]._is_new;\r\n            } else {\r\n                parents[i].addChild(p);\r\n            }\r\n        }\r\n\r\n        p.elType = 'incenter';\r\n        p.setParents(parents);\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create incenter with parent types '\" +\r\n                typeof parents[0] +\r\n                \"', '\" +\r\n                typeof parents[1] +\r\n                \"' and '\" +\r\n                typeof parents[2] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [point,point,point]\"\r\n        );\r\n    }\r\n\r\n    return p;\r\n};\r\n\r\n/**\r\n * @class A circumcircle is the unique circle through three points.\r\n * @pseudo\r\n * @constructor\r\n * @name Circumcircle\r\n * @type JXG.Circle\r\n * @augments JXG.Circle\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 The constructed element is the circle determined by <tt>p1</tt>, <tt>p2</tt>, and <tt>p3</tt>.\r\n * @example\r\n * var p1 = board.create('point', [0.0, 2.0]);\r\n * var p2 = board.create('point', [2.0, 1.0]);\r\n * var p3 = board.create('point', [3.0, 3.0]);\r\n *\r\n * var cc1 = board.create('circumcircle', [p1, p2, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGe65c9861-0bf0-402d-af57-3ab11962f5ac\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var ccex1_board = JXG.JSXGraph.initBoard('JXGe65c9861-0bf0-402d-af57-3ab11962f5ac', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var ccex1_p1 = ccex1_board.create('point', [0.0, 2.0]);\r\n *   var ccex1_p2 = ccex1_board.create('point', [6.0, 1.0]);\r\n *   var ccex1_p3 = ccex1_board.create('point', [3.0, 7.0]);\r\n *   var ccex1_cc1 = ccex1_board.create('circumcircle', [ccex1_p1, ccex1_p2, ccex1_p3]);\r\n * </script><pre>\r\n */\r\nJXG.createCircumcircle = function (board, parents, attributes) {\r\n    var p, c, attr, i;\r\n\r\n    parents = Type.providePoints(board, parents, attributes, 'point');\r\n    if (parents === false) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create circumcircle with parent types '\" +\r\n                typeof parents[0] +\r\n                \"', '\" +\r\n                typeof parents[1] +\r\n                \"' and '\" +\r\n                typeof parents[2] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [point,point,point]\"\r\n        );\r\n    }\r\n\r\n    try {\r\n        attr = Type.copyAttributes(attributes, board.options, \"circumcircle\", 'center');\r\n        p = JXG.createCircumcenter(board, parents, attr);\r\n\r\n        p.dump = false;\r\n\r\n        if (!Type.exists(attributes.layer)) {\r\n            attributes.layer = board.options.layer.circle;\r\n        }\r\n        attr = Type.copyAttributes(attributes, board.options, 'circumcircle');\r\n        c = JXG.createCircle(board, [p, parents[0]], attr);\r\n\r\n        c.elType = 'circumcircle';\r\n        c.setParents(parents);\r\n        c.subs = {\r\n            center: p\r\n        };\r\n        c.inherits.push(c);\r\n        for (i = 0; i < 3; i++) {\r\n            if (Type.exists(parents[i]._is_new)) {\r\n                c.addChild(parents[i]);\r\n                delete parents[i]._is_new;\r\n            } else {\r\n                parents[i].addChild(c);\r\n            }\r\n        }\r\n    } catch (e) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create circumcircle with parent types '\" +\r\n                typeof parents[0] +\r\n                \"', '\" +\r\n                typeof parents[1] +\r\n                \"' and '\" +\r\n                typeof parents[2] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [point,point,point]\"\r\n        );\r\n    }\r\n\r\n    // p is already stored as midpoint in c so there's no need to store it explicitly.\r\n\r\n    return c;\r\n};\r\n\r\n/**\r\n * @class The circle which touches the three sides of a triangle given by three points.\r\n * @pseudo\r\n * @constructor\r\n * @name Incircle\r\n * @type JXG.Circle\r\n * @augments JXG.Circle\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point_JXG.Point} p1,p2,p3 The constructed point is the midpoint of the incircle of\r\n * <tt>p1</tt>, <tt>p2</tt>, and <tt>p3</tt>.\r\n * @example\r\n * var p1 = board.create('point', [0.0, 2.0]);\r\n * var p2 = board.create('point', [2.0, 1.0]);\r\n * var p3 = board.create('point', [3.0, 3.0]);\r\n *\r\n * var ic1 = board.create('incircle', [p1, p2, p3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGe65c9861-0bf0-402d-af57-2ab12962f8ac\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var icex1_board = JXG.JSXGraph.initBoard('JXGe65c9861-0bf0-402d-af57-2ab12962f8ac', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var icex1_p1 = icex1_board.create('point', [0.0, 2.0]);\r\n *   var icex1_p2 = icex1_board.create('point', [6.0, 1.0]);\r\n *   var icex1_p3 = icex1_board.create('point', [3.0, 7.0]);\r\n *   var icex1_ic1 = icex1_board.create('incircle', [icex1_p1, icex1_p2, icex1_p3]);\r\n * </script><pre>\r\n */\r\nJXG.createIncircle = function (board, parents, attributes) {\r\n    var i, p, c, attr;\r\n\r\n    parents = Type.providePoints(board, parents, attributes, 'point');\r\n    if (parents === false) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create circumcircle with parent types '\" +\r\n                typeof parents[0] +\r\n                \"', '\" +\r\n                typeof parents[1] +\r\n                \"' and '\" +\r\n                typeof parents[2] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [point,point,point]\"\r\n        );\r\n    }\r\n    try {\r\n        attr = Type.copyAttributes(attributes, board.options, \"incircle\", 'center');\r\n        p = JXG.createIncenter(board, parents, attr);\r\n\r\n        p.dump = false;\r\n\r\n        if (!Type.exists(attributes.layer)) {\r\n            attributes.layer = board.options.layer.circle;\r\n        }\r\n        attr = Type.copyAttributes(attributes, board.options, 'incircle');\r\n        c = JXG.createCircle(\r\n            board,\r\n            [\r\n                p,\r\n                function () {\r\n                    var a = Mat.hypot(parents[1].X() - parents[2].X(), parents[1].Y() - parents[2].Y()),\r\n                        b = Mat.hypot(parents[0].X() - parents[2].X(), parents[0].Y() - parents[2].Y()),\r\n                        c = Mat.hypot(parents[1].X() - parents[0].X(), parents[1].Y() - parents[0].Y()),\r\n                        s = (a + b + c) / 2;\r\n\r\n                    return Math.sqrt(((s - a) * (s - b) * (s - c)) / s);\r\n                }\r\n            ],\r\n            attr\r\n        );\r\n\r\n        c.elType = 'incircle';\r\n        c.setParents(parents);\r\n        for (i = 0; i < 3; i++) {\r\n            if (Type.exists(parents[i]._is_new)) {\r\n                c.addChild(parents[i]);\r\n                delete parents[i]._is_new;\r\n            } else {\r\n                parents[i].addChild(c);\r\n            }\r\n        }\r\n\r\n        /**\r\n         * The center of the incircle\r\n         * @memberOf Incircle.prototype\r\n         * @type Incenter\r\n         * @name center\r\n         */\r\n        c.center = p;\r\n\r\n        c.subs = {\r\n            center: c.center\r\n        };\r\n        c.inherits.push(p);\r\n    } catch (e) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create circumcircle with parent types '\" +\r\n                typeof parents[0] +\r\n                \"', '\" +\r\n                typeof parents[1] +\r\n                \"' and '\" +\r\n                typeof parents[2] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [point,point,point]\"\r\n        );\r\n    }\r\n\r\n    // p is already stored as midpoint in c so there's no need to store it explicitly.\r\n\r\n    return c;\r\n};\r\n\r\n/**\r\n * @class  Reflect a point, line, circle, curve, polygon across a given line.\r\n * @pseudo\r\n * @description A reflected element (point, polygon, line or curve) is given by a given\r\n * object of the same type and a line of reflection.\r\n * It is determined by the reflection of the given element\r\n * across the given line.\r\n * @constructor\r\n * @name Reflection\r\n * @type JXG.GeometryElement\r\n * @augments JXG.GeometryElement\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point|JXG.Line|JXG.Curve|JXG.Polygon_JXG.Line} p,l The reflection element is the reflection of p across the line l.\r\n * @example\r\n * var p1 = board.create('point', [0.0, 4.0]);\r\n * var p2 = board.create('point', [6.0, 1.0]);\r\n * var l1 = board.create('line', [p1, p2]);\r\n * var p3 = board.create('point', [3.0, 3.0]);\r\n *\r\n * var rp1 = board.create('reflection', [p3, l1]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG087a798e-a36a-4f52-a2b4-29a23a69393b\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var rpex1_board = JXG.JSXGraph.initBoard('JXG087a798e-a36a-4f52-a2b4-29a23a69393b', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var rpex1_p1 = rpex1_board.create('point', [0.0, 4.0]);\r\n *   var rpex1_p2 = rpex1_board.create('point', [6.0, 1.0]);\r\n *   var rpex1_l1 = rpex1_board.create('line', [rpex1_p1, rpex1_p2]);\r\n *   var rpex1_p3 = rpex1_board.create('point', [3.0, 3.0]);\r\n *   var rpex1_rp1 = rpex1_board.create('reflection', [rpex1_p3, rpex1_l1]);\r\n * </script><pre>\r\n * @example\r\n *         // Reflection of more elements\r\n *         // reflection line\r\n *         var li = board.create('line', [1,1,1], {strokeColor: '#aaaaaa'});\r\n *\r\n *         var p1 = board.create('point', [-3,-1], {name: \"A\"});\r\n *         var q1 = board.create('reflection', [p1, li], {name: \"A'\"});\r\n *\r\n *         var l1 = board.create('line', [1,-5,1]);\r\n *         var l2 = board.create('reflection', [l1, li]);\r\n *\r\n *         var cu1 = board.create('curve', [[-3, -3, -2.5, -3, -3, -2.5], [-3, -2, -2, -2, -2.5, -2.5]], {strokeWidth:3});\r\n *         var cu2 = board.create('reflection', [cu1, li], {strokeColor: 'red', strokeWidth:3});\r\n *\r\n *         var pol1 = board.create('polygon', [[-6,-3], [-4,-5], [-5,-1.5]]);\r\n *         var pol2 = board.create('reflection', [pol1, li]);\r\n *\r\n *         var c1 = board.create('circle', [[-2,-2], [-2, -1]]);\r\n *         var c2 = board.create('reflection', [c1, li]);\r\n *\r\n *         var a1 = board.create('arc', [[1, 1], [0, 1], [1, 0]], {strokeColor: 'red'});\r\n *         var a2 = board.create('reflection', [a1, li], {strokeColor: 'red'});\r\n *\r\n *         var s1 = board.create('sector', [[-3.5,-3], [-3.5, -2], [-3.5,-4]], {\r\n *                           anglePoint: {visible:true}, center: {visible: true}, radiusPoint: {visible: true},\r\n *                           fillColor: 'yellow', strokeColor: 'black'});\r\n *         var s2 = board.create('reflection', [s1, li], {fillColor: 'yellow', strokeColor: 'black', fillOpacity: 0.5});\r\n *\r\n *         var an1 = board.create('angle', [[-4,3.9], [-3, 4], [-3, 3]]);\r\n *         var an2 = board.create('reflection', [an1, li]);\r\n *\r\n * </pre><div id=\"JXG8f763af4-d449-11e7-93b3-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG8f763af4-d449-11e7-93b3-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *             // reflection line\r\n *             var li = board.create('line', [1,1,1], {strokeColor: '#aaaaaa'});\r\n *\r\n *             var p1 = board.create('point', [-3,-1], {name: \"A\"});\r\n *             var q1 = board.create('reflection', [p1, li], {name: \"A'\"});\r\n *\r\n *             var l1 = board.create('line', [1,-5,1]);\r\n *             var l2 = board.create('reflection', [l1, li]);\r\n *\r\n *             var cu1 = board.create('curve', [[-3, -3, -2.5, -3, -3, -2.5], [-3, -2, -2, -2, -2.5, -2.5]], {strokeWidth:3});\r\n *             var cu2 = board.create('reflection', [cu1, li], {strokeColor: 'red', strokeWidth:3});\r\n *\r\n *             var pol1 = board.create('polygon', [[-6,-3], [-4,-5], [-5,-1.5]]);\r\n *             var pol2 = board.create('reflection', [pol1, li]);\r\n *\r\n *             var c1 = board.create('circle', [[-2,-2], [-2, -1]]);\r\n *             var c2 = board.create('reflection', [c1, li]);\r\n *\r\n *         var a1 = board.create('arc', [[1, 1], [0, 1], [1, 0]], {strokeColor: 'red'});\r\n *         var a2 = board.create('reflection', [a1, li], {strokeColor: 'red'});\r\n *\r\n *         var s1 = board.create('sector', [[-3.5,-3], [-3.5, -2], [-3.5,-4]], {\r\n *                           anglePoint: {visible:true}, center: {visible: true}, radiusPoint: {visible: true},\r\n *                           fillColor: 'yellow', strokeColor: 'black'});\r\n *         var s2 = board.create('reflection', [s1, li], {fillColor: 'yellow', strokeColor: 'black', fillOpacity: 0.5});\r\n *\r\n *         var an1 = board.create('angle', [[-4,3.9], [-3, 4], [-3, 3]]);\r\n *         var an2 = board.create('reflection', [an1, li]);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createReflection = function (board, parents, attributes) {\r\n    var l, org, r, r_c,\r\n        t, i, attr, attr2,\r\n        errStr = \"\\nPossible parent types: [point|line|curve|polygon|circle|arc|sector, line]\";\r\n\r\n    for (i = 0; i < parents.length; ++i) {\r\n        parents[i] = board.select(parents[i]);\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'reflection');\r\n\r\n    if (Type.isPoint(parents[0])) {\r\n        org = Type.providePoints(board, [parents[0]], attr2)[0];\r\n    } else if (\r\n        parents[0].elementClass === Const.OBJECT_CLASS_CURVE ||\r\n        parents[0].elementClass === Const.OBJECT_CLASS_LINE ||\r\n        parents[0].type === Const.OBJECT_TYPE_POLYGON ||\r\n        parents[0].elementClass === Const.OBJECT_CLASS_CIRCLE\r\n    ) {\r\n        org = parents[0];\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create reflection element with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                errStr\r\n        );\r\n    }\r\n\r\n    if (parents[1].elementClass === Const.OBJECT_CLASS_LINE) {\r\n        l = parents[1];\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create reflected element with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                errStr\r\n        );\r\n    }\r\n    t = JXG.createTransform(board, [l], { type: \"reflect\" });\r\n\r\n    if (Type.isPoint(org)) {\r\n        r = JXG.createPoint(board, [org, t], attr);\r\n\r\n        // Arcs and sectors are treated as curves\r\n    } else if (org.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n        r = JXG.createCurve(board, [org, t], attr);\r\n    } else if (org.elementClass === Const.OBJECT_CLASS_LINE) {\r\n        r = JXG.createLine(board, [org, t], attr);\r\n    } else if (org.type === Const.OBJECT_TYPE_POLYGON) {\r\n        r = JXG.createPolygon(board, [org, t], attr);\r\n    } else if (org.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n        if (attr.type.toLowerCase() === 'euclidean') {\r\n            // Create a circle element from a circle and a Euclidean transformation\r\n            attr2 = Type.copyAttributes(attributes, board.options, \"reflection\", 'center');\r\n            r_c = JXG.createPoint(board, [org.center, t], attr2);\r\n            r_c.prepareUpdate()\r\n                .update()\r\n                .updateVisibility(r_c.evalVisProp('visible'))\r\n                .updateRenderer();\r\n            r = JXG.createCircle(\r\n                board,\r\n                [\r\n                    r_c,\r\n                    function () {\r\n                        return org.Radius();\r\n                    }\r\n                ],\r\n                attr\r\n            );\r\n        } else {\r\n            // Create a conic element from a circle and a projective transformation\r\n            r = JXG.createCircle(board, [org, t], attr);\r\n        }\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create reflected element with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                errStr\r\n        );\r\n    }\r\n\r\n    if (Type.exists(org._is_new)) {\r\n        r.addChild(org);\r\n        delete org._is_new;\r\n    } else {\r\n        // org.addChild(r);\r\n    }\r\n    l.addChild(r);\r\n\r\n    r.elType = 'reflection';\r\n    r.addParents(l);\r\n    r.prepareUpdate().update(); //.updateVisibility(r.evalVisProp('visible')).updateRenderer();\r\n\r\n    if (Type.isPoint(r)) {\r\n        r.generatePolynomial = function () {\r\n            /*\r\n             *  Reflection takes a point R and a line L and creates point P, which is the reflection of R on L.\r\n             *  L is defined by two points A and B.\r\n             *\r\n             * So we have two conditions:\r\n             *\r\n             *   (a)   RP  _|_  AB            (orthogonality condition)\r\n             *   (b)   AR  ==   AP            (distance condition)\r\n             *\r\n             */\r\n            var a1 = l.point1.symbolic.x,\r\n                a2 = l.point1.symbolic.y,\r\n                b1 = l.point2.symbolic.x,\r\n                b2 = l.point2.symbolic.y,\r\n                p1 = org.symbolic.x,\r\n                p2 = org.symbolic.y,\r\n                r1 = r.symbolic.x,\r\n                r2 = r.symbolic.y,\r\n                poly1 = [\"((\", r2, \")-(\", p2, \"))*((\", a2, \")-(\", b2, \"))+((\", a1, \")-(\", b1, \"))*((\", r1, \")-(\", p1, \"))\"].join(\"\"),\r\n                poly2 = [\"((\", r1, \")-(\", a1, \"))^2+((\", r2, \")-(\", a2, \"))^2-((\", p1, \")-(\", a1, \"))^2-((\", p2, \")-(\", a2, \"))^2\"].join(\"\");\r\n\r\n            return [poly1, poly2];\r\n        };\r\n    }\r\n\r\n    return r;\r\n};\r\n\r\n/**\r\n * @class Reflect a point, line, circle, curve, polygon across a given point.\r\n * @pseudo\r\n * @description A mirror element is determined by the reflection of a\r\n * given point, line, circle, curve, polygon across another given point.\r\n * In contrast to generic transformations, mirror elements of circles are again circles.\r\n * @constructor\r\n * @name MirrorElement\r\n * @type JXG.GeometryElement\r\n * @augments JXG.GeometryElement\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point|JXG.Line|JXG.Curve|JXG.Ppolygon_JXG.Point} p1,p2 The constructed element is the mirror image of p2 across p1.\r\n * @example\r\n *         // point of reflection\r\n *         var mirr = board.create('point', [-1,-1], {color: '#aaaaaa'});\r\n *\r\n *         var p1 = board.create('point', [-3,-1], {name: \"A\"});\r\n *         var q1 = board.create('mirrorelement', [p1, mirr], {name: \"A'\"});\r\n *\r\n *         var l1 = board.create('line', [1, -5, 1]);\r\n *         var l2 = board.create('mirrorelement', [l1, mirr]);\r\n *\r\n *         var cu1 = board.create('curve', [[-3, -3, -2.5, -3, -3, -2.5], [-3, -2, -2, -2, -2.5, -2.5]], {strokeWidth:3});\r\n *         var cu2 = board.create('mirrorelement', [cu1, mirr], {strokeColor: 'red', strokeWidth:3});\r\n *\r\n *         var pol1 = board.create('polygon', [[-6,-2], [-4,-4], [-5,-0.5]]);\r\n *         var pol2 = board.create('mirrorelement', [pol1, mirr]);\r\n *\r\n *         var c1 = board.create('circle', [[-6,-6], [-6, -5]]);\r\n *         var c2 = board.create('mirrorelement', [c1, mirr]);\r\n *\r\n *         var a1 = board.create('arc', [[1, 1], [0, 1], [1, 0]], {strokeColor: 'red'});\r\n *         var a2 = board.create('mirrorelement', [a1, mirr], {strokeColor: 'red'});\r\n *\r\n *         var s1 = board.create('sector', [[-3.5,-3], [-3.5, -2], [-3.5,-4]], {\r\n *                           anglePoint: {visible:true}, center: {visible: true}, radiusPoint: {visible: true},\r\n *                           fillColor: 'yellow', strokeColor: 'black'});\r\n *         var s2 = board.create('mirrorelement', [s1, mirr], {fillColor: 'yellow', strokeColor: 'black', fillOpacity: 0.5});\r\n *\r\n *         var an1 = board.create('angle', [[-4,3.9], [-3, 4], [-3, 3]]);\r\n *         var an2 = board.create('mirrorelement', [an1, mirr]);\r\n *\r\n *\r\n * </pre><div id=\"JXG026c779c-d8d9-11e7-93b3-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG026c779c-d8d9-11e7-93b3-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *             // point of reflection\r\n *             var mirr = board.create('point', [-1,-1], {color: '#aaaaaa'});\r\n *\r\n *             var p1 = board.create('point', [-3,-1], {name: \"A\"});\r\n *             var q1 = board.create('mirrorelement', [p1, mirr], {name: \"A'\"});\r\n *\r\n *             var l1 = board.create('line', [1,-5, 1]);\r\n *             var l2 = board.create('mirrorelement', [l1, mirr]);\r\n *\r\n *             var cu1 = board.create('curve', [[-3, -3, -2.5, -3, -3, -2.5], [-3, -2, -2, -2, -2.5, -2.5]], {strokeWidth:3});\r\n *             var cu2 = board.create('mirrorelement', [cu1, mirr], {strokeColor: 'red', strokeWidth:3});\r\n *\r\n *             var pol1 = board.create('polygon', [[-6,-2], [-4,-4], [-5,-0.5]]);\r\n *             var pol2 = board.create('mirrorelement', [pol1, mirr]);\r\n *\r\n *             var c1 = board.create('circle', [[-6,-6], [-6, -5]]);\r\n *             var c2 = board.create('mirrorelement', [c1, mirr]);\r\n *\r\n *         var a1 = board.create('arc', [[1, 1], [0, 1], [1, 0]], {strokeColor: 'red'});\r\n *         var a2 = board.create('mirrorelement', [a1, mirr], {strokeColor: 'red'});\r\n *\r\n *         var s1 = board.create('sector', [[-3.5,-3], [-3.5, -2], [-3.5,-4]], {\r\n *                           anglePoint: {visible:true}, center: {visible: true}, radiusPoint: {visible: true},\r\n *                           fillColor: 'yellow', strokeColor: 'black'});\r\n *         var s2 = board.create('mirrorelement', [s1, mirr], {fillColor: 'yellow', strokeColor: 'black', fillOpacity: 0.5});\r\n *\r\n *         var an1 = board.create('angle', [[-4,3.9], [-3, 4], [-3, 3]]);\r\n *         var an2 = board.create('mirrorelement', [an1, mirr]);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n */\r\nJXG.createMirrorElement = function (board, parents, attributes) {\r\n    var org, i, m, r, r_c, t,\r\n        attr, attr2,\r\n        errStr = \"\\nPossible parent types: [point|line|curve|polygon|circle|arc|sector, point]\";\r\n\r\n    for (i = 0; i < parents.length; ++i) {\r\n        parents[i] = board.select(parents[i]);\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'mirrorelement');\r\n    if (Type.isPoint(parents[0])) {\r\n        // Create point to be mirrored if supplied by coords array.\r\n        org = Type.providePoints(board, [parents[0]], attr)[0];\r\n    } else if (\r\n        parents[0].elementClass === Const.OBJECT_CLASS_CURVE ||\r\n        parents[0].elementClass === Const.OBJECT_CLASS_LINE ||\r\n        parents[0].type === Const.OBJECT_TYPE_POLYGON ||\r\n        parents[0].elementClass === Const.OBJECT_CLASS_CIRCLE\r\n    ) {\r\n        org = parents[0];\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create mirror element with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                errStr\r\n        );\r\n    }\r\n\r\n    if (Type.isPoint(parents[1])) {\r\n        attr2 = Type.copyAttributes(attributes, board.options, \"mirrorelement\", 'point');\r\n        // Create mirror point if supplied by coords array.\r\n        m = Type.providePoints(board, [parents[1]], attr2)[0];\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create mirror element with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                errStr\r\n        );\r\n    }\r\n\r\n    t = JXG.createTransform(board, [Math.PI, m], { type: \"rotate\" });\r\n    if (Type.isPoint(org)) {\r\n        r = JXG.createPoint(board, [org, t], attr);\r\n\r\n        // Arcs and sectors are treated as curves\r\n    } else if (org.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n        r = JXG.createCurve(board, [org, t], attr);\r\n    } else if (org.elementClass === Const.OBJECT_CLASS_LINE) {\r\n        r = JXG.createLine(board, [org, t], attr);\r\n    } else if (org.type === Const.OBJECT_TYPE_POLYGON) {\r\n        r = JXG.createPolygon(board, [org, t], attr);\r\n    } else if (org.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n        if (attr.type.toLowerCase() === 'euclidean') {\r\n            // Create a circle element from a circle and a Euclidean transformation\r\n            attr2 = Type.copyAttributes(attributes, board.options, \"mirrorelement\", 'center');\r\n            r_c = JXG.createPoint(board, [org.center, t], attr2);\r\n            r_c.prepareUpdate()\r\n                .update()\r\n                .updateVisibility(r_c.evalVisProp('visible'))\r\n                .updateRenderer();\r\n            r = JXG.createCircle(\r\n                board,\r\n                [\r\n                    r_c,\r\n                    function () {\r\n                        return org.Radius();\r\n                    }\r\n                ],\r\n                attr\r\n            );\r\n        } else {\r\n            // Create a conic element from a circle and a projective transformation\r\n            r = JXG.createCircle(board, [org, t], attr);\r\n        }\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create mirror element with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                errStr\r\n        );\r\n    }\r\n\r\n    if (Type.exists(org._is_new)) {\r\n        r.addChild(org);\r\n        delete org._is_new;\r\n    } else {\r\n        // org.addChild(r);\r\n    }\r\n    m.addChild(r);\r\n\r\n    r.elType = 'mirrorelement';\r\n    r.addParents(m);\r\n    r.prepareUpdate().update();\r\n\r\n    return r;\r\n};\r\n\r\n/**\r\n * @class A MirrorPoint is a special case of a {@link MirrorElement}.\r\n * @pseudo\r\n * @description A mirror point is determined by the reflection of a given point against another given point.\r\n * @constructor\r\n * @name MirrorPoint\r\n * @type JXG.Point\r\n * @augments JXG.Point\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point_JXG.Point} p1,p2 The constructed point is the reflection of p2 against p1.\r\n *\r\n * This method is superseeded by the more general {@link JXG.createMirrorElement}.\r\n * @example\r\n * var p1 = board.create('point', [3.0, 3.0]);\r\n * var p2 = board.create('point', [6.0, 1.0]);\r\n *\r\n * var mp1 = board.create('mirrorpoint', [p1, p2]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG7eb2a814-6c4b-4caa-8cfa-4183a948d25b\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var mpex1_board = JXG.JSXGraph.initBoard('JXG7eb2a814-6c4b-4caa-8cfa-4183a948d25b', {boundingbox: [-1, 9, 9, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *   var mpex1_p1 = mpex1_board.create('point', [3.0, 3.0]);\r\n *   var mpex1_p2 = mpex1_board.create('point', [6.0, 1.0]);\r\n *   var mpex1_mp1 = mpex1_board.create('mirrorpoint', [mpex1_p1, mpex1_p2]);\r\n * </script><pre>\r\n */\r\nJXG.createMirrorPoint = function (board, parents, attributes) {\r\n    var el = JXG.createMirrorElement(board, parents, attributes);\r\n    el.elType = 'mirrorpoint';\r\n    return el;\r\n};\r\n\r\n/**\r\n * @class The graph of the integral function of a given function in a given interval.\r\n * @pseudo\r\n * @description The Integral element is used to visualize the area under a given curve over a given interval\r\n * and to calculate the area's value. For that a polygon and gliders are used. The polygon displays the area,\r\n * the gliders are used to change the interval dynamically.\r\n * @constructor\r\n * @name Integral\r\n * @type JXG.Curve\r\n * @augments JXG.Curve\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Array_JXG.Curve} i,c The constructed element covers the area between the curve <tt>c</tt> and the x-axis\r\n * within the interval <tt>i</tt>.\r\n * @example\r\n * var c1 = board.create('functiongraph', [function (t) { return Math.cos(t)*t; }]);\r\n * var i1 = board.create('integral', [[-2.0, 2.0], c1]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGd45d7188-6624-4d6e-bebb-1efa2a305c8a\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var intex1_board = JXG.JSXGraph.initBoard('JXGd45d7188-6624-4d6e-bebb-1efa2a305c8a', {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false});\r\n *   var intex1_c1 = intex1_board.create('functiongraph', [function (t) { return Math.cos(t)*t; }]);\r\n *   var intex1_i1 = intex1_board.create('integral', [[-2.0, 2.0], intex1_c1]);\r\n * </script><pre>\r\n */\r\nJXG.createIntegral = function (board, parents, attributes) {\r\n    var interval, curve, attr, start, end,\r\n        startx, starty, endx, endy,\r\n        pa_on_curve, pa_on_axis, pb_on_curve, pb_on_axis,\r\n        txt_fun,\r\n        t = null, p;\r\n\r\n    if (Type.isArray(parents[0]) && parents[1].elementClass === Const.OBJECT_CLASS_CURVE) {\r\n        interval = parents[0];\r\n        curve = parents[1];\r\n    } else if (\r\n        Type.isArray(parents[1]) &&\r\n        parents[0].elementClass === Const.OBJECT_CLASS_CURVE\r\n    ) {\r\n        interval = parents[1];\r\n        curve = parents[0];\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create integral with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [[number|function,number|function],curve]\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'integral');\r\n    attr.withlabel = false; // There is a custom 'label' below.\r\n    p = board.create(\"curve\", [[0], [0]], attr);\r\n\r\n    // Dirty hack: the integral curve is removed from board.objectsList\r\n    // and inserted below again after the pa_/pb_on_axis elements.\r\n    // Otherwise, the filled area lags is updated before the\r\n    // update of the bounds.\r\n    board.objectsList.pop();\r\n\r\n    // Correct the interval if necessary - NOT ANYMORE, GGB's fault\r\n    start = interval[0];\r\n    end = interval[1];\r\n\r\n    if (Type.isFunction(start)) {\r\n        startx = start;\r\n        starty = function () {\r\n            return curve.Y(startx());\r\n        };\r\n        start = startx();\r\n    } else {\r\n        startx = start;\r\n        starty = curve.Y(start);\r\n    }\r\n\r\n    if (Type.isFunction(end)) {\r\n        endx = end;\r\n        endy = function () {\r\n            return curve.Y(endx());\r\n        };\r\n        end = endx();\r\n    } else {\r\n        endx = end;\r\n        endy = curve.Y(end);\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, \"integral\", 'curveleft');\r\n    pa_on_curve = board.create(\"glider\", [startx, starty, curve], attr);\r\n    if (Type.isFunction(startx)) {\r\n        pa_on_curve.hideElement();\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'integral', 'baseleft');\r\n    pa_on_axis = board.create('point', [\r\n            function () {\r\n                if (p.evalVisProp('axis') === 'y') {\r\n                    return 0;\r\n                }\r\n                return pa_on_curve.X();\r\n            },\r\n            function () {\r\n                if (p.evalVisProp('axis') === 'y') {\r\n                    return pa_on_curve.Y();\r\n                }\r\n                return 0;\r\n            }\r\n        ], attr);\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, \"integral\", 'curveright');\r\n    pb_on_curve = board.create(\"glider\", [endx, endy, curve], attr);\r\n    if (Type.isFunction(endx)) {\r\n        pb_on_curve.hideElement();\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, \"integral\", 'baseright');\r\n    pb_on_axis = board.create('point', [\r\n            function () {\r\n                if (p.evalVisProp('axis') === 'y') {\r\n                    return 0;\r\n                }\r\n                return pb_on_curve.X();\r\n            },\r\n            function () {\r\n                if (p.evalVisProp('axis') === 'y') {\r\n                    return pb_on_curve.Y();\r\n                }\r\n\r\n                return 0;\r\n            }\r\n        ], attr);\r\n\r\n    // Re-insert the filled integral curve element\r\n    p._pos = board.objectsList.length;\r\n    board.objectsList.push(p);\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'integral');\r\n    if (attr.withlabel !== false && attr.axis !== 'y') {\r\n        attr = Type.copyAttributes(attributes, board.options, \"integral\", 'label');\r\n        attr = Type.copyAttributes(attr, board.options, 'label');\r\n\r\n        t = board.create('text', [\r\n                function () {\r\n                    var off = new Coords(\r\n                            Const.COORDS_BY_SCREEN,\r\n                            [\r\n                                this.evalVisProp('offset.0') +\r\n                                    this.board.origin.scrCoords[1],\r\n                                0\r\n                            ],\r\n                            this.board,\r\n                            false\r\n                        ),\r\n                        bb = this.board.getBoundingBox(),\r\n                        dx = (bb[2] - bb[0]) * 0.1,\r\n                        x = pb_on_curve.X();\r\n\r\n                    if (x < bb[0]) {\r\n                        x = bb[0] + dx;\r\n                    } else if (x > bb[2]) {\r\n                        x = bb[2] - dx;\r\n                    }\r\n\r\n                    return x + off.usrCoords[1];\r\n                },\r\n                function () {\r\n                    var off = new Coords(\r\n                            Const.COORDS_BY_SCREEN,\r\n                            [\r\n                                0,\r\n                                this.evalVisProp('offset.1') +\r\n                                    this.board.origin.scrCoords[2]\r\n                            ],\r\n                            this.board,\r\n                            false\r\n                        ),\r\n                        bb = this.board.getBoundingBox(),\r\n                        dy = (bb[1] - bb[3]) * 0.1,\r\n                        y = pb_on_curve.Y();\r\n\r\n                    if (y > bb[1]) {\r\n                        y = bb[1] - dy;\r\n                    } else if (y < bb[3]) {\r\n                        y = bb[3] + dy;\r\n                    }\r\n\r\n                    return y + off.usrCoords[2];\r\n                },\r\n                ''\r\n            ], attr);\r\n\r\n        txt_fun = function () {\r\n            var intSymbol = '&int;',\r\n                Int = Numerics.NewtonCotes([pa_on_axis.X(), pb_on_axis.X()], curve.Y),\r\n                digits = t.evalVisProp('digits'),\r\n                val;\r\n\r\n            if (t.useLocale()) {\r\n                val = t.formatNumberLocale(Int, digits);\r\n            } else {\r\n                val = Type.toFixed(Int, digits);\r\n            }\r\n            if (t.evalVisProp('usemathjax') || t.evalVisProp('usekatex')) {\r\n                intSymbol = '\\\\int';\r\n            }\r\n            return intSymbol + ' = ' + val;\r\n        };\r\n        t.setText(txt_fun);\r\n        t.dump = false;\r\n\r\n        pa_on_curve.addChild(t);\r\n        pb_on_curve.addChild(t);\r\n    }\r\n\r\n    // dump stuff\r\n    pa_on_curve.dump = false;\r\n    pa_on_axis.dump = false;\r\n\r\n    pb_on_curve.dump = false;\r\n    pb_on_axis.dump = false;\r\n\r\n    p.elType = 'integral';\r\n    p.setParents([curve.id, interval]);\r\n    p.subs = {\r\n        curveLeft: pa_on_curve,\r\n        baseLeft: pa_on_axis,\r\n        curveRight: pb_on_curve,\r\n        baseRight: pb_on_axis\r\n    };\r\n    p.inherits.push(pa_on_curve, pa_on_axis, pb_on_curve, pb_on_axis);\r\n\r\n    if (attr.withlabel) {\r\n        p.subs.label = t;\r\n        p.inherits.push(t);\r\n    }\r\n\r\n    /**\r\n     * Returns the current value of the integral.\r\n     * @memberOf Integral\r\n     * @name Value\r\n     * @function\r\n     * @returns {Number}\r\n     */\r\n    p.Value = function () {\r\n        return Numerics.I([pa_on_axis.X(), pb_on_axis.X()], curve.Y);\r\n    };\r\n\r\n    /**\r\n     * documented in JXG.Curve\r\n     * @class\r\n     * @ignore\r\n     */\r\n    p.updateDataArray = function () {\r\n        var x, y, i, left, right, lowx, upx, lowy, upy;\r\n\r\n        if (this.evalVisProp('axis') === 'y') {\r\n            if (pa_on_curve.Y() < pb_on_curve.Y()) {\r\n                lowx = pa_on_curve.X();\r\n                lowy = pa_on_curve.Y();\r\n                upx = pb_on_curve.X();\r\n                upy = pb_on_curve.Y();\r\n            } else {\r\n                lowx = pb_on_curve.X();\r\n                lowy = pb_on_curve.Y();\r\n                upx = pa_on_curve.X();\r\n                upy = pa_on_curve.Y();\r\n            }\r\n            left = Math.min(lowx, upx);\r\n            right = Math.max(lowx, upx);\r\n\r\n            x = [0, lowx];\r\n            y = [lowy, lowy];\r\n\r\n            for (i = 0; i < curve.numberPoints; i++) {\r\n                if (\r\n                    lowy <= curve.points[i].usrCoords[2] &&\r\n                    left <= curve.points[i].usrCoords[1] &&\r\n                    curve.points[i].usrCoords[2] <= upy &&\r\n                    curve.points[i].usrCoords[1] <= right\r\n                ) {\r\n                    x.push(curve.points[i].usrCoords[1]);\r\n                    y.push(curve.points[i].usrCoords[2]);\r\n                }\r\n            }\r\n            x.push(upx);\r\n            y.push(upy);\r\n            x.push(0);\r\n            y.push(upy);\r\n\r\n            // close the curve\r\n            x.push(0);\r\n            y.push(lowy);\r\n        } else {\r\n            if (pa_on_axis.X() < pb_on_axis.X()) {\r\n                left = pa_on_axis.X();\r\n                right = pb_on_axis.X();\r\n            } else {\r\n                left = pb_on_axis.X();\r\n                right = pa_on_axis.X();\r\n            }\r\n\r\n            x = [left, left];\r\n            y = [0, curve.Y(left)];\r\n\r\n            for (i = 0; i < curve.numberPoints; i++) {\r\n                if (\r\n                    left <= curve.points[i].usrCoords[1] &&\r\n                    curve.points[i].usrCoords[1] <= right\r\n                ) {\r\n                    x.push(curve.points[i].usrCoords[1]);\r\n                    y.push(curve.points[i].usrCoords[2]);\r\n                }\r\n            }\r\n            x.push(right);\r\n            y.push(curve.Y(right));\r\n            x.push(right);\r\n            y.push(0);\r\n\r\n            // close the curve\r\n            x.push(left);\r\n            y.push(0);\r\n        }\r\n\r\n        this.dataX = x;\r\n        this.dataY = y;\r\n    };\r\n\r\n    pa_on_curve.addChild(p);\r\n    pb_on_curve.addChild(p);\r\n    pa_on_axis.addChild(p);\r\n    pb_on_axis.addChild(p);\r\n\r\n    /**\r\n     * The point on the axis initially corresponding to the lower value of the interval.\r\n     *\r\n     * @name baseLeft\r\n     * @memberOf Integral\r\n     * @type JXG.Point\r\n     */\r\n    p.baseLeft = pa_on_axis;\r\n\r\n    /**\r\n     * The point on the axis initially corresponding to the higher value of the interval.\r\n     *\r\n     * @name baseRight\r\n     * @memberOf Integral\r\n     * @type JXG.Point\r\n     */\r\n    p.baseRight = pb_on_axis;\r\n\r\n    /**\r\n     * The glider on the curve corresponding to the lower value of the interval.\r\n     *\r\n     * @name curveLeft\r\n     * @memberOf Integral\r\n     * @type Glider\r\n     */\r\n    p.curveLeft = pa_on_curve;\r\n\r\n    /**\r\n     * The glider on the axis corresponding to the higher value of the interval.\r\n     *\r\n     * @name curveRight\r\n     * @memberOf Integral\r\n     * @type Glider\r\n     */\r\n    p.curveRight = pb_on_curve;\r\n\r\n    p.methodMap = JXG.deepCopy(p.methodMap, {\r\n        curveLeft: \"curveLeft\",\r\n        baseLeft: \"baseLeft\",\r\n        curveRight: \"curveRight\",\r\n        baseRight: \"baseRight\",\r\n        Value: \"Value\"\r\n    });\r\n\r\n    /**\r\n     * documented in GeometryElement\r\n     * @ignore\r\n     */\r\n    p.label = t;\r\n\r\n    return p;\r\n};\r\n\r\n/**\r\n * @class The area which is the set of solutions of a linear inequality or an inequality\r\n * of a function graph.\r\n * For example, an inequality of type y <= f(x).\r\n * @pseudo\r\n * @description Display the solution set of a linear inequality (less than or equal to).\r\n * To be precise, the solution set of the inequality <i>y <= b/a * x + c/a</i> is shown.\r\n * In case <i>a = 0</i>, that is if the equation of the line is <i>bx + c = 0</i>,\r\n * the area of the inequality <i>bx + c <= 0</i> is shown.\r\n * <p>\r\n * For function graphs the area below the function graph is filled, i.e. the\r\n * area of the inequality y <= f(x).\r\n * With the attribute inverse:true the area of the inequality y >= f(x) is filled.\r\n *\r\n * @param {JXG.Line} l The area drawn will be the area below this line. With the attribute\r\n * inverse:true, the inequality 'greater than or equal to' is shown.\r\n * @constructor\r\n * @name Inequality\r\n * @type JXG.Curve\r\n * @augments JXG.Curve\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @example\r\n * var p = board.create('point', [1, 3]),\r\n *     q = board.create('point', [-2, -4]),\r\n *     l = board.create('line', [p, q]),\r\n *     ineq = board.create('inequality', [l]);\r\n * ineq = board.create('inequality', [l]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG2b703006-fd98-11e1-b79e-ef9e591c002e\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *  var board = JXG.JSXGraph.initBoard('JXG2b703006-fd98-11e1-b79e-ef9e591c002e', {boundingbox:[-4, 6, 10, -6], axis: false, grid: false, keepaspectratio: true}),\r\n *      p = board.create('point', [1, 3]),\r\n *      q = board.create('point', [-2, -4]),\r\n *      l = board.create('line', [p, q]),\r\n *      ineq = board.create('inequality', [l]);\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Plot the inequality\r\n * //     y >= 2/3 x + 1\r\n * // or\r\n * //     0 >= -3y + 2x +1\r\n * var l = board.create('line', [1, 2, -3]),\r\n *     ineq = board.create('inequality', [l], {inverse:true});\r\n * </pre><div class=\"jxgbox\" id=\"JXG1ded3812-2da4-4323-abaf-1db4bad1bfbd\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *  var board = JXG.JSXGraph.initBoard('JXG1ded3812-2da4-4323-abaf-1db4bad1bfbd', {boundingbox:[-4, 6, 10, -6], axis: false, grid: false, keepaspectratio: true}),\r\n *      l = board.create('line', [1, 2, -3]),\r\n *      ineq = board.create('inequality', [l], {inverse:true});\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * var f = board.create('functiongraph', ['sin(x)', -2*Math.PI, 2*Math.PI]);\r\n *\r\n * var ineq_lower = board.create('inequality', [f]);\r\n * var ineq_greater = board.create('inequality', [f], {inverse: true, fillColor: 'yellow'});\r\n *\r\n *\r\n * </pre><div id=\"JXGdb68c574-414c-11e8-839a-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGdb68c574-414c-11e8-839a-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var f = board.create('functiongraph', ['sin(x)', -2*Math.PI, 2*Math.PI]);\r\n *\r\n *     var ineq_lower = board.create('inequality', [f]);\r\n *     var ineq_greater = board.create('inequality', [f], {inverse: true, fillColor: 'yellow'});\r\n *\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createInequality = function (board, parents, attributes) {\r\n    var f, a, attr;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'inequality');\r\n    if (parents[0].elementClass === Const.OBJECT_CLASS_LINE) {\r\n        a = board.create(\"curve\", [[], []], attr);\r\n        a.hasPoint = function () {\r\n            return false;\r\n        };\r\n\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        a.updateDataArray = function () {\r\n            var i1,\r\n                i2,\r\n                // This will be the height of the area. We mustn't rely upon the board height because if we pan the view\r\n                // such that the line is not visible anymore, the borders of the area will get visible in some cases.\r\n                h,\r\n                bb = board.getBoundingBox(),\r\n                inverse = this.evalVisProp('inverse'),\r\n                factor = inverse ? -1 : 1,\r\n                expansion = 1.5,\r\n                w = expansion * Math.max(bb[2] - bb[0], bb[1] - bb[3]),\r\n                // Fake a point (for Math.Geometry.perpendicular)\r\n                // contains centroid of the board\r\n                dp = {\r\n                    coords: {\r\n                        usrCoords: [1, (bb[0] + bb[2]) * 0.5, inverse ? bb[1] : bb[3]]\r\n                    }\r\n                },\r\n                slope1 = parents[0].stdform.slice(1),\r\n                slope2 = slope1;\r\n\r\n            // Calculate the area height as\r\n            //  expansion times the distance of the line to the\r\n            // point in the middle of the top/bottom border.\r\n            h =\r\n                expansion *\r\n                Math.max(\r\n                    Geometry.perpendicular(parents[0], dp, board)[0].distance(\r\n                        Const.COORDS_BY_USER,\r\n                        dp.coords\r\n                    ),\r\n                    w\r\n                );\r\n            h *= factor;\r\n\r\n            // reuse dp\r\n            dp = {\r\n                coords: {\r\n                    usrCoords: [1, (bb[0] + bb[2]) * 0.5, (bb[1] + bb[3]) * 0.5]\r\n                }\r\n            };\r\n\r\n            // If dp is on the line, Geometry.perpendicular will return a point not on the line.\r\n            // Since this somewhat odd behavior of Geometry.perpendicular is needed in GEONExT,\r\n            // it is circumvented here.\r\n            if (\r\n                Math.abs(Mat.innerProduct(dp.coords.usrCoords, parents[0].stdform, 3)) >=\r\n                Mat.eps\r\n            ) {\r\n                dp = Geometry.perpendicular(parents[0], dp, board)[0].usrCoords;\r\n            } else {\r\n                dp = dp.coords.usrCoords;\r\n            }\r\n            i1 = [1, dp[1] + slope1[1] * w, dp[2] - slope1[0] * w];\r\n            i2 = [1, dp[1] - slope2[1] * w, dp[2] + slope2[0] * w];\r\n\r\n            // One of the vectors based in i1 and orthogonal to the parent line has the direction d1 = (slope1, -1)\r\n            // We will go from i1 to i1 + h*d1, from there to i2 + h*d2 (with d2 calculated equivalent to d1) and\r\n            // end up in i2.\r\n            this.dataX = [i1[1], i1[1] + slope1[0] * h, i2[1] + slope2[0] * h, i2[1], i1[1]];\r\n            this.dataY = [i1[2], i1[2] + slope1[1] * h, i2[2] + slope2[1] * h, i2[2], i1[2]];\r\n        };\r\n    } else if (\r\n        parents[0].elementClass === Const.OBJECT_CLASS_CURVE &&\r\n        parents[0].visProp.curvetype === \"functiongraph\"\r\n    ) {\r\n        a = board.create(\"curve\", [[], []], attr);\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        a.updateDataArray = function () {\r\n            var bbox = this.board.getBoundingBox(),\r\n                points = [],\r\n                infty,\r\n                first,\r\n                last,\r\n                len,\r\n                i,\r\n                mi = parents[0].minX(),\r\n                ma = parents[0].maxX(),\r\n                curve_mi,\r\n                curve_ma,\r\n                firstx,\r\n                lastx,\r\n                enlarge = (bbox[1] - bbox[3]) * 0.3, // enlarge the bbox vertically by this amount\r\n                inverse = this.evalVisProp('inverse');\r\n\r\n            // inverse == true <=> Fill area with y >= f(x)\r\n            infty = inverse ? 1 : 3; // we will use either bbox[1] or bbox[3] below\r\n\r\n            this.dataX = [];\r\n            this.dataY = [];\r\n            len = parents[0].points.length;\r\n            if (len === 0) {\r\n                return;\r\n            }\r\n\r\n            bbox[1] += enlarge;\r\n            bbox[3] -= enlarge;\r\n\r\n            last = -1;\r\n            while (last < len - 1) {\r\n                // Find the first point with real coordinates on this curve segment\r\n                for (i = last + 1, first = len; i < len; i++) {\r\n                    if (parents[0].points[i].isReal()) {\r\n                        first = i;\r\n                        break;\r\n                    }\r\n                }\r\n                // No real points found -> exit\r\n                if (first >= len) {\r\n                    break;\r\n                }\r\n\r\n                // Find the last point with real coordinates on this curve segment\r\n                for (i = first, last = len - 1; i < len - 1; i++) {\r\n                    if (!parents[0].points[i + 1].isReal()) {\r\n                        last = i;\r\n                        break;\r\n                    }\r\n                }\r\n\r\n                firstx = parents[0].points[first].usrCoords[1];\r\n                lastx = parents[0].points[last].usrCoords[1];\r\n\r\n                // Restrict the plot interval if the function ends inside of the board\r\n                curve_mi = bbox[0] < mi ? mi : bbox[0];\r\n                curve_ma = bbox[2] > ma ? ma : bbox[2];\r\n\r\n                // Found NaNs\r\n                curve_mi = first === 0 ? curve_mi : Math.max(curve_mi, firstx);\r\n                curve_ma = last === len - 1 ? curve_ma : Math.min(curve_ma, lastx);\r\n\r\n                // First and last relevant x-coordinate of the curve\r\n                curve_mi = first === 0 ? mi : firstx;\r\n                curve_ma = last === len - 1 ? ma : lastx;\r\n\r\n                // Copy the curve points\r\n                points = [];\r\n\r\n                points.push([1, curve_mi, bbox[infty]]);\r\n                points.push([1, curve_mi, parents[0].points[first].usrCoords[2]]);\r\n                for (i = first; i <= last; i++) {\r\n                    points.push(parents[0].points[i].usrCoords);\r\n                }\r\n                points.push([1, curve_ma, parents[0].points[last].usrCoords[2]]);\r\n                points.push([1, curve_ma, bbox[infty]]);\r\n                points.push(points[0]);\r\n\r\n                for (i = 0; i < points.length; i++) {\r\n                    this.dataX.push(points[i][1]);\r\n                    this.dataY.push(points[i][2]);\r\n                }\r\n\r\n                if (last < len - 1) {\r\n                    this.dataX.push(NaN);\r\n                    this.dataY.push(NaN);\r\n                }\r\n            }\r\n        };\r\n\r\n        // Previous code:\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        a.hasPoint = function () {\r\n            return false;\r\n        };\r\n    } else {\r\n        // Not yet practical?\r\n        f = Type.createFunction(parents[0]);\r\n        a.addParentsFromJCFunctions([f]);\r\n\r\n        if (!Type.exists(f)) {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create area with the given parents.\" +\r\n                    \"\\nPossible parent types: [line], [function]\"\r\n            );\r\n        }\r\n    }\r\n\r\n    a.addParents(parents[0]);\r\n    return a;\r\n};\r\n\r\nJXG.registerElement(\"arrowparallel\", JXG.createArrowParallel);\r\nJXG.registerElement(\"bisector\", JXG.createBisector);\r\nJXG.registerElement(\"bisectorlines\", JXG.createAngularBisectorsOfTwoLines);\r\nJXG.registerElement(\"msector\", JXG.createMsector);\r\nJXG.registerElement(\"circumcircle\", JXG.createCircumcircle);\r\nJXG.registerElement(\"circumcirclemidpoint\", JXG.createCircumcenter);\r\nJXG.registerElement(\"circumcenter\", JXG.createCircumcenter);\r\nJXG.registerElement(\"incenter\", JXG.createIncenter);\r\nJXG.registerElement(\"incircle\", JXG.createIncircle);\r\nJXG.registerElement(\"integral\", JXG.createIntegral);\r\nJXG.registerElement(\"midpoint\", JXG.createMidpoint);\r\nJXG.registerElement(\"mirrorelement\", JXG.createMirrorElement);\r\nJXG.registerElement(\"mirrorpoint\", JXG.createMirrorPoint);\r\nJXG.registerElement(\"orthogonalprojection\", JXG.createOrthogonalProjection);\r\nJXG.registerElement(\"parallel\", JXG.createParallel);\r\nJXG.registerElement(\"parallelpoint\", JXG.createParallelPoint);\r\nJXG.registerElement(\"perpendicular\", JXG.createPerpendicular);\r\nJXG.registerElement(\"perpendicularpoint\", JXG.createPerpendicularPoint);\r\nJXG.registerElement(\"perpendicularsegment\", JXG.createPerpendicularSegment);\r\nJXG.registerElement(\"reflection\", JXG.createReflection);\r\nJXG.registerElement(\"inequality\", JXG.createInequality);\r\n\r\n// export default {\r\n//     createArrowParallel: JXG.createArrowParallel,\r\n//     createBisector: JXG.createBisector,\r\n//     createAngularBisectorOfTwoLines: JXG.createAngularBisectorsOfTwoLines,\r\n//     createCircumcircle: JXG.createCircumcircle,\r\n//     createCircumcenter: JXG.createCircumcenter,\r\n//     createIncenter: JXG.createIncenter,\r\n//     createIncircle: JXG.createIncircle,\r\n//     createIntegral: JXG.createIntegral,\r\n//     createMidpoint: JXG.createMidpoint,\r\n//     createMirrorElement: JXG.createMirrorElement,\r\n//     createMirrorPoint: JXG.createMirrorPoint,\r\n//     createNormal: JXG.createNormal,\r\n//     createOrthogonalProjection: JXG.createOrthogonalProjection,\r\n//     createParallel: JXG.createParallel,\r\n//     createParallelPoint: JXG.createParallelPoint,\r\n//     createPerpendicular: JXG.createPerpendicular,\r\n//     createPerpendicularPoint: JXG.createPerpendicularPoint,\r\n//     createPerpendicularSegmen: JXG.createPerpendicularSegment,\r\n//     createReflection: JXG.createReflection,\r\n//     createInequality: JXG.createInequality\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*\r\n    Some functionalities in this file were developed as part of a software project\r\n    with students. We would like to thank all contributors for their help:\r\n\r\n    Winter semester 2023/2024:\r\n        Timm Braun\r\n        Nina Koch\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Const from \"../base/constants.js\";\r\n\r\n/**\r\n * @class A grid is a mesh consisting of vertical and horizontal lines or other geometrical objects.\r\n * @pseudo\r\n * @description A grid is a set of vertical and horizontal lines or other geometrical objects (faces)\r\n * to support the user with element placement or to improve determination of position.\r\n * This method takes up to two facultative parent elements. These are used to set distance between\r\n * grid elements in case of attribute <tt>majorStep</tt> or <tt>minorElements</tt> is set to 'auto'.\r\n * Then the major/minor grid element distance is set to the ticks distance of parent axes.\r\n * It is usually instantiated on the board's creation via the attribute <tt>grid</tt> set to true.\r\n * @constructor\r\n * @name Grid\r\n * @type JXG.Curve\r\n * @augments JXG.Curve\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Axis_JXG.Axis} a1,a2 Optional parent axis.\r\n *\r\n * @example\r\n * // standard grid\r\n * var g = board.create('grid', [], {});\r\n * </pre><div id=\"JXGc8dde3f5-22ef-4c43-9505-34b299b5b24d\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *  (function() {\r\n *      var board = JXG.JSXGraph.initBoard('JXGc8dde3f5-22ef-4c43-9505-34b299b5b24d',\r\n *          {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *      var g = board.create('grid', [], {});\r\n *  })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * // more fancy grid\r\n * var g = board.create('grid', [], {\r\n *     major: {\r\n *         face: 'plus',\r\n *         size: 7,\r\n *         strokeColor: 'green',\r\n *         strokeOpacity: 1,\r\n *     },\r\n *     minor: {\r\n *         size: 4\r\n *     },\r\n *     minorElements: 3,\r\n * });\r\n * </pre><div id=\"JXG02374171-b27c-4ccc-a14a-9f5bd1162623\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG02374171-b27c-4ccc-a14a-9f5bd1162623',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *         var g = board.create('grid', [], {\r\n *             major: {\r\n *                 face: 'plus',\r\n *                 size: 7,\r\n *                 strokeColor: 'green',\r\n *                 strokeOpacity: 1,\r\n *             },\r\n *             minor: {\r\n *                 size: 4\r\n *             },\r\n *             minorElements: 3,\r\n *         });\r\n *     })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * // extreme fancy grid\r\n * var grid = board.create('grid', [], {\r\n *     major: {\r\n *         face: 'regularPolygon',\r\n *         size: 8,\r\n *         strokeColor: 'blue',\r\n *         fillColor: 'orange',\r\n *         strokeOpacity: 1,\r\n *     },\r\n *     minor: {\r\n *         face: 'diamond',\r\n *         size: 4,\r\n *         strokeColor: 'green',\r\n *         fillColor: 'grey',\r\n *     },\r\n *     minorElements: 1,\r\n *     includeBoundaries: false,\r\n * });\r\n * </pre><div id=\"JXG00f3d068-093c-4c1d-a1ab-96c9ee73c173\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG00f3d068-093c-4c1d-a1ab-96c9ee73c173',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *         var grid = board.create('grid', [], {\r\n *             major: {\r\n *                 face: 'regularPolygon',\r\n *                 size: 8,\r\n *                 strokeColor: 'blue',\r\n *                 fillColor: 'orange',\r\n *                 strokeOpacity: 1,\r\n *             },\r\n *             minor: {\r\n *                 face: 'diamond',\r\n *                 size: 4,\r\n *                 strokeColor: 'green',\r\n *                 fillColor: 'grey',\r\n *             },\r\n *             minorElements: 1,\r\n *             includeBoundaries: false,\r\n *         });\r\n *     })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * // grid with parent axes\r\n * var axis1 = board.create('axis', [[-1, -2.5], [1, -2.5]], {\r\n *     ticks: {\r\n *         strokeColor: 'green',\r\n *         strokeWidth: 2,\r\n *         minorticks: 2,\r\n *         majorHeight: 10,\r\n *         drawZero: true\r\n *     }\r\n * });\r\n * var axis2 = board.create('axis', [[3, 0], [3, 2]], {\r\n *     ticks: {\r\n *         strokeColor: 'red',\r\n *         strokeWidth: 2,\r\n *         minorticks: 3,\r\n *         majorHeight: 10,\r\n *         drawZero: true\r\n *     }\r\n * });\r\n * var grid = board.create('grid', [axis1, axis2], {\r\n *     major: {\r\n *         face: 'line'\r\n *     },\r\n *     minor: {\r\n *         face: 'point',\r\n *         size: 3\r\n *     },\r\n *     minorElements: 'auto',\r\n *     includeBoundaries: false,\r\n * });\r\n * </pre><div id=\"JXG0568e385-248c-43a9-87ed-07aceb8cc3ab\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG0568e385-248c-43a9-87ed-07aceb8cc3ab',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *         var axis1 = board.create('axis', [[-1, -2.5], [1, -2.5]], {\r\n *             ticks: {\r\n *                 strokeColor: 'green',\r\n *                 strokeWidth: 2,\r\n *                 minorticks: 2,\r\n *                 majorHeight: 10,\r\n *                 drawZero: true\r\n *             }\r\n *         });\r\n *         var axis2 = board.create('axis', [[3, 0], [3, 2]], {\r\n *             ticks: {\r\n *                 strokeColor: 'red',\r\n *                 strokeWidth: 2,\r\n *                 minorticks: 3,\r\n *                 majorHeight: 10,\r\n *                 drawZero: true\r\n *             }\r\n *         });\r\n *         var grid = board.create('grid', [axis1, axis2], {\r\n *             major: {\r\n *                 face: 'line',\r\n *             },\r\n *             minor: {\r\n *                 face: 'point',\r\n *                 size: 3\r\n *             },\r\n *             minorElements: 'auto',\r\n *             includeBoundaries: false,\r\n *         });\r\n *     }());\r\n * </script><pre>\r\n */\r\nJXG.createGrid = function (board, parents, attributes) {\r\n    var eps = Mat.eps,       // to avoid rounding errors\r\n        maxLines = 5000,    // maximum number of vertical or horizontal grid elements (abort criterion for performance reasons)\r\n\r\n        majorGrid,      // main object which will be returned as grid\r\n        minorGrid,      // sub-object\r\n        parentAxes,     // {Array} array of user defined axes (allowed length 0, 1 or 2)\r\n\r\n        attrGrid,       // attributes for grid\r\n        attrMajor,      // attributes for major grid\r\n        attrMinor,      // attributes for minor grid\r\n\r\n        majorStep,      // {[Number]} distance (in usrCoords) in x- and y-direction between center of two major grid elements\r\n        majorSize = [],\r\n        majorRadius = [], // half of the size of major grid element\r\n\r\n        createDataArrayForFace;  // {Function}\r\n\r\n    parentAxes = parents;\r\n    if (\r\n        parentAxes.length > 2 ||\r\n        (parentAxes.length >= 1 && parentAxes[0].elType !== 'axis') ||\r\n        (parentAxes.length >= 2 && parentAxes[1].elType !== 'axis')\r\n    ) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create 'grid' with parent type '\" +\r\n            parents[0].elType +\r\n            \"'. Possible parent types: [axis,axis]\"\r\n        );\r\n    }\r\n    if (!Type.exists(parentAxes[0]) && Type.exists(board.defaultAxes)) {\r\n        parentAxes[0] = board.defaultAxes.x;\r\n    }\r\n    if (!Type.exists(parentAxes[1]) && Type.exists(board.defaultAxes)) {\r\n        parentAxes[1] = board.defaultAxes.y;\r\n    }\r\n\r\n    /**\r\n     * Creates for each face the right data array for updateDataArray function.\r\n     * This functions also adapts visProps according to face.\r\n\r\n     * @param {String} face Chosen face to be drawn\r\n     * @param {Object} grid Curve/grid to be drawn\r\n     * @param {Number} x x-coordinate of target position\r\n     * @param {Number} y y-coordinate of target position\r\n     * @param {Number} radiusX Half of width in x-direction of face to be drawn\r\n     * @param {Number} radiusY Half of width in y-direction of face to be drawn\r\n     * @param {Array} bbox boundingBox\r\n     *\r\n     * @returns {Array} data array of length 2 (x- and y- coordinated for curve)\r\n     * @private\r\n     * @ignore\r\n     */\r\n    createDataArrayForFace = function (face, grid, x, y, radiusX, radiusY, bbox) {\r\n        var t, q, m, n, array, rx2, ry2;\r\n\r\n        switch (face.toLowerCase()) {\r\n\r\n            // filled point\r\n            case '.':\r\n            case 'point':\r\n                grid.visProp.linecap = 'round';\r\n                grid.visProp.strokewidth = radiusX * grid.board.unitX + radiusY * grid.board.unitY;\r\n                return [\r\n                    [x, x, NaN],\r\n                    [y, y, NaN]\r\n                ];\r\n\r\n            // bezierCircle\r\n            case 'o':\r\n            case 'circle':\r\n                grid.visProp.linecap = 'square';\r\n                grid.bezierDegree = 3;\r\n                q = 4 * Math.tan(Math.PI / 8) / 3;\r\n                return [\r\n                    [\r\n                        x + radiusX, x + radiusX, x + q * radiusX, x,\r\n                        x - q * radiusX, x - radiusX, x - radiusX, x - radiusX,\r\n                        x - q * radiusX, x, x + q * radiusX, x + radiusX,\r\n                        x + radiusX, NaN\r\n                    ], [\r\n                        y, y + q * radiusY, y + radiusY, y + radiusY,\r\n                        y + radiusY, y + q * radiusY, y, y - q * radiusY,\r\n                        y - radiusY, y - radiusY, y - radiusY, y - q * radiusY,\r\n                        y, NaN\r\n                    ]\r\n                ];\r\n\r\n            // polygon\r\n            case 'regpol':\r\n            case 'regularpolygon':\r\n                grid.visProp.linecap = 'round';\r\n                n = grid.evalVisProp('polygonvertices');\r\n                array = [[], []];\r\n                // approximation of circle with variable n\r\n                for (t = 0; t <= 2 * Math.PI; t += (2 * Math.PI) / n) {\r\n                    array[0].push(x - radiusX * Math.sin(t));\r\n                    array[1].push(y - radiusY * Math.cos(t));\r\n                }\r\n                array[0].push(NaN);\r\n                array[1].push(NaN);\r\n                return array;\r\n\r\n            // square\r\n            case '[]':\r\n            case 'square':\r\n                grid.visProp.linecap = 'square';\r\n                return [\r\n                    [x - radiusX, x + radiusX, x + radiusX, x - radiusX, x - radiusX, NaN],\r\n                    [y + radiusY, y + radiusY, y - radiusY, y - radiusY, y + radiusY, NaN]\r\n                ];\r\n\r\n            // diamond\r\n            case '<>':\r\n            case 'diamond':\r\n                grid.visProp.linecap = 'square';\r\n                return [\r\n                    [x, x + radiusX, x, x - radiusX, x, NaN],\r\n                    [y + radiusY, y, y - radiusY, y, y + radiusY, NaN]\r\n                ];\r\n\r\n            // diamond2\r\n            case '<<>>':\r\n            case 'diamond2':\r\n                grid.visProp.linecap = 'square';\r\n                rx2 = radiusX * Math.sqrt(2);\r\n                ry2 = radiusY * Math.sqrt(2);\r\n                return [\r\n                    [x, x + rx2, x, x - rx2, x, NaN],\r\n                    [y + ry2, y, y - ry2, y, y + ry2, NaN]\r\n                ];\r\n\r\n            case 'x':\r\n            case 'cross':\r\n                return [\r\n                    [x - radiusX, x + radiusX, NaN, x - radiusX, x + radiusX, NaN],\r\n                    [y + radiusY, y - radiusY, NaN, y - radiusY, y + radiusY, NaN]\r\n                ];\r\n\r\n            case '+':\r\n            case 'plus':\r\n                return [\r\n                    [x - radiusX, x + radiusX, NaN, x, x, NaN],\r\n                    [y, y, NaN, y - radiusY, y + radiusY, NaN]\r\n                ];\r\n\r\n            case '-':\r\n            case 'minus':\r\n                return [\r\n                    [x - radiusX, x + radiusX, NaN],\r\n                    [y, y, NaN]\r\n                ];\r\n\r\n            case '|':\r\n            case 'divide':\r\n                return [\r\n                    [x, x, NaN],\r\n                    [y - radiusY, y + radiusY, NaN]\r\n                ];\r\n\r\n            case '^':\r\n            case 'a':\r\n            case 'A':\r\n            case 'triangleup':\r\n                return [\r\n                    [x - radiusX, x, x + radiusX, NaN],\r\n                    [y - radiusY, y, y - radiusY, NaN]\r\n                ];\r\n\r\n            case 'v':\r\n            case 'triangledown':\r\n                return [\r\n                    [x - radiusX, x, x + radiusX, NaN],\r\n                    [y + radiusY, y, y + radiusY, NaN]\r\n                ];\r\n\r\n            case '<':\r\n            case 'triangleleft':\r\n                return [\r\n                    [x + radiusX, x, x + radiusX, NaN],\r\n                    [y + radiusY, y, y - radiusY, NaN]\r\n                ];\r\n\r\n            case '>':\r\n            case 'triangleright':\r\n                return [\r\n                    [x - radiusX, x, x - radiusX, NaN],\r\n                    [y + radiusY, y, y - radiusY, NaN]\r\n                ];\r\n\r\n            case 'line':\r\n                m = grid.evalVisProp('margin');\r\n                return [\r\n                    // [x, x, NaN, bbox[0] + (4 / grid.board.unitX), bbox[2] - (4 / grid.board.unitX), NaN],\r\n                    [x, x, NaN, bbox[0] - m / grid.board.unitX, bbox[2] + m / grid.board.unitX, NaN],\r\n                    [bbox[1] + m / grid.board.unitY, bbox[3] - m / grid.board.unitY, NaN, y, y, NaN]\r\n                ];\r\n\r\n            default:\r\n                return [[], []];\r\n        }\r\n    };\r\n\r\n    // Themes\r\n    attrGrid = Type.copyAttributes(attributes, board.options, 'grid');\r\n    Type.mergeAttr(attrGrid, attrGrid.themes[attrGrid.theme], false);\r\n\r\n    // Create majorGrid\r\n    attrMajor = {};\r\n    Type.mergeAttr(attrMajor, attrGrid, true, true);\r\n    Type.mergeAttr(attrMajor, attrGrid.major, true, true);\r\n    majorGrid = board.create('curve', [[null], [null]], attrMajor);\r\n    majorGrid.elType = 'grid';\r\n    majorGrid.type = Const.OBJECT_TYPE_GRID;\r\n\r\n    // Create minorGrid\r\n    attrMinor = {};\r\n    Type.mergeAttr(attrMinor, attrGrid, true, true);\r\n    Type.mergeAttr(attrMinor, attrGrid.minor, true, true);\r\n    if (attrMinor.id === attrMajor.id) {\r\n        attrMinor.id = majorGrid.id + '_minor';\r\n    }\r\n    if (attrMinor.name === attrMajor.name) {\r\n        attrMinor.name = majorGrid.name + '_minor';\r\n    }\r\n    minorGrid = board.create('curve', [[null], [null]], attrMinor);\r\n    minorGrid.elType = 'grid';\r\n    minorGrid.type = Const.OBJECT_TYPE_GRID;\r\n\r\n    majorGrid.minorGrid = minorGrid;\r\n    minorGrid.majorGrid = majorGrid;\r\n\r\n    majorGrid.hasPoint = function () { return false; };\r\n    minorGrid.hasPoint = function () { return false; };\r\n\r\n    majorGrid.inherits.push(minorGrid);\r\n\r\n    majorGrid.updateDataArray = function () {\r\n        var bbox = this.board.getBoundingBox(),\r\n            startX, startY,\r\n            x, y, m,\r\n            dataArr,\r\n            finite, delta,\r\n\r\n            gridX = this.evalVisProp('gridx'), // for backwards compatibility\r\n            gridY = this.evalVisProp('gridy'), // for backwards compatibility\r\n            face = this.evalVisProp('face'),\r\n            drawZero = this.evalVisProp('drawzero'),\r\n            drawZeroOrigin = drawZero === true || (Type.isObject(drawZero) && this.eval(drawZero.origin) === true),\r\n            drawZeroX = drawZero === true || (Type.isObject(drawZero) && this.eval(drawZero.x) === true),\r\n            drawZeroY = drawZero === true || (Type.isObject(drawZero) && this.eval(drawZero.y) === true),\r\n\r\n            includeBoundaries = this.evalVisProp('includeboundaries'),\r\n            forceSquare = this.evalVisProp('forcesquare');\r\n\r\n        this.dataX = [];\r\n        this.dataY = [];\r\n\r\n        // set global majorStep\r\n        majorStep = this.evalVisProp('majorstep');\r\n        if (!Type.isArray(majorStep)) {\r\n            majorStep = [majorStep, majorStep];\r\n        }\r\n        if (majorStep.length < 2) {\r\n            majorStep = [majorStep[0], majorStep[0]];\r\n        }\r\n        if (Type.exists(gridX)) {\r\n            JXG.deprecated(\"gridX\", 'majorStep');\r\n            majorStep[0] = gridX;\r\n        }\r\n        if (Type.exists(gridY)) {\r\n            JXG.deprecated(\"gridY\", 'majorStep');\r\n            majorStep[1] = gridY;\r\n        }\r\n\r\n        if (majorStep[0] === 'auto') {\r\n            // majorStep[0] = 1; // parentAxes[0] may not be defined\r\n            // Prevent too many grid lines if majorstep:'auto'\r\n            delta = Math.pow(10, Math.floor(Math.log(50 / this.board.unitX) / Math.LN10));\r\n            majorStep[0] = delta;\r\n\r\n            if (Type.exists(parentAxes[0])) {\r\n                majorStep[0] = parentAxes[0].ticks[0].getDistanceMajorTicks();\r\n            }\r\n        } else {\r\n            // This allows the value to have unit px, abs, % or fr.\r\n            majorStep[0] = Type.parseNumber(majorStep[0], Math.abs(bbox[1] - bbox[3]), 1 / this.board.unitX);\r\n        }\r\n\r\n        if (majorStep[1] === 'auto') {\r\n            // majorStep[1] = 1; // parentAxes[1] may not be defined\r\n            // Prevent too many grid lines if majorstep:'auto'\r\n            delta = Math.pow(10, Math.floor(Math.log(50 / this.board.unitY) / Math.LN10));\r\n            majorStep[1] = delta;\r\n\r\n            if (Type.exists(parentAxes[1])) {\r\n                majorStep[1] = parentAxes[1].ticks[0].getDistanceMajorTicks();\r\n            }\r\n        } else {\r\n            // This allows the value to have unit px, abs, % or fr.\r\n            majorStep[1] = Type.parseNumber(majorStep[1], Math.abs(bbox[0] - bbox[2]), 1 / this.board.unitY);\r\n        }\r\n\r\n        if (forceSquare === 'min' || forceSquare === true) {\r\n            if (majorStep[0] * this.board.unitX <= majorStep[1] * this.board.unitY) { // compare px-values\r\n                majorStep[1] = majorStep[0] / this.board.unitY * this.board.unitX;\r\n            } else {\r\n                majorStep[0] = majorStep[1] / this.board.unitX * this.board.unitY;\r\n            }\r\n        } else if (forceSquare === 'max') {\r\n            if (majorStep[0] * this.board.unitX <= majorStep[1] * this.board.unitY) { // compare px-values\r\n                majorStep[0] = majorStep[1] / this.board.unitX * this.board.unitY;\r\n            } else {\r\n                majorStep[1] = majorStep[0] / this.board.unitY * this.board.unitX;\r\n            }\r\n        }\r\n\r\n        // Set global majorSize\r\n        majorSize = this.evalVisProp('size');\r\n        if (!Type.isArray(majorSize)) {\r\n            majorSize = [majorSize, majorSize];\r\n        }\r\n        if (majorSize.length < 2) {\r\n            majorSize = [majorSize[0], majorSize[0]];\r\n        }\r\n\r\n        // Here comes a hack:\r\n        // \"majorsize\" is filled by the attribute \"size\" which is usually considered\r\n        // as pixel value. However, usually a number value for size is\r\n        // considered to be in pixel, while parseNumber expects user coords.\r\n        // Therefore, we have to add 'px'.\r\n        if (Type.isNumber(majorSize[0], true)) {\r\n            majorSize[0] = majorSize[0] + 'px';\r\n        }\r\n        if (Type.isNumber(majorSize[1], true)) {\r\n            majorSize[1] = majorSize[1] + 'px';\r\n        }\r\n        majorSize[0] = Type.parseNumber(majorSize[0], majorStep[0], 1 / this.board.unitX);\r\n        majorSize[1] = Type.parseNumber(majorSize[1], majorStep[1], 1 / this.board.unitY);\r\n        majorRadius[0] = majorSize[0] / 2;\r\n        majorRadius[1] = majorSize[1] / 2;\r\n\r\n        // calculate start position of curve\r\n        startX = Mat.roundToStep(bbox[0], majorStep[0]);\r\n        startY = Mat.roundToStep(bbox[1], majorStep[1]);\r\n\r\n        // check if number of grid elements side by side is not too large\r\n        finite = isFinite(startX) && isFinite(startY) &&\r\n            isFinite(bbox[2]) && isFinite(bbox[3]) &&\r\n            Math.abs(bbox[2]) < Math.abs(majorStep[0] * maxLines) &&\r\n            Math.abs(bbox[3]) < Math.abs(majorStep[1] * maxLines);\r\n\r\n        // POI finite = false means that no grid is drawn. Should we change this?\r\n        // Draw grid elements\r\n        if (face.toLowerCase() === 'line') {\r\n            m = majorGrid.evalVisProp('margin');\r\n            for (y = startY; finite && y >= bbox[3]; y -= majorStep[1]) {\r\n                if (\r\n                    (!drawZeroOrigin && Math.abs(y) < eps) ||\r\n                    (!drawZeroY && Math.abs(y) < eps) ||\r\n                    (!includeBoundaries && (\r\n                        y <= bbox[3] + majorRadius[1] ||\r\n                        y >= bbox[1] - majorRadius[1]\r\n                    ))\r\n                ) {\r\n                    continue;\r\n                }\r\n\r\n                dataArr = [\r\n                    [bbox[0] - m / majorGrid.board.unitX, bbox[2] + m / majorGrid.board.unitX, NaN],\r\n                    [y, y, NaN]\r\n                ];\r\n                // Push is drastically faster than concat\r\n                Type.concat(this.dataX, dataArr[0]);\r\n                Type.concat(this.dataY, dataArr[1]);\r\n            }\r\n            for (x = startX; finite && x <= bbox[2]; x += majorStep[0]) {\r\n                if (\r\n                    (!drawZeroOrigin && Math.abs(x) < eps) ||\r\n                    (!drawZeroX && Math.abs(x) < eps) ||\r\n                    (!includeBoundaries && (\r\n                        x <= bbox[0] + majorRadius[0] ||\r\n                        x >= bbox[2] - majorRadius[0]\r\n                    ))\r\n                ) {\r\n                    continue;\r\n                }\r\n\r\n                dataArr = [\r\n                    [x, x, NaN],\r\n                    [bbox[1] + m / majorGrid.board.unitY, bbox[3] - m / majorGrid.board.unitY, NaN]\r\n                ];\r\n                // Push is drastically faster than concat\r\n                Type.concat(this.dataX, dataArr[0]);\r\n                Type.concat(this.dataY, dataArr[1]);\r\n            }\r\n        } else {\r\n            for (y = startY; finite && y >= bbox[3]; y -= majorStep[1]) {\r\n                for (x = startX; finite && x <= bbox[2]; x += majorStep[0]) {\r\n\r\n                    if (\r\n                        (!drawZeroOrigin && Math.abs(y) < eps && Math.abs(x) < eps) ||\r\n                        (!drawZeroX && Math.abs(y) < eps && Math.abs(x) >= eps) ||\r\n                        (!drawZeroY && Math.abs(x) < eps && Math.abs(y) >= eps) ||\r\n                        (!includeBoundaries && (\r\n                            x <= bbox[0] + majorRadius[0] ||\r\n                            x >= bbox[2] - majorRadius[0] ||\r\n                            y <= bbox[3] + majorRadius[1] ||\r\n                            y >= bbox[1] - majorRadius[1]\r\n                        ))\r\n                    ) {\r\n                        continue;\r\n                    }\r\n\r\n                    dataArr = createDataArrayForFace(face, majorGrid, x, y, majorRadius[0], majorRadius[1], bbox);\r\n                    // Push is drastically faster than concat\r\n                    Type.concat(this.dataX, dataArr[0]);\r\n                    Type.concat(this.dataY, dataArr[1]);\r\n                }\r\n            }\r\n        }\r\n    };\r\n\r\n    minorGrid.updateDataArray = function () {\r\n        var bbox = this.board.getBoundingBox(),\r\n            startX, startY,\r\n            x, y, m,\r\n            dataArr,\r\n            finite,\r\n\r\n            minorStep = [],\r\n            minorRadius = [],\r\n            XdisTo0, XdisFrom0, YdisTo0, YdisFrom0, // {Number} absolute distances of minor grid elements center to next major grid element center\r\n            dis0To, dis1To, dis2To, dis3To,         // {Number} absolute distances of borders of the boundingBox to the next major grid element.\r\n            dis0From, dis1From, dis2From, dis3From,\r\n\r\n            minorElements = this.evalVisProp('minorelements'),\r\n            minorSize = this.evalVisProp('size'),\r\n            minorFace = this.evalVisProp('face'),\r\n            minorDrawZero = this.evalVisProp('drawzero'),\r\n            minorDrawZeroX = minorDrawZero === true || (Type.isObject(minorDrawZero) && this.eval(minorDrawZero.x) === true),\r\n            minorDrawZeroY = minorDrawZero === true || (Type.isObject(minorDrawZero) && this.eval(minorDrawZero.y) === true),\r\n\r\n            majorFace = this.majorGrid.evalVisProp('face'),\r\n            majorDrawZero = this.majorGrid.evalVisProp('drawzero'),\r\n            majorDrawZeroOrigin = majorDrawZero === true || (Type.isObject(majorDrawZero) && this.eval(majorDrawZero.origin) === true),\r\n            majorDrawZeroX = majorDrawZero === true || (Type.isObject(majorDrawZero) && this.eval(majorDrawZero.x) === true),\r\n            majorDrawZeroY = majorDrawZero === true || (Type.isObject(majorDrawZero) && this.eval(majorDrawZero.y) === true),\r\n\r\n            includeBoundaries = this.evalVisProp('includeboundaries');\r\n\r\n        this.dataX = [];\r\n        this.dataY = [];\r\n\r\n        // set minorStep\r\n        // minorElements can be 'auto' or a number (also a number like '20')\r\n        if (!Type.isArray(minorElements)) {\r\n            minorElements = [minorElements, minorElements];\r\n        }\r\n        if (minorElements.length < 2) {\r\n            minorElements = [minorElements[0], minorElements[0]];\r\n        }\r\n\r\n        if (Type.isNumber(minorElements[0], true)) {\r\n            minorElements[0] = parseFloat(minorElements[0]);\r\n\r\n        } else { // minorElements[0]  === 'auto'\r\n            minorElements[0] = 3; // parentAxes[0] may not be defined\r\n            if (Type.exists(parentAxes[0])) {\r\n                minorElements[0] = parentAxes[0].eval(parentAxes[0].getAttribute('ticks').minorticks);\r\n            }\r\n        }\r\n        minorStep[0] = majorStep[0] / (minorElements[0] + 1);\r\n\r\n        if (Type.isNumber(minorElements[1], true)) {\r\n            minorElements[1] = parseFloat(minorElements[1]);\r\n\r\n        } else { // minorElements[1] === 'auto'\r\n            minorElements[1] = 3; // parentAxes[1] may not be defined\r\n            if (Type.exists(parentAxes[1])) {\r\n                minorElements[1] = parentAxes[1].eval(parentAxes[1].getAttribute('ticks').minorticks);\r\n            }\r\n        }\r\n        minorStep[1] = majorStep[1] / (minorElements[1] + 1);\r\n\r\n        // set global minorSize\r\n        if (!Type.isArray(minorSize)) {\r\n            minorSize = [minorSize, minorSize];\r\n        }\r\n        if (minorSize.length < 2) {\r\n            minorSize = [minorSize[0], minorSize[0]];\r\n        }\r\n\r\n        // minorRadius = [\r\n        //     Type.parseNumber(minorSize[0], minorStep[0] * 0.5, 1 / this.board.unitX),\r\n        //     Type.parseNumber(minorSize[0], minorStep[0] * 0.5, 1 / this.board.unitY)\r\n        // ];\r\n\r\n        // Here comes a hack:\r\n        // \"minorsize\" is filled by the attribute \"size\" which is usually considered\r\n        // as pixel value. However, usually a number value for size is\r\n        // considered to be in pixel, while parseNumber expects user coords.\r\n        // Therefore, we have to add 'px'.\r\n        if (Type.isNumber(minorSize[0], true)) {\r\n            minorSize[0] = minorSize[0] + 'px';\r\n        }\r\n        if (Type.isNumber(minorSize[1], true)) {\r\n            minorSize[1] = minorSize[1] + 'px';\r\n        }\r\n        minorSize[0] = Type.parseNumber(minorSize[0], minorStep[0], 1 / this.board.unitX);\r\n        minorSize[1] = Type.parseNumber(minorSize[1], minorStep[1], 1 / this.board.unitY);\r\n        minorRadius[0] = minorSize[0] * 0.5;\r\n        minorRadius[1] = minorSize[1] * 0.5;\r\n\r\n        // calculate start position of curve\r\n        startX = Mat.roundToStep(bbox[0], minorStep[0]);\r\n        startY = Mat.roundToStep(bbox[1], minorStep[1]);\r\n\r\n        // check if number of grid elements side by side is not too large\r\n        finite = isFinite(startX) && isFinite(startY) &&\r\n            isFinite(bbox[2]) && isFinite(bbox[3]) &&\r\n            Math.abs(bbox[2]) <= Math.abs(minorStep[0] * maxLines) &&\r\n            Math.abs(bbox[3]) < Math.abs(minorStep[1] * maxLines);\r\n\r\n        // POI finite = false means that no grid is drawn. Should we change this?\r\n\r\n        // draw grid elements\r\n        if (minorFace.toLowerCase() !== 'line') {\r\n            for (y = startY; finite && y >= bbox[3]; y -= minorStep[1]) {\r\n                for (x = startX; finite && x <= bbox[2]; x += minorStep[0]) {\r\n\r\n                    /* explanation:\r\n                         |<___XdisTo0___><___________XdisFrom0___________>\r\n                         |                .                .               .\r\n                     ____|____            .                .           _________\r\n                    |    |    |         ____              ____        |         |\r\n                    |    |    |        |    |            |    |       |         |\r\n                    |    |    |        |____|            |____|       |         |\r\n                    |____|____|           | |              .          |_________|\r\n                         |    |           . \\              .              .\r\n                         |  \\             . minorRadius[0]   .              .\r\n                         |   majorRadius[0] .                .              .\r\n                         |                .                .              .\r\n                         |<----------->   .                .              .\r\n                         |    \\           .                .              .\r\n                         |     XdisTo0 - minorRadius[0] <= majorRadius[0] ? -> exclude\r\n                         |                .                .              .\r\n                         |                .  <--------------------------->\r\n                         |                             \\\r\n                         |                              XdisFrom0 - minorRadius[0] <= majorRadius[0] ? -> exclude\r\n                         |\r\n                   -——---|————————-————---|----------------|---------------|-------->\r\n                         |\r\n                         |<______________________majorStep[0]_____________________>\r\n                         |\r\n                         |<__minorStep[0]____><__minorStep[0]_____><__minorStep[0]_____>\r\n                         |\r\n                         |\r\n                    */\r\n                    XdisTo0 = Mat.roundToStep(Math.abs(x), majorStep[0]);\r\n                    XdisTo0 = Math.abs(XdisTo0 - Math.abs(x));\r\n                    XdisFrom0 = majorStep[0] - XdisTo0;\r\n\r\n                    YdisTo0 = Mat.roundToStep(Math.abs(y), majorStep[1]);\r\n                    YdisTo0 = Math.abs(YdisTo0 - Math.abs(y));\r\n                    YdisFrom0 = majorStep[1] - YdisTo0;\r\n\r\n                    if (majorFace === 'line') {\r\n                        // for majorFace 'line' do not draw minor grid elements on lines\r\n                        if (\r\n                            XdisTo0 - minorRadius[0] - majorRadius[0] < eps ||\r\n                            XdisFrom0 - minorRadius[0] - majorRadius[0] < eps ||\r\n                            YdisTo0 - minorRadius[1] - majorRadius[1] < eps ||\r\n                            YdisFrom0 - minorRadius[1] - majorRadius[1] < eps\r\n                        ) {\r\n                            continue;\r\n                        }\r\n\r\n                    } else {\r\n                        if ((\r\n                            XdisTo0 - minorRadius[0] - majorRadius[0] < eps ||\r\n                            XdisFrom0 - minorRadius[0] - majorRadius[0] < eps\r\n                        ) && (\r\n                                YdisTo0 - minorRadius[1] - majorRadius[1] < eps ||\r\n                                YdisFrom0 - minorRadius[1] - majorRadius[1] < eps\r\n                            )) {\r\n                            // if major grid elements (on 0 or axes) are not existing, minor grid elements have to exist. Otherwise:\r\n                            if ((\r\n                                majorDrawZeroOrigin ||\r\n                                majorRadius[1] - Math.abs(y) + minorRadius[1] < eps ||\r\n                                majorRadius[0] - Math.abs(x) + minorRadius[0] < eps\r\n                            ) && (\r\n                                    majorDrawZeroX ||\r\n                                    majorRadius[1] - Math.abs(y) + minorRadius[1] < eps ||\r\n                                    majorRadius[0] + Math.abs(x) - minorRadius[0] < eps\r\n                                ) && (\r\n                                    majorDrawZeroY ||\r\n                                    majorRadius[0] - Math.abs(x) + minorRadius[0] < eps ||\r\n                                    majorRadius[1] + Math.abs(y) - minorRadius[1] < eps\r\n                                )) {\r\n                                continue;\r\n                            }\r\n                        }\r\n                    }\r\n                    if (\r\n                        (!minorDrawZeroY && Math.abs(x) < eps) ||\r\n                        (!minorDrawZeroX && Math.abs(y) < eps)\r\n                    ) {\r\n                        continue;\r\n                    }\r\n\r\n                    /* explanation of condition below:\r\n\r\n                          |         __dis2To___> _dis2From_      // dis2To bzw. dis2From >= majorRadius[0]\r\n                          |      __/_          \\/         _\\__\r\n                          |     |    |  []     >         |    |\r\n                          |     |____|         >         |____|\r\n                          |                    >\r\n                          |                    >\r\n                          |    x-minorSize[0]  > bbox[2]\r\n                          0               .    >/\r\n                       -——|————————-————.-.——.—>\r\n                          |             . .  . >\r\n                          |             . .  . >\r\n                          |             . .  . > dis2From (<= majorRadius[0])\r\n                          |             . .  .__/\\____\r\n                          |             . .  | >      |\r\n                          |             . [] | > \\/   |\r\n                          |             .    | > /\\   |\r\n                          |             .    |_>______|\r\n                          |             .    . >\r\n                          |             .    . >\r\n                          |             .    bbox[2]+dis2From-majorRadius[0]\r\n                          |             .      >\r\n                          |             .______>_\r\n                          |             |      > |\r\n                          |         []  |   \\/ > |\r\n                          |             |   /\\ > |\r\n                          |             |______>_|\r\n                          |             .    \\_/\r\n                          |             .     dis2To (<= majorRadius[0])\r\n                          |             .      >\r\n                          |             .      >\r\n                          |             bbox[2]-dis2To-majorRadius[0]\r\n                     */\r\n                    dis0To = Math.abs(bbox[0] % majorStep[0]);\r\n                    dis1To = Math.abs(bbox[1] % majorStep[1]);\r\n                    dis2To = Math.abs(bbox[2] % majorStep[0]);\r\n                    dis3To = Math.abs(bbox[3] % majorStep[1]);\r\n                    dis0From = majorStep[0] - dis0To;\r\n                    dis1From = majorStep[1] - dis1To;\r\n                    dis2From = majorStep[0] - dis2To;\r\n                    dis3From = majorStep[1] - dis3To;\r\n\r\n                    if (\r\n                        !includeBoundaries && (\r\n                            (x - minorRadius[0] - bbox[0] - majorRadius[0] + dis0From < eps && dis0From - majorRadius[0] < eps) ||\r\n                            (x - minorRadius[0] - bbox[0] - majorRadius[0] - dis0To < eps && dis0To - majorRadius[0] < eps) ||\r\n                            (-x - minorRadius[0] + bbox[2] - majorRadius[0] + dis2From < eps && dis2From - majorRadius[0] < eps) ||\r\n                            (-x - minorRadius[0] + bbox[2] - majorRadius[0] - dis2To < eps && dis2To - majorRadius[0] < eps) ||\r\n\r\n                            (-y - minorRadius[1] + bbox[1] - majorRadius[1] + dis1From < eps && dis1From - majorRadius[1] < eps) ||\r\n                            (-y - minorRadius[1] + bbox[1] - majorRadius[1] - dis1To < eps && dis1To - majorRadius[1] < eps) ||\r\n                            (y - minorRadius[1] - bbox[3] - majorRadius[1] + dis3From < eps && dis3From - majorRadius[1] < eps) ||\r\n                            (y - minorRadius[1] - bbox[3] - majorRadius[1] - dis3To < eps && dis3To - majorRadius[1] < eps) ||\r\n\r\n                            (-y - minorRadius[1] + bbox[1] < eps) ||\r\n                            (x - minorRadius[0] - bbox[0] < eps) ||\r\n                            (y - minorRadius[1] - bbox[3] < eps) ||\r\n                            (-x - minorRadius[0] + bbox[2] < eps)\r\n                        )\r\n                    ) {\r\n                        continue;\r\n                    }\r\n\r\n                    dataArr = createDataArrayForFace(minorFace, minorGrid, x, y, minorRadius[0], minorRadius[1], bbox);\r\n                    Type.concat(this.dataX, dataArr[0]);\r\n                    Type.concat(this.dataY, dataArr[1]);\r\n                }\r\n            }\r\n        } else {\r\n            m = minorGrid.evalVisProp('margin');\r\n            for (y = startY; finite && y >= bbox[3]; y -= minorStep[1]) {\r\n                YdisTo0 = Mat.roundToStep(Math.abs(y), majorStep[1]);\r\n                YdisTo0 = Math.abs(YdisTo0 - Math.abs(y));\r\n                YdisFrom0 = majorStep[1] - YdisTo0;\r\n\r\n                if (majorFace === 'line') {\r\n                    // for majorFace 'line' do not draw minor grid elements on lines\r\n                    if (\r\n                        YdisTo0 - minorRadius[1] - majorRadius[1] < eps ||\r\n                        YdisFrom0 - minorRadius[1] - majorRadius[1] < eps\r\n                    ) {\r\n                        continue;\r\n                    }\r\n\r\n                } else {\r\n                    if ((\r\n                        YdisTo0 - minorRadius[1] - majorRadius[1] < eps ||\r\n                        YdisFrom0 - minorRadius[1] - majorRadius[1] < eps\r\n                    )) {\r\n                        // if major grid elements (on 0 or axes) are not existing, minor grid elements have to exist. Otherwise:\r\n                        if ((\r\n                            majorDrawZeroOrigin ||\r\n                            majorRadius[1] - Math.abs(y) + minorRadius[1] < eps\r\n                        ) && (\r\n                                majorDrawZeroX ||\r\n                                majorRadius[1] - Math.abs(y) + minorRadius[1] < eps\r\n                            ) && (\r\n                                majorDrawZeroY ||\r\n                                majorRadius[1] + Math.abs(y) - minorRadius[1] < eps\r\n                            )) {\r\n                            continue;\r\n                        }\r\n                    }\r\n                }\r\n                if (!minorDrawZeroX && Math.abs(y) < eps) {\r\n                    continue;\r\n                }\r\n\r\n                dis0To = Math.abs(bbox[0] % majorStep[0]);\r\n                dis1To = Math.abs(bbox[1] % majorStep[1]);\r\n                dis2To = Math.abs(bbox[2] % majorStep[0]);\r\n                dis3To = Math.abs(bbox[3] % majorStep[1]);\r\n                dis0From = majorStep[0] - dis0To;\r\n                dis1From = majorStep[1] - dis1To;\r\n                dis2From = majorStep[0] - dis2To;\r\n                dis3From = majorStep[1] - dis3To;\r\n\r\n                if (\r\n                    !includeBoundaries && (\r\n                        (-y - minorRadius[1] + bbox[1] - majorRadius[1] + dis1From < eps && dis1From - majorRadius[1] < eps) ||\r\n                        (-y - minorRadius[1] + bbox[1] - majorRadius[1] - dis1To < eps && dis1To - majorRadius[1] < eps) ||\r\n                        (y - minorRadius[1] - bbox[3] - majorRadius[1] + dis3From < eps && dis3From - majorRadius[1] < eps) ||\r\n                        (y - minorRadius[1] - bbox[3] - majorRadius[1] - dis3To < eps && dis3To - majorRadius[1] < eps) ||\r\n\r\n                        (-y - minorRadius[1] + bbox[1] < eps) ||\r\n                        (y - minorRadius[1] - bbox[3] < eps)\r\n                    )\r\n                ) {\r\n                    continue;\r\n                }\r\n\r\n                dataArr = [\r\n                    [bbox[0] - m / minorGrid.board.unitX, bbox[2] + m / minorGrid.board.unitX, NaN],\r\n                    [y, y, NaN]\r\n                ];\r\n                Type.concat(this.dataX, dataArr[0]);\r\n                Type.concat(this.dataY, dataArr[1]);\r\n            }\r\n            for (x = startX; finite && x <= bbox[2]; x += minorStep[0]) {\r\n                XdisTo0 = Mat.roundToStep(Math.abs(x), majorStep[0]);\r\n                XdisTo0 = Math.abs(XdisTo0 - Math.abs(x));\r\n                XdisFrom0 = majorStep[0] - XdisTo0;\r\n\r\n                if (majorFace === 'line') {\r\n                    // for majorFace 'line' do not draw minor grid elements on lines\r\n                    if (\r\n                        XdisTo0 - minorRadius[0] - majorRadius[0] < eps ||\r\n                        XdisFrom0 - minorRadius[0] - majorRadius[0] < eps\r\n                    ) {\r\n                        continue;\r\n                    }\r\n\r\n                } else {\r\n                    if ((\r\n                        XdisTo0 - minorRadius[0] - majorRadius[0] < eps ||\r\n                        XdisFrom0 - minorRadius[0] - majorRadius[0] < eps\r\n                    )) {\r\n                        // if major grid elements (on 0 or axes) are not existing, minor grid elements have to exist. Otherwise:\r\n                        if ((\r\n                            majorDrawZeroOrigin ||\r\n                            majorRadius[0] - Math.abs(x) + minorRadius[0] < eps\r\n                        ) && (\r\n                                majorDrawZeroX ||\r\n                                majorRadius[0] + Math.abs(x) - minorRadius[0] < eps\r\n                            ) && (\r\n                                majorDrawZeroY ||\r\n                                majorRadius[0] - Math.abs(x) + minorRadius[0] < eps\r\n                            )) {\r\n                            continue;\r\n                        }\r\n                    }\r\n                }\r\n                if (!minorDrawZeroY && Math.abs(x) < eps) {\r\n                    continue;\r\n                }\r\n\r\n                dis0To = Math.abs(bbox[0] % majorStep[0]);\r\n                dis1To = Math.abs(bbox[1] % majorStep[1]);\r\n                dis2To = Math.abs(bbox[2] % majorStep[0]);\r\n                dis3To = Math.abs(bbox[3] % majorStep[1]);\r\n                dis0From = majorStep[0] - dis0To;\r\n                dis1From = majorStep[1] - dis1To;\r\n                dis2From = majorStep[0] - dis2To;\r\n                dis3From = majorStep[1] - dis3To;\r\n\r\n                if (\r\n                    !includeBoundaries && (\r\n                        (x - minorRadius[0] - bbox[0] - majorRadius[0] + dis0From < eps && dis0From - majorRadius[0] < eps) ||\r\n                        (x - minorRadius[0] - bbox[0] - majorRadius[0] - dis0To < eps && dis0To - majorRadius[0] < eps) ||\r\n                        (-x - minorRadius[0] + bbox[2] - majorRadius[0] + dis2From < eps && dis2From - majorRadius[0] < eps) ||\r\n                        (-x - minorRadius[0] + bbox[2] - majorRadius[0] - dis2To < eps && dis2To - majorRadius[0] < eps) ||\r\n\r\n                        (x - minorRadius[0] - bbox[0] < eps) ||\r\n                        (-x - minorRadius[0] + bbox[2] < eps)\r\n                    )\r\n                ) {\r\n                    continue;\r\n                }\r\n\r\n                dataArr = [\r\n                    [x, x, NaN],\r\n                    [bbox[1] + m / minorGrid.board.unitY, bbox[3] - m / minorGrid.board.unitY, NaN]\r\n                ];\r\n                Type.concat(this.dataX, dataArr[0]);\r\n                Type.concat(this.dataY, dataArr[1]);\r\n            }\r\n        }\r\n    };\r\n\r\n    board.grids.push(majorGrid);\r\n    board.grids.push(minorGrid);\r\n\r\n    minorGrid.dump = false;\r\n\r\n    majorGrid.getParents = minorGrid.getParents = function() {\r\n        return parentAxes.slice();\r\n    };\r\n\r\n    return majorGrid;\r\n};\r\n\r\nJXG.registerElement(\"grid\", JXG.createGrid);\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview In this file the geometry element Image is defined.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"./constants.js\";\r\nimport Coords from \"./coords.js\";\r\nimport GeometryElement from \"./element.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport CoordsElement from \"./coordselement.js\";\r\n\r\n/**\r\n * Construct and handle images\r\n *\r\n * The image can be supplied as an URL or an base64 encoded inline image\r\n * like \"data:image/png;base64, /9j/4AAQSkZJRgA...\" or a function returning\r\n * an URL: function(){ return 'xxx.png; }.\r\n *\r\n * @class Creates a new image object. Do not use this constructor to create a image. Use {@link JXG.Board#create} with\r\n * type {@link Image} instead.\r\n * @augments JXG.GeometryElement\r\n * @augments JXG.CoordsElement\r\n * @param {string|JXG.Board} board The board the new image is drawn on.\r\n * @param {Array} coordinates An array with the user coordinates of the image.\r\n * @param {Object} attributes An object containing visual and - optionally - a name and an id.\r\n * @param {string|function} url An URL string or a function returning an URL string.\r\n * @param  {Array} size Array containing width and height of the image in user coordinates.\r\n *\r\n */\r\nJXG.Image = function (board, coords, attributes, url, size) {\r\n    this.constructor(board, attributes, Const.OBJECT_TYPE_IMAGE, Const.OBJECT_CLASS_OTHER);\r\n    this.element = this.board.select(attributes.anchor);\r\n    this.coordsConstructor(coords);\r\n\r\n    this.W = Type.createFunction(size[0], this.board, \"\");\r\n    this.H = Type.createFunction(size[1], this.board, \"\");\r\n    this.addParentsFromJCFunctions([this.W, this.H]);\r\n\r\n    this.usrSize = [this.W(), this.H()];\r\n\r\n    /**\r\n     * Array of length two containing [width, height] of the image in pixel.\r\n     * @type array\r\n     */\r\n    this.size = [\r\n        Math.abs(this.usrSize[0] * board.unitX),\r\n        Math.abs(this.usrSize[1] * board.unitY)\r\n    ];\r\n\r\n    /**\r\n     * 'href' of the image. This might be an URL, but also a data-uri is allowed.\r\n     * @type string\r\n     */\r\n    this.url = url;\r\n\r\n    this.elType = 'image';\r\n\r\n    // span contains the anchor point and the two vectors\r\n    // spanning the image rectangle.\r\n    this.span = [\r\n        this.coords.usrCoords.slice(0),\r\n        [this.coords.usrCoords[0], this.W(), 0],\r\n        [this.coords.usrCoords[0], 0, this.H()]\r\n    ];\r\n\r\n    //this.parent = board.select(attributes.anchor);\r\n    this.id = this.board.setId(this, 'Im');\r\n\r\n    this.board.renderer.drawImage(this);\r\n    this.board.finalizeAdding(this);\r\n\r\n    this.methodMap = JXG.deepCopy(this.methodMap, {\r\n        addTransformation: \"addTransform\",\r\n        trans: \"addTransform\",\r\n        W: \"W\",\r\n        Width: \"W\",\r\n        H: \"H\",\r\n        Height: \"H\",\r\n        setSize: \"setSize\"\r\n    });\r\n};\r\n\r\nJXG.Image.prototype = new GeometryElement();\r\nType.copyPrototypeMethods(JXG.Image, CoordsElement, 'coordsConstructor');\r\n\r\nJXG.extend(\r\n    JXG.Image.prototype,\r\n    /** @lends JXG.Image.prototype */ {\r\n        /**\r\n         * Checks whether (x,y) is over or near the image;\r\n         * @param {Number} x Coordinate in x direction, screen coordinates.\r\n         * @param {Number} y Coordinate in y direction, screen coordinates.\r\n         * @returns {Boolean} True if (x,y) is over the image, False otherwise.\r\n         */\r\n        hasPoint: function (x, y) {\r\n            var dx,\r\n                dy,\r\n                r,\r\n                type,\r\n                prec,\r\n                c,\r\n                v,\r\n                p,\r\n                dot,\r\n                len = this.transformations.length;\r\n\r\n            if (Type.isObject(this.evalVisProp('precision'))) {\r\n                type = this.board._inputDevice;\r\n                prec = this.evalVisProp('precision.' + type);\r\n            } else {\r\n                // 'inherit'\r\n                prec = this.board.options.precision.hasPoint;\r\n            }\r\n\r\n            // Easy case: no transformation\r\n            if (len === 0) {\r\n                dx = x - this.coords.scrCoords[1];\r\n                dy = this.coords.scrCoords[2] - y;\r\n                r = prec;\r\n\r\n                return dx >= -r && dx - this.size[0] <= r && dy >= -r && dy - this.size[1] <= r;\r\n            }\r\n\r\n            // Image is transformed\r\n            c = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board);\r\n            // v is the vector from anchor point to the drag point\r\n            c = c.usrCoords;\r\n            v = [c[0] - this.span[0][0], c[1] - this.span[0][1], c[2] - this.span[0][2]];\r\n            dot = Mat.innerProduct; // shortcut\r\n\r\n            // Project the drag point to the sides.\r\n            p = dot(v, this.span[1]);\r\n            if (0 <= p && p <= dot(this.span[1], this.span[1])) {\r\n                p = dot(v, this.span[2]);\r\n\r\n                if (0 <= p && p <= dot(this.span[2], this.span[2])) {\r\n                    return true;\r\n                }\r\n            }\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Recalculate the coordinates of lower left corner and the width and height.\r\n         *\r\n         * @returns {JXG.GeometryElement} A reference to the element\r\n         * @private\r\n         */\r\n        update: function (fromParent) {\r\n            if (!this.needsUpdate) {\r\n                return this;\r\n            }\r\n\r\n            this.updateCoords(fromParent);\r\n            this.updateSize();\r\n            this.updateSpan();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Send an update request to the renderer.\r\n         * @private\r\n         */\r\n        updateRenderer: function () {\r\n            return this.updateRendererGeneric('updateImage');\r\n        },\r\n\r\n        /**\r\n         * Updates the internal arrays containing size of the image.\r\n         * @returns {JXG.GeometryElement} A reference to the element\r\n         * @private\r\n         */\r\n        updateSize: function () {\r\n            this.usrSize = [this.W(), this.H()];\r\n            this.size = [\r\n                Math.abs(this.usrSize[0] * this.board.unitX),\r\n                Math.abs(this.usrSize[1] * this.board.unitY)\r\n            ];\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Update the anchor point of the image, i.e. the lower left corner\r\n         * and the two vectors which span the rectangle.\r\n         * @returns {JXG.GeometryElement} A reference to the element\r\n         * @private\r\n         *\r\n         */\r\n        updateSpan: function () {\r\n            var i, j,\r\n                len = this.transformations.length,\r\n                v = [];\r\n\r\n            if (len === 0) {\r\n                this.span = [\r\n                    [this.Z(), this.X(), this.Y()],\r\n                    [this.Z(), this.W(), 0],\r\n                    [this.Z(), 0, this.H()]\r\n                ];\r\n            } else {\r\n                // v contains the three defining corners of the rectangle/image\r\n                v[0] = [this.Z(), this.X(), this.Y()];\r\n                v[1] = [this.Z(), this.X() + this.W(), this.Y()];\r\n                v[2] = [this.Z(), this.X(), this.Y() + this.H()];\r\n                // Transform the three corners\r\n                for (i = 0; i < len; i++) {\r\n                    for (j = 0; j < 3; j++) {\r\n                        v[j] = Mat.matVecMult(this.transformations[i].matrix, v[j]);\r\n                    }\r\n                }\r\n                // Normalize the vectors\r\n                for (j = 0; j < 3; j++) {\r\n                    v[j][1] /= v[j][0];\r\n                    v[j][2] /= v[j][0];\r\n                    v[j][0] /= v[j][0];\r\n                }\r\n                // Compute the two vectors spanning the rectangle\r\n                // by subtracting the anchor point.\r\n                for (j = 1; j < 3; j++) {\r\n                    v[j][0] -= v[0][0];\r\n                    v[j][1] -= v[0][1];\r\n                    v[j][2] -= v[0][2];\r\n                }\r\n                this.span = v;\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        addTransform: function (transform) {\r\n            var i;\r\n\r\n            if (Type.isArray(transform)) {\r\n                for (i = 0; i < transform.length; i++) {\r\n                    this.transformations.push(transform[i]);\r\n                }\r\n            } else {\r\n                this.transformations.push(transform);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        // Documented in element.js\r\n        getParents: function () {\r\n            var p = [this.url, [this.Z(), this.X(), this.Y()], this.usrSize];\r\n\r\n            if (this.parents.length !== 0) {\r\n                p = this.parents;\r\n            }\r\n\r\n            return p;\r\n        },\r\n\r\n        /**\r\n         * Set the width and height of the image. After setting a new size,\r\n         * board.update() or image.fullUpdate()\r\n         * has to be called to make the change visible.\r\n         * @param  {number|function|string} width  Number, function or string\r\n         *                            that determines the new width of the image\r\n         * @param  {number|function|string} height Number, function or string\r\n         *                            that determines the new height of the image\r\n         * @returns {JXG.GeometryElement} A reference to the element\r\n         *\r\n         * @example\r\n         * var im = board.create('image', ['https://jsxgraph.org/distrib/images/uccellino.jpg',\r\n         *                                [-3,-2], [3,3]]);\r\n         * im.setSize(4, 4);\r\n         * board.update();\r\n         *\r\n         * </pre><div id=\"JXG8411e60c-f009-11e5-b1bf-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG8411e60c-f009-11e5-b1bf-901b0e1b8723',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var im = board.create('image', ['https://jsxgraph.org/distrib/images/uccellino.jpg', [-3,-2],    [3,3]]);\r\n         *     //im.setSize(4, 4);\r\n         *     //board.update();\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         * var p0 = board.create('point', [-3, -2]),\r\n         *     im = board.create('image', ['https://jsxgraph.org/distrib/images/uccellino.jpg',\r\n         *                     [function(){ return p0.X(); }, function(){ return p0.Y(); }],\r\n         *                     [3,3]]),\r\n         *     p1 = board.create('point', [1, 2]);\r\n         *\r\n         * im.setSize(function(){ return p1.X() - p0.X(); }, function(){ return p1.Y() - p0.Y(); });\r\n         * board.update();\r\n         *\r\n         * </pre><div id=\"JXG4ce706c0-f00a-11e5-b1bf-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG4ce706c0-f00a-11e5-b1bf-901b0e1b8723',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n         *     var p0 = board.create('point', [-3, -2]),\r\n         *         im = board.create('image', ['https://jsxgraph.org/distrib/images/uccellino.jpg',\r\n         *                         [function(){ return p0.X(); }, function(){ return p0.Y(); }],\r\n         *                         [3,3]]),\r\n         *         p1 = board.create('point', [1, 2]);\r\n         *\r\n         *     im.setSize(function(){ return p1.X() - p0.X(); }, function(){ return p1.Y() - p0.Y(); });\r\n         *     board.update();\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        setSize: function (width, height) {\r\n            this.W = Type.createFunction(width, this.board, \"\");\r\n            this.H = Type.createFunction(height, this.board, \"\");\r\n            this.addParentsFromJCFunctions([this.W, this.H]);\r\n            // this.fullUpdate();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Returns the width of the image in user coordinates.\r\n         * @returns {number} width of the image in user coordinates\r\n         */\r\n        W: function () {}, // Needed for docs, defined in constructor\r\n\r\n        /**\r\n         * Returns the height of the image in user coordinates.\r\n         * @returns {number} height of the image in user coordinates\r\n         */\r\n        H: function () {} // Needed for docs, defined in constructor\r\n    }\r\n);\r\n\r\n/**\r\n * @class Display of an external image.\r\n * @pseudo\r\n * @name Image\r\n * @type JXG.Image\r\n * @augments JXG.Image\r\n * @constructor\r\n * @constructor\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {string,function_Array_Array} url,coords,size url defines the location of the image data. The array coords contains the user coordinates\r\n * of the lower left corner of the image.\r\n *   It can consist of two or three elements of type number, a string containing a GEONE<sub>x</sub>T\r\n *   constraint, or a function which takes no parameter and returns a number. Every element determines one coordinate. If a coordinate is\r\n *   given by a number, the number determines the initial position of a free image. If given by a string or a function that coordinate will be constrained\r\n *   that means the user won't be able to change the image's position directly by mouse because it will be calculated automatically depending on the string\r\n *   or the function's return value. If two parent elements are given the coordinates will be interpreted as 2D affine Euclidean coordinates, if three such\r\n *   parent elements are given they will be interpreted as homogeneous coordinates.\r\n * <p>\r\n * The array size defines the image's width and height in user coordinates.\r\n * @example\r\n * var im = board.create('image', ['https://jsxgraph.org/jsxgraph/distrib/images/uccellino.jpg', [-3,-2], [3,3]]);\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXG9850cda0-7ea0-4750-981c-68bacf9cca57\" style=\"width: 400px; height: 400px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var image_board = JXG.JSXGraph.initBoard('JXG9850cda0-7ea0-4750-981c-68bacf9cca57', {boundingbox: [-4, 4, 4, -4], axis: true, showcopyright: false, shownavigation: false});\r\n *   var image_im = image_board.create('image', ['https://jsxgraph.org/distrib/images/uccellino.jpg', [-3,-2],[3,3]]);\r\n * </script><pre>\r\n */\r\nJXG.createImage = function (board, parents, attributes) {\r\n    var attr,\r\n        im,\r\n        url = parents[0],\r\n        coords = parents[1],\r\n        size = parents[2];\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'image');\r\n    im = CoordsElement.create(JXG.Image, board, coords, attr, url, size);\r\n    if (!im) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create image with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [x,y], [z,x,y], [element,transformation]\"\r\n        );\r\n    }\r\n\r\n    if (attr.rotate !== 0) {\r\n        // This is the default value, i.e. no rotation\r\n        im.addRotation(attr.rotate);\r\n    }\r\n\r\n    return im;\r\n};\r\n\r\nJXG.registerElement(\"image\", JXG.createImage);\r\n\r\nexport default JXG.Image;\r\n// export default {\r\n//     Image: JXG.Image,\r\n//     createImage: JXG.createImage\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview The geometry object slider is defined in this file. Slider stores all\r\n * style and functional properties that are required to draw and use a slider on\r\n * a board.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Coords from \"../base/coords.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Point from \"../base/point.js\";\r\n\r\n/**\r\n * @class A slider can be used to choose values from a given range of numbers.\r\n * @pseudo\r\n * @name Slider\r\n * @augments Glider\r\n * @constructor\r\n * @type JXG.Point\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Array_Array_Array} start,end,range The first two arrays give the start and the end where the slider is drawn\r\n * on the board. The third array gives the start and the end of the range the slider operates as the first resp. the\r\n * third component of the array. The second component of the third array gives its start value.\r\n *\r\n * @example\r\n * // Create a slider with values between 1 and 10, initial position is 5.\r\n * var s = board.create('slider', [[1, 2], [3, 2], [1, 5, 10]]);\r\n * </pre><div class=\"jxgbox\" id=\"JXGcfb51cde-2603-4f18-9cc4-1afb452b374d\" style=\"width: 200px; height: 200px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   (function () {\r\n *     var board = JXG.JSXGraph.initBoard('JXGcfb51cde-2603-4f18-9cc4-1afb452b374d', {boundingbox: [-1, 5, 5, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *     var s = board.create('slider', [[1, 2], [3, 2], [1, 5, 10]]);\r\n *   })();\r\n * </script><pre>\r\n * @example\r\n * // Create a slider taking integer values between 1 and 5. Initial value is 3.\r\n * var s = board.create('slider', [[1, 3], [3, 1], [0, 3, 5]], {\r\n *     snapWidth: 1,\r\n *     minTicksDistance: 60,\r\n *     drawLabels: false\r\n * });\r\n * </pre><div class=\"jxgbox\" id=\"JXGe17128e6-a25d-462a-9074-49460b0d66f4\" style=\"width: 200px; height: 200px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   (function () {\r\n *     var board = JXG.JSXGraph.initBoard('JXGe17128e6-a25d-462a-9074-49460b0d66f4', {boundingbox: [-1, 5, 5, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *     var s = board.create('slider', [[1, 3], [3, 1], [1, 3, 5]], {\r\n *       snapWidth: 1,\r\n *       minTicksDistance: 60,\r\n *       drawLabels: false\r\n *     });\r\n *   })();\r\n * </script><pre>\r\n * @example\r\n *     // Draggable slider\r\n *     var s1 = board.create('slider', [[-3, 1], [2, 1],[-10, 1, 10]], {\r\n *         visible: true,\r\n *         snapWidth: 2,\r\n *         point1: {fixed: false},\r\n *         point2: {fixed: false},\r\n *         baseline: {fixed: false, needsRegularUpdate: true}\r\n *     });\r\n *\r\n * </pre><div id=\"JXGbfc67817-2827-44a1-bc22-40bf312e76f8\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGbfc67817-2827-44a1-bc22-40bf312e76f8',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *         var s1 = board.create('slider', [[-3,1], [2,1],[-10,1,10]], {\r\n *             visible: true,\r\n *             snapWidth: 2,\r\n *             point1: {fixed: false},\r\n *             point2: {fixed: false},\r\n *             baseline: {fixed: false, needsRegularUpdate: true}\r\n *         });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *     // Set the slider by clicking on the base line: attribute 'moveOnUp'\r\n *     var s1 = board.create('slider', [[-3,1], [2,1],[-10,1,10]], {\r\n *         snapWidth: 2,\r\n *         moveOnUp: true // default value\r\n *     });\r\n *\r\n * </pre><div id=\"JXGc0477c8a-b1a7-4111-992e-4ceb366fbccc\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGc0477c8a-b1a7-4111-992e-4ceb366fbccc',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *         var s1 = board.create('slider', [[-3,1], [2,1],[-10,1,10]], {\r\n *             snapWidth: 2,\r\n *             moveOnUp: true // default value\r\n *         });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Set colors\r\n * var sl = board.create('slider', [[-3, 1], [1, 1], [-10, 1, 10]], {\r\n *\r\n *   baseline: { strokeColor: 'blue'},\r\n *   highline: { strokeColor: 'red'},\r\n *   fillColor: 'yellow',\r\n *   label: {fontSize: 24, strokeColor: 'orange'},\r\n *   name: 'xyz', // Not shown, if suffixLabel is set\r\n *   suffixLabel: 'x = ',\r\n *   postLabel: ' u'\r\n *\r\n * });\r\n *\r\n * </pre><div id=\"JXGd96c9e2c-2c25-4131-b6cf-9dbb80819401\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGd96c9e2c-2c25-4131-b6cf-9dbb80819401',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var sl = board.create('slider', [[-3, 1], [1, 1], [-10, 1, 10]], {\r\n *\r\n *       baseline: { strokeColor: 'blue'},\r\n *       highline: { strokeColor: 'red'},\r\n *       fillColor: 'yellow',\r\n *       label: {fontSize: 24, strokeColor: 'orange'},\r\n *       name: 'xyz', // Not shown, if suffixLabel is set\r\n *       suffixLabel: 'x = ',\r\n *       postLabel: ' u'\r\n *\r\n *     });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Create a \"frozen\" slider\r\n * var sli = board.create('slider', [[-4, 4], [-1.5, 4], [-10, 1, 10]], {\r\n *     name:'a',\r\n *     frozen: true\r\n * });\r\n *\r\n * </pre><div id=\"JXG23afea4f-2e91-4006-a505-2895033cf1fc\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG23afea4f-2e91-4006-a505-2895033cf1fc',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var sli = board.create('slider', [[-4, 4], [-1.5, 4], [-10, 1, 10]], {\r\n *         name:'a',\r\n *         frozen: true\r\n *     });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Use MathJax for slider label (don't forget to load MathJax)\r\n * var s = board.create('slider', [[-3, 2], [2, 2], [-10, 1, 10]], {\r\n *     name: 'A^{(2)}',\r\n *     suffixLabel: '\\\\(A^{(2)} = ',\r\n *     unitLabel: ' \\\\;km/h ',\r\n *     postLabel: '\\\\)',\r\n *     label: {useMathJax: true}\r\n * });\r\n *\r\n * </pre><div id=\"JXG76e78c5f-3598-4d44-b43f-1d78fd15302c\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script src=\"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js\" id=\"MathJax-script\"></script>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG76e78c5f-3598-4d44-b43f-1d78fd15302c',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     // Use MathJax for slider label (don't forget to load MathJax)\r\n *     var s = board.create('slider', [[-3,2], [2,2],[-10,1,10]], {\r\n *         name: 'A^{(2)}',\r\n *         suffixLabel: '\\\\(A^{(2)} = ',\r\n *         unitLabel: ' \\\\;km/h ',\r\n *         postLabel: '\\\\)',\r\n *         label: {useMathJax: true}\r\n *     });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n *\r\n */\r\nJXG.createSlider = function (board, parents, attributes) {\r\n    var pos0, pos1,\r\n        smin, start, smax, diff,\r\n        p1, p2, p3, l1, l2,\r\n        ticks, ti, t,\r\n        startx, starty,\r\n        withText, withTicks,\r\n        snapValues, snapValueDistance,\r\n        snapWidth, sw, s,\r\n        attr;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'slider');\r\n    withTicks = attr.withticks;\r\n    withText = attr.withlabel;\r\n    snapWidth = attr.snapwidth;\r\n    snapValues = attr.snapvalues;\r\n    snapValueDistance = attr.snapvaluedistance;\r\n\r\n    // Start point\r\n    p1 = board.create(\"point\", parents[0], attr.point1);\r\n\r\n    // End point\r\n    p2 = board.create(\"point\", parents[1], attr.point2);\r\n    //g = board.create('group', [p1, p2]);\r\n\r\n    // Base line\r\n    l1 = board.create(\"segment\", [p1, p2], attr.baseline);\r\n\r\n    // This is required for a correct projection of the glider onto the segment below\r\n    l1.updateStdform();\r\n\r\n    pos0 = p1.coords.usrCoords.slice(1);\r\n    pos1 = p2.coords.usrCoords.slice(1);\r\n    smin = parents[2][0];\r\n    start = parents[2][1];\r\n    smax = parents[2][2];\r\n    diff = smax - smin;\r\n\r\n    sw = Type.evaluate(snapWidth);\r\n    s = sw === -1 ?\r\n        start :\r\n        Math.round((start - smin)/ sw) * sw + smin;\r\n        // Math.round(start / sw) * sw;\r\n    startx = pos0[0] + ((pos1[0] - pos0[0]) * (s - smin)) / (smax - smin);\r\n    starty = pos0[1] + ((pos1[1] - pos0[1]) * (s - smin)) / (smax - smin);\r\n\r\n    // glider point\r\n    // attr = Type.copyAttributes(attributes, board.options, 'slider');\r\n    // overwrite this in any case; the sliders label is a special text element, not the gliders label.\r\n    // this will be set back to true after the text was created (and only if withlabel was true initially).\r\n    attr.withlabel = false;\r\n    // gliders set snapwidth=-1 by default (i.e. deactivate them)\r\n    p3 = board.create(\"glider\", [startx, starty, l1], attr);\r\n    p3.setAttribute({ snapwidth: snapWidth, snapvalues: snapValues, snapvaluedistance: snapValueDistance });\r\n\r\n    // Segment from start point to glider point: highline\r\n    // attr = Type.copyAttributes(attributes, board.options, \"slider\", 'highline');\r\n    l2 = board.create(\"segment\", [p1, p3], attr.highline);\r\n\r\n    /**\r\n     * Returns the current slider value.\r\n     * @memberOf Slider.prototype\r\n     * @name Value\r\n     * @function\r\n     * @returns {Number}\r\n     */\r\n    p3.Value = function () {\r\n        var d = this._smax - this._smin,\r\n            ev_sw = this.evalVisProp('snapwidth');\r\n\r\n        return ev_sw === -1\r\n            ? this.position * d + this._smin\r\n            : Math.round((this.position * d) / ev_sw) * ev_sw  + this._smin;\r\n    };\r\n\r\n    p3.methodMap = Type.deepCopy(p3.methodMap, {\r\n        Value: \"Value\",\r\n        setValue: \"setValue\",\r\n        smax: \"_smax\",\r\n        // Max: \"_smax\",\r\n        smin: \"_smin\",\r\n        // Min: \"_smin\",\r\n        setMax: \"setMax\",\r\n        setMin: \"setMin\",\r\n        point1: \"point1\",\r\n        point2: \"point2\",\r\n        baseline: \"baseline\",\r\n        highline: \"highline\",\r\n        ticks: \"ticks\",\r\n        label: \"label\"\r\n    });\r\n\r\n    /**\r\n     * End value of the slider range.\r\n     * @memberOf Slider.prototype\r\n     * @name _smax\r\n     * @type Number\r\n     */\r\n    p3._smax = smax;\r\n\r\n    /**\r\n     * Start value of the slider range.\r\n     * @memberOf Slider.prototype\r\n     * @name _smin\r\n     * @type Number\r\n     */\r\n    p3._smin = smin;\r\n\r\n    /**\r\n     * Sets the maximum value of the slider.\r\n     * @memberOf Slider.prototype\r\n     * @function\r\n     * @name setMax\r\n     * @param {Number} val New maximum value\r\n     * @returns {Object} this object\r\n     */\r\n    p3.setMax = function (val) {\r\n        this._smax = val;\r\n        return this;\r\n    };\r\n\r\n    /**\r\n     * Sets the value of the slider. This call must be followed\r\n     * by a board update call.\r\n     * @memberOf Slider.prototype\r\n     * @name setValue\r\n     * @function\r\n     * @param {Number} val New value\r\n     * @returns {Object} this object\r\n     */\r\n    p3.setValue = function (val) {\r\n        var d = this._smax - this._smin;\r\n\r\n        if (Math.abs(d) > Mat.eps) {\r\n            this.position = (val - this._smin) / d;\r\n        } else {\r\n            this.position = 0.0; //this._smin;\r\n        }\r\n        this.position = Math.max(0.0, Math.min(1.0, this.position));\r\n        return this;\r\n    };\r\n\r\n    /**\r\n     * Sets the minimum value of the slider.\r\n     * @memberOf Slider.prototype\r\n     * @name setMin\r\n     * @function\r\n     * @param {Number} val New minimum value\r\n     * @returns {Object} this object\r\n     */\r\n    p3.setMin = function (val) {\r\n        this._smin = val;\r\n        return this;\r\n    };\r\n\r\n    if (withText) {\r\n        // attr = Type.copyAttributes(attributes, board.options, 'slider', 'label');\r\n        t = board.create('text', [\r\n            function () {\r\n                return (p2.X() - p1.X()) * 0.05 + p2.X();\r\n            },\r\n            function () {\r\n                return (p2.Y() - p1.Y()) * 0.05 + p2.Y();\r\n            },\r\n            function () {\r\n                var n,\r\n                    d = p3.evalVisProp('digits'),\r\n                    sl = p3.evalVisProp('suffixlabel'),\r\n                    ul = p3.evalVisProp('unitlabel'),\r\n                    pl = p3.evalVisProp('postlabel');\r\n\r\n                if (d === 2 && p3.evalVisProp('precision') !== 2) {\r\n                    // Backwards compatibility\r\n                    d = p3.evalVisProp('precision');\r\n                }\r\n\r\n                if (sl !== null) {\r\n                    n = sl;\r\n                } else if (p3.name && p3.name !== \"\") {\r\n                    n = p3.name + \" = \";\r\n                } else {\r\n                    n = \"\";\r\n                }\r\n\r\n                if (p3.useLocale()) {\r\n                    n += p3.formatNumberLocale(p3.Value(), d);\r\n                } else {\r\n                    n += Type.toFixed(p3.Value(), d);\r\n                }\r\n\r\n                if (ul !== null) {\r\n                    n += ul;\r\n                }\r\n                if (pl !== null) {\r\n                    n += pl;\r\n                }\r\n\r\n                return n;\r\n            }\r\n        ],\r\n            attr.label\r\n        );\r\n\r\n        /**\r\n         * The text element to the right of the slider, indicating its current value.\r\n         * @memberOf Slider.prototype\r\n         * @name label\r\n         * @type JXG.Text\r\n         */\r\n        p3.label = t;\r\n\r\n        // reset the withlabel attribute\r\n        p3.visProp.withlabel = true;\r\n        p3.hasLabel = true;\r\n    }\r\n\r\n    /**\r\n     * Start point of the base line.\r\n     * @memberOf Slider.prototype\r\n     * @name point1\r\n     * @type JXG.Point\r\n     */\r\n    p3.point1 = p1;\r\n\r\n    /**\r\n     * End point of the base line.\r\n     * @memberOf Slider.prototype\r\n     * @name point2\r\n     * @type JXG.Point\r\n     */\r\n    p3.point2 = p2;\r\n\r\n    /**\r\n     * The baseline the glider is bound to.\r\n     * @memberOf Slider.prototype\r\n     * @name baseline\r\n     * @type JXG.Line\r\n     */\r\n    p3.baseline = l1;\r\n\r\n    /**\r\n     * A line on top of the baseline, indicating the slider's progress.\r\n     * @memberOf Slider.prototype\r\n     * @name highline\r\n     * @type JXG.Line\r\n     */\r\n    p3.highline = l2;\r\n\r\n    if (withTicks) {\r\n        // Function to generate correct label texts\r\n\r\n        // attr = Type.copyAttributes(attributes, board.options, \"slider\", 'ticks');\r\n        if (!Type.exists(attr.generatelabeltext)) {\r\n            attr.ticks.generateLabelText = function (tick, zero, value) {\r\n                var labelText,\r\n                    dFull = p3.point1.Dist(p3.point2),\r\n                    smin = p3._smin,\r\n                    smax = p3._smax,\r\n                    val = (this.getDistanceFromZero(zero, tick) * (smax - smin)) / dFull + smin;\r\n\r\n                if (dFull < Mat.eps || Math.abs(val) < Mat.eps) {\r\n                    // Point is zero\r\n                    labelText = '0';\r\n                } else {\r\n                    labelText = this.formatLabelText(val);\r\n                }\r\n                return labelText;\r\n            };\r\n        }\r\n        ticks = 2;\r\n        ti = board.create(\r\n            \"ticks\",\r\n            [\r\n                p3.baseline,\r\n                p3.point1.Dist(p1) / ticks,\r\n\r\n                function (tick) {\r\n                    var dFull = p3.point1.Dist(p3.point2),\r\n                        d = p3.point1.coords.distance(Const.COORDS_BY_USER, tick);\r\n\r\n                    if (dFull < Mat.eps) {\r\n                        return 0;\r\n                    }\r\n\r\n                    return (d / dFull) * diff + smin;\r\n                }\r\n            ],\r\n            attr.ticks\r\n        );\r\n\r\n        /**\r\n         * Ticks give a rough indication about the slider's current value.\r\n         * @memberOf Slider.prototype\r\n         * @name ticks\r\n         * @type JXG.Ticks\r\n         */\r\n        p3.ticks = ti;\r\n    }\r\n\r\n    // override the point's remove method to ensure the removal of all elements\r\n    p3.remove = function () {\r\n        if (withText) {\r\n            board.removeObject(t);\r\n        }\r\n\r\n        board.removeObject(l2);\r\n        board.removeObject(l1);\r\n        board.removeObject(p2);\r\n        board.removeObject(p1);\r\n\r\n        Point.prototype.remove.call(p3);\r\n    };\r\n\r\n    p1.dump = false;\r\n    p2.dump = false;\r\n    l1.dump = false;\r\n    l2.dump = false;\r\n    if (withText) {\r\n        t.dump = false;\r\n    }\r\n\r\n    // p3.type = Const.OBJECT_TYPE_SLIDER; // No! type has to be Const.OBJECT_TYPE_GLIDER\r\n    p3.elType = 'slider';\r\n    p3.parents = parents;\r\n    p3.subs = {\r\n        point1: p1,\r\n        point2: p2,\r\n        baseLine: l1,\r\n        highLine: l2\r\n    };\r\n    p3.inherits.push(p1, p2, l1, l2);\r\n    // Remove inherits to avoid circular inherits.\r\n    l1.inherits = [];\r\n    l2.inherits = [];\r\n\r\n    if (withTicks) {\r\n        ti.dump = false;\r\n        p3.subs.ticks = ti;\r\n        p3.inherits.push(ti);\r\n    }\r\n\r\n    p3.getParents = function () {\r\n        return [\r\n            this.point1.coords.usrCoords.slice(1),\r\n            this.point2.coords.usrCoords.slice(1),\r\n            [this._smin, this.position * (this._smax - this._smin) + this._smin, this._smax]\r\n        ];\r\n    };\r\n\r\n    p3.baseline.on(\"up\", function (evt) {\r\n        var pos, c;\r\n\r\n        if (p3.evalVisProp('moveonup') && !p3.evalVisProp('fixed')) {\r\n            pos = l1.board.getMousePosition(evt, 0);\r\n            c = new Coords(Const.COORDS_BY_SCREEN, pos, this.board);\r\n            p3.moveTo([c.usrCoords[1], c.usrCoords[2]]);\r\n            p3.triggerEventHandlers(['drag'], [evt]);\r\n        }\r\n    });\r\n\r\n    // This is necessary to show baseline, highline and ticks\r\n    // when opening the board in case the visible attributes are set\r\n    // to 'inherit'.\r\n    p3.prepareUpdate().update();\r\n    if (!board.isSuspendedUpdate) {\r\n        p3.updateVisibility().updateRenderer();\r\n        p3.baseline.prepareUpdate().updateVisibility().updateRenderer(); // prepareUpdate needed because needsRegularUpdate==false\r\n        p3.highline.updateVisibility().updateRenderer();\r\n        if (withTicks) {\r\n            p3.prepareUpdate().ticks.updateVisibility().updateRenderer();\r\n        }\r\n    }\r\n\r\n    return p3;\r\n};\r\n\r\nJXG.registerElement(\"slider\", JXG.createSlider);\r\n\r\n// export default {\r\n//     createSlider: JXG.createSlider\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/**\r\n * @fileoverview Simple prefix parser for measurements and expressions of measurements.\r\n * An expression is given as\r\n * <ul>\r\n * <li> array starting with an operator as first element, followed\r\n * by one or more operands,\r\n * <li> number.\r\n * </ul>\r\n * <p>\r\n * Possible operands are:\r\n * <ul>\r\n * <li> '+', '-', '*', '/'\r\n * </ul>\r\n *\r\n * @example\r\n *\r\n */\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Const from \"../base/constants.js\";\r\n\r\n/**\r\n * Prefix expression parser, i.e. a poor man's parser.\r\n * This is a simple prefix parser for measurements and expressions of measurements,\r\n * see {@link Measurement}.\r\n * An expression is given as\r\n * <ul>\r\n * <li> array starting with an operator as first element, followed\r\n * by one or more operands,\r\n * <li> number.\r\n * </ul>\r\n * <p>\r\n * Possible operators are:\r\n * <ul>\r\n * <li> '+', '-', '*', '/': binary operators\r\n * <li> 'Area', 'Radius', 'Value', 'V', 'L': arbitrary methods of JSXGraph elements, supplied as strings.\r\n * <li> 'exec': call a function\r\n * </ul>\r\n * <p>\r\n * Possible operands are:\r\n * <ul>\r\n * <li> numbers\r\n * <li> strings\r\n * <li> JSXGraph elements in case the operator is a method. Example: ['Area', circle] calls\r\n * the method circle.Area().\r\n * <li> prefix expressions (for binary operators)\r\n * <li> 'exec': call functions. Example: ['exec', 'sin', ['V', slider]] computes 'Math.sin(slider.Value())'.\r\n * As functions only functions in Math or JXG.Math are allowed.\r\n * </ul>\r\n * @namespace\r\n *\r\n * @example\r\n *   ['+', 100, 200]\r\n * @example\r\n * var p1 = board.create('point', [1, 1]);\r\n * var p2 = board.create('point', [1, 3]);\r\n * var seg = board.create('segment', [[-2,-3], [-2, 3]]);\r\n *\r\n * // Valid prefix expression: ['L', seg]\r\n *\r\n * @example\r\n * var p1 = board.create('point', [1, 1]);\r\n * var p2 = board.create('point', [1, 3]);\r\n * var seg = board.create('segment', [[-2,-3], [-2, 3]]);\r\n * var ci = board.create('circle', [p1, 7]);\r\n *\r\n * // Valid prefix expression:  ['+', ['Radius', ci], ['L', seg]]\r\n *\r\n * @example\r\n * var ang = board.create('angle', [[4, 0], [0, 0], [2, 2]]);\r\n * // Valid prefix expression:  ['V', ang, 'degrees']);\r\n */\r\nJXG.PrefixParser = {\r\n    /**\r\n     * Parse a prefix expression and apply an action.\r\n     * @param {array|number} term Expression\r\n     * @param {String} action Determines what to do. So far, the only\r\n     * action available is 'execute', which evaluates the expression.\r\n     * @returns {Number} What ever the action does.\r\n     */\r\n    parse: function (term, action) {\r\n        var method, i, le, res, fun, v;\r\n\r\n        if (Type.isNumber(term) || Type.isString(term)) {\r\n            return term;\r\n        }\r\n        if (!Type.isArray(term) || term.length < 2) {\r\n            throw new Error('prefixParser.parse: term is not an array, number or string');\r\n        }\r\n\r\n        method = term[0];\r\n        le = term.length;\r\n\r\n        if (action === 'execute') {\r\n            if (Type.isInArray(['+', '-', '*', '/'], method)) {\r\n\r\n                res = this.parse(term[1], action);\r\n                for (i = 2; i < le; i++) {\r\n                    v = this.parse(term[i], action);\r\n                    switch (method) {\r\n                        case '+':\r\n                            res += v;\r\n                            break;\r\n                        case '-':\r\n                            res -= v;\r\n                            break;\r\n                        case '*':\r\n                            res *= v;\r\n                            break;\r\n                        case '/':\r\n                            res /= v;\r\n                            break;\r\n                        default:\r\n                    }\r\n                }\r\n            } else if (method === 'exec') {\r\n                fun = term[1];\r\n                v = [];\r\n                for (i = 2; i < le; i++) {\r\n                    v.push(this.parse(term[i], action));\r\n                }\r\n                if (Type.exists(Math[fun])) {\r\n                    res = Math[fun].apply(this, v);\r\n                } else if (Type.exists(Mat[fun])) {\r\n                    res = Mat[fun].apply(this, v);\r\n                } else {\r\n                    throw new Error(\"PrefixParser.parse: \" + fun + \" is not allowed\");\r\n                }\r\n            } else {\r\n                fun = term[0];\r\n\r\n                // Allow shortcut 'V' for 'Value'\r\n                if (fun === 'V') {\r\n                    fun = 'Value';\r\n                }\r\n\r\n                // get coords always with z\r\n                // (its visibility is controlled by the attribute function formatCoords)\r\n                if (fun === 'Coords') {\r\n                    term[2] = 'true';\r\n                }\r\n\r\n                if (!Type.exists(term[1][fun])) {\r\n                    throw new Error(\"PrefixParser.parse: \" + fun + \" is not a method of \" + term[1]);\r\n                }\r\n                v = [];\r\n                for (i = 2; i < le; i++) {\r\n                    v.push(this.parse(term[i], action));\r\n                }\r\n                res = term[1][fun].apply(term[1], v);\r\n            }\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Determine the dimension of the resulting value, i.e. ['L', obj] as well as\r\n     * ['+', ['L', obj1], ['L', obj2]] have dimension 1.\r\n     * <p>\r\n     * ['+', ['Area', obj1], ['L', obj2]] will retrun NaN, because the two\r\n     * operands have conflicting dimensions.\r\n     * <p>\r\n     * If an element is a measurement element, then it's dimension can be set as attribute.\r\n     * This overrules the computed dimension.\r\n     *\r\n     * @param {Array|Number} term Prefix expression\r\n     * @returns Number\r\n     */\r\n    dimension: function (term) {\r\n        var method, i, le, res, fun, d, v, unit;\r\n\r\n        if (Type.isNumber(term)) {\r\n            return 0;\r\n        }\r\n        if (!Type.isArray(term) || term.length < 2) {\r\n            throw new Error('PrefixParser.dimension: term is not an array');\r\n        }\r\n\r\n        method = term[0];\r\n        le = term.length;\r\n\r\n        if (Type.isInArray(['+', '-', '*', '/'], method)) {\r\n\r\n            res = this.dimension(term[1]);\r\n            for (i = 2; i < le; i++) {\r\n                v = this.dimension(term[i]);\r\n                switch (method) {\r\n                    case '+':\r\n                        if (v !== res) {\r\n                            res = NaN;\r\n                        }\r\n                        break;\r\n                    case '-':\r\n                        if (v !== res) {\r\n                            res = NaN;\r\n                        }\r\n                        break;\r\n                    case '*':\r\n                        res += v;\r\n                        break;\r\n                    case '/':\r\n                        res -= v;\r\n                        break;\r\n                    default:\r\n                }\r\n            }\r\n\r\n        } else if (method === 'exec') {\r\n            if (term[2].type === Type.OBJECT_TYPE_MEASUREMENT) {\r\n                res = term[2].Dimension();\r\n                // If attribute \"dim\" is set, this overrules anything else.\r\n                if (Type.exists(term[2].visProp.dim)) {\r\n                    d = term[2].evalVisProp('dim');\r\n                    if (d !== null) {\r\n                        res = d;\r\n                    }\r\n                }\r\n            } else {\r\n                res = 0;\r\n            }\r\n        } else {\r\n            // Allow shortcut 'V' for 'Value'\r\n            fun = term[0];\r\n\r\n            switch (fun) {\r\n                case 'L':\r\n                case 'Length':\r\n                case 'Perimeter':\r\n                case 'Radius':\r\n                case 'R':\r\n                    res = 1;\r\n                    break;\r\n                case 'Area':\r\n                case 'A':\r\n                    res = 2;\r\n                    break;\r\n                default: // 'V', 'Value'\r\n                    if (term[1].type === Type.OBJECT_TYPE_MEASUREMENT) {\r\n                        res = term[1].Dimension();\r\n                        // If attribute \"dim\" is set, this overrules anything else.\r\n                        if (Type.exists(term[1].visProp.dim)) {\r\n                            d = term[1].evalVisProp('dim');\r\n                            if (d !== null) {\r\n                                res = d;\r\n                            }\r\n                        }\r\n                    } else {\r\n                        res = 0;\r\n\r\n                        if (fun === 'Value' || fun === 'V') {\r\n                            // The Value method of sector, angle and arc does not have the same dimension\r\n                            // for all units.\r\n                            if ([Const.OBJECT_TYPE_ARC, Const.OBJECT_TYPE_SECTOR, Const.OBJECT_TYPE_ANGLE].indexOf(term[1].type) >= 0) {\r\n                                unit = '';\r\n                                if (term.length === 3 && Type.isString(term[2])) {\r\n                                    unit = term[2].toLowerCase();\r\n                                }\r\n                                if (unit === '') {\r\n                                    // Default values:\r\n                                    if (term[1].type === Const.OBJECT_TYPE_ANGLE) {\r\n                                        // Default for angle.Value() is radians, i.e. dim 0\r\n                                        res = 0;\r\n                                    } else {\r\n                                        // Default for sector|arc.Value() is length, i.e. dim 1\r\n                                        res = 1;\r\n                                    }\r\n                                } else if (unit.indexOf('len') === 0) {\r\n                                    // Length has dim 1\r\n                                    res = 1;\r\n                                } else {\r\n                                    // Angles in various units has dimension 0\r\n                                    res = 0;\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n            }\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Convert a prefix expression into a new prefix expression in which\r\n     * JSXGraph elements have been replaced by their ids.\r\n     *\r\n     * @param {Array|Number} term\r\n     * @returns {Array|Number}\r\n     */\r\n    toPrefix: function (term) {\r\n        var method, i, le, res;\r\n\r\n        if (Type.isNumber(term)) {\r\n            return term;\r\n        }\r\n        if (!Type.isArray(term) || term.length < 2) {\r\n            throw new Error('PrefixParser.toPrefix: term is not an array');\r\n        }\r\n\r\n        method = term[0];\r\n        le = term.length;\r\n        res = [method];\r\n\r\n        for (i = 1; i < le; i++) {\r\n            if (Type.isInArray(['+', '-', '*', '/'], method)) {\r\n                res.push(this.toPrefix(term[i]));\r\n            } else {\r\n                if (method === 'V' && term[i].type === Type.OBJECT_TYPE_MEASUREMENT) {\r\n                    res = term[i].toPrefix();\r\n                } else if (method === 'exec') {\r\n                    if (i === 1) {\r\n                        res.push(term[i]);\r\n                    } else {\r\n                        res.push(this.toPrefix(term[i]));\r\n                    }\r\n                } else {\r\n                    res = [method, term[i].id];\r\n                }\r\n            }\r\n        }\r\n\r\n        return res;\r\n    },\r\n\r\n    /**\r\n     * Determine parent elements of a prefix expression.\r\n     * @param {Array|Number} term prefix expression\r\n     * @returns Array\r\n     * @private\r\n     */\r\n    getParents: function (term) {\r\n        var method, i, le, res;\r\n\r\n        if (Type.isNumber(term)) {\r\n            return [];\r\n        }\r\n        if (!Type.isArray(term) || term.length < 2) {\r\n            throw new Error('PrefixParser.getParents: term is not an array');\r\n        }\r\n\r\n        method = term[0];\r\n        le = term.length;\r\n        res = [];\r\n\r\n        for (i = 1; i < le; i++) {\r\n            if (Type.isInArray(['+', '-', '*', '/'], method)) {\r\n                Type.concat(res, this.getParents(term[i]));\r\n            } else {\r\n                if (method === 'V' && term[i].type === Type.OBJECT_TYPE_MEASUREMENT) {\r\n                    Type.concat(res, term[i].getParents());\r\n                } else if (method === 'exec') {\r\n                    if (i > 1) {\r\n                        Type.concat(res, this.getParents(term[i]));\r\n                    }\r\n                } else {\r\n                    res.push(term[i]);\r\n                }\r\n            }\r\n        }\r\n\r\n        return res;\r\n    }\r\n};\r\n\r\nexport default JXG.PrefixParser;","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview Geometry objects for measurements are defined in this file. This file stores all\r\n * style and functional properties that are required to use a tape measure on\r\n * a board.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport GeometryElement from \"../base/element.js\";\r\nimport Prefix from \"../parser/prefix.js\";\r\n\r\n/**\r\n * @class A tape measure can be used to measure distances between points.\r\n * <p>\r\n * The two defining points of the tape measure (which is a segment) do not inherit by default the attribute \"visible\" from\r\n * the segment. Otherwise the tape meassure would be inaccessible if the two points coincide and the segment is hidden.\r\n *\r\n * @pseudo\r\n * @name Tapemeasure\r\n * @augments Segment\r\n * @constructor\r\n * @type JXG.Segment\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Array_Array} start,end, The two arrays give the initial position where the tape measure\r\n * is drawn on the board.\r\n * @example\r\n * // Create a tape measure\r\n * var p1 = board.create('point', [0,0]);\r\n * var p2 = board.create('point', [1,1]);\r\n * var p3 = board.create('point', [3,1]);\r\n * var tape = board.create('tapemeasure', [[1, 2], [4, 2]], {name:'dist'});\r\n * </pre><div class=\"jxgbox\" id=\"JXG6d9a2cda-22fe-4cd1-9d94-34283b1bdc01\" style=\"width: 200px; height: 200px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   (function () {\r\n *     var board = JXG.JSXGraph.initBoard('JXG6d9a2cda-22fe-4cd1-9d94-34283b1bdc01', {boundingbox: [-1, 5, 5, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p1 = board.create('point', [0,0]);\r\n *     var p2 = board.create('point', [1,1]);\r\n *     var p3 = board.create('point', [3,1]);\r\n *     var tape = board.create('tapemeasure', [[1, 2], [4, 2]], {name:'dist'} );\r\n *   })();\r\n * </script><pre>\r\n */\r\nJXG.createTapemeasure = function (board, parents, attributes) {\r\n    var pos0, pos1, attr, withTicks, withText, digits, li, p1, p2, n, ti;\r\n\r\n    pos0 = parents[0];\r\n    pos1 = parents[1];\r\n\r\n    // start point\r\n    attr = Type.copyAttributes(attributes, board.options, \"tapemeasure\", 'point1');\r\n    p1 = board.create(\"point\", pos0, attr);\r\n\r\n    // end point\r\n    attr = Type.copyAttributes(attributes, board.options, \"tapemeasure\", 'point2');\r\n    p2 = board.create(\"point\", pos1, attr);\r\n\r\n    p1.setAttribute({ignoredSnapToPoints: [p2.id]});\r\n    p2.setAttribute({ignoredSnapToPoints: [p1.id]});\r\n\r\n    // tape measure line\r\n    attr = Type.copyAttributes(attributes, board.options, 'tapemeasure');\r\n    withTicks = attr.withticks;\r\n    withText = attr.withlabel;\r\n    digits = attr.digits;\r\n\r\n    if (digits === 2 && attr.precision !== 2) {\r\n        // Backward compatibility\r\n        digits = attr.precision;\r\n    }\r\n\r\n    // Below, we will replace the label by the measurement function.\r\n    if (withText) {\r\n        attr.withlabel = true;\r\n    }\r\n    li = board.create(\"segment\", [p1, p2], attr);\r\n    // p1, p2 are already added to li.inherits\r\n\r\n    if (withText) {\r\n        if (attributes.name && attributes.name !== \"\") {\r\n            n = attributes.name + \" = \";\r\n        } else {\r\n            n = \"\";\r\n        }\r\n        li.label.setText(function () {\r\n            var digits = li.label.evalVisProp('digits');\r\n\r\n            if (li.label.useLocale()) {\r\n                return n + li.label.formatNumberLocale(p1.Dist(p2), digits);\r\n            }\r\n            return n + Type.toFixed(p1.Dist(p2), digits);\r\n        });\r\n    }\r\n\r\n    if (withTicks) {\r\n        attr = Type.copyAttributes(attributes, board.options, \"tapemeasure\", 'ticks');\r\n        //ticks  = 2;\r\n        ti = board.create(\"ticks\", [li, 0.1], attr);\r\n        li.inherits.push(ti);\r\n    }\r\n\r\n    // override the segments's remove method to ensure the removal of all elements\r\n    /** @ignore */\r\n    li.remove = function () {\r\n        if (withTicks) {\r\n            li.removeTicks(ti);\r\n        }\r\n\r\n        board.removeObject(p2);\r\n        board.removeObject(p1);\r\n\r\n        GeometryElement.prototype.remove.call(this);\r\n    };\r\n\r\n    /**\r\n     * Returns the length of the tape measure.\r\n     * @name Value\r\n     * @memberOf Tapemeasure.prototype\r\n     * @function\r\n     * @returns {Number} length of tape measure.\r\n     */\r\n    li.Value = function () {\r\n        return p1.Dist(p2);\r\n    };\r\n\r\n    p1.dump = false;\r\n    p2.dump = false;\r\n\r\n    li.elType = 'tapemeasure';\r\n    li.getParents = function () {\r\n        return [\r\n            [p1.X(), p1.Y()],\r\n            [p2.X(), p2.Y()]\r\n        ];\r\n    };\r\n\r\n    li.subs = {\r\n        point1: p1,\r\n        point2: p2\r\n    };\r\n\r\n    if (withTicks) {\r\n        ti.dump = false;\r\n    }\r\n\r\n    li.methodMap = JXG.deepCopy(li.methodMap, {\r\n        Value: \"Value\"\r\n    });\r\n\r\n    li.prepareUpdate().update();\r\n    if (!board.isSuspendedUpdate) {\r\n        li.updateVisibility().updateRenderer();\r\n        // The point updates are necessary in case of snapToGrid==true\r\n        li.point1.updateVisibility().updateRenderer();\r\n        li.point2.updateVisibility().updateRenderer();\r\n    }\r\n\r\n    return li;\r\n};\r\n\r\nJXG.registerElement(\"tapemeasure\", JXG.createTapemeasure);\r\n\r\n/**\r\n * @class Display measurements of geometric elements and the arithmetic operations of measurements.\r\n * Under the hood this is a text element which has a method Value. The text to be displayed\r\n * is the result of the evaluation of a prefix expression, see {@link JXG.PrefixParser}.\r\n * <p>\r\n * The purpose of this element is to display values of measurements of geometric objects, like the radius of a circle,\r\n * as well as expressions consisting of measurements.\r\n *\r\n * @pseudo\r\n * @name Measurement\r\n * @augments Text\r\n * @constructor\r\n * @type JXG.Text\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Point|Array_Point|Array_Array} x,y,expression\r\n * Here, expression is a prefix expression, see {@link JXG.PrefixParser}.\r\n * @example\r\n * var p1 = board.create('point', [1, 1]);\r\n * var p2 = board.create('point', [1, 3]);\r\n * var ci1 = board.create('circle', [p1, p2]);\r\n *\r\n * var m1 = board.create('measurement', [1, -2, ['Area', ci1]], {\r\n *     visible: true,\r\n *     prefix: 'area: ',\r\n *     baseUnit: 'cm'\r\n * });\r\n *\r\n * var m2 = board.create('measurement', [1, -4, ['Radius', ci1]], {\r\n *     prefix: 'radius: ',\r\n *     baseUnit: 'cm'\r\n * });\r\n *\r\n * </pre><div id=\"JXG6359237a-79bc-4689-92fc-38d3ebeb769d\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG6359237a-79bc-4689-92fc-38d3ebeb769d',\r\n *             {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p1 = board.create('point', [1, 1]);\r\n *     var p2 = board.create('point', [1, 3]);\r\n *     var ci1 = board.create('circle', [p1, p2]);\r\n *\r\n *     var m1 = board.create('measurement', [1, -2, ['Area', ci1]], {\r\n *         visible: true,\r\n *         prefix: 'area: ',\r\n *         baseUnit: 'cm'\r\n *     });\r\n *\r\n *     var m2 = board.create('measurement', [1, -4, ['Radius', ci1]], {\r\n *         prefix: 'radius: ',\r\n *         baseUnit: 'cm'\r\n *     });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var p1 = board.create('point', [1, 1]);\r\n * var p2 = board.create('point', [1, 3]);\r\n * var ci1 = board.create('circle', [p1, p2]);\r\n * var seg = board.create('segment', [[-2,-3], [-2, 3]], { firstArrow: true, lastArrow: true});\r\n * var sli = board.create('slider', [[-4, 4], [-1.5, 4], [-10, 1, 10]], {name:'a'});\r\n *\r\n * var m1 = board.create('measurement', [-6, -2, ['Radius', ci1]], {\r\n *     prefix: 'm1: ',\r\n *     baseUnit: 'cm'\r\n * });\r\n *\r\n * var m2 = board.create('measurement', [-6, -4, ['L', seg]], {\r\n *     prefix: 'm2: ',\r\n *     baseUnit: 'cm'\r\n * });\r\n *\r\n * var m3 = board.create('measurement', [-6, -6, ['V', sli]], {\r\n *     prefix: 'm3: ',\r\n *     baseUnit: 'cm',\r\n *     dim: 1\r\n * });\r\n *\r\n * var m4 = board.create('measurement', [2, -6,\r\n *         ['+', ['V', m1], ['V', m2], ['V', m3]]\r\n *     ], {\r\n *     prefix: 'm4: ',\r\n *     baseUnit: 'cm'\r\n * });\r\n *\r\n * </pre><div id=\"JXG49903663-6450-401e-b0d9-f025a6677d4a\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG49903663-6450-401e-b0d9-f025a6677d4a',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p1 = board.create('point', [1, 1]);\r\n *     var p2 = board.create('point', [1, 3]);\r\n *     var ci1 = board.create('circle', [p1, p2]);\r\n *     var seg = board.create('segment', [[-2,-3], [-2, 3]], { firstArrow: true, lastArrow: true});\r\n *     var sli = board.create('slider', [[-4, 4], [-1.5, 4], [-10, 1, 10]], {name:'a'});\r\n *\r\n * var m1 = board.create('measurement', [-6, -2, ['Radius', ci1]], {\r\n *     prefix: 'm1: ',\r\n *     baseUnit: 'cm'\r\n * });\r\n *\r\n * var m2 = board.create('measurement', [-6, -4, ['L', seg]], {\r\n *     prefix: 'm2: ',\r\n *     baseUnit: 'cm'\r\n * });\r\n *\r\n * var m3 = board.create('measurement', [-6, -6, ['V', sli]], {\r\n *     prefix: 'm3: ',\r\n *     baseUnit: 'cm',\r\n *     dim: 1\r\n * });\r\n *\r\n * var m4 = board.create('measurement', [2, -6,\r\n *         ['+', ['V', m1], ['V', m2], ['V', m3]]\r\n *     ], {\r\n *     prefix: 'm4: ',\r\n *     baseUnit: 'cm'\r\n * });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createMeasurement = function (board, parents, attributes) {\r\n    var el, attr,\r\n        x, y, term,\r\n        i;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'measurement');\r\n\r\n    x = parents[0];\r\n    y = parents[1];\r\n    term = parents[2];\r\n\r\n    el = board.create(\"text\", [x, y, ''], attr);\r\n    el.type = Type.OBJECT_TYPE_MEASUREMENT;\r\n    el.elType = 'measurement';\r\n\r\n    el.Value = function () {\r\n        return Prefix.parse(term, 'execute');\r\n    };\r\n\r\n    el.Dimension = function () {\r\n        var d = el.evalVisProp('dim');\r\n\r\n        if (d !== null) {\r\n            return d;\r\n        }\r\n        return Prefix.dimension(term);\r\n    };\r\n\r\n    el.Unit = function (dimension) {\r\n        var unit = '',\r\n            units = el.evalVisProp('units'),\r\n            dim = dimension,\r\n            dims = {}, i;\r\n\r\n        if (!Type.exists(dim)) {\r\n            dim = el.Dimension();\r\n        }\r\n\r\n        if (Type.isArray(dimension)) {\r\n            for (i = 0; i < dimension.length; i++) {\r\n                dims['dim' + dimension[i]] = el.Unit(dimension[i]);\r\n            }\r\n            return dims;\r\n        }\r\n\r\n        if (Type.isObject(units) && Type.exists(units[dim]) && units[dim] !== false) {\r\n            unit = el.eval(units[dim]);\r\n        } else if (Type.isObject(units) && Type.exists(units['dim' + dim]) && units['dim' + dim] !== false) {\r\n            // In some cases, object keys must not be numbers. This allows key 'dim1' instead of '1'.\r\n            unit = el.eval(units['dim' + dim]);\r\n        } else {\r\n            unit = el.evalVisProp('baseunit');\r\n\r\n            if (dim === 0) {\r\n                unit = '';\r\n            } else if (dim > 1 && unit !== '') {\r\n                unit = unit + '^{' + dim + '}';\r\n            }\r\n        }\r\n\r\n        return unit;\r\n    };\r\n\r\n    el.getTerm = function () {\r\n        return term;\r\n    };\r\n\r\n    el.getMethod = function () {\r\n        var method = term[0];\r\n        if (method === 'V') {\r\n            method = 'Value';\r\n        }\r\n        return method;\r\n    };\r\n\r\n    el.toPrefix = function () {\r\n        return Prefix.toPrefix(term);\r\n    };\r\n\r\n    el.getParents = function () {\r\n        return Prefix.getParents(term);\r\n    };\r\n    el.addParents(el.getParents());\r\n    for (i = 0; i < el.parents.length; i++) {\r\n        board.select(el.parents[i]).addChild(el);\r\n    }\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    el.setText(function () {\r\n        var prefix = '',\r\n            suffix = '',\r\n            dim = el.Dimension(),\r\n            digits = el.evalVisProp('digits'),\r\n            unit = el.Unit(),\r\n            val = el.Value(),\r\n            i;\r\n\r\n        if (el.evalVisProp('showprefix')) {\r\n            prefix = el.evalVisProp('prefix');\r\n        }\r\n        if (el.evalVisProp('showsuffix')) {\r\n            suffix = el.evalVisProp('suffix');\r\n        }\r\n\r\n        if (Type.isNumber(val)) {\r\n            if (digits === 'none') {\r\n                // do nothing\r\n            } else if (digits === 'auto') {\r\n                if (el.useLocale()) {\r\n                    val = el.formatNumberLocale(val);\r\n                } else {\r\n                    val = Type.autoDigits(val);\r\n                }\r\n            } else {\r\n                if (el.useLocale()) {\r\n                    val = el.formatNumberLocale(val, digits);\r\n                } else {\r\n                    val = Type.toFixed(val, digits);\r\n                }\r\n            }\r\n        } else if (Type.isArray(val)) {\r\n            for (i = 0; i < val.length; i++) {\r\n                if (!Type.isNumber(val[i])) {\r\n                    continue;\r\n                }\r\n                if (digits === 'none') {\r\n                    // do nothing\r\n                } else if (digits === 'auto') {\r\n                    if (el.useLocale()) {\r\n                        val[i] = el.formatNumberLocale(val[i]);\r\n                    } else {\r\n                        val[i] = Type.autoDigits(val[i]);\r\n                    }\r\n                } else {\r\n                    if (el.useLocale()) {\r\n                        val[i] = el.formatNumberLocale(val[i], digits);\r\n                    } else {\r\n                        val[i] = Type.toFixed(val[i], digits);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (dim === 'coords' && Type.isArray(val)) {\r\n            if (val.length === 2) {\r\n                val.unshift(undefined);\r\n            }\r\n            val = el.visProp.formatcoords(el, val[1], val[2], val[0]);\r\n        }\r\n\r\n        if (dim === 'direction' && Type.isArray(val)) {\r\n            val = el.visProp.formatdirection(el, val[0], val[1]);\r\n        }\r\n\r\n        if (Type.isString(dim)) {\r\n            return prefix + val + suffix;\r\n        }\r\n\r\n        if (isNaN(dim)) {\r\n            return prefix + 'NaN' + suffix;\r\n        }\r\n\r\n        return prefix + val + unit + suffix;\r\n    });\r\n\r\n    el.methodMap = Type.deepCopy(el.methodMap, {\r\n        Value: \"Value\",\r\n        Dimension: \"Dimension\",\r\n        Unit: \"Unit\",\r\n        getTerm: \"getTerm\",\r\n        Term: \"getTerm\",\r\n        getMethod: \"getMethod\",\r\n        Method: \"getMethod\",\r\n        getParents: \"getParents\",\r\n        Parents: \"getParents\"\r\n    });\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"measurement\", JXG.createMeasurement);\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, document: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview The JXG.DataSource is a helper class for data organization. Currently supported data sources are\r\n * javascript arrays and HTML tables.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\nJXG.DataSource = function () {\r\n    this.data = [];\r\n    this.columnHeaders = [];\r\n    this.rowHeaders = [];\r\n\r\n    return this;\r\n};\r\n\r\nJXG.extend(\r\n    JXG.DataSource.prototype,\r\n    /** @lends JXG.DataSource.prototype */ {\r\n        loadFromArray: function (table, columnHeader, rowHeader) {\r\n            var i, j, cell;\r\n\r\n            if (Type.isArray(columnHeader)) {\r\n                this.columnHeaders = columnHeader;\r\n                columnHeader = false;\r\n            }\r\n\r\n            if (Type.isArray(rowHeader)) {\r\n                this.rowHeaders = rowHeader;\r\n                rowHeader = false;\r\n            }\r\n\r\n            this.data = [];\r\n\r\n            if (columnHeader) {\r\n                this.columnHeaders = [];\r\n            }\r\n\r\n            if (rowHeader) {\r\n                this.rowHeaders = [];\r\n            }\r\n\r\n            if (Type.exists(table)) {\r\n                // extract the data\r\n                this.data = [];\r\n\r\n                for (i = 0; i < table.length; i++) {\r\n                    this.data[i] = [];\r\n\r\n                    for (j = 0; j < table[i].length; j++) {\r\n                        cell = table[i][j];\r\n                        if (parseFloat(cell).toString() === cell) {\r\n                            this.data[i][j] = parseFloat(cell);\r\n                        } else if (cell !== \"-\") {\r\n                            this.data[i][j] = cell;\r\n                        } else {\r\n                            this.data[i][j] = NaN;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (columnHeader) {\r\n                    this.columnHeaders = this.data[0].slice(1);\r\n                    this.data = this.data.slice(1);\r\n                }\r\n\r\n                if (rowHeader) {\r\n                    this.rowHeaders = [];\r\n                    for (i = 0; i < this.data.length; i++) {\r\n                        this.rowHeaders.push(this.data[i][0]);\r\n                        this.data[i] = this.data[i].slice(1);\r\n                    }\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        loadFromTable: function (table, columnHeader, rowHeader) {\r\n            var row, i, j, col, cell;\r\n\r\n            if (Type.isArray(columnHeader)) {\r\n                this.columnHeaders = columnHeader;\r\n                columnHeader = false;\r\n            }\r\n\r\n            if (Type.isArray(rowHeader)) {\r\n                this.rowHeaders = rowHeader;\r\n                rowHeader = false;\r\n            }\r\n\r\n            this.data = [];\r\n\r\n            if (columnHeader) {\r\n                this.columnHeaders = [];\r\n            }\r\n\r\n            if (rowHeader) {\r\n                this.rowHeaders = [];\r\n            }\r\n\r\n            // to adjust: examples in examples folder & wiki\r\n            table = document.getElementById(table);\r\n\r\n            if (Type.exists(table)) {\r\n                // extract the data\r\n                row = table.getElementsByTagName('tr');\r\n                this.data = [];\r\n\r\n                for (i = 0; i < row.length; i++) {\r\n                    col = row[i].getElementsByTagName('td');\r\n                    this.data[i] = [];\r\n\r\n                    for (j = 0; j < col.length; j++) {\r\n                        cell = col[j].innerText;\r\n\r\n                        if (parseFloat(cell).toString() === cell) {\r\n                            this.data[i][j] = parseFloat(cell);\r\n                        } else if (cell !== \"-\") {\r\n                            this.data[i][j] = cell;\r\n                        } else {\r\n                            this.data[i][j] = NaN;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (columnHeader) {\r\n                    this.columnHeaders = this.data[0].slice(1);\r\n                    this.data = this.data.slice(1);\r\n                }\r\n\r\n                if (rowHeader) {\r\n                    this.rowHeaders = [];\r\n                    for (i = 0; i < this.data.length; i++) {\r\n                        this.rowHeaders.push(this.data[i][0]);\r\n                        this.data[i] = this.data[i].slice(1);\r\n                    }\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        addColumn: function (name, pos, data) {\r\n            throw new Error(\"not implemented\");\r\n        },\r\n\r\n        addRow: function (name, pos, data) {\r\n            throw new Error(\"not implemented\");\r\n        },\r\n\r\n        getColumn: function (col) {\r\n            var i,\r\n                result = [];\r\n\r\n            // get column index if column is given as column header title\r\n            if (Type.isString(col)) {\r\n                for (i = 0; i < this.columnHeaders.length; i++) {\r\n                    if (col === this.columnHeaders[i]) {\r\n                        col = i;\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n\r\n            // build column array\r\n            for (i = 0; i < this.data.length; i++) {\r\n                if (this.data[i].length > col) {\r\n                    result[i] = parseFloat(this.data[i][col]);\r\n                }\r\n            }\r\n\r\n            return result;\r\n        },\r\n\r\n        getRow: function (row) {\r\n            var result, i;\r\n\r\n            // get column index if column is given as column header title\r\n            if (Type.isString(row)) {\r\n                for (i = 0; i < this.rowHeaders.length; i++) {\r\n                    if (row === this.rowHeaders[i]) {\r\n                        row = i;\r\n                        break;\r\n                    }\r\n                }\r\n            }\r\n\r\n            // allocate memory for result array\r\n            result = [];\r\n\r\n            // build column array. result = this.data[row] is a flat copy and will\r\n            // destroy our local data copy, that's why we're copying it element wise.\r\n            for (i = 0; i < this.data[row].length; i++) {\r\n                result[i] = this.data[row][i];\r\n            }\r\n\r\n            return result;\r\n        }\r\n    }\r\n);\r\n\r\nexport default JXG.DataSource;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, document: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Numerics from \"../math/numerics.js\";\r\nimport Const from \"./constants.js\";\r\nimport Coords from \"./coords.js\";\r\nimport GeometryElement from \"./element.js\";\r\nimport DataSource from \"../parser/datasource.js\";\r\nimport Color from \"../utils/color.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Env from \"../utils/env.js\";\r\n// import Statistics from \"../math/statistics.js\";\r\n// import Curve from \"./curve.js\";\r\n// import Point from \"./point.js\";\r\n// import Text from \"./text.js\";\r\n// import Polygon from \"./polygon.js\";\r\n// import Sector from \"../element/sector.js\";\r\n// import Transform from \"./transformation.js\";\r\n// import Line from \"./line.js\";\r\n// import Circle from \"./circle.js\";\r\n\r\n/**\r\n *\r\n * The Chart class is a basic class for the chart object.\r\n * @class Creates a new basic chart object. Do not use this constructor to create a chart.\r\n * Use {@link JXG.Board#create} with type {@link Chart} instead.\r\n * @constructor\r\n * @augments JXG.GeometryElement\r\n * @param {String|JXG.Board} board The board the new chart is drawn on.\r\n * @param {Array} parent data arrays for the chart\r\n * @param {Object} attributes Javascript object containing attributes like name, id and colors.\r\n *\r\n */\r\nJXG.Chart = function (board, parents, attributes) {\r\n    this.constructor(board, attributes);\r\n\r\n    var x, y, i, c, style, len;\r\n\r\n    if (!Type.isArray(parents) || parents.length === 0) {\r\n        throw new Error(\"JSXGraph: Can't create a chart without data\");\r\n    }\r\n\r\n    /**\r\n     * Contains pointers to the various subelements of the chart.\r\n     */\r\n    this.elements = [];\r\n\r\n    if (Type.isNumber(parents[0])) {\r\n        // parents looks like [a,b,c,..]\r\n        // x has to be filled\r\n\r\n        y = parents;\r\n        x = [];\r\n        for (i = 0; i < y.length; i++) {\r\n            x[i] = i + 1;\r\n        }\r\n    } else if (parents.length === 1 && Type.isArray(parents[0])) {\r\n        // parents looks like [[a,b,c,..]]\r\n        // x has to be filled\r\n\r\n        y = parents[0];\r\n        x = [];\r\n\r\n        len = Type.evaluate(y).length;\r\n        for (i = 0; i < len; i++) {\r\n            x[i] = i + 1;\r\n        }\r\n    } else if (parents.length === 2) {\r\n        // parents looks like [[x0,x1,x2,...],[y1,y2,y3,...]]\r\n        len = Math.min(parents[0].length, parents[1].length);\r\n        x = parents[0].slice(0, len);\r\n        y = parents[1].slice(0, len);\r\n    }\r\n\r\n    if (Type.isArray(y) && y.length === 0) {\r\n        throw new Error(\"JSXGraph: Can't create charts without data.\");\r\n    }\r\n\r\n    // does this really need to be done here? this should be done in createChart and then\r\n    // there should be an extra chart for each chartstyle\r\n    style = attributes.chartstyle.replace(/ /g, \"\").split(\",\");\r\n    for (i = 0; i < style.length; i++) {\r\n        switch (style[i]) {\r\n            case \"bar\":\r\n                c = this.drawBar(board, x, y, attributes);\r\n                break;\r\n            case \"line\":\r\n                c = this.drawLine(board, x, y, attributes);\r\n                break;\r\n            case \"fit\":\r\n                c = this.drawFit(board, x, y, attributes);\r\n                break;\r\n            case \"spline\":\r\n                c = this.drawSpline(board, x, y, attributes);\r\n                break;\r\n            case \"pie\":\r\n                c = this.drawPie(board, y, attributes);\r\n                break;\r\n            case \"point\":\r\n                c = this.drawPoints(board, x, y, attributes);\r\n                break;\r\n            case \"radar\":\r\n                c = this.drawRadar(board, parents, attributes);\r\n                break;\r\n        }\r\n        this.elements.push(c);\r\n    }\r\n    this.id = this.board.setId(this, 'Chart');\r\n\r\n    return this.elements;\r\n};\r\n\r\nJXG.Chart.prototype = new GeometryElement();\r\n\r\nJXG.extend(\r\n    JXG.Chart.prototype,\r\n    /** @lends JXG.Chart.prototype */ {\r\n        /**\r\n         * Create line chart defined by two data arrays.\r\n         *\r\n         * @param  {String|JXG.Board} board      The board the chart is drawn on\r\n         * @param  {Array} x          Array of x-coordinates\r\n         * @param  {Array} y          Array of y-coordinates\r\n         * @param  {Object} attributes  Javascript object containing attributes like colors\r\n         * @returns {JXG.Curve}       JSXGraph curve\r\n         */\r\n        drawLine: function (board, x, y, attributes) {\r\n            // we don't want the line chart to be filled\r\n            attributes.fillcolor = 'none';\r\n            attributes.highlightfillcolor = 'none';\r\n\r\n            return board.create(\"curve\", [x, y], attributes);\r\n        },\r\n\r\n        /**\r\n         * Create line chart that consists of a natural spline curve\r\n         * defined by two data arrays.\r\n         *\r\n         * @param  {String|JXG.Board} board      The board the chart is drawn on\r\n         * @param  {Array} x          Array of x-coordinates\r\n         * @param  {Array} y          Array of y-coordinates\r\n         * @param  {Object} attributes Javascript object containing attributes like colors\r\n         * @returns {JXG.Curve}       JSXGraph (natural) spline curve\r\n         */\r\n        drawSpline: function (board, x, y, attributes) {\r\n            // we don't want the spline chart to be filled\r\n            attributes.fillColor = 'none';\r\n            attributes.highlightfillcolor = 'none';\r\n\r\n            return board.create(\"spline\", [x, y], attributes);\r\n        },\r\n\r\n        /**\r\n         * Create line chart where the curve is given by a regression polynomial\r\n         * defined by two data arrays. The degree of the polynomial is supplied\r\n         * through the attribute \"degree\" in attributes.\r\n         *\r\n         * @param  {String|JXG.Board} board      The board the chart is drawn on\r\n         * @param  {Array} x          Array of x-coordinates\r\n         * @param  {Array} y          Array of y-coordinates\r\n         * @param  {Object} attributes Javascript object containing attributes like colors\r\n         * @returns {JXG.Curve}    JSXGraph function graph object\r\n         */\r\n        drawFit: function (board, x, y, attributes) {\r\n            var deg = attributes.degree;\r\n\r\n            deg = Math.max(parseInt(deg, 10), 1) || 1;\r\n\r\n            // never fill\r\n            attributes.fillcolor = 'none';\r\n            attributes.highlightfillcolor = 'none';\r\n\r\n            return board.create(\r\n                \"functiongraph\",\r\n                [Numerics.regressionPolynomial(deg, x, y)],\r\n                attributes\r\n            );\r\n        },\r\n\r\n        /**\r\n         * Create bar chart defined by two data arrays.\r\n         * Attributes to change the layout of the bar chart are:\r\n         * <ul>\r\n         * <li> width (optional)\r\n         * <li> dir: 'horizontal' or 'vertical'\r\n         * <li> colors: array of colors\r\n         * <li> labels: array of labels\r\n         * </ul>\r\n         *\r\n         * @param  {String|JXG.Board} board      The board the chart is drawn on\r\n         * @param  {Array} x          Array of x-coordinates\r\n         * @param  {Array} y          Array of y-coordinates\r\n         * @param  {Object} attributes Javascript object containing attributes like colors\r\n         * @returns {Array}    Array of JXG polygons defining the bars\r\n         */\r\n        drawBar: function (board, x, y, attributes) {\r\n            var i, text, w,\r\n                xp0, xp1, xp2, yp,\r\n                colors,\r\n                pols = [],\r\n                p = [],\r\n                attr,\r\n                attrSub,\r\n                makeXpFun = function (i, f) {\r\n                    return function () {\r\n                        return x[i]() - f * w;\r\n                    };\r\n                },\r\n                hiddenPoint = {\r\n                    fixed: true,\r\n                    withLabel: false,\r\n                    visible: false,\r\n                    name: \"\"\r\n                };\r\n\r\n            attr = Type.copyAttributes(attributes, board.options, 'chart');\r\n\r\n            // Determine the width of the bars\r\n            if (attr && attr.width) {\r\n                // width given\r\n                w = attr.width;\r\n            } else {\r\n                if (x.length <= 1) {\r\n                    w = 1;\r\n                } else {\r\n                    // Find minimum distance between to bars.\r\n                    w = x[1] - x[0];\r\n                    for (i = 1; i < x.length - 1; i++) {\r\n                        w = x[i + 1] - x[i] < w ? x[i + 1] - x[i] : w;\r\n                    }\r\n                }\r\n                w *= 0.8;\r\n            }\r\n\r\n            attrSub = Type.copyAttributes(attributes, board.options, \"chart\", 'label');\r\n\r\n            for (i = 0; i < x.length; i++) {\r\n                if (Type.isFunction(x[i])) {\r\n                    xp0 = makeXpFun(i, -0.5);\r\n                    xp1 = makeXpFun(i, 0);\r\n                    xp2 = makeXpFun(i, 0.5);\r\n                } else {\r\n                    xp0 = x[i] - w * 0.5;\r\n                    xp1 = x[i];\r\n                    xp2 = x[i] + w * 0.5;\r\n                }\r\n                if (Type.isFunction(y[i])) {\r\n                    yp = y[i]();\r\n                } else {\r\n                    yp = y[i];\r\n                }\r\n                yp = y[i];\r\n\r\n                if (attr.dir === 'horizontal') {\r\n                    // horizontal bars\r\n                    p[0] = board.create(\"point\", [0, xp0], hiddenPoint);\r\n                    p[1] = board.create(\"point\", [yp, xp0], hiddenPoint);\r\n                    p[2] = board.create(\"point\", [yp, xp2], hiddenPoint);\r\n                    p[3] = board.create(\"point\", [0, xp2], hiddenPoint);\r\n\r\n                    if (Type.exists(attr.labels) && Type.exists(attr.labels[i])) {\r\n                        attrSub.anchorX = function (self) {\r\n                            return self.X() >= 0 ? \"left\" : 'right';\r\n                        };\r\n                        attrSub.anchorY = 'middle';\r\n                        text = board.create(\"text\", [yp, xp1, attr.labels[i]], attrSub);\r\n                    }\r\n                } else {\r\n                    // vertical bars\r\n                    p[0] = board.create(\"point\", [xp0, 0], hiddenPoint);\r\n                    p[1] = board.create(\"point\", [xp0, yp], hiddenPoint);\r\n                    p[2] = board.create(\"point\", [xp2, yp], hiddenPoint);\r\n                    p[3] = board.create(\"point\", [xp2, 0], hiddenPoint);\r\n\r\n                    if (Type.exists(attr.labels) && Type.exists(attr.labels[i])) {\r\n                        attrSub.anchorX = 'middle';\r\n                        attrSub.anchorY = function (self) {\r\n                            return self.Y() >= 0 ? \"bottom\" : 'top';\r\n                        };\r\n                        text = board.create(\"text\", [xp1, yp, attr.labels[i]], attrSub);\r\n                    }\r\n                }\r\n\r\n                if (Type.isArray(attr.colors)) {\r\n                    colors = attr.colors;\r\n                    attr.fillcolor = colors[i % colors.length];\r\n                }\r\n\r\n                pols[i] = board.create(\"polygon\", p, attr);\r\n                if (Type.exists(attr.labels) && Type.exists(attr.labels[i])) {\r\n                    pols[i].text = text;\r\n                    pols[i].addChild(text);\r\n                }\r\n            }\r\n\r\n            return pols;\r\n        },\r\n\r\n        /**\r\n         * Create chart consisting of JSXGraph points.\r\n         * Attributes to change the layout of the point chart are:\r\n         * <ul>\r\n         * <li> fixed (Boolean)\r\n         * <li> infoboxArray (Array): Texts for the infobox\r\n         * </ul>\r\n         *\r\n         * @param  {String|JXG.Board} board      The board the chart is drawn on\r\n         * @param  {Array} x          Array of x-coordinates\r\n         * @param  {Array} y          Array of y-coordinates\r\n         * @param  {Object} attributes Javascript object containing attributes like colors\r\n         * @returns {Array} Array of JSXGraph points\r\n         */\r\n        drawPoints: function (board, x, y, attributes) {\r\n            var i,\r\n                points = [],\r\n                infoboxArray = attributes.infoboxarray;\r\n\r\n            attributes.fixed = true;\r\n            attributes.name = \"\";\r\n\r\n            for (i = 0; i < x.length; i++) {\r\n                attributes.infoboxtext = infoboxArray\r\n                    ? infoboxArray[i % infoboxArray.length]\r\n                    : false;\r\n                points[i] = board.create(\"point\", [x[i], y[i]], attributes);\r\n            }\r\n\r\n            return points;\r\n        },\r\n\r\n        /**\r\n         * Create pie chart.\r\n         * Attributes to change the layout of the pie chart are:\r\n         * <ul>\r\n         * <li> labels: array of labels\r\n         * <li> colors: (Array)\r\n         * <li> highlightColors (Array)\r\n         * <li> radius\r\n         * <li> center (coordinate array)\r\n         * <li> highlightOnSector (Boolean)\r\n         * </ul>\r\n         *\r\n         * @param  {String|JXG.Board} board      The board the chart is drawn on\r\n         * @param  {Array} y          Array of x-coordinates\r\n         * @param  {Object} attributes Javascript object containing attributes like colors\r\n         * @returns {Object}  with keys: \"{sectors, points, midpoint}\"\r\n         */\r\n        drawPie: function (board, y, attributes) {\r\n            var i,\r\n                center,\r\n                p = [],\r\n                sector = [],\r\n                // s = Statistics.sum(y),\r\n                colorArray = attributes.colors,\r\n                highlightColorArray = attributes.highlightcolors,\r\n                labelArray = attributes.labels,\r\n                r = attributes.radius || 4,\r\n                radius = r,\r\n                cent = attributes.center || [0, 0],\r\n                xc = cent[0],\r\n                yc = cent[1],\r\n                makeRadPointFun = function (j, fun, xc) {\r\n                    return function () {\r\n                        var s,\r\n                            i,\r\n                            rad,\r\n                            t = 0;\r\n\r\n                        for (i = 0; i <= j; i++) {\r\n                            t += parseFloat(Type.evaluate(y[i]));\r\n                        }\r\n\r\n                        s = t;\r\n                        for (i = j + 1; i < y.length; i++) {\r\n                            s += parseFloat(Type.evaluate(y[i]));\r\n                        }\r\n                        rad = s !== 0 ? (2 * Math.PI * t) / s : 0;\r\n\r\n                        return radius() * Math[fun](rad) + xc;\r\n                    };\r\n                },\r\n                highlightHandleLabel = function (f, s) {\r\n                    var dx = -this.point1.coords.usrCoords[1] + this.point2.coords.usrCoords[1],\r\n                        dy = -this.point1.coords.usrCoords[2] + this.point2.coords.usrCoords[2];\r\n\r\n                    if (Type.exists(this.label)) {\r\n                        this.label.rendNode.style.fontSize =\r\n                            s * this.label.evalVisProp('fontsize') + 'px';\r\n                        this.label.fullUpdate();\r\n                    }\r\n\r\n                    this.point2.coords = new Coords(\r\n                        Const.COORDS_BY_USER,\r\n                        [\r\n                            this.point1.coords.usrCoords[1] + dx * f,\r\n                            this.point1.coords.usrCoords[2] + dy * f\r\n                        ],\r\n                        this.board\r\n                    );\r\n                    this.fullUpdate();\r\n                },\r\n                highlightFun = function () {\r\n                    if (!this.highlighted) {\r\n                        this.highlighted = true;\r\n                        this.board.highlightedObjects[this.id] = this;\r\n                        this.board.renderer.highlight(this);\r\n\r\n                        highlightHandleLabel.call(this, 1.1, 2);\r\n                    }\r\n                },\r\n                noHighlightFun = function () {\r\n                    if (this.highlighted) {\r\n                        this.highlighted = false;\r\n                        this.board.renderer.noHighlight(this);\r\n\r\n                        highlightHandleLabel.call(this, 0.9090909, 1);\r\n                    }\r\n                },\r\n                hiddenPoint = {\r\n                    fixed: true,\r\n                    withLabel: false,\r\n                    visible: false,\r\n                    name: \"\"\r\n                };\r\n\r\n            if (!Type.isArray(labelArray)) {\r\n                labelArray = [];\r\n                for (i = 0; i < y.length; i++) {\r\n                    labelArray[i] = \"\";\r\n                }\r\n            }\r\n\r\n            if (!Type.isFunction(r)) {\r\n                radius = function () {\r\n                    return r;\r\n                };\r\n            }\r\n\r\n            attributes.highlightonsector = attributes.highlightonsector || false;\r\n            attributes.straightfirst = false;\r\n            attributes.straightlast = false;\r\n\r\n            center = board.create(\"point\", [xc, yc], hiddenPoint);\r\n            p[0] = board.create(\r\n                \"point\",\r\n                [\r\n                    function () {\r\n                        return radius() + xc;\r\n                    },\r\n                    function () {\r\n                        return yc;\r\n                    }\r\n                ],\r\n                hiddenPoint\r\n            );\r\n\r\n            for (i = 0; i < y.length; i++) {\r\n                p[i + 1] = board.create(\r\n                    \"point\",\r\n                    [makeRadPointFun(i, \"cos\", xc), makeRadPointFun(i, \"sin\", yc)],\r\n                    hiddenPoint\r\n                );\r\n\r\n                attributes.name = labelArray[i];\r\n                attributes.withlabel = attributes.name !== \"\";\r\n                attributes.fillcolor = colorArray && colorArray[i % colorArray.length];\r\n                attributes.labelcolor = colorArray && colorArray[i % colorArray.length];\r\n                attributes.highlightfillcolor =\r\n                    highlightColorArray && highlightColorArray[i % highlightColorArray.length];\r\n\r\n                sector[i] = board.create(\"sector\", [center, p[i], p[i + 1]], attributes);\r\n\r\n                if (attributes.highlightonsector) {\r\n                    // overwrite hasPoint so that the whole sector is used for highlighting\r\n                    sector[i].hasPoint = sector[i].hasPointSector;\r\n                }\r\n                if (attributes.highlightbysize) {\r\n                    sector[i].highlight = highlightFun;\r\n\r\n                    sector[i].noHighlight = noHighlightFun;\r\n                }\r\n            }\r\n\r\n            // Not enough! We need points, but this gives an error in setAttribute.\r\n            return { sectors: sector, points: p, midpoint: center };\r\n        },\r\n\r\n        /**\r\n         * Create radar chart.\r\n         * Attributes to change the layout of the pie chart are:\r\n         * <ul>\r\n         * <li> paramArray: labels for axes, [ paramx, paramy, paramz ]\r\n         * <li> startShiftRatio: 0 <= offset from chart center <=1\r\n         * <li> endShiftRatio:  0 <= offset from chart radius <=1\r\n         * <li> startShiftArray: Adjust offsets per each axis\r\n         * <li> endShiftArray: Adjust offsets per each axis\r\n         * <li> startArray: Values for inner circle. Default values: minimums\r\n         * <li> start: one value to overwrite all startArray values\r\n         * <li> endArray: Values for outer circle, maximums by default\r\n         * <li> end: one value to overwrite all endArray values\r\n         * <li> labelArray\r\n         * <li> polyStrokeWidth\r\n         * <li> colors\r\n         * <li> highlightcolors\r\n         * <li> labelArray: [ row1, row2, row3 ]\r\n         * <li> radius\r\n         * <li> legendPosition\r\n         * <li> showCircles\r\n         * <li> circleLabelArray\r\n         * <li> circleStrokeWidth\r\n         * </ul>\r\n         *\r\n         * @param  {String|JXG.Board} board      The board the chart is drawn on\r\n         * @param  {Array} parents    Array of coordinates, e.g. [[x1, y1, z1], [x2, y2, z2], [x3, y3, z3]]\r\n         * @param  {Object} attributes Javascript object containing attributes like colors\r\n         * @returns {Object} with keys \"{circles, lines, points, midpoint, polygons}\"\r\n         */\r\n        drawRadar: function (board, parents, attributes) {\r\n            var i,\r\n                j,\r\n                paramArray,\r\n                numofparams,\r\n                maxes,\r\n                mins,\r\n                la,\r\n                pdata,\r\n                ssa,\r\n                esa,\r\n                ssratio,\r\n                esratio,\r\n                sshifts,\r\n                eshifts,\r\n                starts,\r\n                ends,\r\n                labelArray,\r\n                colorArray,\r\n                // highlightColorArray,\r\n                radius,\r\n                myAtts,\r\n                cent,\r\n                xc,\r\n                yc,\r\n                center,\r\n                start_angle,\r\n                rad,\r\n                p,\r\n                line,\r\n                t,\r\n                xcoord,\r\n                ycoord,\r\n                polygons,\r\n                legend_position,\r\n                circles,\r\n                lxoff,\r\n                lyoff,\r\n                cla,\r\n                clabelArray,\r\n                ncircles,\r\n                pcircles,\r\n                angle,\r\n                dr,\r\n                sw,\r\n                data,\r\n                len = parents.length,\r\n                get_anchor = function () {\r\n                    var x1, x2, y1, y2,\r\n                        relCoords = this.evalVisProp('label.offset).slice(0');\r\n\r\n                    x1 = this.point1.X();\r\n                    x2 = this.point2.X();\r\n                    y1 = this.point1.Y();\r\n                    y2 = this.point2.Y();\r\n                    if (x2 < x1) {\r\n                        relCoords[0] = -relCoords[0];\r\n                    }\r\n\r\n                    if (y2 < y1) {\r\n                        relCoords[1] = -relCoords[1];\r\n                    }\r\n\r\n                    this.setLabelRelativeCoords(relCoords);\r\n\r\n                    return new Coords(\r\n                        Const.COORDS_BY_USER,\r\n                        [this.point2.X(), this.point2.Y()],\r\n                        this.board\r\n                    );\r\n                },\r\n                get_transform = function (angle, i) {\r\n                    var t, tscale, trot;\r\n\r\n                    t = board.create(\"transform\", [-(starts[i] - sshifts[i]), 0], {\r\n                        type: \"translate\"\r\n                    });\r\n                    tscale = board.create(\r\n                        \"transform\",\r\n                        [radius / (ends[i] + eshifts[i] - (starts[i] - sshifts[i])), 1],\r\n                        { type: \"scale\" }\r\n                    );\r\n                    t.melt(tscale);\r\n                    trot = board.create(\"transform\", [angle], { type: \"rotate\" });\r\n                    t.melt(trot);\r\n\r\n                    return t;\r\n                };\r\n\r\n            if (len <= 0) {\r\n                throw new Error(\"JSXGraph radar chart: no data\");\r\n            }\r\n            // labels for axes\r\n            paramArray = attributes.paramarray;\r\n            if (!Type.exists(paramArray)) {\r\n                throw new Error(\"JSXGraph radar chart: need paramArray attribute\");\r\n            }\r\n            numofparams = paramArray.length;\r\n            if (numofparams <= 1) {\r\n                throw new Error(\"JSXGraph radar chart: need more than one param in paramArray\");\r\n            }\r\n\r\n            for (i = 0; i < len; i++) {\r\n                if (numofparams !== parents[i].length) {\r\n                    throw new Error(\r\n                        \"JSXGraph radar chart: use data length equal to number of params (\" +\r\n                            parents[i].length +\r\n                            \" != \" +\r\n                            numofparams +\r\n                            \")\"\r\n                    );\r\n                }\r\n            }\r\n\r\n            maxes = [];\r\n            mins = [];\r\n\r\n            for (j = 0; j < numofparams; j++) {\r\n                maxes[j] = parents[0][j];\r\n                mins[j] = maxes[j];\r\n            }\r\n\r\n            for (i = 1; i < len; i++) {\r\n                for (j = 0; j < numofparams; j++) {\r\n                    if (parents[i][j] > maxes[j]) {\r\n                        maxes[j] = parents[i][j];\r\n                    }\r\n\r\n                    if (parents[i][j] < mins[j]) {\r\n                        mins[j] = parents[i][j];\r\n                    }\r\n                }\r\n            }\r\n\r\n            la = [];\r\n            pdata = [];\r\n\r\n            for (i = 0; i < len; i++) {\r\n                la[i] = \"\";\r\n                pdata[i] = [];\r\n            }\r\n\r\n            ssa = [];\r\n            esa = [];\r\n\r\n            // 0 <= Offset from chart center <=1\r\n            ssratio = attributes.startshiftratio || 0;\r\n            // 0 <= Offset from chart radius <=1\r\n            esratio = attributes.endshiftratio || 0;\r\n\r\n            for (i = 0; i < numofparams; i++) {\r\n                ssa[i] = (maxes[i] - mins[i]) * ssratio;\r\n                esa[i] = (maxes[i] - mins[i]) * esratio;\r\n            }\r\n\r\n            // Adjust offsets per each axis\r\n            sshifts = attributes.startshiftarray || ssa;\r\n            eshifts = attributes.endshiftarray || esa;\r\n            // Values for inner circle, minimums by default\r\n            starts = attributes.startarray || mins;\r\n\r\n            if (Type.exists(attributes.start)) {\r\n                for (i = 0; i < numofparams; i++) {\r\n                    starts[i] = attributes.start;\r\n                }\r\n            }\r\n\r\n            // Values for outer circle, maximums by default\r\n            ends = attributes.endarray || maxes;\r\n            if (Type.exists(attributes.end)) {\r\n                for (i = 0; i < numofparams; i++) {\r\n                    ends[i] = attributes.end;\r\n                }\r\n            }\r\n\r\n            if (sshifts.length !== numofparams) {\r\n                throw new Error(\r\n                    \"JSXGraph radar chart: start shifts length is not equal to number of parameters\"\r\n                );\r\n            }\r\n\r\n            if (eshifts.length !== numofparams) {\r\n                throw new Error(\r\n                    \"JSXGraph radar chart: end shifts length is not equal to number of parameters\"\r\n                );\r\n            }\r\n\r\n            if (starts.length !== numofparams) {\r\n                throw new Error(\r\n                    \"JSXGraph radar chart: starts length is not equal to number of parameters\"\r\n                );\r\n            }\r\n\r\n            if (ends.length !== numofparams) {\r\n                throw new Error(\r\n                    \"JSXGraph radar chart: snds length is not equal to number of parameters\"\r\n                );\r\n            }\r\n\r\n            // labels for legend\r\n            labelArray = attributes.labelarray || la;\r\n            colorArray = attributes.colors;\r\n            // highlightColorArray = attributes.highlightcolors;\r\n            radius = attributes.radius || 10;\r\n            sw = attributes.strokewidth || 1;\r\n\r\n            if (!Type.exists(attributes.highlightonsector)) {\r\n                attributes.highlightonsector = false;\r\n            }\r\n\r\n            myAtts = {\r\n                name: attributes.name,\r\n                id: attributes.id,\r\n                strokewidth: sw,\r\n                polystrokewidth: attributes.polystrokewidth || sw,\r\n                strokecolor: attributes.strokecolor || \"black\",\r\n                straightfirst: false,\r\n                straightlast: false,\r\n                fillcolor: attributes.fillColor || \"#FFFF88\",\r\n                fillopacity: attributes.fillOpacity || 0.4,\r\n                highlightfillcolor: attributes.highlightFillColor || \"#FF7400\",\r\n                highlightstrokecolor: attributes.highlightStrokeColor || \"black\",\r\n                gradient: attributes.gradient || \"none\"\r\n            };\r\n\r\n            cent = attributes.center || [0, 0];\r\n            xc = cent[0];\r\n            yc = cent[1];\r\n            center = board.create(\"point\", [xc, yc], {\r\n                name: \"\",\r\n                fixed: true,\r\n                withlabel: false,\r\n                visible: false\r\n            });\r\n            start_angle = Math.PI / 2 - Math.PI / numofparams;\r\n            start_angle = attributes.startangle || 0;\r\n            rad = start_angle;\r\n            p = [];\r\n            line = [];\r\n\r\n            for (i = 0; i < numofparams; i++) {\r\n                rad += (2 * Math.PI) / numofparams;\r\n                xcoord = radius * Math.cos(rad) + xc;\r\n                ycoord = radius * Math.sin(rad) + yc;\r\n\r\n                p[i] = board.create(\"point\", [xcoord, ycoord], {\r\n                    name: \"\",\r\n                    fixed: true,\r\n                    withlabel: false,\r\n                    visible: false\r\n                });\r\n                line[i] = board.create(\"line\", [center, p[i]], {\r\n                    name: paramArray[i],\r\n                    strokeColor: myAtts.strokecolor,\r\n                    strokeWidth: myAtts.strokewidth,\r\n                    strokeOpacity: 1.0,\r\n                    straightFirst: false,\r\n                    straightLast: false,\r\n                    withLabel: true,\r\n                    highlightStrokeColor: myAtts.highlightstrokecolor\r\n                });\r\n                line[i].getLabelAnchor = get_anchor;\r\n                t = get_transform(rad, i);\r\n\r\n                for (j = 0; j < parents.length; j++) {\r\n                    data = parents[j][i];\r\n                    pdata[j][i] = board.create(\"point\", [data, 0], {\r\n                        name: \"\",\r\n                        fixed: true,\r\n                        withlabel: false,\r\n                        visible: false\r\n                    });\r\n                    pdata[j][i].addTransform(pdata[j][i], t);\r\n                }\r\n            }\r\n\r\n            polygons = [];\r\n            for (i = 0; i < len; i++) {\r\n                myAtts.labelcolor = colorArray && colorArray[i % colorArray.length];\r\n                myAtts.strokecolor = colorArray && colorArray[i % colorArray.length];\r\n                myAtts.fillcolor = colorArray && colorArray[i % colorArray.length];\r\n                polygons[i] = board.create(\"polygon\", pdata[i], {\r\n                    withLines: true,\r\n                    withLabel: false,\r\n                    fillColor: myAtts.fillcolor,\r\n                    fillOpacity: myAtts.fillopacity,\r\n                    highlightFillColor: myAtts.highlightfillcolor\r\n                });\r\n\r\n                for (j = 0; j < numofparams; j++) {\r\n                    polygons[i].borders[j].setAttribute(\r\n                        \"strokecolor:\" + colorArray[i % colorArray.length]\r\n                    );\r\n                    polygons[i].borders[j].setAttribute(\r\n                        \"strokewidth:\" + myAtts.polystrokewidth\r\n                    );\r\n                }\r\n            }\r\n\r\n            legend_position = attributes.legendposition || 'none';\r\n            switch (legend_position) {\r\n                case \"right\":\r\n                    lxoff = attributes.legendleftoffset || 2;\r\n                    lyoff = attributes.legendtopoffset || 1;\r\n\r\n                    this.legend = board.create(\r\n                        \"legend\",\r\n                        [xc + radius + lxoff, yc + radius - lyoff],\r\n                        {\r\n                            labels: labelArray,\r\n                            colors: colorArray\r\n                        }\r\n                    );\r\n                    break;\r\n                case \"none\":\r\n                    break;\r\n                default:\r\n                    JXG.debug(\"Unknown legend position\");\r\n            }\r\n\r\n            circles = [];\r\n            if (attributes.showcircles) {\r\n                cla = [];\r\n                for (i = 0; i < 6; i++) {\r\n                    cla[i] = 20 * i;\r\n                }\r\n                cla[0] = '0';\r\n                clabelArray = attributes.circlelabelarray || cla;\r\n                ncircles = clabelArray.length;\r\n\r\n                if (ncircles < 2) {\r\n                    throw new Error(\r\n                        \"JSXGraph radar chart: too less circles in circleLabelArray\"\r\n                    );\r\n                }\r\n\r\n                pcircles = [];\r\n                angle = start_angle + Math.PI / numofparams;\r\n                t = get_transform(angle, 0);\r\n\r\n                myAtts.fillcolor = 'none';\r\n                myAtts.highlightfillcolor = 'none';\r\n                myAtts.strokecolor = attributes.strokecolor || 'black';\r\n                myAtts.strokewidth = attributes.circlestrokewidth || 0.5;\r\n                myAtts.layer = 0;\r\n\r\n                // we have ncircles-1 intervals between ncircles circles\r\n                dr = (ends[0] - starts[0]) / (ncircles - 1);\r\n\r\n                for (i = 0; i < ncircles; i++) {\r\n                    pcircles[i] = board.create(\"point\", [starts[0] + i * dr, 0], {\r\n                        name: clabelArray[i],\r\n                        size: 0,\r\n                        fixed: true,\r\n                        withLabel: true,\r\n                        visible: true\r\n                    });\r\n                    pcircles[i].addTransform(pcircles[i], t);\r\n                    circles[i] = board.create(\"circle\", [center, pcircles[i]], myAtts);\r\n                }\r\n            }\r\n            this.rendNode = polygons[0].rendNode;\r\n            return {\r\n                circles: circles,\r\n                lines: line,\r\n                points: pdata,\r\n                midpoint: center,\r\n                polygons: polygons\r\n            };\r\n        },\r\n\r\n        /**\r\n         * Uses the boards renderer to update the chart.\r\n         * @private\r\n         */\r\n        updateRenderer: function () {\r\n            return this;\r\n        },\r\n\r\n        // documented in base/element\r\n        update: function () {\r\n            if (this.needsUpdate) {\r\n                this.updateDataArray();\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Template for dynamic charts update.\r\n         * This method is used to compute new entries\r\n         * for the arrays this.dataX and\r\n         * this.dataY. It is used in update.\r\n         * Default is an empty method, can be overwritten\r\n         * by the user.\r\n         *\r\n         * @returns {JXG.Chart} Reference to this chart object.\r\n         */\r\n        updateDataArray: function () {\r\n            return this;\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * @class Various types of charts for data visualization.\r\n * @pseudo\r\n * @name Chart\r\n * @augments JXG.Chart\r\n * @constructor\r\n * @type JXG.Chart\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Array} x Array of x-coordinates (default case, see below for alternatives)\r\n * @param {Array} y Array of y-coordinates (default case, see below for alternatives)\r\n * <p>\r\n * The parent array may be of one of the following forms:\r\n * <ol>\r\n * <li> Parents array looks like [number, number, number, ...]. It is interpreted as array of y-coordinates.\r\n * The x coordinates are automatically set to [1, 2, ...]\r\n * <li> Parents array looks like [[number, number, number, ...]]. The content is interpreted as array of y-coordinates.\r\n * The x coordinates are automatically set to [1, 2, ...]x coordinates are automatically set to [1, 2, ...]\r\n * Default case: [[x0,x1,x2,...],[y1,y2,y3,...]]\r\n * </ol>\r\n *\r\n * The attribute value for the key 'chartStyle' determines the type(s) of the chart. 'chartStyle' is a comma\r\n * separated list of strings of the possible chart types\r\n * 'bar', 'fit', 'line',  'pie', 'point', 'radar', 'spline'.\r\n *\r\n * @see JXG.Chart#drawBar\r\n * @see JXG.Chart#drawFit\r\n * @see JXG.Chart#drawLine\r\n * @see JXG.Chart#drawPie\r\n * @see JXG.Chart#drawPoints\r\n * @see JXG.Chart#drawRadar\r\n * @see JXG.Chart#drawSpline\r\n *\r\n * @example\r\n *   board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox:[-0.5,8,9,-2],axis:true});\r\n *\r\n *   var f = [4, 2, -1, 3, 6, 7, 2];\r\n *   var chart = board.create('chart', f,\r\n *                 {chartStyle:'bar',\r\n *                  width:0.8,\r\n *                  labels:f,\r\n *                  colorArray:['#8E1B77','#BE1679','#DC1765','#DA2130','#DB311B','#DF4917','#E36317','#E87F1A',\r\n *                              '#F1B112','#FCF302','#C1E212'],\r\n *                  label: {fontSize:30, display:'internal', anchorX:'left', rotate:90}\r\n *             });\r\n *\r\n * </pre><div id=\"JXG1528c395-9fa4-4210-ada6-7fc5652ed920\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG1528c395-9fa4-4210-ada6-7fc5652ed920',\r\n *             {boundingbox: [-0.5,8,9,-2], axis: true, showcopyright: false, shownavigation: false});\r\n *                 var f = [4,2,-1,3,6,7,2];\r\n *                 var chart = board.create('chart', f,\r\n *                     {chartStyle:'bar',\r\n *                      width:0.8,\r\n *                      labels:f,\r\n *                      colorArray:['#8E1B77','#BE1679','#DC1765','#DA2130','#DB311B','#DF4917','#E36317','#E87F1A',\r\n *                                  '#F1B112','#FCF302','#C1E212'],\r\n *                      label: {fontSize:30, display:'internal', anchorX:'left', rotate:90}\r\n *                 });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *   board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-1, 9, 13, -3], axis:true});\r\n *\r\n *   var s = board.create('slider', [[4,7],[8,7],[1,1,1.5]], {name:'S', strokeColor:'black', fillColor:'white'});\r\n *   var f = [function(){return (s.Value()*4.5).toFixed(2);},\r\n *                      function(){return (s.Value()*(-1)).toFixed(2);},\r\n *                      function(){return (s.Value()*3).toFixed(2);},\r\n *                      function(){return (s.Value()*2).toFixed(2);},\r\n *                      function(){return (s.Value()*(-0.5)).toFixed(2);},\r\n *                      function(){return (s.Value()*5.5).toFixed(2);},\r\n *                      function(){return (s.Value()*2.5).toFixed(2);},\r\n *                      function(){return (s.Value()*(-0.75)).toFixed(2);},\r\n *                      function(){return (s.Value()*3.5).toFixed(2);},\r\n *                      function(){return (s.Value()*2).toFixed(2);},\r\n *                      function(){return (s.Value()*(-1.25)).toFixed(2);}\r\n *                      ];\r\n *   var chart = board.create('chart', [f],\r\n *                                             {chartStyle:'bar',width:0.8,labels:f,\r\n *                                              colorArray:['#8E1B77','#BE1679','#DC1765','#DA2130','#DB311B','#DF4917','#E36317','#E87F1A',\r\n *                                                          '#F1B112','#FCF302','#C1E212']});\r\n *\r\n *   var dataArr = [4,1,3,2,5,6.5,1.5,2,0.5,1.5,-1];\r\n *   var chart2 = board.create('chart', dataArr, {chartStyle:'line,point'});\r\n *   chart2[0].setAttribute('strokeColor:black','strokeWidth:2pt');\r\n *   for(var i=0; i<11;i++) {\r\n *            chart2[1][i].setAttribute({strokeColor:'black',fillColor:'white',face:'[]', size:4, strokeWidth:'2pt'});\r\n *   }\r\n *   board.unsuspendUpdate();\r\n *\r\n * </pre><div id=\"JXG22deb158-48c6-41c3-8157-b88b4b968a55\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG22deb158-48c6-41c3-8157-b88b4b968a55',\r\n *             {boundingbox: [-1, 9, 13, -3], axis: true, showcopyright: false, shownavigation: false});\r\n *                 var s = board.create('slider', [[4,7],[8,7],[1,1,1.5]], {name:'S', strokeColor:'black', fillColor:'white'});\r\n *                 var f = [function(){return (s.Value()*4.5).toFixed(2);},\r\n *                          function(){return (s.Value()*(-1)).toFixed(2);},\r\n *                          function(){return (s.Value()*3).toFixed(2);},\r\n *                          function(){return (s.Value()*2).toFixed(2);},\r\n *                          function(){return (s.Value()*(-0.5)).toFixed(2);},\r\n *                          function(){return (s.Value()*5.5).toFixed(2);},\r\n *                          function(){return (s.Value()*2.5).toFixed(2);},\r\n *                          function(){return (s.Value()*(-0.75)).toFixed(2);},\r\n *                          function(){return (s.Value()*3.5).toFixed(2);},\r\n *                          function(){return (s.Value()*2).toFixed(2);},\r\n *                          function(){return (s.Value()*(-1.25)).toFixed(2);}\r\n *                          ];\r\n *                 var chart = board.create('chart', [f],\r\n *                                                 {chartStyle:'bar',width:0.8,labels:f,\r\n *                                                  colorArray:['#8E1B77','#BE1679','#DC1765','#DA2130','#DB311B','#DF4917','#E36317','#E87F1A',\r\n *                                                              '#F1B112','#FCF302','#C1E212']});\r\n *\r\n *                 var dataArr = [4,1,3,2,5,6.5,1.5,2,0.5,1.5,-1];\r\n *                 var chart2 = board.create('chart', dataArr, {chartStyle:'line,point'});\r\n *                 chart2[0].setAttribute('strokeColor:black','strokeWidth:2pt');\r\n *                 for(var i=0; i<11;i++) {\r\n *                     chart2[1][i].setAttribute({strokeColor:'black',fillColor:'white',face:'[]', size:4, strokeWidth:'2pt'});\r\n *                 }\r\n *                 board.unsuspendUpdate();\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *         var dataArr = [4, 1.2, 3, 7, 5, 4, 1.54, function () { return 2; }];\r\n *         var a = board.create('chart', dataArr, {\r\n *                 chartStyle:'pie', colors:['#B02B2C','#3F4C6B','#C79810','#D15600'],\r\n *                 fillOpacity:0.9,\r\n *                 center:[5,2],\r\n *                 strokeColor:'#ffffff',\r\n *                 strokeWidth:6,\r\n *                 highlightBySize:true,\r\n *                 highlightOnSector:true\r\n *             });\r\n *\r\n * </pre><div id=\"JXG1180b7dd-b048-436a-a5ad-87ffa82d5aff\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG1180b7dd-b048-436a-a5ad-87ffa82d5aff',\r\n *             {boundingbox: [0, 8, 12, -4], axis: true, showcopyright: false, shownavigation: false});\r\n *             var dataArr = [4, 1.2, 3, 7, 5, 4, 1.54, function () { return 2; }];\r\n *             var a = board.create('chart', dataArr, {\r\n *                     chartStyle:'pie', colors:['#B02B2C','#3F4C6B','#C79810','#D15600'],\r\n *                     fillOpacity:0.9,\r\n *                     center:[5,2],\r\n *                     strokeColor:'#ffffff',\r\n *                     strokeWidth:6,\r\n *                     highlightBySize:true,\r\n *                     highlightOnSector:true\r\n *                 });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *             board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-12, 12, 20, -12], axis: false});\r\n *             board.suspendUpdate();\r\n *             // See labelArray and paramArray\r\n *             var dataArr = [[23, 14, 15.0], [60, 8, 25.0], [0, 11.0, 25.0], [10, 15, 20.0]];\r\n *\r\n *             var a = board.create('chart', dataArr, {\r\n *                 chartStyle:'radar',\r\n *                 colorArray:['#0F408D','#6F1B75','#CA147A','#DA2228','#E8801B','#FCF302','#8DC922','#15993C','#87CCEE','#0092CE'],\r\n *                 //fillOpacity:0.5,\r\n *                 //strokeColor:'black',\r\n *                 //strokeWidth:1,\r\n *                 //polyStrokeWidth:1,\r\n *                 paramArray:['Speed','Flexibility', 'Costs'],\r\n *                 labelArray:['Ruby','JavaScript', 'PHP', 'Python'],\r\n *                 //startAngle:Math.PI/4,\r\n *                 legendPosition:'right',\r\n *                 //\"startShiftRatio\": 0.1,\r\n *                 //endShiftRatio:0.1,\r\n *                 //startShiftArray:[0,0,0],\r\n *                 //endShiftArray:[0.5,0.5,0.5],\r\n *                 start:0\r\n *                 //end:70,\r\n *                 //startArray:[0,0,0],\r\n *                 //endArray:[7,7,7],\r\n *                 //radius:3,\r\n *                 //showCircles:true,\r\n *                 //circleLabelArray:[1,2,3,4,5],\r\n *                 //highlightColorArray:['#E46F6A','#F9DF82','#F7FA7B','#B0D990','#69BF8E','#BDDDE4','#92C2DF','#637CB0','#AB91BC','#EB8EBF'],\r\n *             });\r\n *             board.unsuspendUpdate();\r\n *\r\n * </pre><div id=\"JXG985fbbe6-0488-4073-b73b-cb3ebaea488a\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG985fbbe6-0488-4073-b73b-cb3ebaea488a',\r\n *             {boundingbox: [-12, 12, 20, -12], axis: false, showcopyright: false, shownavigation: false});\r\n *                 board.suspendUpdate();\r\n *                 // See labelArray and paramArray\r\n *                 var dataArr = [[23, 14, 15.0], [60, 8, 25.0], [0, 11.0, 25.0], [10, 15, 20.0]];\r\n *\r\n *                 var a = board.create('chart', dataArr, {\r\n *                     chartStyle:'radar',\r\n *                     colorArray:['#0F408D','#6F1B75','#CA147A','#DA2228','#E8801B','#FCF302','#8DC922','#15993C','#87CCEE','#0092CE'],\r\n *                     //fillOpacity:0.5,\r\n *                     //strokeColor:'black',\r\n *                     //strokeWidth:1,\r\n *                     //polyStrokeWidth:1,\r\n *                     paramArray:['Speed','Flexibility', 'Costs'],\r\n *                     labelArray:['Ruby','JavaScript', 'PHP', 'Python'],\r\n *                     //startAngle:Math.PI/4,\r\n *                     legendPosition:'right',\r\n *                     //\"startShiftRatio\": 0.1,\r\n *                     //endShiftRatio:0.1,\r\n *                     //startShiftArray:[0,0,0],\r\n *                     //endShiftArray:[0.5,0.5,0.5],\r\n *                     start:0\r\n *                     //end:70,\r\n *                     //startArray:[0,0,0],\r\n *                     //endArray:[7,7,7],\r\n *                     //radius:3,\r\n *                     //showCircles:true,\r\n *                     //circleLabelArray:[1,2,3,4,5],\r\n *                     //highlightColorArray:['#E46F6A','#F9DF82','#F7FA7B','#B0D990','#69BF8E','#BDDDE4','#92C2DF','#637CB0','#AB91BC','#EB8EBF'],\r\n *                 });\r\n *                 board.unsuspendUpdate();\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * For more examples see\r\n * <ul>\r\n * <li><a href=\"https://jsxgraph.org/wiki/index.php/Charts_from_HTML_tables_-_tutorial\">JSXgraph wiki: Charts from HTML tables - tutorial</a>\r\n * <li><a href=\"https://jsxgraph.org/wiki/index.php/Pie_chart\">JSXgraph wiki: Pie chart</a>\r\n * <li><a href=\"https://jsxgraph.org/wiki/index.php/Different_chart_styles\">JSXgraph wiki: Various chart styles</a>\r\n * <li><a href=\"https://jsxgraph.org/wiki/index.php/Dynamic_bar_chart\">JSXgraph wiki: Dynamic bar chart</a>\r\n * </ul>\r\n */\r\nJXG.createChart = function (board, parents, attributes) {\r\n    var data,\r\n        row,\r\n        i,\r\n        j,\r\n        col,\r\n        charts = [],\r\n        w,\r\n        x,\r\n        showRows,\r\n        attr,\r\n        originalWidth,\r\n        name,\r\n        strokeColor,\r\n        fillColor,\r\n        hStrokeColor,\r\n        hFillColor,\r\n        len,\r\n        table = Env.isBrowser ? board.document.getElementById(parents[0]) : null;\r\n\r\n    if (parents.length === 1 && Type.isString(parents[0])) {\r\n        if (Type.exists(table)) {\r\n            // extract the data\r\n            attr = Type.copyAttributes(attributes, board.options, 'chart');\r\n\r\n            table = new DataSource().loadFromTable(\r\n                parents[0],\r\n                attr.withheaders,\r\n                attr.withheaders\r\n            );\r\n            data = table.data;\r\n            col = table.columnHeaders;\r\n            row = table.rowHeaders;\r\n\r\n            originalWidth = attr.width;\r\n            name = attr.name;\r\n            strokeColor = attr.strokecolor;\r\n            fillColor = attr.fillcolor;\r\n            hStrokeColor = attr.highlightstrokecolor;\r\n            hFillColor = attr.highlightfillcolor;\r\n\r\n            board.suspendUpdate();\r\n\r\n            len = data.length;\r\n            showRows = [];\r\n            if (attr.rows && Type.isArray(attr.rows)) {\r\n                for (i = 0; i < len; i++) {\r\n                    for (j = 0; j < attr.rows.length; j++) {\r\n                        if (\r\n                            attr.rows[j] === i ||\r\n                            (attr.withheaders && attr.rows[j] === row[i])\r\n                        ) {\r\n                            showRows.push(data[i]);\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n            } else {\r\n                showRows = data;\r\n            }\r\n\r\n            len = showRows.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                x = [];\r\n                if (attr.chartstyle && attr.chartstyle.indexOf('bar') !== -1) {\r\n                    if (originalWidth) {\r\n                        w = originalWidth;\r\n                    } else {\r\n                        w = 0.8;\r\n                    }\r\n\r\n                    x.push(1 - w / 2 + ((i + 0.5) * w) / len);\r\n\r\n                    for (j = 1; j < showRows[i].length; j++) {\r\n                        x.push(x[j - 1] + 1);\r\n                    }\r\n\r\n                    attr.width = w / len;\r\n                }\r\n\r\n                if (name && name.length === len) {\r\n                    attr.name = name[i];\r\n                } else if (attr.withheaders) {\r\n                    attr.name = col[i];\r\n                }\r\n\r\n                if (strokeColor && strokeColor.length === len) {\r\n                    attr.strokecolor = strokeColor[i];\r\n                } else {\r\n                    attr.strokecolor = Color.hsv2rgb(((i + 1) / len) * 360, 0.9, 0.6);\r\n                }\r\n\r\n                if (fillColor && fillColor.length === len) {\r\n                    attr.fillcolor = fillColor[i];\r\n                } else {\r\n                    attr.fillcolor = Color.hsv2rgb(((i + 1) / len) * 360, 0.9, 1.0);\r\n                }\r\n\r\n                if (hStrokeColor && hStrokeColor.length === len) {\r\n                    attr.highlightstrokecolor = hStrokeColor[i];\r\n                } else {\r\n                    attr.highlightstrokecolor = Color.hsv2rgb(((i + 1) / len) * 360, 0.9, 1.0);\r\n                }\r\n\r\n                if (hFillColor && hFillColor.length === len) {\r\n                    attr.highlightfillcolor = hFillColor[i];\r\n                } else {\r\n                    attr.highlightfillcolor = Color.hsv2rgb(((i + 1) / len) * 360, 0.9, 0.6);\r\n                }\r\n\r\n                if (attr.chartstyle && attr.chartstyle.indexOf('bar') !== -1) {\r\n                    charts.push(new JXG.Chart(board, [x, showRows[i]], attr));\r\n                } else {\r\n                    charts.push(new JXG.Chart(board, [showRows[i]], attr));\r\n                }\r\n            }\r\n\r\n            board.unsuspendUpdate();\r\n        }\r\n        return charts;\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'chart');\r\n    return new JXG.Chart(board, parents, attr);\r\n};\r\n\r\nJXG.registerElement(\"chart\", JXG.createChart);\r\n\r\n/**\r\n * Legend for chart\r\n *\r\n * The Legend class is a basic class for legends.\r\n * @class Creates a new Legend object. Do not use this constructor to create a legend.\r\n * Use {@link JXG.Board#create} with type {@link Legend} instead.\r\n * <p>\r\n * The legend object consists of segements with labels. These lines can be\r\n * accessed with the property \"lines\" of the element.\r\n * @constructor\r\n * @augments JXG.GeometryElement\r\n * @param {String|JXG.Board} board The board the new legend is drawn on.\r\n * @param {Array} coords Coordinates of the left top point of the legend.\r\n * @param  {Object} attributes Attributes of the legend\r\n */\r\nJXG.Legend = function (board, coords, attributes) {\r\n    var attr;\r\n\r\n    /* Call the constructor of GeometryElement */\r\n    this.constructor();\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'legend');\r\n\r\n    this.board = board;\r\n    this.coords = new Coords(Const.COORDS_BY_USER, coords, this.board);\r\n    this.myAtts = {};\r\n    this.label_array = attr.labelarray || attr.labels;\r\n    this.color_array = attr.colorarray || attr.colors;\r\n    this.opacy_array = attr.strokeopacity || [1];\r\n    this.lines = [];\r\n    this.myAtts.strokewidth = attr.strokewidth || 5;\r\n    this.myAtts.straightfirst = false;\r\n    this.myAtts.straightlast = false;\r\n    this.myAtts.withlabel = true;\r\n    this.myAtts.fixed = true;\r\n    this.myAtts.frozen = attr.frozen || false ;\r\n    this.style = attr.legendstyle || attr.style;\r\n\r\n    if (this.style === 'vertical') {\r\n        this.drawVerticalLegend(board, attr);\r\n    } else {\r\n        throw new Error(\"JSXGraph: Unknown legend style: \" + this.style);\r\n    }\r\n\r\n    this.id = this.board.setId(this, 'Leg');\r\n\r\n};\r\n\r\nJXG.Legend.prototype = new GeometryElement();\r\n\r\n/**\r\n * Draw a vertical legend.\r\n *\r\n * @private\r\n * @param  {String|JXG.Board} board      The board the legend is drawn on\r\n * @param  {Object} attributes Attributes of the legend\r\n */\r\nJXG.Legend.prototype.drawVerticalLegend = function (board, attributes) {\r\n    var i,\r\n        line_length = attributes.linelength || 1,\r\n        offy = (attributes.rowheight || 20) / this.board.unitY,\r\n        getLabelAnchor = function () {\r\n            this.setLabelRelativeCoords(this.visProp.label.offset);\r\n            return new Coords(\r\n                Const.COORDS_BY_USER,\r\n                [this.point2.X(), this.point2.Y()],\r\n                this.board\r\n            );\r\n        };\r\n\r\n    for (i = 0; i < this.label_array.length; i++) {\r\n        this.myAtts.name = this.label_array[i];\r\n        this.myAtts.strokecolor = this.color_array[i % this.color_array.length];\r\n        this.myAtts.highlightstrokecolor = this.color_array[i % this.color_array.length];\r\n        this.myAtts.strokeopacity = this.opacy_array[i % this.opacy_array.length];\r\n        this.myAtts.highlightstrokeopacity = this.opacy_array[i % this.opacy_array.length];\r\n        this.myAtts.label = {\r\n            offset: [10, 0],\r\n            strokeColor: this.color_array[i % this.color_array.length],\r\n            strokeWidth: this.myAtts.strokewidth\r\n        };\r\n\r\n        this.lines[i] = board.create(\r\n            \"line\",\r\n            [\r\n                [this.coords.usrCoords[1], this.coords.usrCoords[2] - i * offy],\r\n                [this.coords.usrCoords[1] + line_length, this.coords.usrCoords[2] - i * offy]\r\n            ],\r\n            this.myAtts\r\n        );\r\n\r\n        if (this.myAtts.frozen){\r\n            this.lines[i].setAttribute({ point1: { frozen: true }, point2: { frozen: true } });\r\n        }\r\n\r\n        this.lines[i].getLabelAnchor = getLabelAnchor;\r\n        this.lines[i]\r\n            .prepareUpdate()\r\n            .update()\r\n            .updateVisibility(this.lines[i].evalVisProp('visible'))\r\n            .updateRenderer();\r\n\r\n        this.addChild(this.lines[i]);\r\n    }\r\n};\r\n\r\n/**\r\n * @class Creates a legend for a chart element.\r\n * Parameter is a pair of coordinates. The label names and  the label colors are\r\n * supplied in the attributes:\r\n * <ul>\r\n * <li> labels (Array): array of strings containing label names\r\n * <li> labelArray (Array): alternative array for label names (has precedence over 'labels')\r\n * <li> colors (Array): array of color values\r\n * <li> colorArray (Array): alternative array for color values (has precedence over 'colors')\r\n * <li> opacities (Array): opacity of a line in the legend\r\n * <li> legendStyle or style: at the time being only 'vertical' is supported.\r\n * <li> rowHeight: height of an entry in the legend (in px)\r\n * <li> linelenght: length of a line in the legend (measured in the coordinate system)\r\n * <li> frozen (Boolean, false):\r\n * </ul>\r\n *\r\n * @pseudo\r\n * @name Legend\r\n * @augments JXG.Legend\r\n * @constructor\r\n * @type JXG.Legend\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Number} x Horizontal coordinate of the left top point of the legend\r\n * @param {Number} y Vertical coordinate of the left top point of the legend\r\n *\r\n * @example\r\n * var board = JXG.JSXGraph.initBoard('jxgbox', {axis:true,boundingbox:[-4,48.3,12.0,-2.3]});\r\n * var x       = [-3,-2,-1,0,1,2,3,4,5,6,7,8];\r\n * var dataArr = [4,7,7,27,33,37,46,22,11,4,1,0];\r\n *\r\n * colors = ['green', 'yellow', 'red', 'blue'];\r\n * board.create('chart', [x,dataArr], {chartStyle:'bar', width:1.0, labels:dataArr, colors: colors} );\r\n * board.create('legend', [8, 45], {labels:dataArr, colors: colors, strokeWidth:5} );\r\n *\r\n * </pre><div id=\"JXGeeb588d9-a4fd-41bf-93f4-cd6f7a016682\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGeeb588d9-a4fd-41bf-93f4-cd6f7a016682',\r\n *             {boundingbox: [-4,48.3,12.0,-2.3], axis: true, showcopyright: false, shownavigation: false});\r\n *     var x       = [-3,-2,-1,0,1,2,3,4,5,6,7,8];\r\n *     var dataArr = [4,7,7,27,33,37,46,22,11,4,1,0];\r\n *\r\n *     colors = ['green', 'yellow', 'red', 'blue'];\r\n *     board.create('chart', [x,dataArr], {chartStyle:'bar', width:1.0, labels:dataArr, colors: colors} );\r\n *     board.create('legend', [8, 45], {labels:dataArr, colors: colors, strokeWidth:5} );\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *   var inputFun, cf = [], cf2 = [], niveaunum,\r\n *     niveauline = [], niveauopac = [],legend;\r\n *\r\n *   inputFun = \"x^2/2-2*x*y+y^2/2\";\r\n *   niveauline = [-3,-2,-1,-0.5, 0, 1,2,3];\r\n *   niveaunum = niveauline.length;\r\n *   for (let i = 0; JXG.Math.lt(i, niveaunum); i++) {\r\n *     let niveaui = niveauline[i];\r\n *     niveauopac.push(((i + 1) / (niveaunum + 1)));\r\n *     cf.push(board.create(\"implicitcurve\", [\r\n *       inputFun + \"-(\" + niveaui.toFixed(2) + \")\", [-2, 2], [-2, 2]], {\r\n *       strokeWidth: 2,\r\n *       strokeColor: JXG.palette.red,\r\n *       strokeOpacity: niveauopac[i],\r\n *       needsRegularUpdate: false,\r\n *       name: \"niveau\"+i,\r\n *       visible: true\r\n *     }));\r\n *   }\r\n *   legend = board.create('legend', [-1.75, 1.75], {\r\n *     labels: niveauline,\r\n *     colors: [cf[0].visProp.strokecolor],\r\n *     strokeOpacity: niveauopac,\r\n *     linelength: 0.2,\r\n *     frozen:true\r\n *   }\r\n *   );\r\n *\r\n *\r\n * </pre><div id=\"JXG079fce93-07b9-426f-a267-ab9c1253e435\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG079fce93-07b9-426f-a267-ab9c1253e435',\r\n *             {boundingbox: [-2, 2, 2, -2], axis: true, showcopyright: false, shownavigation: false});\r\n *       var board, inputFun, cf = [], cf2 = [], niveaunum,\r\n *         niveauline = [], niveauopac = [],legend;\r\n *\r\n *       inputFun = \"x^2/2-2*x*y+y^2/2\";\r\n *       niveauline = [-3,-2,-1,-0.5, 0, 1,2,3];\r\n *       niveaunum = niveauline.length;\r\n *       for (let i = 0; JXG.Math.lt(i, niveaunum); i++) {\r\n *         let niveaui = niveauline[i];\r\n *         niveauopac.push(((i + 1) / (niveaunum + 1)));\r\n *         cf.push(board.create(\"implicitcurve\", [\r\n *           inputFun + \"-(\" + niveaui.toFixed(2) + \")\", [-2, 2], [-2, 2]], {\r\n *           strokeWidth: 2,\r\n *           strokeColor: JXG.palette.red,\r\n *           strokeOpacity: niveauopac[i],\r\n *           needsRegularUpdate: false,\r\n *           name: \"niveau\"+i,\r\n *           visible: true\r\n *         }));\r\n *       }\r\n *       legend = board.create('legend', [-1.75, 1.75], {\r\n *         labels: niveauline,\r\n *         colors: [cf[0].visProp.strokecolor],\r\n *         strokeOpacity: niveauopac,\r\n *         linelength: 0.2,\r\n *         frozen:true\r\n *       }\r\n *       );\r\n *\r\n *\r\n *     })();\r\n *\r\n * </script>\r\n *\r\n *\r\n */\r\nJXG.createLegend = function (board, parents, attributes) {\r\n    //parents are coords of left top point of the legend\r\n    var start_from = [0, 0];\r\n\r\n    if (Type.exists(parents) && parents.length === 2) {\r\n        start_from = parents;\r\n    } else {\r\n        throw new Error(\"JSXGraph: Legend element needs two numbers as parameters\");\r\n    }\r\n\r\n    return new JXG.Legend(board, start_from, attributes);\r\n};\r\n\r\nJXG.registerElement(\"legend\", JXG.createLegend);\r\n\r\nexport default {\r\n    Chart: JXG.Chart,\r\n    Legend: JXG.Legend\r\n    // createChart: JXG.createChart,\r\n    // createLegend: JXG.createLegend\r\n};\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview This file contains code for transformations of geometrical objects.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"./constants.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * A transformation consists of a 3x3 matrix, i.e. it is a projective transformation.\r\n * @class Creates a new transformation object. Do not use this constructor to create a transformation.\r\n * Use {@link JXG.Board#create} with\r\n * type {@link Transformation} instead.\r\n * @constructor\r\n * @param {JXG.Board} board The board the transformation is part of.\r\n * @param {String} type Can be\r\n * <ul><li> 'translate'\r\n * <li> 'scale'\r\n * <li> 'reflect'\r\n * <li> 'rotate'\r\n * <li> 'shear'\r\n * <li> 'generic'\r\n * <li> 'matrix'\r\n * </ul>\r\n * @param {Object} params The parameters depend on the transformation type\r\n *\r\n * <p>\r\n * Translation matrix:\r\n * <pre>\r\n * ( 1  0  0)   ( z )\r\n * ( a  1  0) * ( x )\r\n * ( b  0  1)   ( y )\r\n * </pre>\r\n *\r\n * <p>\r\n * Scale matrix:\r\n * <pre>\r\n * ( 1  0  0)   ( z )\r\n * ( 0  a  0) * ( x )\r\n * ( 0  0  b)   ( y )\r\n * </pre>\r\n *\r\n * <p>\r\n * A rotation matrix with angle a (in Radians)\r\n * <pre>\r\n * ( 1    0        0      )   ( z )\r\n * ( 0    cos(a)   -sin(a)) * ( x )\r\n * ( 0    sin(a)   cos(a) )   ( y )\r\n * </pre>\r\n *\r\n * <p>\r\n * Shear matrix:\r\n * <pre>\r\n * ( 1  0  0)   ( z )\r\n * ( 0  1  a) * ( x )\r\n * ( 0  b  1)   ( y )\r\n * </pre>\r\n *\r\n * <p>Generic transformation:\r\n * <pre>\r\n * ( a  b  c )   ( z )\r\n * ( d  e  f ) * ( x )\r\n * ( g  h  i )   ( y )\r\n * </pre>\r\n *\r\n */\r\nJXG.Transformation = function (board, type, params, is3D) {\r\n    this.elementClass = Const.OBJECT_CLASS_OTHER;\r\n    this.type = Const.OBJECT_TYPE_TRANSFORMATION;\r\n\r\n    if (is3D) {\r\n        this.is3D = true;\r\n        this.matrix = [\r\n            [1, 0, 0, 0],\r\n            [0, 1, 0, 0],\r\n            [0, 0, 1, 0],\r\n            [0, 0, 0, 1]\r\n        ];\r\n    } else {\r\n        this.is3D = false;\r\n        this.matrix = [\r\n            [1, 0, 0],\r\n            [0, 1, 0],\r\n            [0, 0, 1]\r\n        ];\r\n    }\r\n\r\n    this.board = board;\r\n    this.isNumericMatrix = false;\r\n    if (this.is3D) {\r\n        this.setMatrix3D(params[0] /* view3d */, type, params.slice(1));\r\n    } else {\r\n        this.setMatrix(board, type, params);\r\n    }\r\n\r\n    this.methodMap = {\r\n        apply: \"apply\",\r\n        applyOnce: \"applyOnce\",\r\n        bindTo: \"bindTo\",\r\n        bind: \"bindTo\",\r\n        melt: \"melt\",\r\n        meltTo: \"meltTo\"\r\n    };\r\n};\r\n\r\nJXG.Transformation.prototype = {};\r\n\r\nJXG.extend(\r\n    JXG.Transformation.prototype,\r\n    /** @lends JXG.Transformation.prototype */ {\r\n        /**\r\n         * Updates the numerical data for the transformation, i.e. the entry of the subobject matrix.\r\n         * @returns {JXG.Transform} returns pointer to itself\r\n         */\r\n        update: function () {\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the transformation matrix for different types of standard transforms.\r\n         * @param {JXG.Board} board\r\n         * @param {String} type   Transformation type, possible values are\r\n         *                        'translate', 'scale', 'reflect', 'rotate',\r\n         *                        'shear', 'generic'.\r\n         * @param {Array} params Parameters for the various transformation types.\r\n         *\r\n         * <p>A transformation with a generic matrix looks like:\r\n         * <pre>\r\n         * ( a  b  c )   ( z )\r\n         * ( d  e  f ) * ( x )\r\n         * ( g  h  i )   ( y )\r\n         * </pre>\r\n         *\r\n         * The transformation matrix then looks like:\r\n         * <p>\r\n         * Translation matrix:\r\n         * <pre>\r\n         * ( 1  0  0)   ( z )\r\n         * ( a  1  0) * ( x )\r\n         * ( b  0  1)   ( y )\r\n         * </pre>\r\n         *\r\n         * <p>\r\n         * Scale matrix:\r\n         * <pre>\r\n         * ( 1  0  0)   ( z )\r\n         * ( 0  a  0) * ( x )\r\n         * ( 0  0  b)   ( y )\r\n         * </pre>\r\n         *\r\n         * <p>\r\n         * A rotation matrix with angle a (in Radians)\r\n         * <pre>\r\n         * ( 1    0        0      )   ( z )\r\n         * ( 0    cos(a)   -sin(a)) * ( x )\r\n         * ( 0    sin(a)   cos(a) )   ( y )\r\n         * </pre>\r\n         *\r\n         * <p>\r\n         * Shear matrix:\r\n         * <pre>\r\n         * ( 1  0  0)   ( z )\r\n         * ( 0  1  a) * ( x )\r\n         * ( 0  b  1)   ( y )\r\n         * </pre>\r\n         *\r\n         * <p>Generic transformation (9 parameters):\r\n         * <pre>\r\n         * ( a  b  c )   ( z )\r\n         * ( d  e  f ) * ( x )\r\n         * ( g  h  i )   ( y )\r\n         * </pre>\r\n         *\r\n         * <p>Matrix:\r\n         * <pre>\r\n         * (         )   ( z )\r\n         * (    M    ) * ( x )\r\n         * (         )   ( y )\r\n         * </pre>\r\n         */\r\n        setMatrix: function (board, type, params) {\r\n            var i;\r\n                // e, obj; // Handle dependencies\r\n\r\n            this.isNumericMatrix = true;\r\n            for (i = 0; i < params.length; i++) {\r\n                if (typeof params[i] !== 'number') {\r\n                    this.isNumericMatrix = false;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if (type === 'translate') {\r\n                if (params.length !== 2) {\r\n                    throw new Error(\"JSXGraph: translate transformation needs 2 parameters.\");\r\n                }\r\n                this.evalParam = Type.createEvalFunction(board, params, 2);\r\n                this.update = function () {\r\n                    this.matrix[1][0] = this.evalParam(0);\r\n                    this.matrix[2][0] = this.evalParam(1);\r\n                };\r\n            } else if (type === 'scale') {\r\n                if (params.length !== 2) {\r\n                    throw new Error(\"JSXGraph: scale transformation needs 2 parameters.\");\r\n                }\r\n                this.evalParam = Type.createEvalFunction(board, params, 2);\r\n                this.update = function () {\r\n                    this.matrix[1][1] = this.evalParam(0); // x\r\n                    this.matrix[2][2] = this.evalParam(1); // y\r\n                };\r\n                // Input: line or two points\r\n            } else if (type === 'reflect') {\r\n                // line or two points\r\n                if (params.length < 4) {\r\n                    params[0] = board.select(params[0]);\r\n                }\r\n\r\n                // two points\r\n                if (params.length === 2) {\r\n                    params[1] = board.select(params[1]);\r\n                }\r\n\r\n                // 4 coordinates [px,py,qx,qy]\r\n                if (params.length === 4) {\r\n                    this.evalParam = Type.createEvalFunction(board, params, 4);\r\n                }\r\n\r\n                this.update = function () {\r\n                    var x, y, z, xoff, yoff, d, v, p;\r\n                    // Determine homogeneous coordinates of reflections axis\r\n                    // line\r\n                    if (params.length === 1) {\r\n                        v = params[0].stdform;\r\n                    } else if (params.length === 2) {\r\n                        // two points\r\n                        v = Mat.crossProduct(\r\n                            params[1].coords.usrCoords,\r\n                            params[0].coords.usrCoords\r\n                        );\r\n                    } else if (params.length === 4) {\r\n                        // two points coordinates [px,py,qx,qy]\r\n                        v = Mat.crossProduct(\r\n                            [1, this.evalParam(2), this.evalParam(3)],\r\n                            [1, this.evalParam(0), this.evalParam(1)]\r\n                        );\r\n                    }\r\n\r\n                    // Project origin to the line. This gives a finite point p\r\n                    x = v[1];\r\n                    y = v[2];\r\n                    z = v[0];\r\n                    p = [-z * x, -z * y, x * x + y * y];\r\n                    d = p[2];\r\n\r\n                    // Normalize p\r\n                    xoff = p[0] / p[2];\r\n                    yoff = p[1] / p[2];\r\n\r\n                    // x, y is the direction of the line\r\n                    x = -v[2];\r\n                    y = v[1];\r\n\r\n                    this.matrix[1][1] = (x * x - y * y) / d;\r\n                    this.matrix[1][2] = (2 * x * y) / d;\r\n                    this.matrix[2][1] = this.matrix[1][2];\r\n                    this.matrix[2][2] = -this.matrix[1][1];\r\n                    this.matrix[1][0] =\r\n                        xoff * (1 - this.matrix[1][1]) - yoff * this.matrix[1][2];\r\n                    this.matrix[2][0] =\r\n                        yoff * (1 - this.matrix[2][2]) - xoff * this.matrix[2][1];\r\n                };\r\n            } else if (type === 'rotate') {\r\n                if (params.length === 3) {\r\n                    // angle, x, y\r\n                    this.evalParam = Type.createEvalFunction(board, params, 3);\r\n                } else if (params.length > 0 && params.length <= 2) {\r\n                    // angle, p or angle\r\n                    this.evalParam = Type.createEvalFunction(board, params, 1);\r\n\r\n                    if (params.length === 2 && !Type.isArray(params[1])) {\r\n                        params[1] = board.select(params[1]);\r\n                    }\r\n                }\r\n\r\n                this.update = function () {\r\n                    var x,\r\n                        y,\r\n                        beta = this.evalParam(0),\r\n                        co = Math.cos(beta),\r\n                        si = Math.sin(beta);\r\n\r\n                    this.matrix[1][1] = co;\r\n                    this.matrix[1][2] = -si;\r\n                    this.matrix[2][1] = si;\r\n                    this.matrix[2][2] = co;\r\n\r\n                    // rotate around [x,y] otherwise rotate around [0,0]\r\n                    if (params.length > 1) {\r\n                        if (params.length === 3) {\r\n                            x = this.evalParam(1);\r\n                            y = this.evalParam(2);\r\n                        } else {\r\n                            if (Type.isArray(params[1])) {\r\n                                x = params[1][0];\r\n                                y = params[1][1];\r\n                            } else {\r\n                                x = params[1].X();\r\n                                y = params[1].Y();\r\n                            }\r\n                        }\r\n                        this.matrix[1][0] = x * (1 - co) + y * si;\r\n                        this.matrix[2][0] = y * (1 - co) - x * si;\r\n                    }\r\n                };\r\n            } else if (type === 'shear') {\r\n                if (params.length !== 2) {\r\n                    throw new Error(\"JSXGraph: shear transformation needs 2 parameters.\");\r\n                }\r\n\r\n                this.evalParam = Type.createEvalFunction(board, params, 2);\r\n                this.update = function () {\r\n                    this.matrix[1][2] = this.evalParam(0);\r\n                    this.matrix[2][1] = this.evalParam(1);\r\n                };\r\n            } else if (type === 'generic') {\r\n                if (params.length !== 9) {\r\n                    throw new Error(\"JSXGraph: generic transformation needs 9 parameters.\");\r\n                }\r\n\r\n                this.evalParam = Type.createEvalFunction(board, params, 9);\r\n\r\n                this.update = function () {\r\n                    this.matrix[0][0] = this.evalParam(0);\r\n                    this.matrix[0][1] = this.evalParam(1);\r\n                    this.matrix[0][2] = this.evalParam(2);\r\n                    this.matrix[1][0] = this.evalParam(3);\r\n                    this.matrix[1][1] = this.evalParam(4);\r\n                    this.matrix[1][2] = this.evalParam(5);\r\n                    this.matrix[2][0] = this.evalParam(6);\r\n                    this.matrix[2][1] = this.evalParam(7);\r\n                    this.matrix[2][2] = this.evalParam(8);\r\n                };\r\n            } else if (type === 'matrix') {\r\n                if (params.length !== 1) {\r\n                    throw new Error(\"JSXGraph: transformation of type 'matrix' needs 1 parameter.\");\r\n                }\r\n\r\n                this.evalParam = params[0].slice();\r\n                this.update = function () {\r\n                    var i, j;\r\n                    for (i = 0; i < 3; i++) {\r\n                        for (j = 0; j < 3; j++) {\r\n                            this.matrix[i][j] = Type.evaluate(this.evalParam[i][j]);\r\n                        }\r\n                    }\r\n                };\r\n            }\r\n\r\n            // Handle dependencies\r\n            // NO: transformations do not have method addParents\r\n            // if (Type.exists(this.evalParam)) {\r\n            //     for (e in this.evalParam.deps) {\r\n            //         obj = this.evalParam.deps[e];\r\n            //         this.addParents(obj);\r\n            //         obj.addChild(this);\r\n            //     }\r\n            // }\r\n        },\r\n\r\n        /**\r\n         * Set the 3D transformation matrix for different types of standard transforms.\r\n         * @param {JXG.Board} board\r\n         * @param {String} type   Transformation type, possible values are\r\n         *                        'translate', 'scale', 'rotate',\r\n         *                        'rotateX', 'rotateY', 'rotateZ',\r\n         *                        'shear', 'generic'.\r\n         * @param {Array} params Parameters for the various transformation types.\r\n         *\r\n         * <p>A transformation with a generic matrix looks like:\r\n         * <pre>\r\n         * ( a  b  c  d)   ( w )\r\n         * ( e  f  g  h) * ( x )\r\n         * ( i  j  k  l)   ( y )\r\n         * ( m  n  o  p)   ( z )\r\n         * </pre>\r\n         *\r\n         * The transformation matrix then looks like:\r\n         * <p>\r\n         * Translation matrix:\r\n         * <pre>\r\n         * ( 1  0  0  0)   ( w )\r\n         * ( a  1  0  0) * ( x )\r\n         * ( b  0  1  0)   ( y )\r\n         * ( c  0  0  1)   ( z )\r\n         * </pre>\r\n         *\r\n         * <p>\r\n         * Scale matrix:\r\n         * <pre>\r\n         * ( 1  0  0  0)   ( w )\r\n         * ( 0  a  0  0) * ( x )\r\n         * ( 0  0  b  0)   ( y )\r\n         * ( 0  0  0  c)   ( z )\r\n         * </pre>\r\n         *\r\n         * <p>\r\n         * rotateX: a rotation matrix with angle a (in Radians)\r\n         * <pre>\r\n         * ( 1    0        0             )   ( z )\r\n         * ( 0    1        0         0   ) * ( x )\r\n         * ( 0    0      cos(a)   -sin(a)) * ( x )\r\n         * ( 0    0      sin(a)   cos(a) )   ( y )\r\n         * </pre>\r\n         *\r\n         * <p>\r\n         * rotateY: a rotation matrix with angle a (in Radians)\r\n         * <pre>\r\n         * ( 1      0       0           )   ( z )\r\n         * ( 0    cos(a)    0    -sin(a)) * ( x )\r\n         * ( 0      0       1       0   ) * ( x )\r\n         * ( 0    sin(a)    0    cos(a) )   ( y )\r\n         * </pre>\r\n         *\r\n         * <p>\r\n         * rotateZ: a rotation matrix with angle a (in Radians)\r\n         * <pre>\r\n         * ( 1      0                0  )   ( z )\r\n         * ( 0    cos(a)   -sin(a)   0  ) * ( x )\r\n         * ( 0    sin(a)   cos(a)    0  )   ( y )\r\n         * ( 0      0         0      1  ) * ( x )\r\n         * </pre>\r\n         *\r\n         * <p>\r\n         * rotate: a rotation matrix with angle a (in Radians)\r\n         * and normal <i>n</i>.\r\n         *\r\n         */\r\n        setMatrix3D: function(view, type, params) {\r\n            var i,\r\n                board = view.board;\r\n\r\n            this.isNumericMatrix = true;\r\n            for (i = 0; i < params.length; i++) {\r\n                if (typeof params[i] !== 'number') {\r\n                    this.isNumericMatrix = false;\r\n                    break;\r\n                }\r\n            }\r\n\r\n            if (type === 'translate') {\r\n                if (params.length !== 3) {\r\n                    throw new Error(\"JSXGraph: 3D translate transformation needs 3 parameters.\");\r\n                }\r\n                this.evalParam = Type.createEvalFunction(board, params, 3);\r\n                this.update = function () {\r\n                    this.matrix[1][0] = this.evalParam(0);\r\n                    this.matrix[2][0] = this.evalParam(1);\r\n                    this.matrix[3][0] = this.evalParam(2);\r\n                };\r\n            } else if (type === 'scale') {\r\n                if (params.length !== 3 && params.length !== 4) {\r\n                    throw new Error(\"JSXGraph: 3D scale transformation needs either 3 or 4 parameters.\");\r\n                }\r\n                this.evalParam = Type.createEvalFunction(board, params, 3);\r\n                this.update = function () {\r\n                    var x = this.evalParam(0),\r\n                        y = this.evalParam(1),\r\n                        z = this.evalParam(2);\r\n\r\n                    this.matrix[1][1] = x;\r\n                    this.matrix[2][2] = y;\r\n                    this.matrix[3][3] = z;\r\n                };\r\n            } else if (type === 'rotateX') {\r\n                params.splice(1, 0, [1, 0, 0]);\r\n                this.setMatrix3D(view, 'rotate', params);\r\n            } else if (type === 'rotateY') {\r\n                params.splice(1, 0, [0, 1, 0]);\r\n                this.setMatrix3D(view, 'rotate', params);\r\n            } else if (type === 'rotateZ') {\r\n                params.splice(1, 0, [0, 0, 1]);\r\n                this.setMatrix3D(view, 'rotate', params);\r\n            } else if (type === 'rotate') {\r\n                if (params.length < 2) {\r\n                    throw new Error(\"JSXGraph: 3D rotate transformation needs 2 or 3 parameters.\");\r\n                }\r\n                if (params.length === 3 && !Type.isFunction(params[2]) && !Type.isArray(params[2])) {\r\n                    this.evalParam = Type.createEvalFunction(board, params, 2);\r\n                    params[2] = view.select(params[2]);\r\n                } else {\r\n                    this.evalParam = Type.createEvalFunction(board, params, params.length);\r\n                }\r\n                this.update = function () {\r\n                    var a = this.evalParam(0), // angle\r\n                        n = this.evalParam(1), // normal\r\n                        p = [1, 0, 0, 0],\r\n                        co = Math.cos(a),\r\n                        si = Math.sin(a),\r\n                        n1, n2, n3,\r\n                        m1 = [\r\n                            [1, 0, 0, 0],\r\n                            [0, 1, 0, 0],\r\n                            [0, 0, 1, 0],\r\n                            [0, 0, 0, 1]\r\n                        ],\r\n                        m2 = [\r\n                            [1, 0, 0, 0],\r\n                            [0, 1, 0, 0],\r\n                            [0, 0, 1, 0],\r\n                            [0, 0, 0, 1]\r\n                        ],\r\n                        nrm = Mat.norm(n);\r\n\r\n                    if (n.length === 3) {\r\n                        n1 = n[0] / nrm;\r\n                        n2 = n[1] / nrm;\r\n                        n3 = n[2] / nrm;\r\n                    } else {\r\n                        n1 = n[1] / nrm;\r\n                        n2 = n[2] / nrm;\r\n                        n3 = n[3] / nrm;\r\n                    }\r\n                    if (params.length === 3) {\r\n                        if (params.length === 3 && Type.exists(params[2].is3D)) {\r\n                            p = params[2].coords.slice();\r\n                        } else {\r\n                            p = this.evalParam(2);\r\n                        }\r\n                        if (p.length === 3) {\r\n                            p.unshift(1);\r\n                        }\r\n                        m1[1][0] = -p[1];\r\n                        m1[2][0] = -p[2];\r\n                        m1[3][0] = -p[3];\r\n\r\n                        m2[1][0] = p[1];\r\n                        m2[2][0] = p[2];\r\n                        m2[3][0] = p[3];\r\n                    }\r\n\r\n                    this.matrix = [\r\n                        [1, 0, 0, 0],\r\n                        [0, n1 * n1 * (1 - co) +      co, n1 * n2 * (1 - co) - n3 * si, n1 * n3 * (1 - co) + n2 * si],\r\n                        [0, n2 * n1 * (1 - co) + n3 * si, n2 * n2 * (1 - co) +      co, n2 * n3 * (1 - co) - n1 * si],\r\n                        [0, n3 * n1 * (1 - co) - n2 * si, n3 * n2 * (1 - co) + n1 * si, n3 * n3 * (1 - co) +      co]\r\n                    ];\r\n                    this.matrix = Mat.matMatMult(this.matrix, m1);\r\n                    this.matrix = Mat.matMatMult(m2, this.matrix);\r\n                };\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Transform a point element, that are: {@link Point}, {@link Text}, {@link Image}, {@link Point3D}.\r\n         * First, the transformation matrix is updated, then do the matrix-vector-multiplication.\r\n         * <p>\r\n         * Restricted to 2D transformations.\r\n         *\r\n         * @private\r\n         * @param {JXG.GeometryElement} p element which is transformed\r\n         * @param {String} 'self' Apply the transformation to the initialCoords instead of the coords if this is set.\r\n         * @returns {Array}\r\n         */\r\n        apply: function (p, self) {\r\n            var c;\r\n\r\n            this.update();\r\n            if (this.is3D) {\r\n                c = p.coords;\r\n            } else if (Type.exists(self)) {\r\n                c = p.initialCoords.usrCoords;\r\n            } else {\r\n                c = p.coords.usrCoords;\r\n            }\r\n\r\n            return Mat.matVecMult(this.matrix, c);\r\n        },\r\n\r\n        /**\r\n         * Applies a transformation once to a point element, that are: {@link Point}, {@link Text}, {@link Image}, {@link Point3D} or to an array of such elements.\r\n         * If it is a free 2D point, then it can be dragged around later\r\n         * and will overwrite the transformed coordinates.\r\n         * @param {JXG.Point|Array} p\r\n         */\r\n        applyOnce: function (p) {\r\n            var c, len, i;\r\n\r\n            if (!Type.isArray(p)) {\r\n                p = [p];\r\n            }\r\n\r\n            len = p.length;\r\n            for (i = 0; i < len; i++) {\r\n                this.update();\r\n                if (this.is3D) {\r\n                    p[i].coords = Mat.matVecMult(this.matrix, p[i].coords);\r\n                } else {\r\n                    c = Mat.matVecMult(this.matrix, p[i].coords.usrCoords);\r\n                    p[i].coords.setCoordinates(Const.COORDS_BY_USER, c);\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Binds a transformation to a GeometryElement or an array of elements. In every update of the\r\n         * GeometryElement(s), the transformation is executed. That means, in order to immediately\r\n         * apply the transformation after calling bindTo, a call of board.update() has to follow.\r\n         * <p>\r\n         * The transformation is simply appended to the existing list of transformations of the object.\r\n         * It is not fused (melt) with an existing transformation.\r\n         *\r\n         * @param  {Array|JXG.Object} el JXG.Object or array of JXG.Object to\r\n         *                            which the transformation is bound to.\r\n         * @see JXG.Transformation.meltTo\r\n         */\r\n        bindTo: function (el) {\r\n            var i, len;\r\n            if (Type.isArray(el)) {\r\n                len = el.length;\r\n\r\n                for (i = 0; i < len; i++) {\r\n                    el[i].transformations.push(this);\r\n                }\r\n            } else {\r\n                el.transformations.push(this);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Binds a transformation to a GeometryElement or an array of elements. In every update of the\r\n         * GeometryElement(s), the transformation is executed. That means, in order to immediately\r\n         * apply the transformation after calling meltTo, a call of board.update() has to follow.\r\n         * <p>\r\n         * In case the last transformation of the element and this transformation are static,\r\n         * i.e. the transformation matrices do not depend on other elements,\r\n         * the transformation will be fused into (multiplied with) the last transformation of\r\n         * the element. Thus, the list of transformations is kept small.\r\n         * If the transformation will be the first transformation ot the element, it will be cloned\r\n         * to prevent side effects.\r\n         *\r\n         * @param  {Array|JXG.Object} el JXG.Object or array of JXG.Objects to\r\n         *                            which the transformation is bound to.\r\n         *\r\n         * @see JXG.Transformation#bindTo\r\n         */\r\n        meltTo: function (el) {\r\n            var i, elt, t;\r\n\r\n            if (Type.isArray(el)) {\r\n                for (i = 0; i < el.length; i++) {\r\n                    this.meltTo(el[i]);\r\n                }\r\n            } else {\r\n                elt = el.transformations;\r\n                if (elt.length > 0 &&\r\n                    elt[elt.length - 1].isNumericMatrix &&\r\n                    this.isNumericMatrix\r\n                ) {\r\n                    elt[elt.length - 1].melt(this);\r\n                } else {\r\n                    // Use a clone of the transformation.\r\n                    // Otherwise, if the transformation is meltTo twice\r\n                    // the transformation will be changed.\r\n                    t = this.clone();\r\n                    elt.push(t);\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Create a copy of the transformation in case it is static, i.e.\r\n         * if the transformation matrix does not depend on other elements.\r\n         * <p>\r\n         * If the transformation matrix is not static, null will be returned.\r\n         *\r\n         * @returns {JXG.Transformation}\r\n         */\r\n        clone: function() {\r\n            var t = null;\r\n\r\n            if (this.isNumericMatrix) {\r\n                t = new JXG.Transformation(this.board, 'none', []);\r\n                t.matrix = this.matrix.slice();\r\n            }\r\n\r\n            return t;\r\n        },\r\n\r\n        /**\r\n         * Unused\r\n         * @deprecated Use setAttribute\r\n         * @param term\r\n         */\r\n        setProperty: function (term) {\r\n            JXG.deprecated(\"Transformation.setProperty()\", \"Transformation.setAttribute()\");\r\n        },\r\n\r\n        /**\r\n         * Empty method. Unused.\r\n         * @param {Object} term Key-value pairs of the attributes.\r\n         */\r\n        setAttribute: function (term) {},\r\n\r\n        /**\r\n         * Combine two transformations to one transformation. This only works if\r\n         * both of transformation matrices consist of numbers solely, and do not\r\n         * contain functions.\r\n         *\r\n         * Multiplies the transformation with a transformation t from the left.\r\n         * i.e. (this) = (t) join (this)\r\n         * @param  {JXG.Transform} t Transformation which is the left multiplicand\r\n         * @returns {JXG.Transform} the transformation object.\r\n         */\r\n        melt: function (t) {\r\n            var res = [];\r\n\r\n            this.update();\r\n            t.update();\r\n\r\n            res = Mat.matMatMult(t.matrix, this.matrix);\r\n\r\n            this.update = function () {\r\n                this.matrix = res;\r\n            };\r\n\r\n            return this;\r\n        },\r\n\r\n        // Documented in element.js\r\n        // Not yet, since transformations are not listed in board.objects.\r\n        getParents: function () {\r\n            var p = [[].concat.apply([], this.matrix)];\r\n\r\n            if (this.parents.length !== 0) {\r\n                p = this.parents;\r\n            }\r\n\r\n            return p;\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * @class Define projective 2D transformations like translation, rotation, reflection.\r\n * @pseudo\r\n * @description A transformation consists of a 3x3 matrix, i.e. it is a projective transformation.\r\n * <p>\r\n * Internally, a transformation is applied to an element by multiplying the 3x3 matrix from the left to\r\n * the homogeneous coordinates of the element. JSXGraph represents homogeneous coordinates in the order\r\n * (z, x, y). The matrix has the form\r\n * <pre>\r\n * ( a  b  c )   ( z )\r\n * ( d  e  f ) * ( x )\r\n * ( g  h  i )   ( y )\r\n * </pre>\r\n * where in general a=1. If b = c = 0, the transformation is called <i>affine</i>.\r\n * In this case, finite points will stay finite. This is not the case for general projective coordinates.\r\n * <p>\r\n * Transformations acting on texts and images are considered to be affine, i.e. b and c are ignored.\r\n *\r\n * @name Transformation\r\n * @augments JXG.Transformation\r\n * @constructor\r\n * @type JXG.Transformation\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {number|function|JXG.GeometryElement} parameters The parameters depend on the transformation type, supplied as attribute 'type'.\r\n * Possible transformation types are\r\n * <ul>\r\n * <li> 'translate'\r\n * <li> 'scale'\r\n * <li> 'reflect'\r\n * <li> 'rotate'\r\n * <li> 'shear'\r\n * <li> 'generic'\r\n * <li> 'matrix'\r\n * </ul>\r\n * <p>Valid parameters for these types are:\r\n * <dl>\r\n * <dt><b><tt>type:\"translate\"</tt></b></dt><dd><b>x, y</b> Translation vector (two numbers or functions).\r\n * The transformation matrix for x = a and y = b has the form:\r\n * <pre>\r\n * ( 1  0  0)   ( z )\r\n * ( a  1  0) * ( x )\r\n * ( b  0  1)   ( y )\r\n * </pre>\r\n * </dd>\r\n * <dt><b><tt>type:\"scale\"</tt></b></dt><dd><b>scale_x, scale_y</b> Scale vector (two numbers or functions).\r\n * The transformation matrix for scale_x = a and scale_y = b has the form:\r\n * <pre>\r\n * ( 1  0  0)   ( z )\r\n * ( 0  a  0) * ( x )\r\n * ( 0  0  b)   ( y )\r\n * </pre>\r\n * </dd>\r\n * <dt><b><tt>type:\"rotate\"</tt></b></dt><dd> <b>alpha, [point | x, y]</b> The parameters are the angle value in Radians\r\n *     (a number or function), and optionally a coordinate pair (two numbers or functions) or a point element defining the\r\n *                rotation center. If the rotation center is not given, the transformation rotates around (0,0).\r\n * The transformation matrix for angle a and rotating around (0, 0) has the form:\r\n * <pre>\r\n * ( 1    0        0      )   ( z )\r\n * ( 0    cos(a)   -sin(a)) * ( x )\r\n * ( 0    sin(a)   cos(a) )   ( y )\r\n * </pre>\r\n * </dd>\r\n * <dt><b><tt>type:\"shear\"</tt></b></dt><dd><b>shear_x, shear_y</b> Shear vector (two numbers or functions).\r\n * The transformation matrix for shear_x = a and shear_y = b has the form:\r\n * <pre>\r\n * ( 1  0  0)   ( z )\r\n * ( 0  1  a) * ( x )\r\n * ( 0  b  1)   ( y )\r\n * </pre>\r\n * </dd>\r\n * <dt><b><tt>type:\"reflect\"</tt></b></dt><dd>The parameters can either be:\r\n *    <ul>\r\n *      <li> <b>line</b> a line element,\r\n *      <li> <b>p, q</b> two point elements,\r\n *      <li> <b>p_x, p_y, q_x, q_y</b> four numbers or functions  determining a line through points (p_x, p_y) and (q_x, q_y).\r\n *    </ul>\r\n * </dd>\r\n * <dt><b><tt>type:\"generic\"</tt></b></dt><dd><b>a, b, c, d, e, f, g, h, i</b> Nine matrix entries (numbers or functions)\r\n *  for a generic projective transformation.\r\n * The matrix has the form\r\n * <pre>\r\n * ( a  b  c )   ( z )\r\n * ( d  e  f ) * ( x )\r\n * ( g  h  i )   ( y )\r\n * </pre>\r\n * </dd>\r\n * <dt><b><tt>type:\"matrix\"</tt></b></dt><dd><b>M</b> 3x3 transformation matrix containing numbers or functions</dd>\r\n * </dl>\r\n *\r\n *\r\n * @see JXG.Transformation#setMatrix\r\n *\r\n * @example\r\n * // The point B is determined by taking twice the vector A from the origin\r\n *\r\n * var p0 = board.create('point', [0, 3], {name: 'A'}),\r\n *     t = board.create('transform', [function(){ return p0.X(); }, \"Y(A)\"], {type: 'translate'}),\r\n *     p1 = board.create('point', [p0, t], {color: 'blue'});\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXG14167b0c-2ad3-11e5-8dd9-901b0e1b8723\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG14167b0c-2ad3-11e5-8dd9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p0 = board.create('point', [0, 3], {name: 'A'}),\r\n *         t = board.create('transform', [function(){ return p0.X(); }, \"Y(A)\"], {type:'translate'}),\r\n *         p1 = board.create('point', [p0, t], {color: 'blue'});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // The point B is the result of scaling the point A with factor 2 in horizontal direction\r\n * // and with factor 0.5 in vertical direction.\r\n *\r\n * var p1 = board.create('point', [1, 1]),\r\n *     t = board.create('transform', [2, 0.5], {type: 'scale'}),\r\n *     p2 = board.create('point', [p1, t], {color: 'blue'});\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXGa6827a72-2ad3-11e5-8dd9-901b0e1b8723\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGa6827a72-2ad3-11e5-8dd9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p1 = board.create('point', [1, 1]),\r\n *         t = board.create('transform', [2, 0.5], {type: 'scale'}),\r\n *         p2 = board.create('point', [p1, t], {color: 'blue'});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // The point B is rotated around C which gives point D. The angle is determined\r\n * // by the vertical height of point A.\r\n *\r\n * var p0 = board.create('point', [0, 3], {name: 'A'}),\r\n *     p1 = board.create('point', [1, 1]),\r\n *     p2 = board.create('point', [2, 1], {name:'C', fixed: true}),\r\n *\r\n *     // angle, rotation center:\r\n *     t = board.create('transform', ['Y(A)', p2], {type: 'rotate'}),\r\n *     p3 = board.create('point', [p1, t], {color: 'blue'});\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXG747cf11e-2ad4-11e5-8dd9-901b0e1b8723\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG747cf11e-2ad4-11e5-8dd9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p0 = board.create('point', [0, 3], {name: 'A'}),\r\n *         p1 = board.create('point', [1, 1]),\r\n *         p2 = board.create('point', [2, 1], {name:'C', fixed: true}),\r\n *\r\n *         // angle, rotation center:\r\n *         t = board.create('transform', ['Y(A)', p2], {type: 'rotate'}),\r\n *         p3 = board.create('point', [p1, t], {color: 'blue'});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // A concatenation of several transformations.\r\n * var p1 = board.create('point', [1, 1]),\r\n *     t1 = board.create('transform', [-2, -1], {type: 'translate'}),\r\n *     t2 = board.create('transform', [Math.PI/4], {type: 'rotate'}),\r\n *     t3 = board.create('transform', [2, 1], {type: 'translate'}),\r\n *     p2 = board.create('point', [p1, [t1, t2, t3]], {color: 'blue'});\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXGf516d3de-2ad5-11e5-8dd9-901b0e1b8723\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGf516d3de-2ad5-11e5-8dd9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p1 = board.create('point', [1, 1]),\r\n *         t1 = board.create('transform', [-2, -1], {type:'translate'}),\r\n *         t2 = board.create('transform', [Math.PI/4], {type:'rotate'}),\r\n *         t3 = board.create('transform', [2, 1], {type:'translate'}),\r\n *         p2 = board.create('point', [p1, [t1, t2, t3]], {color: 'blue'});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Reflection of point A\r\n * var p1 = board.create('point', [1, 1]),\r\n *     p2 = board.create('point', [1, 3]),\r\n *     p3 = board.create('point', [-2, 0]),\r\n *     l = board.create('line', [p2, p3]),\r\n *     t = board.create('transform', [l], {type: 'reflect'}),  // Possible are l, l.id, l.name\r\n *     p4 = board.create('point', [p1, t], {color: 'blue'});\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXG6f374a04-2ad6-11e5-8dd9-901b0e1b8723\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG6f374a04-2ad6-11e5-8dd9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p1 = board.create('point', [1, 1]),\r\n *         p2 = board.create('point', [1, 3]),\r\n *         p3 = board.create('point', [-2, 0]),\r\n *         l = board.create('line', [p2, p3]),\r\n *         t = board.create('transform', [l], {type:'reflect'}),  // Possible are l, l.id, l.name\r\n *         p4 = board.create('point', [p1, t], {color: 'blue'});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Type: 'matrix'\r\n *         var y = board.create('slider', [[-3, 1], [-3, 4], [0, 1, 6]]);\r\n *         var t1 = board.create('transform', [\r\n *             [\r\n *                 [1, 0, 0],\r\n *                 [0, 1, 0],\r\n *                 [() => y.Value(), 0, 1]\r\n *             ]\r\n *         ], {type: 'matrix'});\r\n *\r\n *         var A = board.create('point', [2, -3]);\r\n *         var B = board.create('point', [A, t1]);\r\n *\r\n * </pre><div id=\"JXGd2bfd46c-3c0c-45c5-a92b-583fad0eb3ec\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGd2bfd46c-3c0c-45c5-a92b-583fad0eb3ec',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *             var y = board.create('slider', [[-3, 1], [-3, 4], [0, 1, 6]]);\r\n *             var t1 = board.create('transform', [\r\n *                 [\r\n *                     [1, 0, 0],\r\n *                     [0, 1, 0],\r\n *                     [() => y.Value(), 0, 1]\r\n *                 ]\r\n *             ], {type: 'matrix'});\r\n *\r\n *             var A = board.create('point', [2, -3]);\r\n *             var B = board.create('point', [A, t1]);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // One time application of a transform to points A, B\r\n * var p1 = board.create('point', [1, 1]),\r\n *     p2 = board.create('point', [-1, -2]),\r\n *     t = board.create('transform', [3, 2], {type: 'shear'});\r\n * t.applyOnce([p1, p2]);\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXGb6cee1c4-2ad6-11e5-8dd9-901b0e1b8723\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGb6cee1c4-2ad6-11e5-8dd9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8, -8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p1 = board.create('point', [1, 1]),\r\n *         p2 = board.create('point', [-1, -2]),\r\n *         t = board.create('transform', [3, 2], {type: 'shear'});\r\n *     t.applyOnce([p1, p2]);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Construct a square of side length 2 with the\r\n * // help of transformations\r\n *     var sq = [],\r\n *         right = board.create('transform', [2, 0], {type: 'translate'}),\r\n *         up = board.create('transform', [0, 2], {type: 'translate'}),\r\n *         pol, rot, p0;\r\n *\r\n *     // The first point is free\r\n *     sq[0] = board.create('point', [0, 0], {name: 'Drag me'}),\r\n *\r\n *     // Construct the other free points by transformations\r\n *     sq[1] = board.create('point', [sq[0], right]),\r\n *     sq[2] = board.create('point', [sq[0], [right, up]]),\r\n *     sq[3] = board.create('point', [sq[0], up]),\r\n *\r\n *     // Polygon through these four points\r\n *     pol = board.create('polygon', sq, {\r\n *             fillColor:'blue',\r\n *             gradient:'radial',\r\n *             gradientsecondcolor:'white',\r\n *             gradientSecondOpacity:'0'\r\n *     }),\r\n *\r\n *     p0 = board.create('point', [0, 3], {name: 'angle'}),\r\n *     // Rotate the square around point sq[0] by dragging A vertically.\r\n *     rot = board.create('transform', ['Y(angle)', sq[0]], {type: 'rotate'});\r\n *\r\n *     // Apply the rotation to all but the first point of the square\r\n *     rot.bindTo(sq.slice(1));\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXGc7f9097e-2ad7-11e5-8dd9-901b0e1b8723\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGc7f9097e-2ad7-11e5-8dd9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     // Construct a square of side length 2 with the\r\n *     // help of transformations\r\n *     var sq = [],\r\n *         right = board.create('transform', [2, 0], {type: 'translate'}),\r\n *         up = board.create('transform', [0, 2], {type: 'translate'}),\r\n *         pol, rot, p0;\r\n *\r\n *     // The first point is free\r\n *     sq[0] = board.create('point', [0, 0], {name: 'Drag me'}),\r\n *\r\n *     // Construct the other free points by transformations\r\n *     sq[1] = board.create('point', [sq[0], right]),\r\n *     sq[2] = board.create('point', [sq[0], [right, up]]),\r\n *     sq[3] = board.create('point', [sq[0], up]),\r\n *\r\n *     // Polygon through these four points\r\n *     pol = board.create('polygon', sq, {\r\n *             fillColor:'blue',\r\n *             gradient:'radial',\r\n *             gradientsecondcolor:'white',\r\n *             gradientSecondOpacity:'0'\r\n *     }),\r\n *\r\n *     p0 = board.create('point', [0, 3], {name: 'angle'}),\r\n *     // Rotate the square around point sq[0] by dragging A vertically.\r\n *     rot = board.create('transform', ['Y(angle)', sq[0]], {type: 'rotate'});\r\n *\r\n *     // Apply the rotation to all but the first point of the square\r\n *     rot.bindTo(sq.slice(1));\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Text transformation\r\n * var p0 = board.create('point', [0, 0], {name: 'p_0'});\r\n * var p1 = board.create('point', [3, 0], {name: 'p_1'});\r\n * var txt = board.create('text',[0.5, 0, 'Hello World'], {display:'html'});\r\n *\r\n * // If p_0 is dragged, translate p_1 and text accordingly\r\n * var tOff = board.create('transform', [() => p0.X(), () => p0.Y()], {type:'translate'});\r\n * tOff.bindTo(txt);\r\n * tOff.bindTo(p1);\r\n *\r\n * // Rotate text around p_0 by dragging point p_1\r\n * var tRot = board.create('transform', [\r\n *     () => Math.atan2(p1.Y() - p0.Y(), p1.X() - p0.X()), p0], {type:'rotate'});\r\n * tRot.bindTo(txt);\r\n *\r\n * // Scale text by dragging point \"p_1\"\r\n * // We do this by\r\n * // - moving text by -p_0 (inverse of transformation tOff),\r\n * // - scale the text (because scaling is relative to (0,0))\r\n * // - move the text back by +p_0\r\n * var tOffInv = board.create('transform', [\r\n *         () => -p0.X(),\r\n *         () => -p0.Y()\r\n * ], {type:'translate'});\r\n * var tScale = board.create('transform', [\r\n *         // Some scaling factor\r\n *         () => p1.Dist(p0) / 3,\r\n *         () => p1.Dist(p0) / 3\r\n * ], {type:'scale'});\r\n * tOffInv.bindTo(txt); tScale.bindTo(txt); tOff.bindTo(txt);\r\n *\r\n * </pre><div id=\"JXG50d6d546-3b91-41dd-8c0f-3eaa6cff7e66\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG50d6d546-3b91-41dd-8c0f-3eaa6cff7e66',\r\n *             {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p0 = board.create('point', [0, 0], {name: 'p_0'});\r\n *     var p1 = board.create('point', [3, 0], {name: 'p_1'});\r\n *     var txt = board.create('text',[0.5, 0, 'Hello World'], {display:'html'});\r\n *\r\n *     // If p_0 is dragged, translate p_1 and text accordingly\r\n *     var tOff = board.create('transform', [() => p0.X(), () => p0.Y()], {type:'translate'});\r\n *     tOff.bindTo(txt);\r\n *     tOff.bindTo(p1);\r\n *\r\n *     // Rotate text around p_0 by dragging point p_1\r\n *     var tRot = board.create('transform', [\r\n *         () => Math.atan2(p1.Y() - p0.Y(), p1.X() - p0.X()), p0], {type:'rotate'});\r\n *     tRot.bindTo(txt);\r\n *\r\n *     // Scale text by dragging point \"p_1\"\r\n *     // We do this by\r\n *     // - moving text by -p_0 (inverse of transformation tOff),\r\n *     // - scale the text (because scaling is relative to (0,0))\r\n *     // - move the text back by +p_0\r\n *     var tOffInv = board.create('transform', [\r\n *             () => -p0.X(),\r\n *             () => -p0.Y()\r\n *     ], {type:'translate'});\r\n *     var tScale = board.create('transform', [\r\n *             // Some scaling factor\r\n *             () => p1.Dist(p0) / 3,\r\n *             () => p1.Dist(p0) / 3\r\n *     ], {type:'scale'});\r\n *     tOffInv.bindTo(txt); tScale.bindTo(txt); tOff.bindTo(txt);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createTransform = function (board, parents, attributes) {\r\n    return new JXG.Transformation(board, attributes.type, parents);\r\n};\r\n\r\nJXG.registerElement('transform', JXG.createTransform);\r\n\r\n/**\r\n * @class Define projective 3D transformations like translation, rotation, reflection.\r\n * @pseudo\r\n * @description A transformation consists of a 4x4 matrix, i.e. it is a projective transformation.\r\n * <p>\r\n * Internally, a transformation is applied to an element by multiplying the 4x4 matrix from the left to\r\n * the homogeneous coordinates of the element. JSXGraph represents homogeneous coordinates in the order\r\n * (w, x, y, z). If the coordinate is a finite point, w=1. The matrix has the form\r\n * <pre>\r\n * ( a b c d)   ( w )\r\n * ( e f g h) * ( x )\r\n * ( i j k l)   ( y )\r\n * ( m n o p)   ( z )\r\n * </pre>\r\n * where in general a=1. If b = c = d = 0, the transformation is called <i>affine</i>.\r\n * In this case, finite points will stay finite. This is not the case for general projective coordinates.\r\n * <p>\r\n *\r\n * @name Transformation3D\r\n * @augments JXG.Transformation\r\n * @constructor\r\n * @type JXG.Transformation\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {number|function|JXG.GeometryElement3D} parameters The parameters depend on the transformation type, supplied as attribute 'type'.\r\n *  Possible transformation types are\r\n * <ul>\r\n * <li> 'translate'\r\n * <li> 'scale'\r\n * <li> 'rotate'\r\n * <li> 'rotateX'\r\n * <li> 'rotateY'\r\n * <li> 'rotateZ'\r\n * </ul>\r\n * <p>Valid parameters for these types are:\r\n * <dl>\r\n * <dt><b><tt>type:\"translate\"</tt></b></dt><dd><b>x, y, z</b> Translation vector (three numbers or functions).\r\n * The transformation matrix for x = a, y = b, and z = c has the form:\r\n * <pre>\r\n * ( 1  0  0  0)   ( w )\r\n * ( a  1  0  0) * ( x )\r\n * ( b  0  1  0)   ( y )\r\n * ( c  0  0  c)   ( z )\r\n * </pre>\r\n * </dd>\r\n * <dt><b><tt>type:\"scale\"</tt></b></dt><dd><b>scale_x, scale_y, scale_z</b> Scale vector (three numbers or functions).\r\n * The transformation matrix for scale_x = a, scale_y = b, scale_z = c has the form:\r\n * <pre>\r\n * ( 1  0  0  0)   ( w )\r\n * ( 0  a  0  0) * ( x )\r\n * ( 0  0  b  0)   ( y )\r\n * ( 0  0  0  c)   ( z )\r\n * </pre>\r\n * </dd>\r\n * <dt><b><tt>type:\"rotate\"</tt></b></dt><dd><b>a, n, [p=[0,0,0]]</b> angle (in radians), normal, [point].\r\n * Rotate with angle a around the normal vector n through the point p.\r\n * </dd>\r\n * <dt><b><tt>type:\"rotateX\"</tt></b></dt><dd><b>a, [p=[0,0,0]]</b> angle (in radians), [point].\r\n * Rotate with angle a around the normal vector (1, 0, 0) through the point p.\r\n * </dd>\r\n * <dt><b><tt>type:\"rotateY\"</tt></b></dt><dd><b>a, [p=[0,0,0]]</b> angle (in radians), [point].\r\n * Rotate with angle a around the normal vector (0, 1, 0) through the point p.\r\n * </dd>\r\n * <dt><b><tt>type:\"rotateZ\"</tt></b></dt><dd><b>a, [p=[0,0,0]]</b> angle (in radians), [point].\r\n * Rotate with angle a around the normal vector (0, 0, 1) through the point p.\r\n * </dd>\r\n * </dl>\r\n *\r\n * @example\r\n * var bound = [-5, 5];\r\n * var view = board.create('view3d',\r\n *     [\r\n *         [-5, -5], [8, 8],\r\n *         [bound, bound, bound]\r\n *     ], {\r\n *         projection: \"central\",\r\n *         depthOrder: { enabled: true },\r\n *         axesPosition: 'border' // 'center', 'none'\r\n *     }\r\n * );\r\n *\r\n * var slider = board.create('slider', [[-4, 6], [0, 6], [0, 0, 5]]);\r\n *\r\n * var p1 = view.create('point3d', [1, 2, 2], { name: 'drag me', size: 5 });\r\n *\r\n * // Translate from p1 by fixed amount\r\n * var t1 = view.create('transform3d', [2, 3, 2], { type: 'translate' });\r\n * // Translate from p1 by dynamic amount\r\n * var t2 = view.create('transform3d', [() => slider.Value() + 3, 0, 0], { type: 'translate' });\r\n *\r\n * view.create('point3d', [p1, t1], { name: 'translate fixed', size: 5 });\r\n * view.create('point3d', [p1, t2], { name: 'translate by func', size: 5 });\r\n *\r\n * </pre><div id=\"JXG2409bb0a-90d7-4c1e-ae9f-85e8a776acec\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG2409bb0a-90d7-4c1e-ae9f-85e8a776acec',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var bound = [-5, 5];\r\n *     var view = board.create('view3d',\r\n *         [\r\n *             [-5, -5], [8, 8],\r\n *             [bound, bound, bound]\r\n *         ], {\r\n *             projection: \"central\",\r\n *             depthOrder: { enabled: true },\r\n *             axesPosition: 'border' // 'center', 'none'\r\n *         }\r\n *     );\r\n *\r\n *     var slider = board.create('slider', [[-4, 6], [0, 6], [0, 0, 5]]);\r\n *\r\n *     var p1 = view.create('point3d', [1, 2, 2], { name: 'drag me', size: 5 });\r\n *\r\n *     // Translate from p1 by fixed amount\r\n *     var t1 = view.create('transform3d', [2, 3, 2], { type: 'translate' });\r\n *     // Translate from p1 by dynamic amount\r\n *     var t2 = view.create('transform3d', [() => slider.Value() + 3, 0, 0], { type: 'translate' });\r\n *\r\n *     view.create('point3d', [p1, t1], { name: 'translate fixed', size: 5 });\r\n *     view.create('point3d', [p1, t2], { name: 'translate by func', size: 5 });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createTransform3D = function (board, parents, attributes) {\r\n    return new JXG.Transformation(board, attributes.type, parents, true);\r\n};\r\n\r\nJXG.registerElement('transform3d', JXG.createTransform3D);\r\n\r\nexport default JXG.Transformation;\r\n\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview The JSXGraph object Turtle is defined. It acts like\r\n * \"turtle graphics\".\r\n * @author A.W.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"./constants.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport GeometryElement from \"./element.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Constructs a new Turtle object.\r\n * @class This is the Turtle class.\r\n * It is derived from {@link JXG.GeometryElement}.\r\n * It stores all properties required\r\n * to move a turtle.\r\n * @constructor\r\n * @param {JXG.Board} board The board the new turtle is drawn on.\r\n * @param {Array} parents Start position and start direction of the turtle. Possible values are\r\n * [x, y, angle]\r\n * [[x, y], angle]\r\n * [x, y]\r\n * [[x, y]]\r\n * @param {Object} attributes Attributes to change the visual properties of the turtle object\r\n * All angles are in degrees.\r\n *\r\n * @example\r\n *\r\n * //creates a figure 8 animation\r\n * var board = JXG.JSXGraph.initBoard('jxgbox',{boundingbox: [-250, 250, 250, -250]});\r\n * var t = board.create('turtle',[0, 0], {strokeOpacity:0.5});\r\n * t.setPenSize(3);\r\n * t.right(90);\r\n * var alpha = 0;\r\n *\r\n * var run = function() {\r\n *  t.forward(2);\r\n *  if (Math.floor(alpha / 360) % 2 === 0) {\r\n *   t.left(1);        // turn left by 1 degree\r\n *  } else {\r\n *   t.right(1);       // turn right by 1 degree\r\n *  }\r\n *  alpha += 1;\r\n *\r\n *  if (alpha < 1440) {  // stop after two rounds\r\n *   setTimeout(run, 20);\r\n *  }\r\n * }\r\n *\r\n *run();\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXG14167b1c-2ad3-11e5-8dd9-901b0e1b8723\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var brd = JXG.JSXGraph.initBoard('JXG14167b1c-2ad3-11e5-8dd9-901b0e1b8723',\r\n *             {boundingbox: [-250, 250, 250, -250], axis: true, showcopyright: false, shownavigation: false});\r\n *               var t = brd.create('turtle',[0, 0], {strokeOpacity:0.5});\r\n *               t.setPenSize(3);\r\n *               t.right(90);\r\n *               var alpha = 0;\r\n *\r\n *              var run = function() {\r\n *              t.forward(2);\r\n *             if (Math.floor(alpha / 360) % 2 === 0) {\r\n *                t.left(1);        // turn left by 1 degree\r\n *              } else {\r\n *                   t.right(1);       // turn right by 1 degree\r\n *             }\r\n *             alpha += 1;\r\n *\r\n *             if (alpha < 1440) {  // stop after two rounds\r\n *                 setTimeout(run, 20);\r\n *               }\r\n *             }\r\n *\r\n *          run();\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n */\r\nJXG.Turtle = function (board, parents, attributes) {\r\n    var x, y, dir;\r\n\r\n    this.constructor(board, attributes, Const.OBJECT_TYPE_TURTLE, Const.OBJECT_CLASS_OTHER);\r\n\r\n    this.turtleIsHidden = false;\r\n    this.board = board;\r\n    this.visProp.curveType = 'plot';\r\n\r\n    // Save visProp in this._attributes.\r\n    // this._attributes is overwritten by setPenSize, setPenColor...\r\n    // Setting the color or size affects the turtle from the time of\r\n    // calling the method,\r\n    // whereas Turtle.setAttribute affects all turtle curves.\r\n    this._attributes = Type.copyAttributes(this.visProp, board.options, 'turtle');\r\n    delete this._attributes.id;\r\n\r\n    x = 0;\r\n    y = 0;\r\n    dir = 90;\r\n\r\n    if (parents.length !== 0) {\r\n        // [x,y,dir]\r\n        if (parents.length === 3) {\r\n            // Only numbers are accepted at the moment\r\n            x = parents[0];\r\n            y = parents[1];\r\n            dir = parents[2];\r\n        } else if (parents.length === 2) {\r\n            // [[x,y],dir]\r\n            if (Type.isArray(parents[0])) {\r\n                x = parents[0][0];\r\n                y = parents[0][1];\r\n                dir = parents[1];\r\n                // [x,y]\r\n            } else {\r\n                x = parents[0];\r\n                y = parents[1];\r\n            }\r\n            // [[x,y]]\r\n        } else {\r\n            x = parents[0][0];\r\n            y = parents[0][1];\r\n        }\r\n    }\r\n\r\n    this.init(x, y, dir);\r\n\r\n        this.methodMap = Type.deepCopy(this.methodMap, {\r\n            forward: 'forward',\r\n            fd: 'forward',\r\n            back: 'back',\r\n            bk: 'back',\r\n            right: 'right',\r\n            rt: 'right',\r\n            left: 'left',\r\n            lt: 'left',\r\n            penUp: 'penUp',\r\n            pu: 'penUp',\r\n            up: 'penUp',\r\n            penDown: 'penDown',\r\n            pd: 'penDown',\r\n            down: 'penDown',\r\n            clearScreen: 'clearScreen',\r\n            cs: 'clearScreen',\r\n            clean: 'clean',\r\n            setPos: 'setPos',\r\n            home: 'home',\r\n            hideTurtle: 'hideTurtle',\r\n            ht: 'hideTurtle',\r\n            hide: 'hideTurtle',\r\n            showTurtle: 'showTurtle',\r\n            st: 'showTurtle',\r\n            show: 'showTurtle',\r\n            penSize: 'setPenSize',\r\n            setPenSize: 'setPenSize',\r\n            penColor: 'setPenColor',\r\n            setPenColor: 'setPenColor',\r\n            highlightPenColor: 'setHighlightPenColor',\r\n            setHighlightPenColor: 'setHighlightPenColor',\r\n            getPenColor: 'getPenColor',\r\n            Color: 'getPenColor',\r\n            getHighlightPenColor: 'getHighlightPenColor',\r\n            HighlightColor: 'getHighlightPenColor',\r\n            getPenSize: 'getPenSize',\r\n            Size: 'getPenSize',\r\n            pushTurtle: 'pushTurtle',\r\n            push: 'pushTurtle',\r\n            popTurtle: 'popTurtle',\r\n            pop: 'popTurtle',\r\n            lookTo: 'lookTo',\r\n            pos: 'pos',\r\n            Pos: 'pos',\r\n            moveTo: 'moveTo',\r\n            X: 'X',\r\n            Y: 'Y'\r\n        });\r\n\r\n    return this;\r\n};\r\n\r\nJXG.Turtle.prototype = new GeometryElement();\r\n\r\nJXG.extend(\r\n    JXG.Turtle.prototype,\r\n    /** @lends JXG.Turtle.prototype */ {\r\n        /**\r\n         * Initialize a new turtle or reinitialize a turtle after {@link JXG.Turtle#clearScreen}.\r\n         * @private\r\n         */\r\n        init: function (x, y, dir) {\r\n            var hiddenPointAttr = {\r\n                fixed: true,\r\n                name: \"\",\r\n                visible: false,\r\n                withLabel: false\r\n            };\r\n\r\n            this.arrowLen =\r\n                20 / Mat.hypot(this.board.unitX, this.board.unitY);\r\n\r\n            this.pos = [x, y];\r\n            this.isPenDown = true;\r\n            this.dir = 90;\r\n            this.stack = [];\r\n            this.objects = [];\r\n            this.curve = this.board.create(\r\n                \"curve\",\r\n                [[this.pos[0]], [this.pos[1]]],\r\n                this._attributes\r\n            );\r\n            this.objects.push(this.curve);\r\n\r\n            this.turtle = this.board.create(\"point\", this.pos, hiddenPointAttr);\r\n            this.objects.push(this.turtle);\r\n\r\n            this.turtle2 = this.board.create(\r\n                \"point\",\r\n                [this.pos[0], this.pos[1] + this.arrowLen],\r\n                hiddenPointAttr\r\n            );\r\n            this.objects.push(this.turtle2);\r\n\r\n            this.visProp.arrow.lastArrow = true;\r\n            this.visProp.arrow.straightFirst = false;\r\n            this.visProp.arrow.straightLast = false;\r\n            this.arrow = this.board.create(\r\n                \"line\",\r\n                [this.turtle, this.turtle2],\r\n                this.visProp.arrow\r\n            );\r\n            this.objects.push(this.arrow);\r\n\r\n            this.subs = {\r\n                arrow: this.arrow\r\n            };\r\n            this.inherits.push(this.arrow);\r\n\r\n            this.right(90 - dir);\r\n            this.board.update();\r\n        },\r\n\r\n        /**\r\n         * Move the turtle forward.\r\n         * @param {Number} len of forward move in user coordinates\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        forward: function (len) {\r\n            if (len === 0) {\r\n                return this;\r\n            }\r\n\r\n            var t,\r\n                dx = len * Math.cos((this.dir * Math.PI) / 180),\r\n                dy = len * Math.sin((this.dir * Math.PI) / 180);\r\n\r\n            if (!this.turtleIsHidden) {\r\n                t = this.board.create(\"transform\", [dx, dy], { type: \"translate\" });\r\n\r\n                t.applyOnce(this.turtle);\r\n                t.applyOnce(this.turtle2);\r\n            }\r\n\r\n            if (this.isPenDown) {\r\n                // IE workaround\r\n                if (this.curve.dataX.length >= 8192) {\r\n                    this.curve = this.board.create(\r\n                        \"curve\",\r\n                        [[this.pos[0]], [this.pos[1]]],\r\n                        this._attributes\r\n                    );\r\n                    this.objects.push(this.curve);\r\n                }\r\n            }\r\n\r\n            this.pos[0] += dx;\r\n            this.pos[1] += dy;\r\n\r\n            if (this.isPenDown) {\r\n                this.curve.dataX.push(this.pos[0]);\r\n                this.curve.dataY.push(this.pos[1]);\r\n            }\r\n\r\n            this.board.update();\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Move the turtle backwards.\r\n         * @param {Number} len of backwards move in user coordinates\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        back: function (len) {\r\n            return this.forward(-len);\r\n        },\r\n\r\n        /**\r\n         * Rotate the turtle direction to the right\r\n         * @param {Number} angle of the rotation in degrees\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        right: function (angle) {\r\n            this.dir -= angle;\r\n            this.dir %= 360;\r\n\r\n            if (!this.turtleIsHidden) {\r\n                var t = this.board.create(\r\n                    \"transform\",\r\n                    [(-angle * Math.PI) / 180, this.turtle],\r\n                    { type: \"rotate\" }\r\n                );\r\n                t.applyOnce(this.turtle2);\r\n            }\r\n\r\n            this.board.update();\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Rotate the turtle direction to the right.\r\n         * @param {Number} angle of the rotation in degrees\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        left: function (angle) {\r\n            return this.right(-angle);\r\n        },\r\n\r\n        /**\r\n         * Pen up, stops visible drawing\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        penUp: function () {\r\n            this.isPenDown = false;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Pen down, continues visible drawing\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        penDown: function () {\r\n            this.isPenDown = true;\r\n            this.curve = this.board.create(\r\n                \"curve\",\r\n                [[this.pos[0]], [this.pos[1]]],\r\n                this._attributes\r\n            );\r\n            this.objects.push(this.curve);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Removes the turtle curve from the board. The turtle stays in its position.\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        clean: function () {\r\n            var i, el;\r\n\r\n            for (i = 0; i < this.objects.length; i++) {\r\n                el = this.objects[i];\r\n                if (el.type === Const.OBJECT_TYPE_CURVE) {\r\n                    this.board.removeObject(el);\r\n                    this.objects.splice(i, 1);\r\n                }\r\n            }\r\n\r\n            this.curve = this.board.create(\r\n                \"curve\",\r\n                [[this.pos[0]], [this.pos[1]]],\r\n                this._attributes\r\n            );\r\n            this.objects.push(this.curve);\r\n            this.board.update();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         *  Removes the turtle completely and resets it to its initial position and direction.\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        clearScreen: function () {\r\n            // var i,\r\n            //     el,\r\n            //     len = this.objects.length;\r\n            // for (i = len - 1; i >= 0; i--) {\r\n            //     el = this.objects[i];\r\n            //     this.board.removeObject(el);\r\n            // }\r\n            // It is much faster to remove the whole array of pathes.\r\n            this.board.removeObject(this.objects);\r\n            this.objects = [];\r\n\r\n            this.init(0, 0, 90);\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         *  Moves the turtle without drawing to a new position\r\n         * @param {Number} x new x- coordinate\r\n         * @param {Number} y new y- coordinate\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        setPos: function (x, y) {\r\n            var t;\r\n\r\n            if (Type.isArray(x)) {\r\n                this.pos = x;\r\n            } else {\r\n                this.pos = [x, y];\r\n            }\r\n\r\n            if (!this.turtleIsHidden) {\r\n                this.turtle.setPositionDirectly(Const.COORDS_BY_USER, [x, y]);\r\n                this.turtle2.setPositionDirectly(Const.COORDS_BY_USER, [x, y + this.arrowLen]);\r\n                t = this.board.create(\r\n                    \"transform\",\r\n                    [(-(this.dir - 90) * Math.PI) / 180, this.turtle],\r\n                    { type: \"rotate\" }\r\n                );\r\n                t.applyOnce(this.turtle2);\r\n            }\r\n\r\n            this.curve = this.board.create(\r\n                \"curve\",\r\n                [[this.pos[0]], [this.pos[1]]],\r\n                this._attributes\r\n            );\r\n            this.objects.push(this.curve);\r\n            this.board.update();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         *  Sets the pen size. Equivalent to setAttribute({strokeWidth:size})\r\n         * but affects only the future turtle.\r\n         * @param {Number} size\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        setPenSize: function (size) {\r\n            //this.visProp.strokewidth = size;\r\n            this.curve = this.board.create(\r\n                \"curve\",\r\n                [[this.pos[0]], [this.pos[1]]],\r\n                this.copyAttr(\"strokeWidth\", size)\r\n            );\r\n            this.objects.push(this.curve);\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         *  Sets the pen color. Equivalent to setAttribute({strokeColor:color})\r\n         * but affects only the future turtle.\r\n         * @param {String} color\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        setPenColor: function (color) {\r\n            this.curve = this.board.create(\r\n                \"curve\",\r\n                [[this.pos[0]], [this.pos[1]]],\r\n                this.copyAttr(\"strokeColor\", color)\r\n            );\r\n            this.objects.push(this.curve);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Get attribute of the last turtle curve object.\r\n         *\r\n         * @param {String} key\r\n         * @returns attribute value\r\n         * @private\r\n         */\r\n        getPenAttribute: function(key) {\r\n            var pos, le = this.objects.length;\r\n            if (le === 4) {\r\n                // No new turtle objects have been created\r\n                pos = 0;\r\n            } else {\r\n                pos = le - 1;\r\n            }\r\n            return this.objects[pos].evalVisProp(key);\r\n        },\r\n\r\n        /**\r\n         * Get most recently set turtle size (in pixel).\r\n         * @returns Number Size of the last turtle segment in pixel.\r\n         */\r\n        getPenSize: function() {\r\n            return this.getPenAttribute('strokewidth');\r\n        },\r\n\r\n        /**\r\n         * Get most recently set turtle color.\r\n         * @returns String RGB color value of the last turtle segment.\r\n         */\r\n        getPenColor: function() {\r\n            return this.getPenAttribute('strokecolor');\r\n        },\r\n\r\n        /**\r\n         * Get most recently set turtle color.\r\n         * @returns String RGB highlight color value of the last turtle segment.\r\n         */\r\n         getHighlightPenColor: function() {\r\n            return this.getPenAttribute('highlightstrokecolor');\r\n        },\r\n\r\n        /**\r\n         *  Sets the highlight pen color. Equivalent to setAttribute({highlightStrokeColor:color})\r\n         * but affects only the future turtle.\r\n         * @param {String} color\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        setHighlightPenColor: function (color) {\r\n            //this.visProp.highlightstrokecolor = colStr;\r\n            this.curve = this.board.create(\r\n                \"curve\",\r\n                [[this.pos[0]], [this.pos[1]]],\r\n                this.copyAttr(\"highlightStrokeColor\", color)\r\n            );\r\n            this.objects.push(this.curve);\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Sets properties of the turtle, see also {@link JXG.GeometryElement#setAttribute}.\r\n         * Sets the property for all curves of the turtle in the past and in the future.\r\n         * @param {Object} attributes key:value pairs\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        setAttribute: function (attributes) {\r\n            var i,\r\n                el,\r\n                tmp,\r\n                len = this.objects.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                el = this.objects[i];\r\n                if (el.type === Const.OBJECT_TYPE_CURVE) {\r\n                    el.setAttribute(attributes);\r\n                }\r\n            }\r\n\r\n            // Set visProp of turtle\r\n            tmp = this.visProp.id;\r\n            this.visProp = Type.deepCopy(this.curve.visProp);\r\n            this.visProp.id = tmp;\r\n            this._attributes = Type.deepCopy(this.visProp);\r\n            delete this._attributes.id;\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set a future attribute of the turtle.\r\n         * @private\r\n         * @param {String} key\r\n         * @param {Number|String} val\r\n         * @returns {Object} pointer to the attributes object\r\n         */\r\n        copyAttr: function (key, val) {\r\n            this._attributes[key.toLowerCase()] = val;\r\n            return this._attributes;\r\n        },\r\n\r\n        /**\r\n         * Sets the visibility of the turtle head to true,\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        showTurtle: function () {\r\n            this.turtleIsHidden = false;\r\n            this.arrow.setAttribute({ visible: true });\r\n            this.visProp.arrow.visible = false;\r\n            this.setPos(this.pos[0], this.pos[1]);\r\n            this.board.update();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Sets the visibility of the turtle head to false,\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        hideTurtle: function () {\r\n            this.turtleIsHidden = true;\r\n            this.arrow.setAttribute({ visible: false });\r\n            this.visProp.arrow.visible = false;\r\n            this.board.update();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Moves the turtle to position [0,0].\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        home: function () {\r\n            this.pos = [0, 0];\r\n            this.setPos(this.pos[0], this.pos[1]);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         *  Pushes the position of the turtle on the stack.\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        pushTurtle: function () {\r\n            this.stack.push([this.pos[0], this.pos[1], this.dir]);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         *  Gets the last position of the turtle on the stack, sets the turtle to this position and removes this\r\n         * position from the stack.\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        popTurtle: function () {\r\n            var status = this.stack.pop();\r\n            this.pos[0] = status[0];\r\n            this.pos[1] = status[1];\r\n            this.dir = status[2];\r\n            this.setPos(this.pos[0], this.pos[1]);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Rotates the turtle into a new direction.\r\n         * There are two possibilities:\r\n         * @param {Number|Array} target If a number is given, it is interpreted as the new direction to look to; If an array\r\n         * consisting of two Numbers is given targeted is used as a pair coordinates.\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        lookTo: function (target) {\r\n            var ax, ay, bx, by, beta;\r\n\r\n            if (Type.isArray(target)) {\r\n                ax = this.pos[0];\r\n                ay = this.pos[1];\r\n                bx = target[0];\r\n                by = target[1];\r\n\r\n                // Rotate by the slope of the line [this.pos, target]\r\n                beta = Math.atan2(by - ay, bx - ax);\r\n                this.right(this.dir - (beta * 180) / Math.PI);\r\n            } else if (Type.isNumber(target)) {\r\n                this.right(this.dir - target);\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Moves the turtle to a given coordinate pair.\r\n         * The direction is not changed.\r\n         * @param {Array} target Coordinates of the point where the turtle looks to.\r\n         * @returns {JXG.Turtle} pointer to the turtle object\r\n         */\r\n        moveTo: function (target) {\r\n            var dx, dy, t;\r\n\r\n            if (Type.isArray(target)) {\r\n                dx = target[0] - this.pos[0];\r\n                dy = target[1] - this.pos[1];\r\n\r\n                if (!this.turtleIsHidden) {\r\n                    t = this.board.create(\"transform\", [dx, dy], { type: \"translate\" });\r\n                    t.applyOnce(this.turtle);\r\n                    t.applyOnce(this.turtle2);\r\n                }\r\n\r\n                if (this.isPenDown) {\r\n                    // IE workaround\r\n                    if (this.curve.dataX.length >= 8192) {\r\n                        this.curve = this.board.create(\r\n                            \"curve\",\r\n                            [[this.pos[0]], [this.pos[1]]],\r\n                            this._attributes\r\n                        );\r\n                        this.objects.push(this.curve);\r\n                    }\r\n                }\r\n\r\n                this.pos[0] = target[0];\r\n                this.pos[1] = target[1];\r\n\r\n                if (this.isPenDown) {\r\n                    this.curve.dataX.push(this.pos[0]);\r\n                    this.curve.dataY.push(this.pos[1]);\r\n                }\r\n                this.board.update();\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Alias for {@link JXG.Turtle#forward}\r\n         */\r\n        fd: function (len) {\r\n            return this.forward(len);\r\n        },\r\n        /**\r\n         * Alias for {@link JXG.Turtle#back}\r\n         */\r\n        bk: function (len) {\r\n            return this.back(len);\r\n        },\r\n        /**\r\n         * Alias for {@link JXG.Turtle#left}\r\n         */\r\n        lt: function (angle) {\r\n            return this.left(angle);\r\n        },\r\n        /**\r\n         * Alias for {@link JXG.Turtle#right}\r\n         */\r\n        rt: function (angle) {\r\n            return this.right(angle);\r\n        },\r\n        /**\r\n         * Alias for {@link JXG.Turtle#penUp}\r\n         */\r\n        pu: function () {\r\n            return this.penUp();\r\n        },\r\n        /**\r\n         * Alias for {@link JXG.Turtle#penDown}\r\n         */\r\n        pd: function () {\r\n            return this.penDown();\r\n        },\r\n        /**\r\n         * Alias for {@link JXG.Turtle#hideTurtle}\r\n         */\r\n        ht: function () {\r\n            return this.hideTurtle();\r\n        },\r\n        /**\r\n         * Alias for {@link JXG.Turtle#showTurtle}\r\n         */\r\n        st: function () {\r\n            return this.showTurtle();\r\n        },\r\n        /**\r\n         * Alias for {@link JXG.Turtle#clearScreen}\r\n         */\r\n        cs: function () {\r\n            return this.clearScreen();\r\n        },\r\n        /**\r\n         * Alias for {@link JXG.Turtle#pushTurtle}\r\n         */\r\n        push: function () {\r\n            return this.pushTurtle();\r\n        },\r\n        /**\r\n         * Alias for {@link JXG.Turtle#popTurtle}\r\n         */\r\n        pop: function () {\r\n            return this.popTurtle();\r\n        },\r\n\r\n        /**\r\n         * The \"co\"-coordinate of the turtle curve at position t is returned.\r\n         *\r\n         * @param {Number} t parameter\r\n         * @param {String} co. Either 'X' or 'Y'.\r\n         * @returns {Number} x-coordinate of the turtle position or x-coordinate of turtle at position t\r\n         */\r\n        evalAt: function (t, co) {\r\n            var i,\r\n                j,\r\n                el,\r\n                tc,\r\n                len = this.objects.length;\r\n\r\n            for (i = 0, j = 0; i < len; i++) {\r\n                el = this.objects[i];\r\n\r\n                if (el.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n                    if (j <= t && t < j + el.numberPoints) {\r\n                        tc = t - j;\r\n                        return el[co](tc);\r\n                    }\r\n                    j += el.numberPoints;\r\n                }\r\n            }\r\n\r\n            return this[co]();\r\n        },\r\n\r\n        /**\r\n         * if t is not supplied the x-coordinate of the turtle is returned. Otherwise\r\n         * the x-coordinate of the turtle curve at position t is returned.\r\n         * @param {Number} t parameter\r\n         * @returns {Number} x-coordinate of the turtle position or x-coordinate of turtle at position t\r\n         */\r\n        X: function (t) {\r\n            if (!Type.exists(t)) {\r\n                return this.pos[0];\r\n            }\r\n\r\n            return this.evalAt(t, 'X');\r\n        },\r\n\r\n        /**\r\n         * if t is not supplied the y-coordinate of the turtle is returned. Otherwise\r\n         * the y-coordinate of the turtle curve at position t is returned.\r\n         * @param {Number} t parameter\r\n         * @returns {Number} x-coordinate of the turtle position or x-coordinate of turtle at position t\r\n         */\r\n        Y: function (t) {\r\n            if (!Type.exists(t)) {\r\n                return this.pos[1];\r\n            }\r\n            return this.evalAt(t, 'Y');\r\n        },\r\n\r\n        /**\r\n         * @returns {Number} z-coordinate of the turtle position\r\n         */\r\n        Z: function (t) {\r\n            return 1.0;\r\n        },\r\n\r\n        /**\r\n         * Gives the lower bound of the parameter if the turtle is treated as parametric curve.\r\n         */\r\n        minX: function () {\r\n            return 0;\r\n        },\r\n\r\n        /**\r\n         * Gives the upper bound of the parameter if the turtle is treated as parametric curve.\r\n         * May be overwritten in @see generateTerm.\r\n         */\r\n        maxX: function () {\r\n            var i,\r\n                el,\r\n                len = this.objects.length,\r\n                np = 0;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                el = this.objects[i];\r\n                if (el.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n                    np += this.objects[i].numberPoints;\r\n                }\r\n            }\r\n            return np;\r\n        },\r\n\r\n        /**\r\n         * Checks whether (x,y) is near the curve.\r\n         * @param {Number} x Coordinate in x direction, screen coordinates.\r\n         * @param {Number} y Coordinate in y direction, screen coordinates.\r\n         * @returns {Boolean} True if (x,y) is near the curve, False otherwise.\r\n         */\r\n        hasPoint: function (x, y) {\r\n            var i, el;\r\n\r\n            // run through all curves of this turtle\r\n            for (i = 0; i < this.objects.length; i++) {\r\n                el = this.objects[i];\r\n\r\n                if (el.type === Const.OBJECT_TYPE_CURVE) {\r\n                    if (el.hasPoint(x, y)) {\r\n                        // So what??? All other curves have to be notified now (for highlighting)\r\n                        return true;\r\n                        // This has to be done, yet.\r\n                    }\r\n                }\r\n            }\r\n            return false;\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * @class A turtle is a graphic paradigm similar to the programming languages Logo or PostScript.\r\n * @pseudo\r\n * @description  Creates a new turtle\r\n * @name Turtle\r\n * @augments JXG.Turtle\r\n * @constructor\r\n * @type JXG.Turtle\r\n *\r\n * @param {JXG.Board} board The board the turtle is put on.\r\n * @param {Array} parents\r\n * @param {Object} attributes Object containing properties for the element such as stroke-color and visibility. See {@link JXG.GeometryElement#setAttribute}\r\n * @returns {JXG.Turtle} Reference to the created turtle object.\r\n */\r\nJXG.createTurtle = function (board, parents, attributes) {\r\n    var attr;\r\n    parents = parents || [];\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'turtle');\r\n    return new JXG.Turtle(board, parents, attr);\r\n};\r\n\r\nJXG.registerElement(\"turtle\", JXG.createTurtle);\r\n\r\nexport default JXG.Turtle;\r\n// export default {\r\n//     Turtle: JXG.Turtle,\r\n//     createTurtle: JXG.createTurtle\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview In this file the geometry object Ticks is defined. Ticks provides\r\n * methods for creation and management of ticks on an axis.\r\n * @author graphjs\r\n * @version 0.1\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Numerics from \"../math/numerics.js\";\r\nimport Const from \"./constants.js\";\r\nimport GeometryElement from \"./element.js\";\r\nimport Coords from \"./coords.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Creates ticks for an axis.\r\n * @class Ticks provides methods for creation and management\r\n * of ticks on an axis.\r\n * @param {JXG.Line} line Reference to the axis the ticks are drawn on.\r\n * @param {Number|Array} ticks Number defining the distance between two major ticks or an array defining static ticks.\r\n * @param {Object} attributes Properties\r\n * @see JXG.Line#addTicks\r\n * @constructor\r\n * @augments JXG.GeometryElement\r\n */\r\nJXG.Ticks = function (line, ticks, attributes) {\r\n    this.constructor(line.board, attributes, Const.OBJECT_TYPE_TICKS, Const.OBJECT_CLASS_OTHER);\r\n\r\n    /**\r\n     * The line the ticks belong to.\r\n     * @type JXG.Line\r\n     * @private\r\n     */\r\n    this.line = line;\r\n\r\n    /**\r\n     * The board the ticks line is drawn on.\r\n     * @type JXG.Board\r\n     * @private\r\n     */\r\n    this.board = this.line.board;\r\n\r\n    // /**\r\n    //  * A function calculating ticks delta depending on the ticks number.\r\n    //  * @type Function\r\n    //  */\r\n    // // this.ticksFunction = null;\r\n\r\n    /**\r\n     * Array of fixed ticks.\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.fixedTicks = null;\r\n\r\n    /**\r\n     * Flag if the ticks are equidistant. If true, their distance is defined by ticksFunction.\r\n     * @type Boolean\r\n     * @private\r\n     */\r\n    this.equidistant = false;\r\n\r\n    /**\r\n     * A list of labels which have to be displayed in updateRenderer.\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.labelsData = [];\r\n\r\n    if (Type.isFunction(ticks)) {\r\n        this.ticksFunction = ticks;\r\n        throw new Error(\"Function arguments are no longer supported.\");\r\n    }\r\n\r\n    if (Type.isArray(ticks)) {\r\n        this.fixedTicks = ticks;\r\n    } else {\r\n        // Obsolete:\r\n        // if (Math.abs(ticks) < Mat.eps || ticks < 0) {\r\n        //     ticks = attributes.defaultdistance;\r\n        // }\r\n        this.equidistant = true;\r\n    }\r\n\r\n    // /**\r\n    //  * Least distance between two ticks, measured in pixels.\r\n    //  * @type int\r\n    //  */\r\n    // // this.minTicksDistance = attributes.minticksdistance;\r\n\r\n    /**\r\n     * Stores the ticks coordinates\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.ticks = [];\r\n\r\n    // /**\r\n    //  * Distance between two major ticks in user coordinates\r\n    //  * @type Number\r\n    //  */\r\n    // this.ticksDelta = 1;\r\n\r\n    /**\r\n     * Array where the labels are saved. There is an array element for every tick,\r\n     * even for minor ticks which don't have labels. In this case the array element\r\n     * contains just <tt>null</tt>.\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.labels = [];\r\n\r\n    /**\r\n     * Used to ensure the uniqueness of label ids this counter is used.\r\n     * @type number\r\n     * @private\r\n     */\r\n    this.labelCounter = 0;\r\n\r\n    this.id = this.line.addTicks(this);\r\n    this.elType = 'ticks';\r\n    this.inherits.push(this.labels);\r\n    this.board.setId(this, 'Ti');\r\n};\r\n\r\nJXG.Ticks.prototype = new GeometryElement();\r\n\r\nJXG.extend(\r\n    JXG.Ticks.prototype,\r\n    /** @lends JXG.Ticks.prototype */ {\r\n        // /**\r\n        //  * Ticks function:\r\n        //  * determines the distance (in user units) of two major ticks.\r\n        //  * See above in constructor and in @see JXG.GeometryElement#setAttribute\r\n        //  *\r\n        //  * @private\r\n        //  * @param {Number} ticks Distance between two major ticks\r\n        //  * @returns {Function} returns method ticksFunction\r\n        //  */\r\n        // // makeTicksFunction: function (ticks) {\r\n        //     // return function () {\r\n        //         ticksFunction: function () {\r\n        //                     var delta, b, dist,\r\n        //                     number_major_tick_intervals = 5;\r\n\r\n        //                 if (this.evalVisProp('insertticks')) {\r\n        //                     b = this.getLowerAndUpperBounds(this.getZeroCoordinates(), 'ticksdistance');\r\n        //                     dist = b.upper - b.lower;\r\n\r\n        //                     // delta: Proposed distance in user units between two major ticks\r\n        //                     delta = Math.pow(10, Math.floor(Math.log(dist / number_major_tick_intervals) / Math.LN10));\r\n        // console.log(\"delta\", delta,  b.upper, b.lower, dist, dist / number_major_tick_intervals * 1.1)\r\n        //                     if (5 * delta < dist / number_major_tick_intervals * 1.1) {\r\n        //                         return 5 * delta;\r\n        //                     }\r\n        //                     if (2 * delta < dist / number_major_tick_intervals * 1.1) {\r\n        //                         return 2 * delta;\r\n        //                     }\r\n\r\n        //                     // < v1.6.0:\r\n        //                     // delta = Math.pow(10, Math.floor(Math.log(0.6 * dist) / Math.LN10));\r\n        //                     if (false && dist <= 6 * delta) {\r\n        //                         delta *= 0.5;\r\n        //                     }\r\n        //                     return delta;\r\n        //                 }\r\n\r\n        //                 // In case of insertTicks==false\r\n        //                 return this.evalVisProp('ticksdistance');\r\n        //                 // return ticks;\r\n        //             // };\r\n        //         },\r\n\r\n        /**\r\n         * Checks whether (x,y) is near the line.\r\n         * Only available for line elements,  not for ticks on curves.\r\n         * @param {Number} x Coordinate in x direction, screen coordinates.\r\n         * @param {Number} y Coordinate in y direction, screen coordinates.\r\n         * @returns {Boolean} True if (x,y) is near the line, False otherwise.\r\n         */\r\n        hasPoint: function (x, y) {\r\n            var i, t, r, type,\r\n                len = (this.ticks && this.ticks.length) || 0;\r\n\r\n            if (\r\n                !this.line.evalVisProp('scalable') ||\r\n                this.line.elementClass === Const.OBJECT_CLASS_CURVE\r\n            ) {\r\n                return false;\r\n            }\r\n\r\n            if (Type.isObject(this.evalVisProp('precision'))) {\r\n                type = this.board._inputDevice;\r\n                r = this.evalVisProp('precision.' + type);\r\n            } else {\r\n                // 'inherit'\r\n                r = this.board.options.precision.hasPoint;\r\n            }\r\n            r += this.evalVisProp('strokewidth') * 0.5;\r\n\r\n            // Ignore non-axes and axes that are not horizontal or vertical\r\n            if (\r\n                this.line.stdform[1] !== 0 &&\r\n                this.line.stdform[2] !== 0 &&\r\n                this.line.type !== Const.OBJECT_TYPE_AXIS\r\n            ) {\r\n                return false;\r\n            }\r\n\r\n            for (i = 0; i < len; i++) {\r\n                t = this.ticks[i];\r\n\r\n                // Skip minor ticks\r\n                if (t[2]) {\r\n                    // Ignore ticks at zero\r\n                    if (\r\n                        !(\r\n                            (this.line.stdform[1] === 0 &&\r\n                                Math.abs(t[0][0] - this.line.point1.coords.scrCoords[1]) <\r\n                                Mat.eps) ||\r\n                            (this.line.stdform[2] === 0 &&\r\n                                Math.abs(t[1][0] - this.line.point1.coords.scrCoords[2]) <\r\n                                Mat.eps)\r\n                        )\r\n                    ) {\r\n                        // tick length is not zero, ie. at least one pixel\r\n                        if (\r\n                            Math.abs(t[0][0] - t[0][1]) >= 1 ||\r\n                            Math.abs(t[1][0] - t[1][1]) >= 1\r\n                        ) {\r\n                            // Allow dragging near axes only.\r\n                            if (this.line.stdform[1] === 0) {\r\n                                if (\r\n                                    Math.abs(y - this.line.point1.coords.scrCoords[2]) < 2 * r &&\r\n                                    t[0][0] - r < x && x < t[0][1] + r\r\n                                ) {\r\n                                    return true;\r\n                                }\r\n                            } else if (this.line.stdform[2] === 0) {\r\n                                if (\r\n                                    Math.abs(x - this.line.point1.coords.scrCoords[1]) < 2 * r &&\r\n                                    t[1][0] - r < y && y < t[1][1] + r\r\n                                ) {\r\n                                    return true;\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Sets x and y coordinate of the tick.\r\n         * @param {number} method The type of coordinates used here. Possible values are {@link JXG.COORDS_BY_USER} and {@link JXG.COORDS_BY_SCREEN}.\r\n         * @param {Array} coords coordinates in screen/user units\r\n         * @param {Array} oldcoords previous coordinates in screen/user units\r\n         * @returns {JXG.Ticks} this element\r\n         */\r\n        setPositionDirectly: function (method, coords, oldcoords) {\r\n            var dx, dy,\r\n                c = new Coords(method, coords, this.board),\r\n                oldc = new Coords(method, oldcoords, this.board),\r\n                bb = this.board.getBoundingBox();\r\n\r\n            if (\r\n                this.line.type !== Const.OBJECT_TYPE_AXIS ||\r\n                !this.line.evalVisProp('scalable')\r\n            ) {\r\n                return this;\r\n            }\r\n\r\n            if (\r\n                Math.abs(this.line.stdform[1]) < Mat.eps &&\r\n                Math.abs(c.usrCoords[1] * oldc.usrCoords[1]) > Mat.eps\r\n            ) {\r\n                // Horizontal line\r\n                dx = oldc.usrCoords[1] / c.usrCoords[1];\r\n                bb[0] *= dx;\r\n                bb[2] *= dx;\r\n                this.board.setBoundingBox(bb, this.board.keepaspectratio, 'update');\r\n            } else if (\r\n                Math.abs(this.line.stdform[2]) < Mat.eps &&\r\n                Math.abs(c.usrCoords[2] * oldc.usrCoords[2]) > Mat.eps\r\n            ) {\r\n                // Vertical line\r\n                dy = oldc.usrCoords[2] / c.usrCoords[2];\r\n                bb[3] *= dy;\r\n                bb[1] *= dy;\r\n                this.board.setBoundingBox(bb, this.board.keepaspectratio, 'update');\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * (Re-)calculates the ticks coordinates.\r\n         * @private\r\n         */\r\n        calculateTicksCoordinates: function () {\r\n            var coordsZero, b, r_max, bb;\r\n\r\n            if (this.line.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                // Calculate Ticks width and height in Screen and User Coordinates\r\n                this.setTicksSizeVariables();\r\n\r\n                // If the parent line is not finite, we can stop here.\r\n                if (Math.abs(this.dx) < Mat.eps && Math.abs(this.dy) < Mat.eps) {\r\n                    return;\r\n                }\r\n            }\r\n\r\n            // Get Zero (coords element for lines, number for curves)\r\n            coordsZero = this.getZeroCoordinates();\r\n\r\n            // Calculate lower bound and upper bound limits based on distance\r\n            // between p1 and center and p2 and center\r\n            if (this.line.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                b = this.getLowerAndUpperBounds(coordsZero, 'ticksdistance');\r\n            } else {\r\n                b = {\r\n                    lower: this.line.minX(),\r\n                    upper: this.line.maxX(),\r\n                    a1: 0,\r\n                    a2: 0,\r\n                    m1: 0,\r\n                    m2: 0\r\n                };\r\n            }\r\n\r\n            if (this.evalVisProp('type') === 'polar') {\r\n                bb = this.board.getBoundingBox();\r\n                r_max = Math.max(\r\n                    Mat.hypot(bb[0], bb[1]),\r\n                    Mat.hypot(bb[2], bb[3])\r\n                );\r\n                b.upper = r_max;\r\n            }\r\n\r\n            // Clean up\r\n            this.ticks = [];\r\n            this.labelsData = [];\r\n            // Create Ticks Coordinates and Labels\r\n            if (this.equidistant) {\r\n                this.generateEquidistantTicks(coordsZero, b);\r\n            } else {\r\n                this.generateFixedTicks(coordsZero, b);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Sets the variables used to set the height and slope of each tick.\r\n         *\r\n         * @private\r\n         */\r\n        setTicksSizeVariables: function (pos) {\r\n            var d,\r\n                mi,\r\n                ma,\r\n                len,\r\n                distMaj = this.evalVisProp('majorheight') * 0.5,\r\n                distMin = this.evalVisProp('minorheight') * 0.5;\r\n\r\n            // For curves:\r\n            if (Type.exists(pos)) {\r\n                mi = this.line.minX();\r\n                ma = this.line.maxX();\r\n                len = this.line.points.length;\r\n                if (len < 2) {\r\n                    this.dxMaj = 0;\r\n                    this.dyMaj = 0;\r\n                } else if (Mat.relDif(pos, mi) < Mat.eps) {\r\n                    this.dxMaj =\r\n                        this.line.points[0].usrCoords[2] - this.line.points[1].usrCoords[2];\r\n                    this.dyMaj =\r\n                        this.line.points[1].usrCoords[1] - this.line.points[0].usrCoords[1];\r\n                } else if (Mat.relDif(pos, ma) < Mat.eps) {\r\n                    this.dxMaj =\r\n                        this.line.points[len - 2].usrCoords[2] -\r\n                        this.line.points[len - 1].usrCoords[2];\r\n                    this.dyMaj =\r\n                        this.line.points[len - 1].usrCoords[1] -\r\n                        this.line.points[len - 2].usrCoords[1];\r\n                } else {\r\n                    this.dxMaj = -Numerics.D(this.line.Y)(pos);\r\n                    this.dyMaj = Numerics.D(this.line.X)(pos);\r\n                }\r\n            } else {\r\n                // ticks width and height in screen units\r\n                this.dxMaj = this.line.stdform[1];\r\n                this.dyMaj = this.line.stdform[2];\r\n            }\r\n            this.dxMin = this.dxMaj;\r\n            this.dyMin = this.dyMaj;\r\n\r\n            // ticks width and height in user units\r\n            this.dx = this.dxMaj;\r\n            this.dy = this.dyMaj;\r\n\r\n            // After this, the length of the vector (dxMaj, dyMaj) in screen coordinates is equal to distMaj pixel.\r\n            d = Mat.hypot(this.dxMaj * this.board.unitX, this.dyMaj * this.board.unitY);\r\n            this.dxMaj *= (distMaj / d) * this.board.unitX;\r\n            this.dyMaj *= (distMaj / d) * this.board.unitY;\r\n            this.dxMin *= (distMin / d) * this.board.unitX;\r\n            this.dyMin *= (distMin / d) * this.board.unitY;\r\n\r\n            // Grid-like ticks?\r\n            this.minStyle = this.evalVisProp('minorheight') < 0 ? \"infinite\" : 'finite';\r\n            this.majStyle = this.evalVisProp('majorheight') < 0 ? \"infinite\" : 'finite';\r\n        },\r\n\r\n        /**\r\n         * Returns the coordinates of the point zero of the line.\r\n         *\r\n         * If the line is an {@link Axis}, the coordinates of the projection of the board's zero point is returned\r\n         *\r\n         * Otherwise, the coordinates of the point that acts as zero are\r\n         * established depending on the value of {@link JXG.Ticks#anchor}\r\n         *\r\n         * @returns {JXG.Coords} Coords object for the zero point on the line\r\n         * @private\r\n         */\r\n        getZeroCoordinates: function () {\r\n            var c1x, c1y, c1z, c2x, c2y, c2z,\r\n                t, mi, ma,\r\n                ev_a = this.evalVisProp('anchor');\r\n\r\n            if (this.line.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                if (this.line.type === Const.OBJECT_TYPE_AXIS) {\r\n                    return Geometry.projectPointToLine(\r\n                        {\r\n                            coords: {\r\n                                usrCoords: [1, 0, 0]\r\n                            }\r\n                        },\r\n                        this.line,\r\n                        this.board\r\n                    );\r\n                }\r\n                c1z = this.line.point1.coords.usrCoords[0];\r\n                c1x = this.line.point1.coords.usrCoords[1];\r\n                c1y = this.line.point1.coords.usrCoords[2];\r\n                c2z = this.line.point2.coords.usrCoords[0];\r\n                c2x = this.line.point2.coords.usrCoords[1];\r\n                c2y = this.line.point2.coords.usrCoords[2];\r\n\r\n                if (ev_a === 'right') {\r\n                    return this.line.point2.coords;\r\n                }\r\n                if (ev_a === 'middle') {\r\n                    return new Coords(\r\n                        Const.COORDS_BY_USER,\r\n                        [(c1z + c2z) * 0.5, (c1x + c2x) * 0.5, (c1y + c2y) * 0.5],\r\n                        this.board\r\n                    );\r\n                }\r\n                if (Type.isNumber(ev_a)) {\r\n                    return new Coords(\r\n                        Const.COORDS_BY_USER,\r\n                        [\r\n                            c1z + (c2z - c1z) * ev_a,\r\n                            c1x + (c2x - c1x) * ev_a,\r\n                            c1y + (c2y - c1y) * ev_a\r\n                        ],\r\n                        this.board\r\n                    );\r\n                }\r\n                return this.line.point1.coords;\r\n            }\r\n            mi = this.line.minX();\r\n            ma = this.line.maxX();\r\n            if (ev_a === 'right') {\r\n                t = ma;\r\n            } else if (ev_a === 'middle') {\r\n                t = (mi + ma) * 0.5;\r\n            } else if (Type.isNumber(ev_a)) {\r\n                t = mi * (1 - ev_a) + ma * ev_a;\r\n                // t = ev_a;\r\n            } else {\r\n                t = mi;\r\n            }\r\n            return t;\r\n        },\r\n\r\n        /**\r\n         * Calculate the lower and upper bounds for tick rendering.\r\n         * If {@link JXG.Ticks#includeBoundaries} is false, the boundaries will exclude point1 and point2.\r\n         *\r\n         * @param  {JXG.Coords} coordsZero\r\n         * @returns {String} [type] If type=='ticksdistance', the bounds are\r\n         *                         the intersection of the line with the bounding box of the board, respecting\r\n         *                         the value of the line attribute 'margin' and the width of arrow heads.\r\n         *                         Otherwise, it is the projection of the corners of the bounding box\r\n         *                         to the line - without the attribute 'margin' and width of arrow heads.\r\n         *  <br>\r\n         *                         The first case is needed to determine which ticks are displayed, i.e. where to stop.\r\n         *                         The second case is to determine the distance between ticks in case of 'insertTicks:true'.\r\n         * @returns {Object}     {lower: Number, upper: Number } containing the lower and upper bounds in user units.\r\n         *\r\n         * @private\r\n         */\r\n        getLowerAndUpperBounds: function (coordsZero, type) {\r\n            var lowerBound, upperBound,\r\n                fA, lA,\r\n                point1, point2,\r\n                isPoint1inBoard, isPoint2inBoard,\r\n                // We use the distance from zero to P1 and P2 to establish lower and higher points\r\n                dZeroPoint1, dZeroPoint2,\r\n                arrowData,\r\n                // angle,\r\n                a1, a2, m1, m2,\r\n                eps = Mat.eps * 10,\r\n                ev_sf = this.line.evalVisProp('straightfirst'),\r\n                ev_sl = this.line.evalVisProp('straightlast'),\r\n                ev_i = this.evalVisProp('includeboundaries');\r\n\r\n            // The line's defining points that will be adjusted to be within the board limits\r\n            if (this.line.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n                return {\r\n                    lower: this.line.minX(),\r\n                    upper: this.line.maxX()\r\n                };\r\n            }\r\n\r\n            point1 = new Coords(Const.COORDS_BY_USER, this.line.point1.coords.usrCoords, this.board);\r\n            point2 = new Coords(Const.COORDS_BY_USER, this.line.point2.coords.usrCoords, this.board);\r\n\r\n            // Are the original defining points within the board?\r\n            isPoint1inBoard =\r\n                Math.abs(point1.usrCoords[0]) >= Mat.eps &&\r\n                point1.scrCoords[1] >= 0.0 &&\r\n                point1.scrCoords[1] <= this.board.canvasWidth &&\r\n                point1.scrCoords[2] >= 0.0 &&\r\n                point1.scrCoords[2] <= this.board.canvasHeight;\r\n            isPoint2inBoard =\r\n                Math.abs(point2.usrCoords[0]) >= Mat.eps &&\r\n                point2.scrCoords[1] >= 0.0 &&\r\n                point2.scrCoords[1] <= this.board.canvasWidth &&\r\n                point2.scrCoords[2] >= 0.0 &&\r\n                point2.scrCoords[2] <= this.board.canvasHeight;\r\n\r\n            // Adjust line limit points to be within the board\r\n            if (Type.exists(type) && type === 'ticksdistance') {\r\n                // The good old calcStraight is needed for determining the distance between major ticks.\r\n                // Here, only the visual area is of importance\r\n                Geometry.calcStraight(this.line, point1, point2, 0);\r\n                m1 = this.getDistanceFromZero(coordsZero, point1);\r\n                m2 = this.getDistanceFromZero(coordsZero, point2);\r\n                Geometry.calcStraight(this.line, point1, point2, this.line.evalVisProp('margin'));\r\n                m1 = this.getDistanceFromZero(coordsZero, point1) - m1;\r\n                m2 = this.getDistanceFromZero(coordsZero, point2).m2;\r\n            } else {\r\n                // This function projects the corners of the board to the line.\r\n                // This is important for diagonal lines with infinite tick lines.\r\n                Geometry.calcLineDelimitingPoints(this.line, point1, point2);\r\n            }\r\n\r\n            // Shorten ticks bounds such that ticks are not through arrow heads\r\n            fA = this.line.evalVisProp('firstarrow');\r\n            lA = this.line.evalVisProp('lastarrow');\r\n\r\n            a1 = this.getDistanceFromZero(coordsZero, point1);\r\n            a2 = this.getDistanceFromZero(coordsZero, point2);\r\n            if (fA || lA) {\r\n                // Do not display ticks at through arrow heads.\r\n                // In arrowData we ignore the highlighting status.\r\n                // Ticks would appear to be too nervous.\r\n                arrowData = this.board.renderer.getArrowHeadData(\r\n                    this.line,\r\n                    this.line.evalVisProp('strokewidth'),\r\n                    ''\r\n                );\r\n\r\n                this.board.renderer.getPositionArrowHead(\r\n                    this.line,\r\n                    point1,\r\n                    point2,\r\n                    arrowData\r\n                );\r\n            }\r\n            // Calculate (signed) distance from Zero to P1 and to P2\r\n            dZeroPoint1 = this.getDistanceFromZero(coordsZero, point1);\r\n            dZeroPoint2 = this.getDistanceFromZero(coordsZero, point2);\r\n\r\n            // Recompute lengths of arrow heads\r\n            a1 = dZeroPoint1 - a1;\r\n            a2 = dZeroPoint1 - a2;\r\n\r\n            // We have to establish if the direction is P1->P2 or P2->P1 to set the lower and upper\r\n            // bounds appropriately. As the distances contain also a sign to indicate direction,\r\n            // we can compare dZeroPoint1 and dZeroPoint2 to establish the line direction\r\n            if (dZeroPoint1 < dZeroPoint2) {\r\n                // Line goes P1->P2\r\n                lowerBound = dZeroPoint1;\r\n                upperBound = dZeroPoint2;\r\n\r\n                if (!ev_sf && isPoint1inBoard && !ev_i) {\r\n                    lowerBound += eps;\r\n                }\r\n                if (!ev_sl && isPoint2inBoard && !ev_i) {\r\n                    upperBound -= eps;\r\n                }\r\n            } else if (dZeroPoint2 < dZeroPoint1) {\r\n                // Line goes P2->P1\r\n                // Does this happen at all?\r\n                lowerBound = dZeroPoint2;\r\n                upperBound = dZeroPoint1;\r\n\r\n                if (!ev_sl && isPoint2inBoard && !ev_i) {\r\n                    lowerBound += eps;\r\n                }\r\n                if (!ev_sf && isPoint1inBoard && !ev_i) {\r\n                    upperBound -= eps;\r\n                }\r\n            } else {\r\n                // P1 = P2 = Zero, we can't do a thing\r\n                lowerBound = 0;\r\n                upperBound = 0;\r\n            }\r\n\r\n            return {\r\n                lower: lowerBound,\r\n                upper: upperBound,\r\n                a1: a1,\r\n                a2: a2,\r\n                m1: m1,\r\n                m2: m2\r\n            };\r\n        },\r\n\r\n        /**\r\n         * Calculates the signed distance in user coordinates from zero to a given point.\r\n         * Sign is positive, if the direction from zero to point is the same as the direction\r\n         * zero to point2 of the line.\r\n         *\r\n         * @param  {JXG.Coords} zero  coordinates of the point considered zero\r\n         * @param  {JXG.Coords} point coordinates of the point to find out the distance\r\n         * @returns {Number}           distance between zero and point, including its sign\r\n         * @private\r\n         */\r\n        getDistanceFromZero: function (zero, point) {\r\n            var p1, p2, dirLine, dirPoint, distance;\r\n\r\n            p1 = this.line.point1.coords;\r\n            p2 = this.line.point2.coords;\r\n            distance = zero.distance(Const.COORDS_BY_USER, point);\r\n\r\n            // Establish sign\r\n            dirLine = [\r\n                p2.usrCoords[0] - p1.usrCoords[0],\r\n                p2.usrCoords[1] - p1.usrCoords[1],\r\n                p2.usrCoords[2] - p1.usrCoords[2]\r\n            ];\r\n            dirPoint = [\r\n                point.usrCoords[0] - zero.usrCoords[0],\r\n                point.usrCoords[1] - zero.usrCoords[1],\r\n                point.usrCoords[2] - zero.usrCoords[2]\r\n            ];\r\n            if (Mat.innerProduct(dirLine, dirPoint, 3) < 0) {\r\n                distance *= -1;\r\n            }\r\n\r\n            return distance;\r\n        },\r\n\r\n        /**\r\n         * Creates ticks coordinates and labels automatically.\r\n         * The frequency of ticks is affected by the values of {@link JXG.Ticks#insertTicks}, {@link JXG.Ticks#minTicksDistance},\r\n         * and {@link JXG.Ticks#ticksDistance}\r\n         *\r\n         * @param  {JXG.Coords} coordsZero coordinates of the point considered zero\r\n         * @param  {Object}     bounds     contains the lower and upper bounds for ticks placement\r\n         * @private\r\n         */\r\n        generateEquidistantTicks: function (coordsZero, bounds) {\r\n            var tickPosition,\r\n                eps = Mat.eps,\r\n                deltas, ticksDelta,\r\n                // ev_mia = this.evalVisProp('minorticksinarrow'),\r\n                // ev_maa = this.evalVisProp('minorticksinarrow'),\r\n                // ev_mla = this.evalVisProp('minorticksinarrow'),\r\n                ev_mt = this.evalVisProp('minorticks');\r\n\r\n            // Determine a proposed distance between major ticks in user units\r\n            ticksDelta = this.getDistanceMajorTicks();\r\n\r\n            // Obsolete, since this.equidistant is always true at this point\r\n            // ticksDelta = this.equidistant ? this.ticksFunction(1) : this.ticksDelta;\r\n\r\n            if (this.line.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                // Calculate x and y distances between two points on the line which are 1 unit apart\r\n                // In essence, these are cosine and sine.\r\n                deltas = this.getXandYdeltas();\r\n            }\r\n\r\n            ticksDelta *= this.evalVisProp('scale');\r\n\r\n            // In case of insertTicks, adjust ticks distance to satisfy the minTicksDistance restriction.\r\n            // if (ev_it) { // } && this.minTicksDistance > Mat.eps) {\r\n            //     ticksDelta = this.adjustTickDistance(ticksDelta, coordsZero, deltas);\r\n            // }\r\n\r\n            // Convert ticksdelta to the distance between two minor ticks\r\n            ticksDelta /= (ev_mt + 1);\r\n            this.ticksDelta = ticksDelta;\r\n\r\n            if (ticksDelta < Mat.eps) {\r\n                return;\r\n            }\r\n            if (Math.abs(bounds.upper - bounds.lower) > ticksDelta * 2048) {\r\n                JXG.warn(\"JSXGraph ticks: too many ticks (>2048). Please increase ticksDistance.\");\r\n                return;\r\n            }\r\n\r\n            // Position ticks from zero to the positive side while not reaching the upper boundary\r\n            tickPosition = 0;\r\n            if (!this.evalVisProp('drawzero')) {\r\n                tickPosition = ticksDelta;\r\n            }\r\n            if (tickPosition < bounds.lower) {\r\n                // Jump from 0 to bounds.lower\r\n                tickPosition = Math.floor((bounds.lower - eps) / ticksDelta) * ticksDelta;\r\n            }\r\n            while (tickPosition <= bounds.upper + eps) {\r\n                // Only draw ticks when we are within bounds, ignore case where tickPosition < lower < upper\r\n                if (tickPosition >= bounds.lower - eps) {\r\n                    this.processTickPosition(coordsZero, tickPosition, ticksDelta, deltas);\r\n                }\r\n                tickPosition += ticksDelta;\r\n\r\n                // Emergency out (probably obsolete)\r\n                if (bounds.upper - tickPosition > ticksDelta * 10000) {\r\n                    break;\r\n                }\r\n            }\r\n\r\n            // Position ticks from zero (not inclusive) to the negative side while not reaching the lower boundary\r\n            tickPosition = -ticksDelta;\r\n            if (tickPosition > bounds.upper) {\r\n                // Jump from -ticksDelta to bounds.upper\r\n                tickPosition = Math.ceil((bounds.upper + eps) / (-ticksDelta)) * (-ticksDelta);\r\n            }\r\n            while (tickPosition >= bounds.lower - eps) {\r\n                // Only draw ticks when we are within bounds, ignore case where lower < upper < tickPosition\r\n                if (tickPosition <= bounds.upper + eps) {\r\n                    this.processTickPosition(coordsZero, tickPosition, ticksDelta, deltas);\r\n                }\r\n                tickPosition -= ticksDelta;\r\n\r\n                // Emergency out (probably obsolete)\r\n                if (tickPosition - bounds.lower > ticksDelta * 10000) {\r\n                    break;\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Calculates the distance between two major ticks in user units.\r\n         * <ul>\r\n         * <li> If the attribute \"insertTicks\" is false, the value of the attribute\r\n         * \"ticksDistance\" is returned. The attribute \"minTicksDistance\" is ignored in this case.\r\n         * <li> If the attribute \"insertTicks\" is true, the attribute \"ticksDistance\" is ignored.\r\n         * The distance between two major ticks is computed\r\n         * as <i>a 10<sup>i</sup></i>, where <i>a</i> is one of <i>{1, 2, 5}</i> and\r\n         * the number <i>a 10<sup>i</sup></i> is maximized such that there are approximately\r\n         * 6 major ticks and there are at least \"minTicksDistance\" pixel between minor ticks.\r\n         * The latter restriction has priority over the number of major ticks.\r\n         * </ul>\r\n         * @returns Number\r\n         * @private\r\n         */\r\n        getDistanceMajorTicks: function () {\r\n            var delta, delta2,\r\n                b, d, dist,\r\n                scale,\r\n                numberMajorTicks = 5,\r\n                maxDist, minDist, ev_mt;\r\n\r\n            if (this.evalVisProp('insertticks')) {\r\n                // Case of insertTicks==true:\r\n                // Here, we ignore the attribute 'margin'\r\n                b = this.getLowerAndUpperBounds(this.getZeroCoordinates(), '');\r\n\r\n                dist = (b.upper - b.lower);\r\n                scale = this.evalVisProp('scale');\r\n\r\n                maxDist = dist / (numberMajorTicks + 1) / scale;\r\n                minDist = this.evalVisProp('minticksdistance') / scale;\r\n                ev_mt = this.evalVisProp('minorticks');\r\n\r\n                d = this.getXandYdeltas();\r\n                d.x *= this.board.unitX;\r\n                d.y *= this.board.unitY;\r\n                minDist /= Mat.hypot(d.x, d.y);\r\n                minDist *= (ev_mt + 1);\r\n\r\n                // Determine minimal delta to fulfill the minTicksDistance constraint\r\n                delta = Math.pow(10, Math.floor(Math.log(minDist) / Math.LN10));\r\n                if (2 * delta >= minDist) {\r\n                    delta *= 2;\r\n                } else if (5 * delta >= minDist) {\r\n                    delta *= 5;\r\n                }\r\n\r\n                // Determine maximal delta to fulfill the constraint to have approx. \"numberMajorTicks\" majorTicks\r\n                delta2 = Math.pow(10, Math.floor(Math.log(maxDist) / Math.LN10));\r\n                if (5 * delta2 < maxDist) {\r\n                    delta2 *= 5;\r\n                } else if (2 * delta2 < maxDist) {\r\n                    delta2 *= 2;\r\n                }\r\n\r\n                // Take the larger value of the two delta's, that is\r\n                // minTicksDistance has priority over numberMajorTicks\r\n                delta = Math.max(delta, delta2);\r\n\r\n                // < v1.6.0:\r\n                // delta = Math.pow(10, Math.floor(Math.log(0.6 * dist) / Math.LN10));\r\n                // if (false && dist <= 6 * delta) {\r\n                //     delta *= 0.5;\r\n                // }\r\n                return delta;\r\n            }\r\n\r\n            // Case of insertTicks==false\r\n            return this.evalVisProp('ticksdistance');\r\n        },\r\n\r\n        //         /**\r\n        //          * Auxiliary method used by {@link JXG.Ticks#generateEquidistantTicks} to adjust the\r\n        //          * distance between two ticks depending on {@link JXG.Ticks#minTicksDistance} value\r\n        //          *\r\n        //          * @param  {Number}     ticksDelta  distance between two major ticks in user coordinates\r\n        //          * @param  {JXG.Coords} coordsZero  coordinates of the point considered zero\r\n        //          * @param  {Object}     deltas      x and y distance in pixel between two user units\r\n        //          * @param  {Object}     bounds      upper and lower bound of the tick positions in user units.\r\n        //          * @private\r\n        //          */\r\n        //         adjustTickDistance: function (ticksDelta, coordsZero, deltas) {\r\n        //             var nx,\r\n        //                 ny,\r\n        //                 // bounds,\r\n        //                 distScr,\r\n        //                 sgn = 1,\r\n        //                 ev_mintd = this.evalVisProp('minticksdistance'),\r\n        //                 ev_minti = this.evalVisProp('minorticks');\r\n\r\n        //             if (this.line.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n        //                 return ticksDelta;\r\n        //             }\r\n        //             // Seems to be ignored:\r\n        //             // bounds = this.getLowerAndUpperBounds(coordsZero, 'ticksdistance');\r\n\r\n        //             // distScr is the distance between two major Ticks in pixel\r\n        //             nx = coordsZero.usrCoords[1] + deltas.x * ticksDelta;\r\n        //             ny = coordsZero.usrCoords[2] + deltas.y * ticksDelta;\r\n        //             distScr = coordsZero.distance(\r\n        //                 Const.COORDS_BY_SCREEN,\r\n        //                 new Coords(Const.COORDS_BY_USER, [nx, ny], this.board)\r\n        //             );\r\n        // // console.log(deltas, distScr, this.board.unitX, this.board.unitY, \"ticksDelta:\", ticksDelta);\r\n\r\n        //             if (ticksDelta === 0.0) {\r\n        //                 return 0.0;\r\n        //             }\r\n\r\n        // // console.log(\":\", distScr, ev_minti + 1, distScr / (ev_minti + 1), ev_mintd)\r\n        //             while (false && distScr / (ev_minti + 1) < ev_mintd) {\r\n        //                 if (sgn === 1) {\r\n        //                     ticksDelta *= 2;\r\n        //                 } else {\r\n        //                     ticksDelta *= 5;\r\n        //                 }\r\n        //                 sgn *= -1;\r\n\r\n        //                 nx = coordsZero.usrCoords[1] + deltas.x * ticksDelta;\r\n        //                 ny = coordsZero.usrCoords[2] + deltas.y * ticksDelta;\r\n        //                 distScr = coordsZero.distance(\r\n        //                     Const.COORDS_BY_SCREEN,\r\n        //                     new Coords(Const.COORDS_BY_USER, [nx, ny], this.board)\r\n        //                 );\r\n        //             }\r\n\r\n        //             return ticksDelta;\r\n        //         },\r\n\r\n        /**\r\n         * Auxiliary method used by {@link JXG.Ticks#generateEquidistantTicks} to create a tick\r\n         * in the line at the given tickPosition.\r\n         *\r\n         * @param  {JXG.Coords} coordsZero    coordinates of the point considered zero\r\n         * @param  {Number}     tickPosition  current tick position relative to zero\r\n         * @param  {Number}     ticksDelta    distance between two major ticks in user coordinates\r\n         * @param  {Object}     deltas      x and y distance between two major ticks\r\n         * @private\r\n         */\r\n        processTickPosition: function (coordsZero, tickPosition, ticksDelta, deltas) {\r\n            var x,\r\n                y,\r\n                tickCoords,\r\n                ti,\r\n                ev_mt,\r\n                isLabelPosition,\r\n                ticksPerLabel = this.evalVisProp('ticksperlabel'),\r\n                labelVal = null;\r\n\r\n            // Calculates tick coordinates\r\n            if (this.line.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                x = coordsZero.usrCoords[1] + tickPosition * deltas.x;\r\n                y = coordsZero.usrCoords[2] + tickPosition * deltas.y;\r\n            } else {\r\n                x = this.line.X(coordsZero + tickPosition);\r\n                y = this.line.Y(coordsZero + tickPosition);\r\n            }\r\n            tickCoords = new Coords(Const.COORDS_BY_USER, [x, y], this.board);\r\n            if (this.line.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n                labelVal = coordsZero + tickPosition;\r\n                this.setTicksSizeVariables(labelVal);\r\n            }\r\n\r\n            ev_mt = this.evalVisProp('minorticks');\r\n            // Test if tick is a major tick.\r\n            // This is the case if tickPosition/ticksDelta is\r\n            // a multiple of the number of minorticks+1\r\n            tickCoords.major =\r\n                Math.round(tickPosition / ticksDelta) % (ev_mt + 1) === 0;\r\n\r\n            if (!ticksPerLabel) {\r\n                // In case of null, 0 or false, majorTicks are labelled\r\n                ticksPerLabel = ev_mt + 1;\r\n            }\r\n            isLabelPosition = Math.round(tickPosition / ticksDelta) % ticksPerLabel === 0;\r\n\r\n            // Compute the start position and the end position of a tick.\r\n            // If both positions are out of the canvas, ti is empty.\r\n            ti = this.createTickPath(tickCoords, tickCoords.major);\r\n            if (ti.length === 3) {\r\n                this.ticks.push(ti);\r\n                if (isLabelPosition && this.evalVisProp('drawlabels')) {\r\n                    // Create a label at this position\r\n                    this.labelsData.push(\r\n                        this.generateLabelData(\r\n                            this.generateLabelText(tickCoords, coordsZero, labelVal),\r\n                            tickCoords,\r\n                            this.ticks.length\r\n                        )\r\n                    );\r\n                } else {\r\n                    // minor ticks have no labels\r\n                    this.labelsData.push(null);\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Creates ticks coordinates and labels based on {@link JXG.Ticks#fixedTicks} and {@link JXG.Ticks#labels}.\r\n         *\r\n         * @param  {JXG.Coords} coordsZero Coordinates of the point considered zero\r\n         * @param  {Object}     bounds     contains the lower and upper bounds for ticks placement\r\n         * @private\r\n         */\r\n        generateFixedTicks: function (coordsZero, bounds) {\r\n            var tickCoords,\r\n                labelText,\r\n                i,\r\n                ti,\r\n                x,\r\n                y,\r\n                eps2 = Mat.eps,\r\n                fixedTick,\r\n                hasLabelOverrides = Type.isArray(this.visProp.labels),\r\n                deltas,\r\n                ev_dl = this.evalVisProp('drawlabels');\r\n\r\n            if (this.line.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                // Calculate x and y distances between two points on the line which are 1 unit apart\r\n                // In essence, these are cosine and sine.\r\n                deltas = this.getXandYdeltas();\r\n            }\r\n            for (i = 0; i < this.fixedTicks.length; i++) {\r\n                if (this.line.elementClass === Const.OBJECT_CLASS_LINE) {\r\n                    fixedTick = this.fixedTicks[i];\r\n                    x = coordsZero.usrCoords[1] + fixedTick * deltas.x;\r\n                    y = coordsZero.usrCoords[2] + fixedTick * deltas.y;\r\n                } else {\r\n                    fixedTick = coordsZero + this.fixedTicks[i];\r\n                    x = this.line.X(fixedTick);\r\n                    y = this.line.Y(fixedTick);\r\n                }\r\n                tickCoords = new Coords(Const.COORDS_BY_USER, [x, y], this.board);\r\n\r\n                if (this.line.elementClass === Const.OBJECT_CLASS_CURVE) {\r\n                    this.setTicksSizeVariables(fixedTick);\r\n                }\r\n\r\n                // Compute the start position and the end position of a tick.\r\n                // If tick is out of the canvas, ti is empty.\r\n                ti = this.createTickPath(tickCoords, true);\r\n                if (\r\n                    ti.length === 3 &&\r\n                    fixedTick >= bounds.lower - eps2 &&\r\n                    fixedTick <= bounds.upper + eps2\r\n                ) {\r\n                    this.ticks.push(ti);\r\n\r\n                    if (ev_dl && (hasLabelOverrides || Type.exists(this.visProp.labels[i]))) {\r\n                        labelText = hasLabelOverrides\r\n                            ? this.evalVisProp('labels.' + i)\r\n                            : fixedTick;\r\n                        this.labelsData.push(\r\n                            this.generateLabelData(\r\n                                this.generateLabelText(tickCoords, coordsZero, labelText),\r\n                                tickCoords,\r\n                                i\r\n                            )\r\n                        );\r\n                    } else {\r\n                        this.labelsData.push(null);\r\n                    }\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Calculates the x and y distances in user coordinates between two units in user space.\r\n         * In essence, these are cosine and sine. The only work to be done is to determine\r\n         * the direction of the line.\r\n         *\r\n         * @returns {Object}\r\n         * @private\r\n         */\r\n        getXandYdeltas: function () {\r\n            var // Auxiliary points to store the start and end of the line according to its direction\r\n                point1UsrCoords,\r\n                point2UsrCoords,\r\n                distP1P2 = this.line.point1.Dist(this.line.point2);\r\n\r\n            // if (this.line.type === Const.OBJECT_TYPE_AXIS) {\r\n            //     // When line is an Axis, direction depends on board coordinates system\r\n            //     // Assume line.point1 and line.point2 are in correct order\r\n            //     point1UsrCoords = this.line.point1.coords.usrCoords;\r\n            //     point2UsrCoords = this.line.point2.coords.usrCoords;\r\n            //     // Check if direction is incorrect, then swap\r\n            //     if (\r\n            //         point1UsrCoords[1] > point2UsrCoords[1] ||\r\n            //         (Math.abs(point1UsrCoords[1] - point2UsrCoords[1]) < Mat.eps &&\r\n            //             point1UsrCoords[2] > point2UsrCoords[2])\r\n            //     ) {\r\n            //         point1UsrCoords = this.line.point2.coords.usrCoords;\r\n            //         point2UsrCoords = this.line.point1.coords.usrCoords;\r\n            //     }\r\n            // } /* if (this.line.elementClass === Const.OBJECT_CLASS_LINE)*/ else {\r\n                // Line direction is always from P1 to P2 for non axis types\r\n                point1UsrCoords = this.line.point1.coords.usrCoords;\r\n                point2UsrCoords = this.line.point2.coords.usrCoords;\r\n            // }\r\n            return {\r\n                x: (point2UsrCoords[1] - point1UsrCoords[1]) / distP1P2,\r\n                y: (point2UsrCoords[2] - point1UsrCoords[2]) / distP1P2\r\n            };\r\n        },\r\n\r\n        /**\r\n         * Check if (parts of) the tick is inside the canvas. The tick intersects the boundary\r\n         * at two positions: [x[0], y[0]] and [x[1], y[1]] in screen coordinates.\r\n         * @param  {Array}  x Array of length two\r\n         * @param  {Array}  y Array of length two\r\n         * @return {Boolean}   true if parts of the tick are inside of the canvas or on the boundary.\r\n         */\r\n        _isInsideCanvas: function (x, y, m) {\r\n            var cw = this.board.canvasWidth,\r\n                ch = this.board.canvasHeight;\r\n\r\n            if (m === undefined) {\r\n                m = 0;\r\n            }\r\n            return (\r\n                (x[0] >= m && x[0] <= cw - m && y[0] >= m && y[0] <= ch - m) ||\r\n                (x[1] >= m && x[1] <= cw - m && y[1] >= m && y[1] <= ch - m)\r\n            );\r\n        },\r\n\r\n        /**\r\n         * @param {JXG.Coords} coords Coordinates of the tick on the line.\r\n         * @param {Boolean} major True if tick is major tick.\r\n         * @returns {Array} Array of length 3 containing path coordinates in screen coordinates\r\n         *                 of the tick (arrays of length 2). 3rd entry is true if major tick otherwise false.\r\n         *                 If the tick is outside of the canvas, the return array is empty.\r\n         * @private\r\n         */\r\n        createTickPath: function (coords, major) {\r\n            var c,\r\n                lineStdForm,\r\n                intersection,\r\n                dxs,\r\n                dys,\r\n                dxr,\r\n                dyr,\r\n                alpha,\r\n                style,\r\n                x = [-2000000, -2000000],\r\n                y = [-2000000, -2000000],\r\n                i, r, r_max, bb, full, delta,\r\n                // Used for infinite ticks\r\n                te0, te1, // Tick ending visProps\r\n                dists; // 'signed' distances of intersections to the parent line\r\n\r\n            c = coords.scrCoords;\r\n            if (major) {\r\n                dxs = this.dxMaj;\r\n                dys = this.dyMaj;\r\n                style = this.majStyle;\r\n                te0 = this.evalVisProp('majortickendings.0') > 0;\r\n                te1 = this.evalVisProp('majortickendings.1') > 0;\r\n            } else {\r\n                dxs = this.dxMin;\r\n                dys = this.dyMin;\r\n                style = this.minStyle;\r\n                te0 = this.evalVisProp('tickendings.0') > 0;\r\n                te1 = this.evalVisProp('tickendings.1') > 0;\r\n            }\r\n            lineStdForm = [-dys * c[1] - dxs * c[2], dys, dxs];\r\n\r\n            // For all ticks regardless if of finite or infinite\r\n            // tick length the intersection with the canvas border is\r\n            // computed.\r\n            if (major && this.evalVisProp('type') === 'polar') {\r\n                // polar style\r\n                bb = this.board.getBoundingBox();\r\n                full = 2.0 * Math.PI;\r\n                delta = full / 180;\r\n                //ratio = this.board.unitY / this.board.X;\r\n\r\n                // usrCoords: Test if 'circle' is inside of the canvas\r\n                c = coords.usrCoords;\r\n                r = Mat.hypot(c[1], c[2]);\r\n                r_max = Math.max(\r\n                    Mat.hypot(bb[0], bb[1]),\r\n                    Mat.hypot(bb[2], bb[3])\r\n                );\r\n\r\n                if (r < r_max) {\r\n                    // Now, switch to screen coords\r\n                    x = [];\r\n                    y = [];\r\n                    for (i = 0; i <= full; i += delta) {\r\n                        x.push(\r\n                            this.board.origin.scrCoords[1] + r * Math.cos(i) * this.board.unitX\r\n                        );\r\n                        y.push(\r\n                            this.board.origin.scrCoords[2] + r * Math.sin(i) * this.board.unitY\r\n                        );\r\n                    }\r\n                    return [x, y, major];\r\n                }\r\n            } else {\r\n                // line style\r\n                if (style === 'infinite') {\r\n                    // Problematic are infinite ticks which have set tickendings:[0,1].\r\n                    // For example, this is the default setting for minor ticks\r\n                    if (this.evalVisProp('ignoreinfinitetickendings')) {\r\n                        te0 = te1 = true;\r\n                    }\r\n                    intersection = Geometry.meetLineBoard(lineStdForm, this.board);\r\n\r\n                    if (te0 && te1) {\r\n                        x[0] = intersection[0].scrCoords[1];\r\n                        x[1] = intersection[1].scrCoords[1];\r\n                        y[0] = intersection[0].scrCoords[2];\r\n                        y[1] = intersection[1].scrCoords[2];\r\n                    } else {\r\n                        // Assuming the usrCoords of both intersections are normalized, a 'signed distance'\r\n                        // with respect to the parent line is computed for the intersections. The sign is\r\n                        // used to conclude whether the point is either at the left or right side of the\r\n                        // line. The magnitude can be used to compare the points and determine which point\r\n                        // is closest to the line.\r\n                        dists = [\r\n                            Mat.innerProduct(\r\n                                intersection[0].usrCoords.slice(1, 3),\r\n                                this.line.stdform.slice(1, 3)\r\n                            ) + this.line.stdform[0],\r\n                            Mat.innerProduct(\r\n                                intersection[1].usrCoords.slice(1, 3),\r\n                                this.line.stdform.slice(1, 3)\r\n                            ) + this.line.stdform[0]\r\n                        ];\r\n\r\n                        // Reverse intersection array order if first intersection is not the leftmost one.\r\n                        if (dists[0] < dists[1]) {\r\n                            intersection.reverse();\r\n                            dists.reverse();\r\n                        }\r\n\r\n                        if (te0) { // Left-infinite tick\r\n                            if (dists[0] < 0) { // intersections at the wrong side of line\r\n                                return [];\r\n                            } else if (dists[1] < 0) { // 'default' case, tick drawn from line to board bounds\r\n                                x[0] = intersection[0].scrCoords[1];\r\n                                y[0] = intersection[0].scrCoords[2];\r\n                                x[1] = c[1];\r\n                                y[1] = c[2];\r\n                            } else { // tick visible, but coords of tick on line are outside the visible area\r\n                                x[0] = intersection[0].scrCoords[1];\r\n                                y[0] = intersection[0].scrCoords[2];\r\n                                x[1] = intersection[1].scrCoords[1];\r\n                                y[1] = intersection[1].scrCoords[2];\r\n                            }\r\n                        } else if (te1) { // Right-infinite tick\r\n                            if (dists[1] > 0) { // intersections at the wrong side of line\r\n                                return [];\r\n                            } else if (dists[0] > 0) { // 'default' case, tick drawn from line to board bounds\r\n                                x[0] = c[1];\r\n                                y[0] = c[2];\r\n                                x[1] = intersection[1].scrCoords[1];\r\n                                y[1] = intersection[1].scrCoords[2];\r\n                            } else { // tick visible, but coords of tick on line are outside the visible area\r\n                                x[0] = intersection[0].scrCoords[1];\r\n                                y[0] = intersection[0].scrCoords[2];\r\n                                x[1] = intersection[1].scrCoords[1];\r\n                                y[1] = intersection[1].scrCoords[2];\r\n                            }\r\n                        }\r\n                    }\r\n                } else {\r\n                    if (this.evalVisProp('face') === \">\") {\r\n                        alpha = Math.PI / 4;\r\n                    } else if (this.evalVisProp('face') === \"<\") {\r\n                        alpha = -Math.PI / 4;\r\n                    } else {\r\n                        alpha = 0;\r\n                    }\r\n                    dxr = Math.cos(alpha) * dxs - Math.sin(alpha) * dys;\r\n                    dyr = Math.sin(alpha) * dxs + Math.cos(alpha) * dys;\r\n\r\n                    x[0] = c[1] + dxr * te0;\r\n                    y[0] = c[2] - dyr * te0;\r\n                    x[1] = c[1];\r\n                    y[1] = c[2];\r\n\r\n                    alpha = -alpha;\r\n                    dxr = Math.cos(alpha) * dxs - Math.sin(alpha) * dys;\r\n                    dyr = Math.sin(alpha) * dxs + Math.cos(alpha) * dys;\r\n\r\n                    x[2] = c[1] - dxr * te1;\r\n                    y[2] = c[2] + dyr * te1;\r\n                }\r\n\r\n                // Check if (parts of) the tick is inside the canvas.\r\n                if (this._isInsideCanvas(x, y)) {\r\n                    return [x, y, major];\r\n                }\r\n            }\r\n\r\n            return [];\r\n        },\r\n\r\n        /**\r\n         * Format label texts. Show the desired number of digits\r\n         * and use utf-8 minus sign.\r\n         * @param  {Number} value Number to be displayed\r\n         * @return {String}       The value converted into a string.\r\n         * @private\r\n         */\r\n        formatLabelText: function (value) {\r\n            var labelText,\r\n                digits,\r\n                ev_um = this.evalVisProp('label.usemathjax'),\r\n                ev_uk = this.evalVisProp('label.usekatex'),\r\n                ev_s = this.evalVisProp('scalesymbol');\r\n\r\n            if (Type.isNumber(value)) {\r\n                if (this.evalVisProp('label.tofraction')) {\r\n                    if (ev_um) {\r\n                        labelText = '\\\\(' + Type.toFraction(value, true) + '\\\\)';\r\n                    } else {\r\n                        labelText = Type.toFraction(value, ev_uk);\r\n                    }\r\n                } else {\r\n                    digits = this.evalVisProp('digits');\r\n                    if (this.useLocale()) {\r\n                        labelText = this.formatNumberLocale(value, digits);\r\n                    } else {\r\n                        labelText = (Math.round(value * 1e11) / 1e11).toString();\r\n\r\n                        if (\r\n                            labelText.length > this.evalVisProp('maxlabellength') ||\r\n                            labelText.indexOf('e') !== -1\r\n                        ) {\r\n                            if (this.evalVisProp('precision') !== 3 && digits === 3) {\r\n                                // Use the deprecated attribute \"precision\"\r\n                                digits = this.evalVisProp('precision');\r\n                            }\r\n\r\n                            //labelText = value.toPrecision(digits).toString();\r\n                            labelText = value.toExponential(digits).toString();\r\n                        }\r\n                    }\r\n                }\r\n\r\n                if (this.evalVisProp('beautifulscientificticklabels')) {\r\n                    labelText = this.beautifyScientificNotationLabel(labelText);\r\n                }\r\n\r\n                if (labelText.indexOf('.') > -1 && labelText.indexOf('e') === -1) {\r\n                    // trim trailing zeros\r\n                    labelText = labelText.replace(/0+$/, \"\");\r\n                    // trim trailing .\r\n                    labelText = labelText.replace(/\\.$/, \"\");\r\n                }\r\n            } else {\r\n                labelText = value.toString();\r\n            }\r\n\r\n            if (ev_s.length > 0) {\r\n                if (labelText === '1') {\r\n                    labelText = ev_s;\r\n                } else if (labelText === \"-1\") {\r\n                    labelText = \"-\" + ev_s;\r\n                } else if (labelText !== '0') {\r\n                    labelText = labelText + ev_s;\r\n                }\r\n            }\r\n\r\n            if (this.evalVisProp('useunicodeminus')) {\r\n                labelText = labelText.replace(/-/g, \"\\u2212\");\r\n            }\r\n            return labelText;\r\n        },\r\n\r\n        /**\r\n         * Formats label texts to make labels displayed in scientific notation look beautiful.\r\n         * For example, label 5.00e+6 will become 5•10⁶, label -1.00e-7 will become into -1•10⁻⁷\r\n         * @param {String} labelText - The label that we want to convert\r\n         * @returns {String} If labelText was not in scientific notation, return labelText without modifications.\r\n         * Otherwise returns beautified labelText with proper superscript notation.\r\n         */\r\n        beautifyScientificNotationLabel: function (labelText) {\r\n            var returnString;\r\n\r\n            if (labelText.indexOf('e') === -1) {\r\n                return labelText;\r\n            }\r\n\r\n            // Clean up trailing 0's, so numbers like 5.00e+6.0 for example become into 5e+6\r\n            returnString =\r\n                parseFloat(labelText.substring(0, labelText.indexOf('e'))) +\r\n                labelText.substring(labelText.indexOf('e'));\r\n\r\n            // Replace symbols like -,0,1,2,3,4,5,6,7,8,9 with their superscript version.\r\n            // Gets rid of + symbol since there is no need for it anymore.\r\n            returnString = returnString.replace(/e(.*)$/g, function (match, $1) {\r\n                var temp = \"\\u2022\" + '10';\r\n                // Note: Since board ticks do not support HTTP elements like <sub>, we need to replace\r\n                // all the numbers with superscript Unicode characters.\r\n                temp += $1\r\n                    .replace(/-/g, \"\\u207B\")\r\n                    .replace(/\\+/g, \"\")\r\n                    .replace(/0/g, \"\\u2070\")\r\n                    .replace(/1/g, \"\\u00B9\")\r\n                    .replace(/2/g, \"\\u00B2\")\r\n                    .replace(/3/g, \"\\u00B3\")\r\n                    .replace(/4/g, \"\\u2074\")\r\n                    .replace(/5/g, \"\\u2075\")\r\n                    .replace(/6/g, \"\\u2076\")\r\n                    .replace(/7/g, \"\\u2077\")\r\n                    .replace(/8/g, \"\\u2078\")\r\n                    .replace(/9/g, \"\\u2079\");\r\n\r\n                return temp;\r\n            });\r\n\r\n            return returnString;\r\n        },\r\n\r\n        /**\r\n         * Creates the label text for a given tick. A value for the text can be provided as a number or string\r\n         *\r\n         * @param  {JXG.Coords}    tick  The Coords-object of the tick to create a label for\r\n         * @param  {JXG.Coords}    zero  The Coords-object of line's zero\r\n         * @param  {Number|String} value A predefined value for this tick\r\n         * @returns {String}\r\n         * @private\r\n         */\r\n        generateLabelText: function (tick, zero, value) {\r\n            var labelText, distance;\r\n\r\n            // No value provided, equidistant, so assign distance as value\r\n            if (!Type.exists(value)) {\r\n                // could be null or undefined\r\n                distance = this.getDistanceFromZero(zero, tick);\r\n                if (Math.abs(distance) < Mat.eps) {\r\n                    // Point is zero\r\n                    return '0';\r\n                }\r\n                value = distance / this.evalVisProp('scale');\r\n            }\r\n            labelText = this.formatLabelText(value);\r\n\r\n            return labelText;\r\n        },\r\n\r\n        /**\r\n         * Create a tick label data, i.e. text and coordinates\r\n         * @param  {String}     labelText\r\n         * @param  {JXG.Coords} tick\r\n         * @param  {Number}     tickNumber\r\n         * @returns {Object} with properties 'x', 'y', 't' (text), 'i' (tick number) or null in case of o label\r\n         * @private\r\n         */\r\n        generateLabelData: function (labelText, tick, tickNumber) {\r\n            var xa, ya, m, fs;\r\n\r\n            // Test if large portions of the label are inside of the canvas\r\n            // This is the last chance to abandon the creation of the label if it is mostly\r\n            // outside of the canvas.\r\n            fs = this.evalVisProp('label.fontsize');\r\n            xa = [tick.scrCoords[1], tick.scrCoords[1]];\r\n            ya = [tick.scrCoords[2], tick.scrCoords[2]];\r\n            m = fs === undefined ? 12 : fs;\r\n            m *= 0.5;\r\n            if (!this._isInsideCanvas(xa, ya, m)) {\r\n                return null;\r\n            }\r\n\r\n            xa = this.evalVisProp('label.offset')[0];\r\n            ya = this.evalVisProp('label.offset')[1];\r\n\r\n            return {\r\n                x: tick.usrCoords[1] + xa / this.board.unitX,\r\n                y: tick.usrCoords[2] + ya / this.board.unitY,\r\n                t: labelText,\r\n                i: tickNumber\r\n            };\r\n        },\r\n\r\n        /**\r\n         * Recalculate the tick positions and the labels.\r\n         * @returns {JXG.Ticks}\r\n         */\r\n        update: function () {\r\n            if (this.needsUpdate) {\r\n                //this.visPropCalc.visible = this.evalVisProp('visible');\r\n                // A canvas with no width or height will create an endless loop, so ignore it\r\n                if (this.board.canvasWidth !== 0 && this.board.canvasHeight !== 0) {\r\n                    this.calculateTicksCoordinates();\r\n                }\r\n                // this.updateVisibility(this.line.visPropCalc.visible);\r\n                //\r\n                // for (var i = 0; i < this.labels.length; i++) {\r\n                //     if (this.labels[i] !== null) {\r\n                //         this.labels[i].prepareUpdate()\r\n                //             .updateVisibility(this.line.visPropCalc.visible)\r\n                //             .updateRenderer();\r\n                //     }\r\n                // }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Uses the boards renderer to update the arc.\r\n         * @returns {JXG.Ticks} Reference to the object.\r\n         */\r\n        updateRenderer: function () {\r\n            if (!this.needsUpdate) {\r\n                return this;\r\n            }\r\n\r\n            if (this.visPropCalc.visible) {\r\n                this.board.renderer.updateTicks(this);\r\n            }\r\n            this.updateRendererLabels();\r\n\r\n            this.setDisplayRendNode();\r\n            // if (this.visPropCalc.visible != this.visPropOld.visible) {\r\n            //     this.board.renderer.display(this, this.visPropCalc.visible);\r\n            //     this.visPropOld.visible = this.visPropCalc.visible;\r\n            // }\r\n\r\n            this.needsUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Updates the label elements of the major ticks.\r\n         *\r\n         * @private\r\n         * @returns {JXG.Ticks} Reference to the object.\r\n         */\r\n        updateRendererLabels: function () {\r\n            var i, j, lenData, lenLabels, attr, label, ld, visible;\r\n\r\n            // The number of labels needed\r\n            lenData = this.labelsData.length;\r\n            // The number of labels which already exist\r\n            // The existing labels are stored in this.labels[]\r\n            // The new label positions and label values are stored in this.labelsData[]\r\n            lenLabels = this.labels.length;\r\n\r\n            for (i = 0, j = 0; i < lenData; i++) {\r\n                if (this.labelsData[i] === null) {\r\n                    // This is a tick without label\r\n                    continue;\r\n                }\r\n\r\n                ld = this.labelsData[i];\r\n                if (j < lenLabels) {\r\n                    // Take an already existing text element\r\n                    label = this.labels[j];\r\n                    label.setText(ld.t);\r\n                    label.setCoords(ld.x, ld.y);\r\n                    j++;\r\n                } else {\r\n                    // A new text element is needed\r\n                    this.labelCounter += 1;\r\n\r\n                    attr = Type.deepCopy(this.visProp.label);\r\n                    attr.isLabel = true;\r\n                    attr.priv = this.visProp.priv;\r\n                    attr.id = this.id + ld.i + \"Label\" + this.labelCounter;\r\n\r\n                    label = JXG.createText(this.board, [ld.x, ld.y, ld.t], attr);\r\n                    this.addChild(label);\r\n                    label.setParents(this);\r\n                    label.isDraggable = false;\r\n                    label.dump = false;\r\n                    this.labels.push(label);\r\n                }\r\n\r\n                // Look-ahead if the label inherits visibility.\r\n                // If yes, update label.\r\n                visible = this.evalVisProp('label.visible');\r\n                if (visible === 'inherit') {\r\n                    visible = this.visPropCalc.visible;\r\n                }\r\n\r\n                label.prepareUpdate().updateVisibility(visible).updateRenderer();\r\n\r\n                label.distanceX = this.evalVisProp('label.offset')[0];\r\n                label.distanceY = this.evalVisProp('label.offset')[1];\r\n            }\r\n\r\n            // Hide unused labels\r\n            lenData = j;\r\n            for (j = lenData; j < lenLabels; j++) {\r\n                this.board.renderer.display(this.labels[j], false);\r\n                // Tick labels have the attribute \"visible: 'inherit'\"\r\n                // This must explicitly set to false, otherwise\r\n                // this labels would be set to visible in the upcoming\r\n                // update of the labels.\r\n                this.labels[j].visProp.visible = this.labels[j].visPropCalc.visible = false;\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        hideElement: function () {\r\n            var i;\r\n\r\n            JXG.deprecated(\"Element.hideElement()\", \"Element.setDisplayRendNode()\");\r\n\r\n            this.visPropCalc.visible = false;\r\n            this.board.renderer.display(this, false);\r\n            for (i = 0; i < this.labels.length; i++) {\r\n                if (Type.exists(this.labels[i])) {\r\n                    this.labels[i].hideElement();\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        showElement: function () {\r\n            var i;\r\n\r\n            JXG.deprecated(\"Element.showElement()\", \"Element.setDisplayRendNode()\");\r\n\r\n            this.visPropCalc.visible = true;\r\n            this.board.renderer.display(this, false);\r\n\r\n            for (i = 0; i < this.labels.length; i++) {\r\n                if (Type.exists(this.labels[i])) {\r\n                    this.labels[i].showElement();\r\n                }\r\n            }\r\n\r\n            return this;\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * @class Ticks are used as distance markers on a line or curve.\r\n * They are mainly used for axis elements and slider elements. Ticks may stretch infinitely\r\n * or finitely, which can be set with {@link Ticks#majorHeight} and {@link Ticks#minorHeight}.\r\n * <p>\r\n * There are the following ways to position the tick lines:\r\n * <ol>\r\n *  <li> If an array is given as optional second parameter for the constructor\r\n * like e.g. <tt>board.create('ticks', [line, [1, 4, 5]])</tt>, then there will be (fixed) ticks at position\r\n * 1, 4 and 5 of the line.\r\n *  <li> If there is only one parameter given, like e.g. <tt>board.create('ticks', [line])</tt>, the ticks will be set\r\n * equidistant across the line element. There are two variants:\r\n *    <ol type=\"i\">\r\n *      <li> Setting the attribute <tt>insertTicks:false</tt>: in this case the distance between two major ticks\r\n *          is determined by the attribute <tt>ticksDistance</tt>. This distance is given in user units.\r\n *      <li> Setting the attribute <tt>insertTicks:true</tt>: in this case the distance between two major ticks\r\n *          is set automatically, depending on\r\n *          <ul>\r\n *              <li> the size of the board,\r\n *              <li> the attribute <tt>minTicksDistance</tt>,  which is the minimum distance between two consecutive minor ticks (in pixel).\r\n *          </ul>\r\n * The distance between two major ticks is a value of the form\r\n * <i>a 10<sup>i</sup></i>, where <i>a</i> is one of <i>{1, 2, 5}</i> and\r\n * the number <i>a 10<sup>i</sup></i> is maximized such that there are approximately\r\n * 6 major ticks and there are at least \"minTicksDistance\" pixel between minor ticks.\r\n * </ol>\r\n * <p>\r\n * For arbitrary lines (and not axes) a \"zero coordinate\" is determined\r\n * which defines where the first tick is positioned. This zero coordinate\r\n * can be altered with the attribute <tt>anchor</tt>. Possible values are \"left\", \"middle\", \"right\" or a number.\r\n * The default value is \"left\".\r\n *\r\n * @pseudo\r\n * @name Ticks\r\n * @augments JXG.Ticks\r\n * @constructor\r\n * @type JXG.Ticks\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Line|JXG.Curve} line The parents consist of the line or curve the ticks are going to be attached to.\r\n * @param {Array} [ticks] Optional array of numbers. If given, a fixed number of static ticks is created\r\n * at these user-supplied positions.\r\n * <p>\r\n * Deprecated: Alternatively, a number defining the distance between two major ticks\r\n * can be specified. However, this is meanwhile ignored. Use attribute <tt>ticksDistance</tt> instead.\r\n *\r\n * @example\r\n * // Add ticks to line 'l1' through 'p1' and 'p2'. The major ticks are\r\n * // two units apart and 40 px long.\r\n *   var p1 = board.create('point', [0, 3]);\r\n *   var p2 = board.create('point', [1, 3]);\r\n *   var l1 = board.create('line', [p1, p2]);\r\n *   var t = board.create('ticks', [l1], {\r\n *      ticksDistance: 2,\r\n *      majorHeight: 40\r\n *   });\r\n * </pre><div class=\"jxgbox\" id=\"JXGee7f2d68-75fc-4ec0-9931-c76918427e63\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXGee7f2d68-75fc-4ec0-9931-c76918427e63', {\r\n *   boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: true});\r\n *   var p1 = board.create('point', [0, 3]);\r\n *   var p2 = board.create('point', [1, 3]);\r\n *   var l1 = board.create('line', [p1, p2]);\r\n *   var t = board.create('ticks', [l1, 2], {ticksDistance: 2, majorHeight: 40});\r\n * })();\r\n * </script><pre>\r\n * @example\r\n *  // Create ticks labels as fractions\r\n * board.create('axis', [[0,1], [1,1]], {\r\n *     ticks: {\r\n *         label: {\r\n *             toFraction: true,\r\n *             useMathjax: true,\r\n *             display: 'html',\r\n *             anchorX: 'middle',\r\n *             offset: [0, -10]\r\n *         }\r\n *     }\r\n * });\r\n *\r\n * </pre><div id=\"JXG4455acb2-6bf3-4801-8887-d7fcc1e4e1da\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script src=\"https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js\" id=\"MathJax-script\"></script>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG4455acb2-6bf3-4801-8887-d7fcc1e4e1da',\r\n *             {boundingbox: [-1.2, 2.3, 1.2, -2.3], axis: true, showcopyright: false, shownavigation: false});\r\n *             board.create('axis', [[0,1], [1,1]], {\r\n *                 ticks: {\r\n *                     label: {\r\n *                         toFraction: true,\r\n *             useMathjax: true,\r\n *             display: 'html',\r\n *             anchorX: 'middle',\r\n *             offset: [0, -10]\r\n *                     }\r\n *                 }\r\n *             });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n */\r\nJXG.createTicks = function (board, parents, attributes) {\r\n    var el,\r\n        dist,\r\n        attr = Type.copyAttributes(attributes, board.options, 'ticks');\r\n\r\n    if (parents.length < 2) {\r\n        dist = attr.ticksdistance; // Will be ignored anyhow and attr.ticksDistance will be used instead\r\n    } else {\r\n        dist = parents[1];\r\n    }\r\n\r\n    if (\r\n        parents[0].elementClass === Const.OBJECT_CLASS_LINE ||\r\n        parents[0].elementClass === Const.OBJECT_CLASS_CURVE\r\n    ) {\r\n        el = new JXG.Ticks(parents[0], dist, attr);\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create Ticks with parent types '\" + typeof parents[0] + \"'.\"\r\n        );\r\n    }\r\n\r\n    // deprecated\r\n    if (Type.isFunction(attr.generatelabelvalue)) {\r\n        el.generateLabelText = attr.generatelabelvalue;\r\n    }\r\n    if (Type.isFunction(attr.generatelabeltext)) {\r\n        el.generateLabelText = attr.generatelabeltext;\r\n    }\r\n\r\n    el.setParents(parents[0]);\r\n    el.isDraggable = true;\r\n    el.fullUpdate(parents[0].visPropCalc.visible);\r\n\r\n    return el;\r\n};\r\n\r\n/**\r\n * @class Hatches are collections of short line segments used to mark congruent lines or curves.\r\n * @pseudo\r\n * @name Hatch\r\n * @augments JXG.Ticks\r\n * @constructor\r\n * @type JXG.Ticks\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Line|JXG.curve} line The line or curve the hatch marks are going to be attached to.\r\n * @param {Number} numberofhashes Number of dashes. The distance of the hashes can be controlled with the attribute ticksDistance.\r\n * @example\r\n * // Create an axis providing two coords pairs.\r\n *   var p1 = board.create('point', [0, 3]);\r\n *   var p2 = board.create('point', [1, 3]);\r\n *   var l1 = board.create('line', [p1, p2]);\r\n *   var t = board.create('hatch', [l1, 3]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG4a20af06-4395-451c-b7d1-002757cf01be\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG4a20af06-4395-451c-b7d1-002757cf01be', {boundingbox: [-1, 7, 7, -1], showcopyright: false, shownavigation: false});\r\n *   var p1 = board.create('point', [0, 3]);\r\n *   var p2 = board.create('point', [1, 3]);\r\n *   var l1 = board.create('line', [p1, p2]);\r\n *   var t = board.create('hatch', [l1, 3]);\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Alter the position of the hatch\r\n *\r\n * var p = board.create('point', [-5, 0]);\r\n * var q = board.create('point', [5, 0]);\r\n * var li = board.create('line', [p, q]);\r\n * var h = board.create('hatch', [li, 2], {anchor: 0.2, ticksDistance:0.4});\r\n *\r\n * </pre><div id=\"JXG05d720ee-99c9-11e6-a9c7-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG05d720ee-99c9-11e6-a9c7-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *\r\n *     var p = board.create('point', [-5, 0]);\r\n *     var q = board.create('point', [5, 0]);\r\n *     var li = board.create('line', [p, q]);\r\n *     var h = board.create('hatch', [li, 2], {anchor: 0.2, ticksDistance:0.4});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Alternative hatch faces\r\n *\r\n * var li = board.create('line', [[-6,0], [6,3]]);\r\n * var h1 = board.create('hatch', [li, 2], {tickEndings: [1,1], face:'|'});\r\n * var h2 = board.create('hatch', [li, 2], {tickEndings: [1,1], face:'>', anchor: 0.3});\r\n * var h3 = board.create('hatch', [li, 2], {tickEndings: [1,1], face:'<', anchor: 0.7});\r\n *\r\n * </pre><div id=\"JXG974f7e89-eac8-4187-9aa3-fb8068e8384b\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG974f7e89-eac8-4187-9aa3-fb8068e8384b',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     // Alternative hatch faces\r\n *\r\n *     var li = board.create('line', [[-6,0], [6,3]]);\r\n *     var h1 = board.create('hatch', [li, 2], {tickEndings: [1,1], face:'|'});\r\n *     var h2 = board.create('hatch', [li, 2], {tickEndings: [1,1], face:'>', anchor: 0.3});\r\n *     var h3 = board.create('hatch', [li, 2], {tickEndings: [1,1], face:'<', anchor: 0.7});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createHatchmark = function (board, parents, attributes) {\r\n    var num, i, base, width, totalwidth, el,\r\n        pos = [],\r\n        attr = Type.copyAttributes(attributes, board.options, 'hatch');\r\n\r\n    if (\r\n        (parents[0].elementClass !== Const.OBJECT_CLASS_LINE &&\r\n            parents[0].elementClass !== Const.OBJECT_CLASS_CURVE) ||\r\n        typeof parents[1] !== \"number\"\r\n    ) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create Hatch mark with parent types '\" +\r\n            typeof parents[0] +\r\n            \"' and '\" +\r\n            typeof parents[1] +\r\n            \" and ''\" +\r\n            typeof parents[2] +\r\n            \"'.\"\r\n        );\r\n    }\r\n\r\n    num = parents[1];\r\n    width = attr.ticksdistance;\r\n    totalwidth = (num - 1) * width;\r\n    base = -totalwidth * 0.5;\r\n\r\n    for (i = 0; i < num; i++) {\r\n        pos[i] = base + i * width;\r\n    }\r\n\r\n    el = board.create('ticks', [parents[0], pos], attr);\r\n    el.elType = 'hatch';\r\n    parents[0].inherits.push(el);\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"ticks\", JXG.createTicks);\r\nJXG.registerElement(\"hash\", JXG.createHatchmark);\r\nJXG.registerElement(\"hatch\", JXG.createHatchmark);\r\n\r\nexport default JXG.Ticks;\r\n// export default {\r\n//     Ticks: JXG.Ticks,\r\n//     createTicks: JXG.createTicks,\r\n//     createHashmark: JXG.createHatchmark,\r\n//     createHatchmark: JXG.createHatchmark\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph and JSXCompressor.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n    JSXCompressor is free software dual licensed under the GNU LGPL or Apache License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n      OR\r\n      * Apache License Version 2.0\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License, Apache\r\n    License, and the MIT License along with JSXGraph. If not, see\r\n    <https://www.gnu.org/licenses/>, <https://www.apache.org/licenses/LICENSE-2.0.html>,\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true, bitwise: true*/\r\n\r\n/**\r\n * @fileoverview Utilities for uncompressing and base64 decoding\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\n\r\n// Zip routine constants\r\n\r\nvar bitReverse = [\r\n        0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0,\r\n        0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8,\r\n        0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94,\r\n        0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,\r\n        0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2,\r\n        0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca,\r\n        0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86,\r\n        0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,\r\n        0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe,\r\n        0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1,\r\n        0x31, 0xb1, 0x71, 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99,\r\n        0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,\r\n        0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad,\r\n        0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3,\r\n        0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b,\r\n        0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,\r\n        0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7,\r\n        0x77, 0xf7, 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf,\r\n        0x3f, 0xbf, 0x7f, 0xff\r\n    ],\r\n    cplens = [\r\n        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99,\r\n        115, 131, 163, 195, 227, 258, 0, 0\r\n    ],\r\n    cplext = [\r\n        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0,\r\n        99, 99\r\n    ] /* 99==invalid */,\r\n    cpdist = [\r\n        0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0007, 0x0009, 0x000d, 0x0011, 0x0019, 0x0021,\r\n        0x0031, 0x0041, 0x0061, 0x0081, 0x00c1, 0x0101, 0x0181, 0x0201, 0x0301, 0x0401, 0x0601,\r\n        0x0801, 0x0c01, 0x1001, 0x1801, 0x2001, 0x3001, 0x4001, 0x6001\r\n    ],\r\n    cpdext = [\r\n        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12,\r\n        12, 13, 13\r\n    ],\r\n    border = [16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15],\r\n    NAMEMAX = 256;\r\n\r\n// Util namespace\r\nJXG.Util = JXG.Util || {};\r\n\r\n/**\r\n * @class Unzip class\r\n * Class for gunzipping, unzipping and base64 decoding of files.\r\n * It is used for reading GEONExT, Geogebra and Intergeo files.\r\n *\r\n * Only Huffman codes are decoded in gunzip.\r\n * The code is based on the source code for gunzip.c by Pasi Ojala\r\n * @see http://www.cs.tut.fi/~albert/Dev/gunzip/gunzip.c\r\n * @see http://www.cs.tut.fi/~albert\r\n */\r\nJXG.Util.Unzip = function (barray) {\r\n    var gpflags,\r\n        // SIZE,\r\n        fileout,\r\n        flens,\r\n        fmax,\r\n        outputArr = [],\r\n        files = 0,\r\n        unzipped = [],\r\n        buf32k = new Array(32768),\r\n        bIdx = 0,\r\n        modeZIP = false,\r\n        barraylen = barray.length,\r\n        bytepos = 0,\r\n        bb = 1,\r\n        // bits = 0,\r\n        literalTree = new Array(288),\r\n        distanceTree = new Array(32),\r\n        treepos = 0,\r\n        Places = null,\r\n        // crc,\r\n        // output = \"\",\r\n        // debug = false,\r\n        // bitpos = 0,\r\n        // Places2 = null,\r\n        // impDistanceTree = new Array(64),\r\n        // impLengthTree = new Array(64),\r\n        len = 0,\r\n        fpos = new Array(17),\r\n        nameBuf = [];\r\n\r\n    fpos[0] = 0;\r\n\r\n    function readByte() {\r\n        // bits += 8;\r\n\r\n        if (bytepos < barraylen) {\r\n            return barray[bytepos++];\r\n        }\r\n\r\n        return -1;\r\n    }\r\n\r\n    function byteAlign() {\r\n        bb = 1;\r\n    }\r\n\r\n    function readBit() {\r\n        var carry;\r\n\r\n        // Prevent problems on iOS7 with >>\r\n        try {\r\n            // bits++;\r\n            carry = bb & 1;\r\n            bb >>= 1;\r\n\r\n            if (bb === 0) {\r\n                bb = readByte();\r\n                carry = bb & 1;\r\n                bb = (bb >> 1) | 0x80;\r\n            }\r\n        } catch (e) {\r\n            console.log(\"Probably problems on iOS7 with >>\");\r\n            throw e;\r\n        }\r\n\r\n        return carry;\r\n    }\r\n\r\n    function readBits(a) {\r\n        var res = 0,\r\n            i = a;\r\n\r\n        // Prevent problems on iOS7 with >>\r\n        try {\r\n            while (i--) {\r\n                res = (res << 1) | readBit();\r\n            }\r\n\r\n            if (a) {\r\n                res = bitReverse[res] >> (8 - a);\r\n            }\r\n        } catch (e) {\r\n            console.log(\"Probably problems on iOS7 with >>\");\r\n            throw e;\r\n        }\r\n        return res;\r\n    }\r\n\r\n    function flushBuffer() {\r\n        bIdx = 0;\r\n    }\r\n\r\n    function addBuffer(a) {\r\n        // SIZE++;\r\n        buf32k[bIdx++] = a;\r\n        outputArr.push(String.fromCharCode(a));\r\n\r\n        if (bIdx === 0x8000) {\r\n            bIdx = 0;\r\n        }\r\n    }\r\n\r\n    function HufNode() {\r\n        this.b0 = 0;\r\n        this.b1 = 0;\r\n        this.jump = null;\r\n        this.jumppos = -1;\r\n    }\r\n\r\n    function isPat() {\r\n        var endless = true;\r\n        while (endless) {\r\n            if (fpos[len] >= fmax) {\r\n                return -1;\r\n            }\r\n\r\n            if (flens[fpos[len]] === len) {\r\n                return fpos[len]++;\r\n            }\r\n\r\n            fpos[len]++;\r\n        }\r\n    }\r\n\r\n    function rec() {\r\n        var curplace = Places[treepos],\r\n            tmp;\r\n\r\n        if (len === 17) {\r\n            return -1;\r\n        }\r\n        treepos++;\r\n        len++;\r\n\r\n        tmp = isPat();\r\n\r\n        if (tmp >= 0) {\r\n            /* leaf cell for 0-bit */\r\n            curplace.b0 = tmp;\r\n        } else {\r\n            /* Not a Leaf cell */\r\n            curplace.b0 = 0x8000;\r\n\r\n            if (rec()) {\r\n                return -1;\r\n            }\r\n        }\r\n\r\n        tmp = isPat();\r\n\r\n        if (tmp >= 0) {\r\n            /* leaf cell for 1-bit */\r\n            curplace.b1 = tmp;\r\n            /* Just for the display routine */\r\n            curplace.jump = null;\r\n        } else {\r\n            /* Not a Leaf cell */\r\n            curplace.b1 = 0x8000;\r\n            curplace.jump = Places[treepos];\r\n            curplace.jumppos = treepos;\r\n            if (rec()) {\r\n                return -1;\r\n            }\r\n        }\r\n        len--;\r\n\r\n        return 0;\r\n    }\r\n\r\n    function createTree(currentTree, numval, lengths, show) {\r\n        var i;\r\n\r\n        Places = currentTree;\r\n        treepos = 0;\r\n        flens = lengths;\r\n        fmax = numval;\r\n\r\n        for (i = 0; i < 17; i++) {\r\n            fpos[i] = 0;\r\n        }\r\n        len = 0;\r\n\r\n        if (rec()) {\r\n            return -1;\r\n        }\r\n\r\n        return 0;\r\n    }\r\n\r\n    function decodeValue(currentTree) {\r\n        var len,\r\n            i, b,\r\n            endless = true,\r\n            xtreepos = 0,\r\n            X = currentTree[xtreepos];\r\n\r\n        /* decode one symbol of the data */\r\n        while (endless) {\r\n            b = readBit();\r\n\r\n            if (b) {\r\n                if (!(X.b1 & 0x8000)) {\r\n                    /* If leaf node, return data */\r\n                    return X.b1;\r\n                }\r\n\r\n                X = X.jump;\r\n                len = currentTree.length;\r\n\r\n                for (i = 0; i < len; i++) {\r\n                    if (currentTree[i] === X) {\r\n                        xtreepos = i;\r\n                        break;\r\n                    }\r\n                }\r\n            } else {\r\n                if (!(X.b0 & 0x8000)) {\r\n                    /* If leaf node, return data */\r\n                    return X.b0;\r\n                }\r\n                xtreepos++;\r\n                X = currentTree[xtreepos];\r\n            }\r\n        }\r\n    }\r\n\r\n    function deflateLoop() {\r\n        var last, c, type, i, j, l, ll, ll2,\r\n            len, blockLen, dist, cSum, n,// z,\r\n            literalCodes, distCodes, lenCodes,\r\n            endless = true;\r\n\r\n        do {\r\n            last = readBit();\r\n            type = readBits(2);\r\n\r\n            if (type === 0) {\r\n                // Stored\r\n                byteAlign();\r\n                blockLen = readByte();\r\n                blockLen |= readByte() << 8;\r\n\r\n                cSum = readByte();\r\n                cSum |= readByte() << 8;\r\n\r\n                if ((blockLen ^ ~cSum) & 0xffff) {\r\n                    JXG.debug(\"BlockLen checksum mismatch\\n\");\r\n                }\r\n\r\n                while (blockLen--) {\r\n                    c = readByte();\r\n                    addBuffer(c);\r\n                }\r\n            } else if (type === 1) {\r\n                /* Fixed Huffman tables -- fixed decode routine */\r\n                while (endless) {\r\n                    /*\r\n                         256    0000000        0\r\n                         :   :     :\r\n                         279    0010111        23\r\n                         0   00110000    48\r\n                         :    :      :\r\n                         143    10111111    191\r\n                         280 11000000    192\r\n                         :    :      :\r\n                         287 11000111    199\r\n                         144    110010000    400\r\n                         :    :       :\r\n                         255    111111111    511\r\n\r\n                         Note the bit order!\r\n                         */\r\n\r\n                    j = bitReverse[readBits(7)] >> 1;\r\n\r\n                    if (j > 23) {\r\n                        j = (j << 1) | readBit(); /* 48..255 */\r\n\r\n                        if (j > 199) {\r\n                            /* 200..255 */\r\n                            j -= 128; /*  72..127 */\r\n                            j = (j << 1) | readBit(); /* 144..255 << */\r\n                        } else {\r\n                            /*  48..199 */\r\n                            j -= 48; /*   0..151 */\r\n                            if (j > 143) {\r\n                                j = j + 136; /* 280..287 << */\r\n                                /*   0..143 << */\r\n                            }\r\n                        }\r\n                    } else {\r\n                        /*   0..23 */\r\n                        j += 256; /* 256..279 << */\r\n                    }\r\n\r\n                    if (j < 256) {\r\n                        addBuffer(j);\r\n                    } else if (j === 256) {\r\n                        /* EOF */\r\n                        break;\r\n                    } else {\r\n                        j -= 256 + 1; /* bytes + EOF */\r\n                        len = readBits(cplext[j]) + cplens[j];\r\n                        j = bitReverse[readBits(5)] >> 3;\r\n\r\n                        if (cpdext[j] > 8) {\r\n                            dist = readBits(8);\r\n                            dist |= readBits(cpdext[j] - 8) << 8;\r\n                        } else {\r\n                            dist = readBits(cpdext[j]);\r\n                        }\r\n\r\n                        dist += cpdist[j];\r\n\r\n                        for (j = 0; j < len; j++) {\r\n                            c = buf32k[(bIdx - dist) & 0x7fff];\r\n                            addBuffer(c);\r\n                        }\r\n                    }\r\n                } // while\r\n            } else if (type === 2) {\r\n                // \"static\" just to preserve stack\r\n                ll = new Array(288 + 32);\r\n\r\n                // Dynamic Huffman tables\r\n                literalCodes = 257 + readBits(5);\r\n                distCodes = 1 + readBits(5);\r\n                lenCodes = 4 + readBits(4);\r\n\r\n                for (j = 0; j < 19; j++) {\r\n                    ll[j] = 0;\r\n                }\r\n\r\n                // Get the decode tree code lengths\r\n\r\n                for (j = 0; j < lenCodes; j++) {\r\n                    ll[border[j]] = readBits(3);\r\n                }\r\n                len = distanceTree.length;\r\n\r\n                for (i = 0; i < len; i++) {\r\n                    distanceTree[i] = new HufNode();\r\n                }\r\n\r\n                if (createTree(distanceTree, 19, ll, 0)) {\r\n                    flushBuffer();\r\n                    return 1;\r\n                }\r\n\r\n                //read in literal and distance code lengths\r\n                n = literalCodes + distCodes;\r\n                i = 0;\r\n                // z = -1;\r\n\r\n                while (i < n) {\r\n                    // z++;\r\n                    j = decodeValue(distanceTree);\r\n\r\n                    // length of code in bits (0..15)\r\n                    if (j < 16) {\r\n                        ll[i++] = j;\r\n                        // repeat last length 3 to 6 times\r\n                    } else if (j === 16) {\r\n                        j = 3 + readBits(2);\r\n\r\n                        if (i + j > n) {\r\n                            flushBuffer();\r\n                            return 1;\r\n                        }\r\n                        l = i ? ll[i - 1] : 0;\r\n\r\n                        while (j--) {\r\n                            ll[i++] = l;\r\n                        }\r\n                    } else {\r\n                        // 3 to 10 zero length codes\r\n                        if (j === 17) {\r\n                            j = 3 + readBits(3);\r\n                            // j == 18: 11 to 138 zero length codes\r\n                        } else {\r\n                            j = 11 + readBits(7);\r\n                        }\r\n\r\n                        if (i + j > n) {\r\n                            flushBuffer();\r\n                            return 1;\r\n                        }\r\n\r\n                        while (j--) {\r\n                            ll[i++] = 0;\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // Can overwrite tree decode tree as it is not used anymore\r\n                len = literalTree.length;\r\n                for (i = 0; i < len; i++) {\r\n                    literalTree[i] = new HufNode();\r\n                }\r\n\r\n                if (createTree(literalTree, literalCodes, ll, 0)) {\r\n                    flushBuffer();\r\n                    return 1;\r\n                }\r\n\r\n                len = literalTree.length;\r\n\r\n                for (i = 0; i < len; i++) {\r\n                    distanceTree[i] = new HufNode();\r\n                }\r\n\r\n                ll2 = [];\r\n\r\n                for (i = literalCodes; i < ll.length; i++) {\r\n                    ll2[i - literalCodes] = ll[i];\r\n                }\r\n\r\n                if (createTree(distanceTree, distCodes, ll2, 0)) {\r\n                    flushBuffer();\r\n                    return 1;\r\n                }\r\n\r\n                while (endless) {\r\n                    j = decodeValue(literalTree);\r\n\r\n                    // In C64: if carry set\r\n                    if (j >= 256) {\r\n                        j -= 256;\r\n                        if (j === 0) {\r\n                            // EOF\r\n                            break;\r\n                        }\r\n\r\n                        j -= 1;\r\n                        len = readBits(cplext[j]) + cplens[j];\r\n                        j = decodeValue(distanceTree);\r\n\r\n                        if (cpdext[j] > 8) {\r\n                            dist = readBits(8);\r\n                            dist |= readBits(cpdext[j] - 8) << 8;\r\n                        } else {\r\n                            dist = readBits(cpdext[j]);\r\n                        }\r\n\r\n                        dist += cpdist[j];\r\n\r\n                        while (len--) {\r\n                            c = buf32k[(bIdx - dist) & 0x7fff];\r\n                            addBuffer(c);\r\n                        }\r\n                    } else {\r\n                        addBuffer(j);\r\n                    }\r\n                }\r\n            }\r\n        } while (!last);\r\n\r\n        flushBuffer();\r\n        byteAlign();\r\n\r\n        return 0;\r\n    }\r\n\r\n    /**\r\n     * nextFile:\r\n     * Extract the next file from the compressed archive.\r\n     * Calls skipdir() to proceed recursively.\r\n     *\r\n     * @return {Boolean}  false if the end of files' data section has baseElement\r\n     * reached. Then, then all recursive functions are stopped immediately.\r\n     *\r\n     */\r\n    function nextFile() {\r\n        /* eslint-disable no-unused-vars */\r\n        var i,\r\n            c,\r\n            extralen,\r\n            filelen,\r\n            size,\r\n            compSize,\r\n            crc,\r\n            method,\r\n            tmp = [];\r\n\r\n        // Prevent problems on iOS7 with >>\r\n        try {\r\n            outputArr = [];\r\n            modeZIP = false;\r\n            tmp[0] = readByte();\r\n            tmp[1] = readByte();\r\n\r\n            //GZIP\r\n            if (tmp[0] === 0x78 && tmp[1] === 0xda) {\r\n                deflateLoop();\r\n                unzipped[files] = [outputArr.join(\"\"), \"geonext.gxt\"];\r\n                files++;\r\n            }\r\n\r\n            //GZIP\r\n            if (tmp[0] === 0x1f && tmp[1] === 0x8b) {\r\n                skipdir();\r\n                unzipped[files] = [outputArr.join(\"\"), \"file\"];\r\n                files++;\r\n            }\r\n\r\n            //ZIP\r\n            if (tmp[0] === 0x50 && tmp[1] === 0x4b) {\r\n                modeZIP = true;\r\n                tmp[2] = readByte();\r\n                tmp[3] = readByte();\r\n\r\n                if (tmp[2] === 0x03 && tmp[3] === 0x04) {\r\n                    //MODE_ZIP\r\n                    tmp[0] = readByte();\r\n                    tmp[1] = readByte();\r\n\r\n                    gpflags = readByte();\r\n                    gpflags |= readByte() << 8;\r\n\r\n                    method = readByte();\r\n                    method |= readByte() << 8;\r\n\r\n                    readByte();\r\n                    readByte();\r\n                    readByte();\r\n                    readByte();\r\n\r\n                    crc = readByte();\r\n                    crc |= readByte() << 8;\r\n                    crc |= readByte() << 16;\r\n                    crc |= readByte() << 24;\r\n\r\n                    compSize = readByte();\r\n                    compSize |= readByte() << 8;\r\n                    compSize |= readByte() << 16;\r\n                    compSize |= readByte() << 24;\r\n\r\n                    size = readByte();\r\n                    size |= readByte() << 8;\r\n                    size |= readByte() << 16;\r\n                    size |= readByte() << 24;\r\n\r\n                    filelen = readByte();\r\n                    filelen |= readByte() << 8;\r\n\r\n                    extralen = readByte();\r\n                    extralen |= readByte() << 8;\r\n\r\n                    i = 0;\r\n                    nameBuf = [];\r\n\r\n                    while (filelen--) {\r\n                        c = readByte();\r\n                        if ((c === \"/\") | (c === \":\")) {\r\n                            i = 0;\r\n                        } else if (i < NAMEMAX - 1) {\r\n                            nameBuf[i++] = String.fromCharCode(c);\r\n                        }\r\n                    }\r\n\r\n                    if (!fileout) {\r\n                        fileout = nameBuf;\r\n                    }\r\n\r\n                    i = 0;\r\n                    while (i < extralen) {\r\n                        c = readByte();\r\n                        i++;\r\n                    }\r\n\r\n                    // SIZE = 0;\r\n                    if (method === 8) {\r\n                        deflateLoop();\r\n                        unzipped[files] = new Array(2);\r\n                        unzipped[files][0] = outputArr.join(\"\");\r\n                        unzipped[files][1] = nameBuf.join(\"\");\r\n                        files++;\r\n                    }\r\n\r\n                    if (skipdir()) {\r\n                        // We are beyond the files' data in the zip archive.\r\n                        // Let's get out immediately...\r\n                        return false;\r\n                    }\r\n                }\r\n                return true;\r\n            }\r\n        } catch (e) {\r\n            console.log(\"Probably problems on iOS7 with >>\");\r\n            throw e;\r\n        }\r\n        return false;\r\n        /* eslint-enable no-unused-vars */\r\n    }\r\n\r\n    /**\r\n     * Test if the end of the files' data part of the archive has baseElement\r\n     * reached. If not, uncompressing is resumed.\r\n     *\r\n     * @return {Boolean}  true if the end of the files' data sections have\r\n     * been reached.\r\n     *\r\n     * @private\r\n     */\r\n    function skipdir() {\r\n        /* eslint-disable no-unused-vars */\r\n        var crc, compSize, size, os, i, c,\r\n            tmp = [];\r\n\r\n        if (gpflags & 8) {\r\n            tmp[0] = readByte();\r\n            tmp[1] = readByte();\r\n            tmp[2] = readByte();\r\n            tmp[3] = readByte();\r\n\r\n            // signature for data descriptor record: 0x08074b50\r\n            // 12 bytes:\r\n            //  crc 4 bytes\r\n            //  compressed size 4 bytes\r\n            // uncompressed size 4 bytes\r\n            if (tmp[0] === 0x50 && tmp[1] === 0x4b && tmp[2] === 0x07 && tmp[3] === 0x08) {\r\n                crc = readByte();\r\n                crc |= readByte() << 8;\r\n                crc |= readByte() << 16;\r\n                crc |= readByte() << 24;\r\n            } else {\r\n                crc = tmp[0] | (tmp[1] << 8) | (tmp[2] << 16) | (tmp[3] << 24);\r\n            }\r\n\r\n            compSize = readByte();\r\n            compSize |= readByte() << 8;\r\n            compSize |= readByte() << 16;\r\n            compSize |= readByte() << 24;\r\n\r\n            size = readByte();\r\n            size |= readByte() << 8;\r\n            size |= readByte() << 16;\r\n            size |= readByte() << 24;\r\n        }\r\n\r\n        if (modeZIP) {\r\n            if (nextFile()) {\r\n                // A file has been decompressed, we have to proceed\r\n                return false;\r\n            }\r\n        }\r\n\r\n        tmp[0] = readByte();\r\n        if (tmp[0] !== 8) {\r\n            // It seems, we are beyond the files' data in the zip archive.\r\n            // We'll skip the rest..\r\n            return true;\r\n        }\r\n\r\n        // There is another file in the zip file. We proceed...\r\n        gpflags = readByte();\r\n\r\n        readByte();\r\n        readByte();\r\n        readByte();\r\n        readByte();\r\n\r\n        readByte();\r\n        os = readByte();\r\n\r\n        if (gpflags & 4) {\r\n            tmp[0] = readByte();\r\n            tmp[2] = readByte();\r\n            len = tmp[0] + 256 * tmp[1];\r\n            for (i = 0; i < len; i++) {\r\n                readByte();\r\n            }\r\n        }\r\n\r\n        if (gpflags & 8) {\r\n            i = 0;\r\n            nameBuf = [];\r\n\r\n            c = readByte();\r\n            while (c) {\r\n                if (c === \"7\" || c === \":\") {\r\n                    i = 0;\r\n                }\r\n\r\n                if (i < NAMEMAX - 1) {\r\n                    nameBuf[i++] = c;\r\n                }\r\n\r\n                c = readByte();\r\n            }\r\n        }\r\n\r\n        if (gpflags & 16) {\r\n            c = readByte();\r\n            while (c) {\r\n                c = readByte();\r\n            }\r\n        }\r\n\r\n        if (gpflags & 2) {\r\n            readByte();\r\n            readByte();\r\n        }\r\n\r\n        deflateLoop();\r\n\r\n        crc = readByte();\r\n        crc |= readByte() << 8;\r\n        crc |= readByte() << 16;\r\n        crc |= readByte() << 24;\r\n\r\n        size = readByte();\r\n        size |= readByte() << 8;\r\n        size |= readByte() << 16;\r\n        size |= readByte() << 24;\r\n\r\n        if (modeZIP) {\r\n            if (nextFile()) {\r\n                // A file has been decompressed, we have to proceed\r\n                return false;\r\n            }\r\n        }\r\n\r\n        // We are here in non-ZIP-files only,\r\n        // In that case the eturn value doesn't matter\r\n        return false;\r\n        /* eslint-enable no-unused-vars */\r\n\r\n    }\r\n\r\n    JXG.Util.Unzip.prototype.unzipFile = function (name) {\r\n        var i;\r\n\r\n        this.unzip();\r\n\r\n        for (i = 0; i < unzipped.length; i++) {\r\n            if (unzipped[i][1] === name) {\r\n                return unzipped[i][0];\r\n            }\r\n        }\r\n\r\n        return \"\";\r\n    };\r\n\r\n    JXG.Util.Unzip.prototype.unzip = function () {\r\n        nextFile();\r\n        return unzipped;\r\n    };\r\n};\r\n\r\nexport default JXG.Util;\r\n","/*\r\n JessieCode Computer algebra algorithms\r\n\r\n    Copyright 2011-2019\r\n        Michael Gerhaeuser,\r\n        Alfred Wassermann\r\n\r\n    JessieCode is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JessieCode is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JessieCode. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, window: true, console: true, self: true, document: true, parser: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n/*eslint eqeqeq: \"off\"*/\r\n\r\n/**\r\n * @fileoverview Here, the computer algebra algorithms are implemented.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"../utils/type.js\";\r\n// import Const from \"../base/constants.js\";\r\n// import Text from \"../base/text.js\";\r\n// import Mat from \"../math/math.js\";\r\n// import Geometry from \"../math/geometry.js\";\r\n// import Statistics from \"../math/statistics.js\";\r\n// import Env from \"../utils/env.js\";\r\n\r\n/**\r\n * A JessieCode object provides an interface to the parser and stores all variables and objects used within a JessieCode script.\r\n * The optional argument <tt>code</tt> is interpreted after initializing. To evaluate more code after initializing a JessieCode instance\r\n * please use {@link JXG.JessieCode#parse}. For code snippets like single expressions use {@link JXG.JessieCode#snippet}.\r\n * @constructor\r\n * @param {String} [code] Code to parse.\r\n * @param {Boolean} [geonext=false] Geonext compatibility mode.\r\n */\r\nJXG.CA = function (node, createNode, parser) {\r\n    this.node = node;\r\n    this.createNode = createNode;\r\n    this.parser = parser;\r\n};\r\n\r\nJXG.extend(\r\n    JXG.CA.prototype,\r\n    /** @lends JXG.CA.prototype */ {\r\n        findMapNode: function (mapname, node) {\r\n            var i, len, ret;\r\n\r\n            //console.log(\"FINDMAP\", node);\r\n            if (node.value === \"op_assign\" && node.children[0].value === mapname) {\r\n                return node.children[1];\r\n            } else if (node.children) {\r\n                len = node.children.length;\r\n                for (i = 0; i < len; ++i) {\r\n                    ret = this.findMapNode(mapname, node.children[i]);\r\n                    if (ret !== null) {\r\n                        return ret;\r\n                    }\r\n                }\r\n            }\r\n            return null;\r\n        },\r\n\r\n        /**\r\n         * Declare all subnodes as math nodes,\r\n         * i.e recursively set node.isMath = true;\r\n         */\r\n        setMath: function (node) {\r\n            var i, len;\r\n\r\n            if (\r\n                (node.type == \"node_op\" &&\r\n                    (node.value == \"op_add\" ||\r\n                        node.value == \"op_sub\" ||\r\n                        node.value == \"op_mul\" ||\r\n                        node.value == \"op_div\" ||\r\n                        node.value == \"op_neg\" ||\r\n                        node.value == \"op_execfun\" ||\r\n                        node.value == \"op_exp\")) ||\r\n                node.type == \"node_var\" ||\r\n                node.type == \"node_const\"\r\n            ) {\r\n                node.isMath = true;\r\n            }\r\n            if (node.children) {\r\n                len = node.children.length;\r\n                for (i = 0; i < len; ++i) {\r\n                    this.setMath(node.children[i]);\r\n                }\r\n            }\r\n        },\r\n\r\n        deriveElementary: function (node, varname) {\r\n            var fun = node.children[0].value,\r\n                arg = node.children[1],\r\n                newNode;\r\n\r\n            switch (fun) {\r\n                case \"abs\":\r\n                    // x / sqrt(x * x)\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_div\",\r\n                        arg[0],\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_execfun\",\r\n                            this.createNode(\"node_var\", 'sqrt'),\r\n                            [\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_mul\",\r\n                                    Type.deepCopy(arg[0]),\r\n                                    Type.deepCopy(arg[0])\r\n                                )\r\n                            ]\r\n                        )\r\n                    );\r\n                    break;\r\n\r\n                case \"sqrt\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_div\",\r\n                        this.createNode(\"node_const\", 1.0),\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_mul\",\r\n                            this.createNode(\"node_const\", 2.0),\r\n                            this.createNode(\r\n                                node.type,\r\n                                node.value,\r\n                                Type.deepCopy(node.children[0]),\r\n                                Type.deepCopy(node.children[1])\r\n                            )\r\n                        )\r\n                    );\r\n                    break;\r\n\r\n                case \"sin\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_execfun\",\r\n                        this.createNode(\"node_var\", 'cos'),\r\n                        Type.deepCopy(arg)\r\n                    );\r\n                    break;\r\n\r\n                case \"cos\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_neg\",\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_execfun\",\r\n                            this.createNode(\"node_var\", 'sin'),\r\n                            Type.deepCopy(arg)\r\n                        )\r\n                    );\r\n                    break;\r\n\r\n                case \"tan\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_div\",\r\n                        this.createNode(\"node_const\", 1.0),\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_exp\",\r\n                            this.createNode(\r\n                                \"node_op\",\r\n                                \"op_execfun\",\r\n                                this.createNode(\"node_var\", 'cos'),\r\n                                Type.deepCopy(arg)\r\n                            ),\r\n                            this.createNode(\"node_const\", 2)\r\n                        )\r\n                    );\r\n                    break;\r\n\r\n                case \"cot\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_neg\",\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_div\",\r\n                            this.createNode(\"node_const\", 1.0),\r\n                            this.createNode(\r\n                                \"node_op\",\r\n                                \"op_exp\",\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_execfun\",\r\n                                    this.createNode(\"node_var\", 'sin'),\r\n                                    Type.deepCopy(arg)\r\n                                ),\r\n                                this.createNode(\"node_const\", 2)\r\n                            )\r\n                        )\r\n                    );\r\n                    break;\r\n\r\n                case \"exp\":\r\n                    newNode = this.createNode(\r\n                        node.type,\r\n                        node.value,\r\n                        Type.deepCopy(node.children[0]),\r\n                        Type.deepCopy(node.children[1])\r\n                    );\r\n                    break;\r\n\r\n                case \"pow\":\r\n                    // (f^g)' = f^g*(f'g/f + g' log(f))\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_mul\",\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_execfun\",\r\n                            Type.deepCopy(node.children[0]),\r\n                            Type.deepCopy(node.children[1])\r\n                        ),\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_add\",\r\n                            this.createNode(\r\n                                \"node_op\",\r\n                                \"op_mul\",\r\n                                this.derivative(node.children[1][0], varname),\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_div\",\r\n                                    Type.deepCopy(node.children[1][1]),\r\n                                    Type.deepCopy(node.children[1][0])\r\n                                )\r\n                            ),\r\n                            this.createNode(\r\n                                \"node_op\",\r\n                                \"op_mul\",\r\n                                this.derivative(node.children[1][1], varname),\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_execfun\",\r\n                                    this.createNode(\"node_var\", 'log'),\r\n                                    [Type.deepCopy(node.children[1][0])]\r\n                                )\r\n                            )\r\n                        )\r\n                    );\r\n                    break;\r\n\r\n                case \"log\":\r\n                case \"ln\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_div\",\r\n                        this.createNode(\"node_const\", 1.0),\r\n                        // Attention: single variable mode\r\n                        Type.deepCopy(arg[0])\r\n                    );\r\n                    break;\r\n\r\n                case \"log2\":\r\n                case \"lb\":\r\n                case \"ld\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_mul\",\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_div\",\r\n                            this.createNode(\"node_const\", 1.0),\r\n                            // Attention: single variable mode\r\n                            Type.deepCopy(arg[0])\r\n                        ),\r\n                        this.createNode(\"node_const\", 1.4426950408889634) // 1/log(2)\r\n                    );\r\n                    break;\r\n\r\n                case \"log10\":\r\n                case \"lg\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_mul\",\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_div\",\r\n                            this.createNode(\"node_const\", 1.0),\r\n                            // Attention: single variable mode\r\n                            Type.deepCopy(arg[0])\r\n                        ),\r\n                        this.createNode(\"node_const\", 0.43429448190325176) // 1/log(10)\r\n                    );\r\n                    break;\r\n\r\n                case \"asin\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_div\",\r\n                        this.createNode(\"node_const\", 1.0),\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_execfun\",\r\n                            this.createNode(\"node_var\", 'sqrt'),\r\n                            [\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_sub\",\r\n                                    this.createNode(\"node_const\", 1.0),\r\n                                    this.createNode(\r\n                                        \"node_op\",\r\n                                        \"op_mul\",\r\n                                        Type.deepCopy(arg[0]),\r\n                                        Type.deepCopy(arg[0])\r\n                                    )\r\n                                )\r\n                            ]\r\n                        )\r\n                    );\r\n                    break;\r\n\r\n                case \"acos\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_neg\",\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_div\",\r\n                            this.createNode(\"node_const\", 1.0),\r\n                            this.createNode(\r\n                                \"node_op\",\r\n                                \"op_execfun\",\r\n                                this.createNode(\"node_var\", 'sqrt'),\r\n                                [\r\n                                    this.createNode(\r\n                                        \"node_op\",\r\n                                        \"op_sub\",\r\n                                        this.createNode(\"node_const\", 1.0),\r\n                                        this.createNode(\r\n                                            \"node_op\",\r\n                                            \"op_mul\",\r\n                                            Type.deepCopy(arg[0]),\r\n                                            Type.deepCopy(arg[0])\r\n                                        )\r\n                                    )\r\n                                ]\r\n                            )\r\n                        )\r\n                    );\r\n                    break;\r\n\r\n                //case 'atan2':\r\n\r\n                case \"atan\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_div\",\r\n                        this.createNode(\"node_const\", 1.0),\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_add\",\r\n                            this.createNode(\"node_const\", 1.0),\r\n                            this.createNode(\r\n                                \"node_op\",\r\n                                \"op_mul\",\r\n                                Type.deepCopy(arg[0]),\r\n                                Type.deepCopy(arg[0])\r\n                            )\r\n                        )\r\n                    );\r\n                    break;\r\n\r\n                case \"acot\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_neg\",\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_div\",\r\n                            this.createNode(\"node_const\", 1.0),\r\n                            this.createNode(\r\n                                \"node_op\",\r\n                                \"op_add\",\r\n                                this.createNode(\"node_const\", 1.0),\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_mul\",\r\n                                    Type.deepCopy(arg[0]),\r\n                                    Type.deepCopy(arg[0])\r\n                                )\r\n                            )\r\n                        )\r\n                    );\r\n                    break;\r\n\r\n                case \"sinh\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_execfun\",\r\n                        this.createNode(\"node_var\", 'cosh'),\r\n                        [Type.deepCopy(arg[0])]\r\n                    );\r\n                    break;\r\n\r\n                case \"cosh\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_execfun\",\r\n                        this.createNode(\"node_var\", 'sinh'),\r\n                        [Type.deepCopy(arg[0])]\r\n                    );\r\n                    break;\r\n\r\n                case \"tanh\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_sub\",\r\n                        this.createNode(\"node_const\", 1.0),\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_exp\",\r\n                            this.createNode(\r\n                                \"node_op\",\r\n                                \"op_execfun\",\r\n                                this.createNode(\"node_var\", 'tanh'),\r\n                                [Type.deepCopy(arg[0])]\r\n                            ),\r\n                            this.createNode(\"node_const\", 2.0)\r\n                        )\r\n                    );\r\n                    break;\r\n\r\n                case \"asinh\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_div\",\r\n                        this.createNode(\"node_const\", 1.0),\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_execfun\",\r\n                            this.createNode(\"node_var\", 'sqrt'),\r\n                            [\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_add\",\r\n                                    this.createNode(\r\n                                        \"node_op\",\r\n                                        \"op_mul\",\r\n                                        Type.deepCopy(arg[0]),\r\n                                        Type.deepCopy(arg[0])\r\n                                    ),\r\n                                    this.createNode(\"node_const\", 1.0)\r\n                                )\r\n                            ]\r\n                        )\r\n                    );\r\n                    break;\r\n\r\n                case \"acosh\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_div\",\r\n                        this.createNode(\"node_const\", 1.0),\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_execfun\",\r\n                            this.createNode(\"node_var\", 'sqrt'),\r\n                            [\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_sub\",\r\n                                    this.createNode(\r\n                                        \"node_op\",\r\n                                        \"op_mul\",\r\n                                        Type.deepCopy(arg[0]),\r\n                                        Type.deepCopy(arg[0])\r\n                                    ),\r\n                                    this.createNode(\"node_const\", 1.0)\r\n                                )\r\n                            ]\r\n                        )\r\n                    );\r\n                    break;\r\n\r\n                case \"atanh\":\r\n                    newNode = this.createNode(\r\n                        \"node_op\",\r\n                        \"op_div\",\r\n                        this.createNode(\"node_const\", 1.0),\r\n                        this.createNode(\r\n                            \"node_op\",\r\n                            \"op_sub\",\r\n                            this.createNode(\"node_const\", 1.0),\r\n                            this.createNode(\r\n                                \"node_op\",\r\n                                \"op_mul\",\r\n                                Type.deepCopy(arg[0]),\r\n                                Type.deepCopy(arg[0])\r\n                            )\r\n                        )\r\n                    );\r\n                    break;\r\n\r\n                default:\r\n                    newNode = this.createNode(\"node_const\", 0.0);\r\n                    console.log('Derivative of \"' + fun + '\" not yet implemented');\r\n                    throw new Error(\"Error(\" + this.line + \"): \");\r\n                //  this._error('Derivative of \"' + fun + '\" not yet implemented');\r\n            }\r\n\r\n            return newNode;\r\n        },\r\n\r\n        derivative: function (node, varname) {\r\n            var newNode;\r\n\r\n            switch (node.type) {\r\n                case \"node_op\":\r\n                    switch (node.value) {\r\n                        /*\r\n                        case 'op_map':\r\n                            if (true) {\r\n                                newNode = this.createNode('node_op', 'op_map',\r\n                                        Type.deepCopy(node.children[0]),\r\n                                        this.derivative(node.children[1], varname)\r\n                                    );\r\n                            } else {\r\n                                newNode = this.derivative(node.children[1], varname);\r\n                            }\r\n                            break;\r\n                        */\r\n                        case \"op_execfun\":\r\n                            // f'(g(x))g'(x)\r\n                            if (node.children[0].value == 'pow') {\r\n                                newNode = this.deriveElementary(node, varname);\r\n                            } else {\r\n                                if (node.children[1].length === 0) {\r\n                                    newNode = this.createNode(\"node_const\", 0.0);\r\n                                } else {\r\n                                    newNode = this.createNode(\r\n                                        \"node_op\",\r\n                                        \"op_mul\",\r\n                                        this.deriveElementary(node, varname),\r\n                                        // Warning: single variable mode\r\n                                        this.derivative(node.children[1][0], varname)\r\n                                    );\r\n                                }\r\n                            }\r\n                            break;\r\n\r\n                        case \"op_div\":\r\n                            // (f'g − g'f )/(g*g)\r\n                            newNode = this.createNode(\r\n                                \"node_op\",\r\n                                \"op_div\",\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_sub\",\r\n                                    this.createNode(\r\n                                        \"node_op\",\r\n                                        \"op_mul\",\r\n                                        this.derivative(node.children[0], varname),\r\n                                        Type.deepCopy(node.children[1])\r\n                                    ),\r\n                                    this.createNode(\r\n                                        \"node_op\",\r\n                                        \"op_mul\",\r\n                                        Type.deepCopy(node.children[0]),\r\n                                        this.derivative(node.children[1], varname)\r\n                                    )\r\n                                ),\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_mul\",\r\n                                    Type.deepCopy(node.children[1]),\r\n                                    Type.deepCopy(node.children[1])\r\n                                )\r\n                            );\r\n                            break;\r\n\r\n                        case \"op_mul\":\r\n                            // fg' + f'g\r\n                            newNode = this.createNode(\r\n                                \"node_op\",\r\n                                \"op_add\",\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_mul\",\r\n                                    Type.deepCopy(node.children[0]),\r\n                                    this.derivative(node.children[1], varname)\r\n                                ),\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_mul\",\r\n                                    this.derivative(node.children[0], varname),\r\n                                    Type.deepCopy(node.children[1])\r\n                                )\r\n                            );\r\n                            break;\r\n\r\n                        case \"op_neg\":\r\n                            newNode = this.createNode(\r\n                                \"node_op\",\r\n                                \"op_neg\",\r\n                                this.derivative(node.children[0], varname)\r\n                            );\r\n                            break;\r\n\r\n                        case \"op_add\":\r\n                        case \"op_sub\":\r\n                            newNode = this.createNode(\r\n                                \"node_op\",\r\n                                node.value,\r\n                                this.derivative(node.children[0], varname),\r\n                                this.derivative(node.children[1], varname)\r\n                            );\r\n                            break;\r\n\r\n                        case \"op_exp\":\r\n                            // (f^g)' = f^g*(f'g/f + g' log(f))\r\n                            newNode = this.createNode(\r\n                                \"node_op\",\r\n                                \"op_mul\",\r\n                                Type.deepCopy(node),\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_add\",\r\n                                    this.createNode(\r\n                                        \"node_op\",\r\n                                        \"op_mul\",\r\n                                        this.derivative(node.children[0], varname),\r\n                                        this.createNode(\r\n                                            \"node_op\",\r\n                                            \"op_div\",\r\n                                            Type.deepCopy(node.children[1]),\r\n                                            Type.deepCopy(node.children[0])\r\n                                        )\r\n                                    ),\r\n                                    this.createNode(\r\n                                        \"node_op\",\r\n                                        \"op_mul\",\r\n                                        this.derivative(node.children[1], varname),\r\n                                        this.createNode(\r\n                                            \"node_op\",\r\n                                            \"op_execfun\",\r\n                                            this.createNode(\"node_var\", 'log'),\r\n                                            [Type.deepCopy(node.children[0])]\r\n                                        )\r\n                                    )\r\n                                )\r\n                            );\r\n                            break;\r\n                    }\r\n                    break;\r\n\r\n                case \"node_var\":\r\n                    //console.log('node_var', node);\r\n                    if (node.value === varname) {\r\n                        newNode = this.createNode(\"node_const\", 1.0);\r\n                    } else {\r\n                        newNode = this.createNode(\"node_const\", 0.0);\r\n                    }\r\n                    break;\r\n\r\n                case \"node_const\":\r\n                    newNode = this.createNode(\"node_const\", 0.0);\r\n                    break;\r\n\r\n                case \"node_const_bool\":\r\n                    break;\r\n\r\n                case \"node_str\":\r\n                    break;\r\n            }\r\n\r\n            return newNode;\r\n        },\r\n\r\n        /**\r\n         * f = map (x) -> x*sin(x);\r\n         * Usages:\r\n         *   h = D(f, x);\r\n         *   h = map (x) -> D(f, x);\r\n         * or\r\n         *   D(x^2, x);\r\n         */\r\n        expandDerivatives: function (node, parent, ast) {\r\n            var len, i, j, mapNode, codeNode,\r\n                ret, node2, newNode, mapName,\r\n                varname, vArray, order, isMap;\r\n\r\n            ret = 0;\r\n            if (!node) {\r\n                return ret;\r\n            }\r\n\r\n            this.line = node.line;\r\n            this.col = node.col;\r\n\r\n            // First we have to go down in the tree.\r\n            // This ensures that in cases like D(D(f,x),x) the inner D is expanded first.\r\n            len = node.children.length;\r\n            for (i = 0; i < len; ++i) {\r\n                if (node.children[i] && node.children[i].type) {\r\n                    node.children[i] = this.expandDerivatives(node.children[i], node, ast);\r\n                } else if (Type.isArray(node.children[i])) {\r\n                    for (j = 0; j < node.children[i].length; ++j) {\r\n                        if (node.children[i][j] && node.children[i][j].type) {\r\n                            node.children[i][j] = this.expandDerivatives(\r\n                                node.children[i][j],\r\n                                node,\r\n                                ast\r\n                            );\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            switch (node.type) {\r\n                case \"node_op\":\r\n                    switch (node.value) {\r\n                        case \"op_execfun\":\r\n                            if (node.children[0] && node.children[0].value === 'D') {\r\n                                /*\r\n                                 * Distinguish the cases:\r\n                                 *   D(f, x) where f is map -> isMap = true\r\n                                 * and\r\n                                 *   D(2*x, x), D(sin(x), x), ...  -> isMap = false\r\n                                 */\r\n                                isMap = false;\r\n                                if (node.children[1][0].type == \"node_var\") {\r\n                                    mapName = node.children[1][0].value;\r\n                                    mapNode = this.findMapNode(mapName, ast);\r\n                                    if (mapNode !== null) {\r\n                                        isMap = true;\r\n                                    }\r\n                                }\r\n\r\n                                if (isMap) {\r\n                                    /*\r\n                                     * Derivative of map, that is compute D(f,x)\r\n                                     * where e.g. f = map (x) -> x^2\r\n                                     *\r\n                                     * First step: find node where the map is defined\r\n                                     */\r\n                                    // Already done above\r\n                                    // mapName = node.children[1][0].value;\r\n                                    // mapNode = this.findMapNode(mapName, ast);\r\n                                    vArray = mapNode.children[0];\r\n\r\n                                    // Variable name for differentiation\r\n                                    if (node.children[1].length >= 2) {\r\n                                        varname = node.children[1][1].value;\r\n                                    } else {\r\n                                        varname = mapNode.children[0][0]; // Usually it's 'x'\r\n                                    }\r\n                                    codeNode = mapNode.children[1];\r\n                                } else {\r\n                                    /*\r\n                                     * Derivative of expression, e.g.\r\n                                     *     D(2*x, x) or D(sin(x), x)\r\n                                     */\r\n                                    codeNode = node.children[1][0];\r\n                                    vArray = [\"x\"];\r\n\r\n                                    // Variable name for differentiation and order\r\n                                    if (node.children[1].length >= 2) {\r\n                                        varname = node.children[1][1].value;\r\n                                    } else {\r\n                                        varname = 'x';\r\n                                    }\r\n                                }\r\n\r\n                                // Differentiation order\r\n                                if (node.children[1].length >= 3) {\r\n                                    order = node.children[1][2].value;\r\n                                } else {\r\n                                    order = 1;\r\n                                }\r\n\r\n                                // Create node which contains the derivative\r\n                                newNode = codeNode;\r\n                                //newNode = this.removeTrivialNodes(newNode);\r\n                                if (order >= 1) {\r\n                                    while (order >= 1) {\r\n                                        newNode = this.derivative(newNode, varname);\r\n                                        newNode = this.removeTrivialNodes(newNode);\r\n                                        order--;\r\n                                    }\r\n                                }\r\n\r\n                                // Replace the node containing e.g. D(f,x) by the derivative.\r\n                                if (parent.type == \"node_op\" && parent.value == \"op_assign\") {\r\n                                    // If D is an assignment it has to be replaced by a map\r\n                                    // h = D(f, x)\r\n                                    node2 = this.createNode(\r\n                                        \"node_op\",\r\n                                        \"op_map\",\r\n                                        vArray,\r\n                                        newNode\r\n                                    );\r\n                                } else {\r\n                                    node2 = newNode;\r\n                                }\r\n\r\n                                this.setMath(node2);\r\n                                node.type = node2.type;\r\n                                node.value = node2.value;\r\n                                if (node2.children.length > 0) {\r\n                                    node.children[0] = node2.children[0];\r\n                                }\r\n                                if (node2.children.length > 1) {\r\n                                    node.children[1] = node2.children[1];\r\n                                }\r\n                            }\r\n                    }\r\n                    break;\r\n\r\n                case \"node_var\":\r\n                case \"node_const\":\r\n                case \"node_const_bool\":\r\n                case \"node_str\":\r\n                    break;\r\n            }\r\n\r\n            return node;\r\n        },\r\n\r\n        removeTrivialNodes: function (node) {\r\n            var i, len, n0, n1, swap;\r\n\r\n            // In case of 'op_execfun' the children[1] node is an array.\r\n            if (Type.isArray(node)) {\r\n                len = node.length;\r\n                for (i = 0; i < len; ++i) {\r\n                    node[i] = this.removeTrivialNodes(node[i]);\r\n                }\r\n            }\r\n            if (node.type != \"node_op\" || !node.children) {\r\n                return node;\r\n            }\r\n\r\n            len = node.children.length;\r\n            for (i = 0; i < len; ++i) {\r\n                this.mayNotBeSimplified = false;\r\n                do {\r\n                    node.children[i] = this.removeTrivialNodes(node.children[i]);\r\n                } while (this.mayNotBeSimplified);\r\n            }\r\n\r\n            switch (node.value) {\r\n                // Allow maps of the form\r\n                //  map (x) -> x;\r\n                case \"op_map\":\r\n                    n0 = node.children[0];\r\n                    n1 = node.children[1];\r\n                    if (n1.type == \"node_var\") {\r\n                        for (i = 0; i < n0.length; ++i) {\r\n                            // Allow maps of the form map(x) -> x\r\n                            if (n0[i] == n1.value) {\r\n                                n1.isMath = true;\r\n                                break;\r\n                            }\r\n                        }\r\n                    }\r\n                    break;\r\n\r\n                // a + 0 -> a\r\n                // 0 + a -> a\r\n                case \"op_add\":\r\n                    n0 = node.children[0];\r\n                    n1 = node.children[1];\r\n                    if (n0.type == \"node_const\" && n0.value === 0.0) {\r\n                        return n1;\r\n                    }\r\n                    if (n1.type == \"node_const\" && n1.value === 0.0) {\r\n                        return n0;\r\n                    }\r\n\r\n                    // const + const -> const\r\n                    if (n0.type == \"node_const\" && n1.type == \"node_const\") {\r\n                        n0.value += n1.value;\r\n                        return n0;\r\n                    }\r\n                    break;\r\n\r\n                // 1 * a = a\r\n                // a * 1 = a\r\n                // a * 0 = 0\r\n                // 0 * a = 0\r\n                // - * - = +\r\n                // Order children\r\n                case \"op_mul\":\r\n                    n0 = node.children[0];\r\n                    n1 = node.children[1];\r\n                    if (n0.type == \"node_const\" && n0.value == 1.0) {\r\n                        return n1;\r\n                    }\r\n                    if (n1.type == \"node_const\" && n1.value == 1.0) {\r\n                        return n0;\r\n                    }\r\n                    if (n0.type == \"node_const\" && n0.value === 0.0) {\r\n                        return n0;\r\n                    }\r\n                    if (n1.type == \"node_const\" && n1.value === 0.0) {\r\n                        return n1;\r\n                    }\r\n                    if (n1.type == \"node_const\" && n1.value === 0.0) {\r\n                        return n1;\r\n                    }\r\n\r\n                    // (-a) * (-b) -> a*b\r\n                    if (\r\n                        n0.type == \"node_op\" &&\r\n                        n0.value == \"op_neg\" &&\r\n                        n1.type == \"node_op\" &&\r\n                        n1.value == \"op_neg\"\r\n                    ) {\r\n                        node.children = [n0.children[0], n1.children[0]];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n                    // (-a) * b -> -(a*b)\r\n                    if (n0.value == \"op_neg\" && n1.value != \"op_neg\") {\r\n                        node.type = \"node_op\";\r\n                        node.value = \"op_neg\";\r\n                        node.children = [\r\n                            this.createNode(\"node_op\", \"op_mul\", n0.children[0], n1)\r\n                        ];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n                    // a * (-b) -> -(a*b)\r\n                    if (n0.value != \"op_neg\" && n1.value == \"op_neg\") {\r\n                        node.type = \"node_op\";\r\n                        node.value = \"op_neg\";\r\n                        node.children = [\r\n                            this.createNode(\"node_op\", \"op_mul\", n0, n1.children[0])\r\n                        ];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n                    // (1 / a) * b -> a / b\r\n                    if (\r\n                        n0.value == \"op_div\" &&\r\n                        n0.children[0].type == \"node_const\" &&\r\n                        n0.children[0].value == 1.0\r\n                    ) {\r\n                        node.type = \"node_op\";\r\n                        node.value = \"op_div\";\r\n                        node.children = [n1, n0.children[1]];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n                    // a * (1 / b) -> a / b\r\n                    if (\r\n                        n1.value == \"op_div\" &&\r\n                        n1.children[0].type == \"node_const\" &&\r\n                        n1.children[0].value == 1.0\r\n                    ) {\r\n                        node.type = \"node_op\";\r\n                        node.value = \"op_div\";\r\n                        node.children = [n0, n1.children[1]];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n\r\n                    // Order children\r\n                    // a * const -> const * a\r\n                    if (n0.type != \"node_const\" && n1.type == \"node_const\") {\r\n                        node.children = [n1, n0];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n                    // a + (-const) -> -const + a\r\n                    if (\r\n                        n0.type != \"node_const\" &&\r\n                        n1.type == \"node_op\" &&\r\n                        n1.value == \"op_neg\" &&\r\n                        n1.children[0].type == \"node_const\"\r\n                    ) {\r\n                        node.children = [n1, n0];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n\r\n                    // a * var -> var * a\r\n                    // a * fun -> fun * a\r\n                    if (\r\n                        n0.type == \"node_op\" &&\r\n                        n0.value != \"op_execfun\" &&\r\n                        (n1.type == \"node_var\" ||\r\n                            (n1.type == \"node_op\" && n1.value == \"op_execfun\"))\r\n                    ) {\r\n                        node.children = [n1, n0];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n\r\n                    // a + (-var) -> -var  + a\r\n                    if (\r\n                        n0.type != \"node_op\" &&\r\n                        n1.type == \"node_op\" &&\r\n                        n1.value == \"op_neg\" &&\r\n                        n1.children[0].type == \"node_var\"\r\n                    ) {\r\n                        node.children = [n1, n0];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n                    // a * (const * b) -> const * (a*b)\r\n                    // a * (const / b) -> const * (a/b)\r\n                    if (\r\n                        n0.type != \"node_const\" &&\r\n                        n1.type == \"node_op\" &&\r\n                        (n1.value == \"op_mul\" || n1.value == \"op_div\") &&\r\n                        n1.children[0].type == \"node_const\"\r\n                    ) {\r\n                        swap = n1.children[0];\r\n                        n1.children[0] = n0;\r\n                        node.children = [swap, n1];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n\r\n                    // (const * a) * b -> const * (a * b)\r\n                    if (\r\n                        n1.type != \"node_const\" &&\r\n                        n0.type == \"node_op\" &&\r\n                        n0.value == \"op_mul\" &&\r\n                        n0.children[0].type == \"node_const\"\r\n                    ) {\r\n                        node.children = [\r\n                            n0.children[0],\r\n                            this.createNode(\"node_op\", \"op_mul\", n0.children[1], n1)\r\n                        ];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n\r\n                    // const * const -> const\r\n                    if (n0.type == \"node_const\" && n1.type == \"node_const\") {\r\n                        n0.value *= n1.value;\r\n                        return n0;\r\n                    }\r\n\r\n                    // const * (const * a) -> const * a\r\n                    // const * (const / a) -> const / a\r\n                    if (\r\n                        n0.type == \"node_const\" &&\r\n                        n1.type == \"node_op\" &&\r\n                        (n1.value == \"op_mul\" || n1.value == \"op_div\") &&\r\n                        n1.children[0].type == \"node_const\"\r\n                    ) {\r\n                        n1.children[0].value *= n0.value;\r\n                        return n1;\r\n                    }\r\n\r\n                    // a * a-> a^2\r\n                    n0.hash = this.parser.compile(n0);\r\n                    n1.hash = this.parser.compile(n1);\r\n                    if (n0.hash === n1.hash) {\r\n                        node.value = \"op_exp\";\r\n                        node.children[1] = this.createNode(\"node_const\", 2.0);\r\n                        return node;\r\n                    }\r\n\r\n                    if (\r\n                        n0.type == \"node_const\" &&\r\n                        n1.type == \"node_op\" &&\r\n                        (n1.value == \"op_mul\" || n1.value == \"op_div\") &&\r\n                        n1.children[0].type == \"node_const\"\r\n                    ) {\r\n                        n1.children[0].value *= n0.value;\r\n                        return n1;\r\n                    }\r\n\r\n                    // a * a^b -> a^(b+1)\r\n                    if (n1.type == \"node_op\" && n1.value == \"op_exp\") {\r\n                        if (!n0.hash) {\r\n                            n0.hash = this.parser.compile(n0);\r\n                        }\r\n                        if (!n1.children[0].hash) {\r\n                            n1.children[0].hash = this.parser.compile(n1.children[0]);\r\n                        }\r\n                        if (n0.hash === n1.children[0].hash) {\r\n                            n1.children[1] = this.createNode(\r\n                                \"node_op\",\r\n                                \"op_add\",\r\n                                n1.children[1],\r\n                                this.createNode(\"node_const\", 1.0)\r\n                            );\r\n                            this.mayNotBeSimplified = true;\r\n                            return n1;\r\n                        }\r\n                    }\r\n\r\n                    // a^b * a^c -> a^(b+c)\r\n                    if (\r\n                        n0.type == \"node_op\" &&\r\n                        n0.value == \"op_exp\" &&\r\n                        n1.type == \"node_op\" &&\r\n                        n1.value == \"op_exp\"\r\n                    ) {\r\n                        n0.children[0].hash = this.parser.compile(n0.children[0]);\r\n                        n1.children[0].hash = this.parser.compile(n1.children[0]);\r\n                        if (n0.children[0].hash === n1.children[0].hash) {\r\n                            n0.children[1] = this.createNode(\r\n                                \"node_op\",\r\n                                \"op_add\",\r\n                                n0.children[1],\r\n                                n1.children[1]\r\n                            );\r\n                            this.mayNotBeSimplified = true;\r\n                            return n0;\r\n                        }\r\n                    }\r\n\r\n                    break;\r\n\r\n                // 0 - a -> -a\r\n                // a - 0 -> a\r\n                // a - a -> 0\r\n                case \"op_sub\":\r\n                    n0 = node.children[0];\r\n                    n1 = node.children[1];\r\n                    if (n0.type == \"node_const\" && n0.value === 0.0) {\r\n                        node.value = \"op_neg\";\r\n                        node.children[0] = n1;\r\n                        return node;\r\n                    }\r\n                    if (n1.type == \"node_const\" && n1.value === 0.0) {\r\n                        return n0;\r\n                    }\r\n                    if (\r\n                        n0.type == \"node_const\" &&\r\n                        n1.type == \"node_const\" &&\r\n                        n0.value == n1.value\r\n                    ) {\r\n                        return this.createNode(\"node_const\", 0.0);\r\n                    }\r\n                    if (\r\n                        n0.type == \"node_var\" &&\r\n                        n1.type == \"node_var\" &&\r\n                        n0.value == n1.value\r\n                    ) {\r\n                        return this.createNode(\"node_const\", 0.0);\r\n                    }\r\n\r\n                    // const - const -> const\r\n                    if (n0.type == \"node_const\" && n1.type == \"node_const\") {\r\n                        n0.value -= n1.value;\r\n                        return n0;\r\n                    }\r\n\r\n                    // const * a - const * a -> const * a\r\n                    if (\r\n                        n0.type == \"node_op\" &&\r\n                        n0.value == \"op_mul\" &&\r\n                        n1.type == \"node_op\" &&\r\n                        n1.value == \"op_mul\"\r\n                    ) {\r\n                        n0.children[1].hash = this.parser.compile(n0.children[1]);\r\n                        n1.children[1].hash = this.parser.compile(n1.children[1]);\r\n                        if (n0.children[1].hash === n1.children[1].hash) {\r\n                            node.value = \"op_mul\";\r\n                            node.children = [\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_sub\",\r\n                                    n0.children[0],\r\n                                    n1.children[0]\r\n                                ),\r\n                                n0.children[1]\r\n                            ];\r\n                            this.mayNotBeSimplified = true;\r\n                            return node;\r\n                        }\r\n                    }\r\n                    // const * a - a -> (const - 1) * a\r\n                    if (n0.type == \"node_op\" && n0.value == \"op_mul\") {\r\n                        n0.children[1].hash = this.parser.compile(n0.children[1]);\r\n                        n1.hash = this.parser.compile(n1);\r\n                        if (n0.children[1].hash === n1.hash) {\r\n                            node.value = \"op_mul\";\r\n                            node.children = [\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_sub\",\r\n                                    n0.children[0],\r\n                                    this.createNode(\"node_const\", 1.0)\r\n                                ),\r\n                                n1\r\n                            ];\r\n                            this.mayNotBeSimplified = true;\r\n                            return node;\r\n                        }\r\n                    }\r\n                    // a - const*a -> (const - 1) * a\r\n                    if (n1.type == \"node_op\" && n1.value == \"op_mul\") {\r\n                        n1.children[1].hash = this.parser.compile(n1.children[1]);\r\n                        n0.hash = this.parser.compile(n0);\r\n                        if (n1.children[1].hash === n0.hash) {\r\n                            node.value = \"op_mul\";\r\n                            node.children = [\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_sub\",\r\n                                    this.createNode(\"node_const\", 1.0),\r\n                                    n1.children[0]\r\n                                ),\r\n                                n0\r\n                            ];\r\n                            this.mayNotBeSimplified = true;\r\n                            return node;\r\n                        }\r\n                    }\r\n\r\n                    break;\r\n\r\n                // -0 -> 0\r\n                // -(-b) = b\r\n                case \"op_neg\":\r\n                    n0 = node.children[0];\r\n                    if (n0.type == \"node_const\" && n0.value === 0.0) {\r\n                        return n0;\r\n                    }\r\n                    if (n0.type == \"node_op\" && n0.value == \"op_neg\") {\r\n                        return n0.children[0];\r\n                    }\r\n                    break;\r\n\r\n                // a / a -> 1, a != 0\r\n                // 0 / a -> 0, a != 0\r\n                // a / 0 -> Infinity, a != 0\r\n                // 0 / 0 -> NaN, a == 0\r\n                case \"op_div\":\r\n                    n0 = node.children[0];\r\n                    n1 = node.children[1];\r\n                    if (\r\n                        n0.type == \"node_const\" &&\r\n                        n1.type == \"node_const\" &&\r\n                        n0.value == n1.value &&\r\n                        n0.value !== 0\r\n                    ) {\r\n                        n0.value = 1.0;\r\n                        return n0;\r\n                    }\r\n                    if (\r\n                        n0.type == \"node_const\" &&\r\n                        n0.value === 0 &&\r\n                        n1.type == \"node_const\" &&\r\n                        n1.value !== 0\r\n                    ) {\r\n                        n0.value = 0.0;\r\n                        return n0;\r\n                    }\r\n\r\n                    // Risky: 0 / (something != 0) -> 0.0\r\n                    if (\r\n                        n0.type == \"node_const\" &&\r\n                        n0.value === 0 &&\r\n                        (n1.type == \"node_op\" || n1.type == \"node_var\")\r\n                    ) {\r\n                        node.type = \"node_const\";\r\n                        node.value = 0.0;\r\n                        return node;\r\n                    }\r\n\r\n                    if (\r\n                        n0.type == \"node_var\" &&\r\n                        n1.type == \"node_var\" &&\r\n                        n0.value == n1.value\r\n                    ) {\r\n                        return this.createNode(\"node_const\", 1.0);\r\n                    }\r\n                    if (\r\n                        n0.type == \"node_const\" &&\r\n                        n0.value !== 0 &&\r\n                        n1.type == \"node_const\" &&\r\n                        n1.value === 0\r\n                    ) {\r\n                        if (n0.value > 0.0) {\r\n                            n0.value = Infinity;\r\n                        } else {\r\n                            n0.value = -Infinity; // Do we ever need this?\r\n                        }\r\n                        return n0;\r\n                    }\r\n\r\n                    // (-a) / (-b) -> a/b\r\n                    if (\r\n                        n0.type == \"node_op\" &&\r\n                        n0.value == \"op_neg\" &&\r\n                        n1.type == \"node_op\" &&\r\n                        n1.value == \"op_neg\"\r\n                    ) {\r\n                        node.children = [n0.children[0], n1.children[0]];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n                    // (-a) / b -> -(a/b)\r\n                    if (n0.value == \"op_neg\" && n1.value != \"op_neg\") {\r\n                        node.type = \"node_op\";\r\n                        node.value = \"op_neg\";\r\n                        node.children = [\r\n                            this.createNode(\"node_op\", \"op_div\", n0.children[0], n1)\r\n                        ];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n                    // a / (-b) -> -(a/b)\r\n                    if (n0.value != \"op_neg\" && n1.value == \"op_neg\") {\r\n                        node.type = \"node_op\";\r\n                        node.value = \"op_neg\";\r\n                        node.children = [\r\n                            this.createNode(\"node_op\", \"op_div\", n0, n1.children[0])\r\n                        ];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n\r\n                    // a^b / a -> a^(b-1)\r\n                    if (n0.type == \"node_op\" && n0.value == \"op_exp\") {\r\n                        if (!n1.hash) {\r\n                            n1.hash = this.parser.compile(n1);\r\n                        }\r\n                        if (!n0.children[0].hash) {\r\n                            n0.children[0].hash = this.parser.compile(n0.children[0]);\r\n                        }\r\n                        if (n1.hash === n0.children[0].hash) {\r\n                            n0.children[1] = this.createNode(\r\n                                \"node_op\",\r\n                                \"op_sub\",\r\n                                n0.children[1],\r\n                                this.createNode(\"node_const\", 1.0)\r\n                            );\r\n                            this.mayNotBeSimplified = true;\r\n                            return n0;\r\n                        }\r\n                    }\r\n\r\n                    // (const * a) / b -> const * (a / b)\r\n                    if (\r\n                        n1.type != \"node_const\" &&\r\n                        n0.type == \"node_op\" &&\r\n                        n0.value == \"op_mul\" &&\r\n                        n0.children[0].type == \"node_const\"\r\n                    ) {\r\n                        node.value = \"op_mul\";\r\n                        node.children = [\r\n                            n0.children[0],\r\n                            this.createNode(\"node_op\", \"op_div\", n0.children[1], n1)\r\n                        ];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n\r\n                    // a^b / a^c -> a^(b-c)\r\n                    if (\r\n                        n0.type == \"node_op\" &&\r\n                        n0.value == \"op_exp\" &&\r\n                        n1.type == \"node_op\" &&\r\n                        n1.value == \"op_exp\"\r\n                    ) {\r\n                        n0.children[0].hash = this.parser.compile(n0.children[0]);\r\n                        n1.children[0].hash = this.parser.compile(n1.children[0]);\r\n                        if (n0.children[0].hash === n1.children[0].hash) {\r\n                            n0.children[1] = this.createNode(\r\n                                \"node_op\",\r\n                                \"op_sub\",\r\n                                n0.children[1],\r\n                                n1.children[1]\r\n                            );\r\n                            this.mayNotBeSimplified = true;\r\n                            return n0;\r\n                        }\r\n                    }\r\n\r\n                    break;\r\n\r\n                // a^0 = 1\r\n                // a^1 -> a\r\n                // 1^a -> 1\r\n                // 0^a -> 0: a const != 0\r\n                case \"op_exp\":\r\n                    n0 = node.children[0];\r\n                    n1 = node.children[1];\r\n                    if (n1.type == \"node_const\" && n1.value === 0.0) {\r\n                        n1.value = 1.0;\r\n                        return n1;\r\n                    }\r\n                    if (n1.type == \"node_const\" && n1.value == 1.0) {\r\n                        return n0;\r\n                    }\r\n                    if (n0.type == \"node_const\" && n0.value == 1.0) {\r\n                        return n0;\r\n                    }\r\n                    if (\r\n                        n0.type == \"node_const\" &&\r\n                        n0.value === 0.0 &&\r\n                        n1.type == \"node_const\" &&\r\n                        n1.value !== 0.0\r\n                    ) {\r\n                        return n0;\r\n                    }\r\n\r\n                    // (a^b)^c -> a^(b*c)\r\n                    if (n0.type == \"node_op\" && n0.value == \"op_exp\") {\r\n                        node.children = [\r\n                            n0.children[0],\r\n                            this.createNode(\"node_op\", \"op_mul\", n0.children[1], n1)\r\n                        ];\r\n                        return node;\r\n                    }\r\n                    break;\r\n            }\r\n\r\n            switch (node.value) {\r\n                // const_1 + const_2 -> (const_1 + const_2)\r\n                // a + a -> 2*a\r\n                // a + (-b) = a - b\r\n                case \"op_add\":\r\n                    n0 = node.children[0];\r\n                    n1 = node.children[1];\r\n                    if (\r\n                        n0.type == \"node_const\" &&\r\n                        n1.type == \"node_const\" &&\r\n                        n0.value == n1.value\r\n                    ) {\r\n                        n0.value += n1.value;\r\n                        return n0;\r\n                    }\r\n\r\n                    if (\r\n                        n0.type == \"node_var\" &&\r\n                        n1.type == \"node_var\" &&\r\n                        n0.value == n1.value\r\n                    ) {\r\n                        node.children[0] = this.createNode(\"node_const\", 2.0);\r\n                        node.value = \"op_mul\";\r\n                        return node;\r\n                    }\r\n\r\n                    if (n0.type == \"node_op\" && n0.value == \"op_neg\") {\r\n                        node.value = \"op_sub\";\r\n                        node.children[0] = n1;\r\n                        node.children[1] = n0.children[0];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n\r\n                    if (n1.type == \"node_op\" && n1.value == \"op_neg\") {\r\n                        node.value = \"op_sub\";\r\n                        node.children[1] = n1.children[0];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n\r\n                    // const * a + const * a -> const * a\r\n                    if (\r\n                        n0.type == \"node_op\" &&\r\n                        n0.value == \"op_mul\" &&\r\n                        n1.type == \"node_op\" &&\r\n                        n1.value == \"op_mul\"\r\n                    ) {\r\n                        n0.children[1].hash = this.parser.compile(n0.children[1]);\r\n                        n1.children[1].hash = this.parser.compile(n1.children[1]);\r\n                        if (n0.children[1].hash === n1.children[1].hash) {\r\n                            node.value = \"op_mul\";\r\n                            node.children = [\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_add\",\r\n                                    n0.children[0],\r\n                                    n1.children[0]\r\n                                ),\r\n                                n0.children[1]\r\n                            ];\r\n                            this.mayNotBeSimplified = true;\r\n                            return node;\r\n                        }\r\n                    }\r\n                    // const * a + a -> (const + 1) * a\r\n                    if (n0.type == \"node_op\" && n0.value == \"op_mul\") {\r\n                        n0.children[1].hash = this.parser.compile(n0.children[1]);\r\n                        n1.hash = this.parser.compile(n1);\r\n                        if (n0.children[1].hash === n1.hash) {\r\n                            node.value = \"op_mul\";\r\n                            node.children = [\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_add\",\r\n                                    n0.children[0],\r\n                                    this.createNode(\"node_const\", 1.0)\r\n                                ),\r\n                                n1\r\n                            ];\r\n                            this.mayNotBeSimplified = true;\r\n                            return node;\r\n                        }\r\n                    }\r\n                    // a + const*a -> (const + 1) * a\r\n                    if (n1.type == \"node_op\" && n1.value == \"op_mul\") {\r\n                        n1.children[1].hash = this.parser.compile(n1.children[1]);\r\n                        n0.hash = this.parser.compile(n0);\r\n                        if (n1.children[1].hash === n0.hash) {\r\n                            node.value = \"op_mul\";\r\n                            node.children = [\r\n                                this.createNode(\r\n                                    \"node_op\",\r\n                                    \"op_add\",\r\n                                    this.createNode(\"node_const\", 1.0),\r\n                                    n1.children[0]\r\n                                ),\r\n                                n0\r\n                            ];\r\n                            this.mayNotBeSimplified = true;\r\n                            return node;\r\n                        }\r\n                    }\r\n\r\n                    break;\r\n\r\n                // a - (-b) = a + b\r\n                case \"op_sub\":\r\n                    n0 = node.children[0];\r\n                    n1 = node.children[1];\r\n                    if (n1.type == \"node_op\" && n1.value == \"op_neg\") {\r\n                        node.value = \"op_add\";\r\n                        node.children[1] = n1.children[0];\r\n                        this.mayNotBeSimplified = true;\r\n                        return node;\r\n                    }\r\n                    break;\r\n\r\n                case \"op_execfun\":\r\n                    return this.simplifyElementary(node);\r\n            }\r\n\r\n            return node;\r\n        },\r\n\r\n        simplifyElementary: function (node) {\r\n            var fun = node.children[0].value,\r\n                arg = node.children[1];\r\n\r\n            // Catch errors of the form sin()\r\n            if (arg.length == 0) {\r\n                return node;\r\n            }\r\n\r\n            switch (fun) {\r\n                // sin(0) -> 0\r\n                // sin(PI) -> 0\r\n                // sin (int * PI) -> 0\r\n                // sin (PI * int) -> 0\r\n                // Same for tan()\r\n                case \"sin\":\r\n                case \"tan\":\r\n                    if (arg[0].type == \"node_const\" && arg[0].value === 0) {\r\n                        node.type = \"node_const\";\r\n                        node.value = 0.0;\r\n                        return node;\r\n                    }\r\n                    if (arg[0].type == \"node_var\" && arg[0].value == 'PI') {\r\n                        node.type = \"node_const\";\r\n                        node.value = 0.0;\r\n                        return node;\r\n                    }\r\n                    if (\r\n                        arg[0].type == \"node_op\" &&\r\n                        arg[0].value == \"op_mul\" &&\r\n                        arg[0].children[0].type == \"node_const\" &&\r\n                        arg[0].children[0].value % 1 === 0 &&\r\n                        arg[0].children[1].type == \"node_var\" &&\r\n                        arg[0].children[1].value == \"PI\"\r\n                    ) {\r\n                        node.type = \"node_const\";\r\n                        node.value = 0.0;\r\n                        return node;\r\n                    }\r\n                    break;\r\n\r\n                // cos(0) -> 1.0\r\n                // cos(PI) -> -1.0\r\n                // cos(int * PI) -> +/- 1.0\r\n                // cos(PI * int) -> +/- 1.0\r\n                case \"cos\":\r\n                    if (arg[0].type == \"node_const\" && arg[0].value === 0) {\r\n                        node.type = \"node_const\";\r\n                        node.value = 1.0;\r\n                        return node;\r\n                    }\r\n                    if (arg[0].type == \"node_var\" && arg[0].value == 'PI') {\r\n                        node.type = \"node_op\";\r\n                        node.value = \"op_neg\";\r\n                        node.children = [this.createNode(\"node_const\", 1.0)];\r\n                        return node;\r\n                    }\r\n                    /*\r\n                    if (arg[0].type == 'node_op' && arg[0].value == 'op_mul' &&\r\n                        ((arg[0].children[0].type == 'node_const' && arg[0].children[0].value % 1 === 0 &&\r\n                         arg[0].children[1].type == 'node_var' && arg[0].children[1].value == 'PI') ||\r\n                         (arg[0].children[1].type == 'node_const' && arg[0].children[1].value % 1 === 0 &&\r\n                          arg[0].children[0].type == 'node_var' && arg[0].children[0].value == 'PI'))) {\r\n                        node.type = 'node_const';\r\n                        node.value = 1.0;\r\n                        return node;\r\n                    }\r\n                    */\r\n                    break;\r\n\r\n                // exp(0) -> 1\r\n                case \"exp\":\r\n                    if (arg[0].type == \"node_const\" && arg[0].value === 0) {\r\n                        node.type = \"node_const\";\r\n                        node.value = 1.0;\r\n                        return node;\r\n                    }\r\n                    break;\r\n\r\n                // pow(a, 0) -> 1\r\n                case \"pow\":\r\n                    if (arg[1].type == \"node_const\" && arg[1].value === 0) {\r\n                        node.type = \"node_const\";\r\n                        node.value = 1.0;\r\n                        return node;\r\n                    }\r\n                    break;\r\n            }\r\n\r\n            return node;\r\n        }\r\n    }\r\n);\r\n\r\nexport default JXG.CA;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview The JXG.Dump namespace provides methods to save a board to javascript.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"./type.js\";\r\n\r\n/**\r\n * The JXG.Dump namespace provides classes and methods to save a board to javascript.\r\n * @namespace\r\n */\r\nJXG.Dump = {\r\n    /**\r\n     * Adds markers to every element of the board\r\n     * @param {JXG.Board} board\r\n     * @param {Array|String} markers\r\n     * @param {Array} values\r\n     */\r\n    addMarkers: function (board, markers, values) {\r\n        var e, l, i;\r\n\r\n        if (!Type.isArray(markers)) {\r\n            markers = [markers];\r\n        }\r\n\r\n        if (!Type.isArray(values)) {\r\n            values = [values];\r\n        }\r\n\r\n        l = Math.min(markers.length, values.length);\r\n\r\n        markers.length = l;\r\n        values.length = l;\r\n\r\n        for (e in board.objects) {\r\n            if (board.objects.hasOwnProperty(e)) {\r\n                for (i = 0; i < l; i++) {\r\n                    board.objects[e][markers[i]] = values[i];\r\n                }\r\n            }\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Removes markers from every element on the board.\r\n     * @param {JXG.Board} board\r\n     * @param {Array|String} markers\r\n     */\r\n    deleteMarkers: function (board, markers) {\r\n        var e, l, i;\r\n\r\n        if (!Type.isArray(markers)) {\r\n            markers = [markers];\r\n        }\r\n\r\n        l = markers.length;\r\n\r\n        markers.length = l;\r\n\r\n        for (e in board.objects) {\r\n            if (board.objects.hasOwnProperty(e)) {\r\n                for (i = 0; i < l; i++) {\r\n                    delete board.objects[e][markers[i]];\r\n                }\r\n            }\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Stringifies a string, i.e. puts some quotation marks around <tt>s</tt> if it is of type string.\r\n     * @param {*} s\r\n     * @returns {String} \" + s + \"\r\n     */\r\n    str: function (s) {\r\n        if (typeof s === \"string\" && s.slice(0, 7) !== 'function') {\r\n            s = '\"' + s + '\"';\r\n        }\r\n\r\n        return s;\r\n    },\r\n\r\n    /**\r\n     * Eliminate default values given by {@link JXG.Options} from the attributes object.\r\n     * @param {Object} instance Attribute object of the element\r\n     * @param {Object} s Arbitrary number of objects <tt>instance</tt> will be compared to. Usually these are\r\n     * sub-objects of the {@link JXG.Board#options} structure.\r\n     * @returns {Object} Minimal attributes object\r\n     */\r\n    minimizeObject: function (instance, s) {\r\n        var p,\r\n            pl,\r\n            i,\r\n            def = {},\r\n            copy = Type.deepCopy(instance),\r\n            defaults = [];\r\n\r\n        for (i = 1; i < arguments.length; i++) {\r\n            defaults.push(arguments[i]);\r\n        }\r\n\r\n        def = Type.deepCopy(def, JXG.Options.elements, true);\r\n        for (i = defaults.length; i > 0; i--) {\r\n            def = Type.deepCopy(def, defaults[i - 1], true);\r\n        }\r\n\r\n        for (p in def) {\r\n            if (def.hasOwnProperty(p)) {\r\n                pl = p.toLowerCase();\r\n\r\n                if (def[p] !== null && typeof def[p] !== \"object\" && def[p] === copy[pl]) {\r\n                    // console.log(\"delete\", p);\r\n                    delete copy[pl];\r\n                }\r\n            }\r\n        }\r\n\r\n        return copy;\r\n    },\r\n\r\n    /**\r\n     * Prepare the attributes object for an element to be dumped as JavaScript or JessieCode code.\r\n     * @param {JXG.Board} board\r\n     * @param {JXG.GeometryElement} obj Geometry element which attributes object is generated\r\n     * @returns {Object} An attributes object.\r\n     */\r\n    prepareAttributes: function (board, obj) {\r\n        var a, s, o;\r\n\r\n        o = JXG.Options[obj.elType] || {};\r\n        a = this.minimizeObject(obj.getAttributes(), o);\r\n\r\n        for (s in obj.subs) {\r\n            if (obj.subs.hasOwnProperty(s)) {\r\n                a[s] = this.minimizeObject(\r\n                    obj.subs[s].getAttributes(),\r\n                    o[s],\r\n                    JXG.Options[obj.subs[s].elType] || {}\r\n                );\r\n                a[s].id = obj.subs[s].id;\r\n                a[s].name = obj.subs[s].name;\r\n            }\r\n        }\r\n\r\n        a.id = obj.id;\r\n        a.name = obj.name;\r\n\r\n        return a;\r\n    },\r\n\r\n    setBoundingBox: function (methods, board, boardVarName) {\r\n        methods.push({\r\n            obj: boardVarName,\r\n            method: \"setBoundingBox\",\r\n            params: [board.getBoundingBox(), board.keepaspectratio]\r\n        });\r\n\r\n        return methods;\r\n    },\r\n\r\n    /**\r\n     * Generate a save-able structure with all elements. This is used by {@link JXG.Dump#toJessie} and\r\n     * {@link JXG.Dump#toJavaScript} to generate the script.\r\n     * @param {JXG.Board} board\r\n     * @returns {Array} An array with all metadata necessary to save the construction.\r\n     */\r\n    dump: function (board) {\r\n        var e,\r\n            obj,\r\n            element,\r\n            s,\r\n            props = [],\r\n            methods = [],\r\n            elementList = [],\r\n            len = board.objectsList.length;\r\n\r\n        this.addMarkers(board, \"dumped\", false);\r\n\r\n        for (e = 0; e < len; e++) {\r\n            obj = board.objectsList[e];\r\n            element = {};\r\n\r\n            if (!obj.dumped && obj.dump) {\r\n                element.type = obj.getType();\r\n                element.parents = obj.getParents().slice();\r\n\r\n                // Extract coordinates of a point\r\n                if (element.type === \"point\" && element.parents[0] === 1) {\r\n                    element.parents = element.parents.slice(1);\r\n                }\r\n\r\n                for (s = 0; s < element.parents.length; s++) {\r\n                    if (\r\n                        Type.isString(element.parents[s]) &&\r\n                        element.parents[s][0] !== \"'\" &&\r\n                        element.parents[s][0] !== '\"'\r\n                    ) {\r\n                        element.parents[s] = '\"' + element.parents[s] + '\"';\r\n                    } else if (Type.isArray(element.parents[s])) {\r\n                        element.parents[s] = \"[\" + element.parents[s].toString() + \"]\";\r\n                    }\r\n                }\r\n\r\n                element.attributes = this.prepareAttributes(board, obj);\r\n                if (element.type === \"glider\" && obj.onPolygon) {\r\n                    props.push({\r\n                        obj: obj.id,\r\n                        prop: \"onPolygon\",\r\n                        val: true\r\n                    });\r\n                }\r\n\r\n                elementList.push(element);\r\n            }\r\n        }\r\n\r\n        this.deleteMarkers(board, 'dumped');\r\n\r\n        return {\r\n            elements: elementList,\r\n            props: props,\r\n            methods: methods\r\n        };\r\n    },\r\n\r\n    /**\r\n     * Converts an array of different values into a parameter string that can be used by the code generators.\r\n     * @param {Array} a\r\n     * @param {function} converter A function that is used to transform the elements of <tt>a</tt>. Usually\r\n     * {@link JXG.toJSON} or {@link JXG.Dump.toJCAN} are used.\r\n     * @returns {String}\r\n     */\r\n    arrayToParamStr: function (a, converter) {\r\n        var i,\r\n            s = [];\r\n\r\n        for (i = 0; i < a.length; i++) {\r\n            s.push(converter.call(this, a[i]));\r\n        }\r\n\r\n        return s.join(\", \");\r\n    },\r\n\r\n    /**\r\n     * Converts a JavaScript object into a JCAN (JessieCode Attribute Notation) string.\r\n     * @param {Object} obj A JavaScript object, functions will be ignored.\r\n     * @returns {String} The given object stored in a JCAN string.\r\n     */\r\n    toJCAN: function (obj) {\r\n        var i, list, prop;\r\n\r\n        switch (typeof obj) {\r\n            case \"object\":\r\n                if (obj) {\r\n                    list = [];\r\n\r\n                    if (Type.isArray(obj)) {\r\n                        for (i = 0; i < obj.length; i++) {\r\n                            list.push(this.toJCAN(obj[i]));\r\n                        }\r\n\r\n                        return \"[\" + list.join(\",\") + \"]\";\r\n                    }\r\n\r\n                    for (prop in obj) {\r\n                        if (obj.hasOwnProperty(prop)) {\r\n                            list.push(prop + \": \" + this.toJCAN(obj[prop]));\r\n                        }\r\n                    }\r\n\r\n                    return \"<<\" + list.join(\", \") + \">> \";\r\n                }\r\n                return 'null';\r\n            case \"string\":\r\n                return \"'\" + obj.replace(/\\\\/g, \"\\\\\\\\\").replace(/([\"'])/g, \"\\\\$1\") + \"'\";\r\n            case \"number\":\r\n            case \"boolean\":\r\n                return obj.toString();\r\n            case \"null\":\r\n                return 'null';\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Saves the construction in <tt>board</tt> to JessieCode.\r\n     * @param {JXG.Board} board\r\n     * @returns {String} JessieCode\r\n     */\r\n    toJessie: function (board) {\r\n        var i,\r\n            elements,\r\n            id,\r\n            dump = this.dump(board),\r\n            script = [];\r\n\r\n        dump.methods = this.setBoundingBox(dump.methods, board, \"$board\");\r\n\r\n        elements = dump.elements;\r\n\r\n        for (i = 0; i < elements.length; i++) {\r\n            if (elements[i].attributes.name.length > 0) {\r\n                script.push(\"// \" + elements[i].attributes.name);\r\n            }\r\n            script.push(\r\n                \"s\" + i + \" = \" + elements[i].type + \"(\" + elements[i].parents.join(\", \") + \") \" + this.toJCAN(elements[i].attributes).replace(/\\n/, \"\\\\n\") + \";\"\r\n            );\r\n\r\n            if (elements[i].type === 'axis') {\r\n                // Handle the case that remove[All]Ticks had been called.\r\n                id = elements[i].attributes.id;\r\n                if (board.objects[id].defaultTicks === null) {\r\n                    script.push(\"s\" + i + \".removeAllTicks();\");\r\n                }\r\n            }\r\n            script.push(\"\");\r\n        }\r\n\r\n        for (i = 0; i < dump.methods.length; i++) {\r\n            script.push(\r\n                dump.methods[i].obj +\r\n                    \".\" +\r\n                    dump.methods[i].method +\r\n                    \"(\" +\r\n                    this.arrayToParamStr(dump.methods[i].params, this.toJCAN) +\r\n                    \");\"\r\n            );\r\n            script.push(\"\");\r\n        }\r\n\r\n        for (i = 0; i < dump.props.length; i++) {\r\n            script.push(\r\n                dump.props[i].obj +\r\n                    \".\" +\r\n                    dump.props[i].prop +\r\n                    \" = \" +\r\n                    this.toJCAN(dump.props[i].val) +\r\n                    \";\"\r\n            );\r\n            script.push(\"\");\r\n        }\r\n\r\n        return script.join(\"\\n\");\r\n    },\r\n\r\n    /**\r\n     * Saves the construction in <tt>board</tt> to JavaScript.\r\n     * @param {JXG.Board} board\r\n     * @returns {String} JavaScript\r\n     */\r\n    toJavaScript: function (board) {\r\n        var i,\r\n            elements,\r\n            id,\r\n            dump = this.dump(board),\r\n            script = [];\r\n\r\n        dump.methods = this.setBoundingBox(dump.methods, board, 'board');\r\n\r\n        elements = dump.elements;\r\n\r\n        for (i = 0; i < elements.length; i++) {\r\n            script.push(\r\n                'board.create(\"' +\r\n                    elements[i].type +\r\n                    '\", [' +\r\n                    elements[i].parents.join(\", \") +\r\n                    \"], \" +\r\n                    Type.toJSON(elements[i].attributes) +\r\n                    \");\"\r\n            );\r\n\r\n            if (elements[i].type === 'axis') {\r\n                // Handle the case that remove[All]Ticks had been called.\r\n                id = elements[i].attributes.id;\r\n                if (board.objects[id].defaultTicks === null) {\r\n                    script.push(\r\n                        'board.objects[\"' +\r\n                            id +\r\n                            '\"].removeTicks(board.objects[\"' +\r\n                            id +\r\n                            '\"].defaultTicks);'\r\n                    );\r\n                }\r\n            }\r\n        }\r\n\r\n        for (i = 0; i < dump.methods.length; i++) {\r\n            script.push(\r\n                dump.methods[i].obj +\r\n                    \".\" +\r\n                    dump.methods[i].method +\r\n                    \"(\" +\r\n                    this.arrayToParamStr(dump.methods[i].params, Type.toJSON) +\r\n                    \");\"\r\n            );\r\n            script.push(\"\");\r\n        }\r\n\r\n        for (i = 0; i < dump.props.length; i++) {\r\n            script.push(\r\n                dump.props[i].obj +\r\n                    \".\" +\r\n                    dump.props[i].prop +\r\n                    \" = \" +\r\n                    Type.toJSON(dump.props[i].val) +\r\n                    \";\"\r\n            );\r\n            script.push(\"\");\r\n        }\r\n\r\n        return script.join(\"\\n\");\r\n    }\r\n};\r\n\r\nexport default JXG.Dump;\r\n","/*\r\n    Copyright 2018-2025\r\n        Alfred Wassermann,\r\n        Tigran Saluev\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview In this file the Comb element is defined.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * @class A marker to display domains of inequalities.\r\n * The comb element is defined by two points.\r\n * @pseudo\r\n * @name Comb\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n * @throws {Error} If the element cannot be constructed with the given parent\r\n *  objects an exception is thrown.\r\n * Parameter options:\r\n * @param {JXG.Point,array,function_JXG.Point,array,function} point1,point2 Parent elements\r\n * can be two elements either of type {@link JXG.Point} or array of\r\n * numbers describing the coordinates of a point. In the latter case the point\r\n * will be constructed automatically as a fixed invisible point.\r\n * It is possible to provide a function returning an array or a point,\r\n * instead of providing an array or a point.\r\n * @example\r\n * // Create a simple horizontal comb with invisible endpoints\r\n * var c = board.create('comb', [[1, 0], [3, 0]]);\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXG951ccb6a-52bc-4dc2-80e9-43db064f0f1b\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG951ccb6a-52bc-4dc2-80e9-43db064f0f1b', {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false}),\r\n *     c = board.create('comb', [[1, 0], [3, 0]]);\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * var p1 = board.create('glider', [-3, 0, board.defaultAxes.x]);\r\n * var p2 = board.create('glider', [-1, 0, board.defaultAxes.x]);\r\n * var c1 = board.create('comb', [p1, p2], {width: 0.2, frequency: 0.1, angle: Math.PI / 4});\r\n *\r\n * </pre><div id=\"JXG04186fd2-6340-11e8-9fb9-901b0e1b8723\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG04186fd2-6340-11e8-9fb9-901b0e1b8723',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p1 = board.create('glider', [-3, 0, board.defaultAxes.x]);\r\n *     var p2 = board.create('glider', [-1, 0, board.defaultAxes.x]);\r\n *     var c1 = board.create('comb', [p1, p2], {width: 0.2, frequency: 0.1, angle: Math.PI / 4});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var s = board.create('slider', [[1,3], [4,3], [0.1, 0.3, 0.8]]);\r\n * var p1 = board.create('glider', [-3, 0, board.defaultAxes.x]);\r\n * var p2 = board.create('glider', [-1, 0, board.defaultAxes.x]);\r\n * var c1 = board.create('comb', [p1, p2], {\r\n *     width: function(){ return 4*s.Value(); },\r\n *     reverse: function(){ return (s.Value()<0.5) ? false : true; },\r\n *     frequency: function(){ return s.Value(); },\r\n *     angle: function(){ return s.Value() * Math.PI / 2; },\r\n *     curve: {\r\n *         strokeColor: 'red'\r\n *     }\r\n * });\r\n *\r\n * </pre><div id=\"JXG6eb1bcd1-407e-4f13-8f0c-45ef39a0cfb3\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG6eb1bcd1-407e-4f13-8f0c-45ef39a0cfb3',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var s = board.create('slider', [[1,3], [4,3], [0.1, 0.3, 0.8]]);\r\n *     var p1 = board.create('glider', [-3, 0, board.defaultAxes.x]);\r\n *     var p2 = board.create('glider', [-1, 0, board.defaultAxes.x]);\r\n *     var c1 = board.create('comb', [p1, p2], {\r\n *         width: function(){ return 4*s.Value(); },\r\n *         reverse: function(){ return (s.Value()<0.5) ? false : true; },\r\n *         frequency: function(){ return s.Value(); },\r\n *         angle: function(){ return s.Value() * Math.PI / 2; },\r\n *         curve: {\r\n *             strokeColor: 'red'\r\n *         }\r\n *     });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createComb = function (board, parents, attributes) {\r\n    var p1, p2, c, attr, parent_types;\r\n    //ds, angle, width, p;\r\n\r\n    if (parents.length === 2) {\r\n        // point 1 given by coordinates\r\n        if (Type.isArray(parents[0]) && parents[0].length > 1) {\r\n            attr = Type.copyAttributes(attributes, board.options, \"comb\", 'point1');\r\n            p1 = board.create(\"point\", parents[0], attr);\r\n        } else if (Type.isString(parents[0]) || Type.isPoint(parents[0])) {\r\n            p1 = board.select(parents[0]);\r\n        } else if (Type.isFunction(parents[0]) && Type.isPoint(parents[0]())) {\r\n            p1 = parents[0]();\r\n        } else if (\r\n            Type.isFunction(parents[0]) &&\r\n            parents[0]().length &&\r\n            parents[0]().length >= 2\r\n        ) {\r\n            attr = Type.copyAttributes(attributes, board.options, \"comb\", 'point1');\r\n            p1 = JXG.createPoint(board, parents[0](), attr);\r\n        } else {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create comb with parent types '\" +\r\n                    typeof parents[0] +\r\n                    \"' and '\" +\r\n                    typeof parents[1] +\r\n                    \"'.\" +\r\n                    \"\\nPossible parent types: [point,point], [[x1,y1],[x2,y2]]\"\r\n            );\r\n        }\r\n\r\n        // point 2 given by coordinates\r\n        if (Type.isArray(parents[1]) && parents[1].length > 1) {\r\n            attr = Type.copyAttributes(attributes, board.options, \"comb\", 'point2');\r\n            p2 = board.create(\"point\", parents[1], attr);\r\n        } else if (Type.isString(parents[1]) || Type.isPoint(parents[1])) {\r\n            p2 = board.select(parents[1]);\r\n        } else if (Type.isFunction(parents[1]) && Type.isPoint(parents[1]())) {\r\n            p2 = parents[1]();\r\n        } else if (\r\n            Type.isFunction(parents[1]) &&\r\n            parents[1]().length &&\r\n            parents[1]().length >= 2\r\n        ) {\r\n            attr = Type.copyAttributes(attributes, board.options, \"comb\", 'point2');\r\n            p2 = JXG.createPoint(board, parents[1](), attr);\r\n        } else {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create comb with parent types '\" +\r\n                    typeof parents[0] +\r\n                    \"' and '\" +\r\n                    typeof parents[1] +\r\n                    \"'.\" +\r\n                    \"\\nPossible parent types: [point,point], [[x1,y1],[x2,y2]]\"\r\n            );\r\n        }\r\n    } else {\r\n        parent_types = parents.map(function (parent) {\r\n            return \"'\" + typeof parent + \"'\";\r\n        });\r\n        throw new Error(\r\n            \"JSXGraph: Can't create comb with parent types \" +\r\n                parent_types.join(\", \") +\r\n                \".\" +\r\n                \"\\nPossible parent types: [point,point], [[x1,y1],[x2,y2]]\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'comb');\r\n    // Type.merge(attr, Type.copyAttributes(attributes, board.options, 'comb', 'curve'));\r\n     c = board.create('curve', [[0], [0]], attr);\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    c.updateDataArray = function () {\r\n        var s = 0,\r\n            max_s = p1.Dist(p2),\r\n            cs, sn, dx, dy, x, y, f,\r\n            p1_inner = p1,\r\n            p2_inner = p2,\r\n            ds, angle, width;\r\n\r\n        ds = c.evalVisProp('frequency');\r\n        angle = -c.evalVisProp('angle');\r\n        width = c.evalVisProp('width');\r\n        if (c.evalVisProp('reverse')) {\r\n            p1_inner = p2;\r\n            p2_inner = p1;\r\n            angle = -angle;\r\n        }\r\n        cs = Math.cos(angle);\r\n        sn = Math.sin(angle);\r\n        dx = (p2_inner.X() - p1_inner.X()) / max_s;\r\n        dy = (p2_inner.Y() - p1_inner.Y()) / max_s;\r\n\r\n        // But instead of lifting by sin(angle), we want lifting by width.\r\n        cs *= width / Math.abs(sn);\r\n        sn *= width / Math.abs(sn);\r\n\r\n        this.dataX = [];\r\n        this.dataY = [];\r\n        // TODO Handle infinite bounds?\r\n        while (s < max_s) {\r\n            x = p1_inner.X() + dx * s;\r\n            y = p1_inner.Y() + dy * s;\r\n\r\n            // We may need to cut the last piece of a comb.\r\n            f = Math.min(cs, max_s - s) / Math.abs(cs);\r\n            sn *= f;\r\n            cs *= f;\r\n\r\n            this.dataX.push(x);\r\n            this.dataY.push(y);\r\n\r\n            this.dataX.push(x + dx * cs + dy * sn);\r\n            this.dataY.push(y - dx * sn + dy * cs);\r\n\r\n            this.dataX.push(NaN); // Force a jump\r\n            this.dataY.push(NaN);\r\n            s += ds;\r\n        }\r\n    };\r\n\r\n    return c;\r\n};\r\n\r\nJXG.registerElement(\"comb\", JXG.createComb);\r\n\r\n// export default {\r\n//     createComb: JXG.createComb\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview Example file for a triangle implemented as a extension to JSXGraph.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Polygon from \"../base/polygon.js\";\r\n\r\nvar priv = {\r\n    removeSlopeTriangle: function () {\r\n        Polygon.prototype.remove.call(this);\r\n\r\n        this.board.removeObject(this.toppoint);\r\n        this.board.removeObject(this.glider);\r\n\r\n        this.board.removeObject(this.baseline);\r\n        this.board.removeObject(this.basepoint);\r\n\r\n        this.board.removeObject(this.label);\r\n\r\n        if (this._isPrivateTangent) {\r\n            this.board.removeObject(this.tangent);\r\n        }\r\n    },\r\n    Value: function () {\r\n        return this.tangent.getSlope();\r\n    },\r\n    Direction: function() {\r\n        return this.tangent.Direction();\r\n    }\r\n};\r\n\r\n/**\r\n * @class Slope triangle to visualize the slope of a tangent to a curve, circle or line.\r\n * @pseudo\r\n * @name Slopetriangle\r\n * @augments JXG.Line\r\n * @constructor\r\n * @type JXG.Polygon\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * Parameter options:\r\n * @param {JXG.Line} t A tangent based on a glider on some object, e.g. curve, circle, line or turtle.\r\n * @param {JXG.Line_JXG.Point} li, p A line and a point on that line.\r\n *  The user has to take care that the point is a member of the line.\r\n * @example\r\n * // Create a slopetriangle on a tangent\r\n * var f = board.create('plot', ['sin(x)']),\r\n *     g = board.create('glider', [1, 2, f]),\r\n *     t = board.create('tangent', [g]),\r\n *\r\n *     st = board.create('slopetriangle', [t]);\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXG951ccb6a-52bc-4dc2-80e9-43db064f0f1b\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXG951ccb6a-52bc-4dc2-80e9-43db064f0f1b', {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false}),\r\n *     f = board.create('plot', ['sin(x)']),\r\n *     g = board.create('glider', [1, 2, f]),\r\n *     t = board.create('tangent', [g]),\r\n *\r\n *     st = board.create('slopetriangle', [t]);\r\n * })();\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Create a on a line and a point on that line\r\n * var p1 = board.create('point', [-2, 3]),\r\n *     p2 = board.create('point', [2, -3]),\r\n *     li = board.create('line', [p1, p2]),\r\n *     p = board.create('glider', [0, 0, li]),\r\n *\r\n *     st = board.create('slopetriangle', [li, p]);\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXGb52f451c-22cf-4677-852a-0bb9d764ee95\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function () {\r\n *   var board = JXG.JSXGraph.initBoard('JXGb52f451c-22cf-4677-852a-0bb9d764ee95', {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false}),\r\n *     p1 = board.create('point', [-2, 3]),\r\n *     p2 = board.create('point', [2, -3]),\r\n *     li = board.create('line', [p1, p2]),\r\n *     p = board.create('glider', [0, 0, li]),\r\n *\r\n *     st = board.create('slopetriangle', [li, p]);\r\n * })();\r\n * </script><pre>\r\n */\r\nJXG.createSlopeTriangle = function (board, parents, attributes) {\r\n    var el, tangent, tglide, glider,\r\n        toppoint, baseline, basepoint,\r\n        label, attr,\r\n        isPrivateTangent = false;\r\n\r\n    if (parents.length === 1 && parents[0].type === Const.OBJECT_TYPE_TANGENT) {\r\n        tangent = parents[0];\r\n        tglide = tangent.glider;\r\n    } else if (parents.length === 1 && parents[0].type === Const.OBJECT_TYPE_GLIDER) {\r\n        tglide = parents[0];\r\n        attr = Type.copyAttributes(attributes, board.options, \"slopetriangle\", 'tangent');\r\n        tangent = board.create(\"tangent\", [tglide], attr);\r\n        isPrivateTangent = true;\r\n    } else if (\r\n        parents.length === 2 &&\r\n        parents[0].elementClass === Const.OBJECT_CLASS_LINE &&\r\n        Type.isPoint(parents[1])\r\n    ) {\r\n        tangent = parents[0];\r\n        tglide = parents[1];\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create slope triangle with parent types '\" +\r\n                typeof parents[0] +\r\n                \"'.\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, \"slopetriangle\", 'basepoint');\r\n    basepoint = board.create(\r\n        \"point\",\r\n        [\r\n            function () {\r\n                return [tglide.X() + 1, tglide.Y()];\r\n            }\r\n        ],\r\n        attr\r\n    );\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, \"slopetriangle\", 'baseline');\r\n    baseline = board.create(\"line\", [tglide, basepoint], attr);\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, \"slopetriangle\", 'glider');\r\n    glider = board.create(\"glider\", [tglide.X() + 1, tglide.Y(), baseline], attr);\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, \"slopetriangle\", 'toppoint');\r\n    toppoint = board.create(\r\n        \"point\",\r\n        [\r\n            function () {\r\n                return [\r\n                    glider.X(),\r\n                    glider.Y() + (glider.X() - tglide.X()) * tangent.getSlope()\r\n                ];\r\n            }\r\n        ],\r\n        attr\r\n    );\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'slopetriangle');\r\n    // attr.borders = Type.copyAttributes(attr.borders, board.options, \"slopetriangle\", 'borders');\r\n    el = board.create(\"polygon\", [tglide, glider, toppoint], attr);\r\n\r\n    /**\r\n     * Returns the value of the slope triangle, that is the slope of the tangent.\r\n     * @name Value\r\n     * @memberOf Slopetriangle.prototype\r\n     * @function\r\n     * @returns {Number} slope of the tangent.\r\n     */\r\n    el.Value = priv.Value;\r\n\r\n    /**\r\n     * Returns the direction of the slope triangle, that is the direction of the tangent.\r\n     * @name Direction\r\n     * @memberOf Slopetriangle.prototype\r\n     * @see Line#Direction\r\n     * @function\r\n     * @returns {Number} slope of the tangent.\r\n     */\r\n    el.Direction = priv.Direction;\r\n    el.tangent = tangent;\r\n    el._isPrivateTangent = isPrivateTangent;\r\n\r\n    //el.borders[0].setArrow(false, {type: 2, size: 10});\r\n    //el.borders[1].setArrow(false, {type: 2, size: 10});\r\n    el.borders[2].setArrow(false, false);\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, \"slopetriangle\", 'label');\r\n    //label = board.create(\"text\", [\r\n    //         function () {\r\n    //             return glider.X() + 0.1;\r\n    //         },\r\n    //         function () {\r\n    //             return (glider.Y() + toppoint.Y()) * 0.5;\r\n    //         },\r\n    //         function () {\r\n    //             return \"\";\r\n    //         }\r\n    //     ],\r\n    //     attr\r\n    // );\r\n\r\n    attr = Type.copyAttributes(attr, board.options, 'label');\r\n    // Add label to vertical polygon edge\r\n    attr.isLabel = true;\r\n    attr.anchor = el.borders[1];\r\n    attr.priv = el.borders[1].visProp.priv;\r\n    attr.id = el.borders[1].id + 'Label';\r\n\r\n    label = board.create(\"text\", [0, 0, function () { return \"\"; }], attr);\r\n    label.needsUpdate = true;\r\n    label.dump = false;\r\n    el.borders[1].label = label;\r\n    el.borders[1].hasLabel = true;\r\n    el.borders[1].visProp.withlabel = true;\r\n\r\n    label._setText(function () {\r\n        var digits = label.evalVisProp('digits');\r\n\r\n        if (label.useLocale()) {\r\n            return label.formatNumberLocale(el.Value(), digits);\r\n        }\r\n        return Type.toFixed(el.Value(), digits);\r\n    });\r\n    label.fullUpdate();\r\n\r\n    el.glider = glider;\r\n    el.basepoint = basepoint;\r\n    el.baseline = baseline;\r\n    el.toppoint = toppoint;\r\n    el.label = label;\r\n\r\n    el.subs = {\r\n        glider: glider,\r\n        basePoint: basepoint,\r\n        baseLine: baseline,\r\n        topPoint: toppoint,\r\n        label: label\r\n    };\r\n    el.inherits.push(glider, basepoint, baseline, toppoint, label);\r\n\r\n    el.methodMap = JXG.deepCopy(el.methodMap, {\r\n        tangent: \"tangent\",\r\n        glider: \"glider\",\r\n        basepoint: \"basepoint\",\r\n        baseline: \"baseline\",\r\n        toppoint: \"toppoint\",\r\n        label: \"label\",\r\n        Value: \"Value\",\r\n        V: \"Value\",\r\n        Direction: \"Direction\"\r\n    });\r\n\r\n    el.remove = priv.removeSlopeTriangle;\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"slopetriangle\", JXG.createSlopeTriangle);\r\n\r\n// export default {\r\n//     createSlopeTriangle: JXG.createSlopeTriangle\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, window: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview In this file the Text element is defined.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Env from \"../utils/env.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\nvar priv = {\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    CheckboxChangeEventHandler: function () {\r\n        this._value = this.rendNodeCheckbox.checked;\r\n        this.board.update();\r\n    }\r\n};\r\n\r\n/**\r\n * @class A text element that contains an HTML checkbox tag.\r\n * For this element, the attribute \"display\" has to have the value 'html' (which is the default).\r\n *\r\n * <p><b>Setting a CSS class:</b> The attribute <tt>cssClass</tt> affects the HTML div element that contains the checkbox element. To change the CSS properties of the HTML checkbox element a selector of the form\r\n * <tt>.mycheck > checkbox { ... }</tt> has to be used. See the analog example for buttons:\r\n * {@link Button}.\r\n *\r\n * <p><b>Access the checkbox element with JavaScript:</b>\r\n * The underlying HTML checkbox element can be accessed through the sub-object 'rendNodeCheck', e.g. to\r\n * add event listeners.\r\n *\r\n * @pseudo\r\n * @name Checkbox\r\n * @augments Text\r\n * @constructor\r\n * @type JXG.Text\r\n *\r\n * @param {number,function_number,function_String,function} x,y,label Parent elements for checkbox elements.\r\n *   <p>\r\n *   x and y are the coordinates of the lower left corner of the text box.\r\n *    The position of the text is fixed,\r\n *   x and y are numbers. The position is variable if x or y are functions.\r\n *   <p>\r\n *   The label of the input element may be given as string or function.\r\n *   <p>\r\n *   The value of the checkbox can be controlled with the attribute <tt>checked</tt>\r\n *   <p>The HTML node can be accessed with <tt>element.rendNodeCheckbox</tt>\r\n *\r\n * @example\r\n *   // Create a checkbox element at position [0,3].\r\n *   var checkbox = board.create('checkbox', [0, 3, 'Change Y'], {});\r\n *   var p = board.create('point', [\r\n *       function(){ return 0.5;}, // X-coordinate\r\n *       function() {\r\n *           y = 0.5;\r\n *           if (checkbox.Value()) {\r\n *               y += 0.5;\r\n *           }\r\n *           return y;\r\n *       }]);\r\n * </pre><div class=\"jxgbox\" id=\"JXG0e835e0b-ed0c-4b85-b682-78158c0e6f5c\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function() {\r\n *   var t1_board = JXG.JSXGraph.initBoard('JXG0e835e0b-ed0c-4b85-b682-78158c0e6f5c', {boundingbox: [-3, 6, 5, -3], axis: true, showcopyright: false, shownavigation: false});\r\n *   var checkbox = t1_board.create('checkbox', [0, 3, 'Change Y'], {});\r\n *   var p = t1_board.create('point', [\r\n *       function(){ return 0.5;}, // X-coordinate\r\n *       function() {\r\n *           y = 0.5;\r\n *           if (checkbox.Value()) {\r\n *               y += 0.5;\r\n *           }\r\n *           return y;\r\n *       }]);\r\n * })();\r\n * </script><pre>\r\n *\r\n * The checkbox can be supplied with custom-made events by using the property rendNodeCheckbox.\r\n * @example\r\n * var checkbox = board.create('checkbox', [0, 4, 'Click me']),\r\n *     p = board.create('point', [1, 1]);\r\n *\r\n * JXG.addEvent(checkbox.rendNodeCheckbox, 'change', function() {\r\n *     if (this.Value()) {\r\n *         p.moveTo([4, 1]);\r\n *     } else {\r\n *         p.moveTo([1, 1]);\r\n *     }\r\n * }, checkbox);\r\n * </pre><div class=\"jxgbox\" id=\"JXGb2f2345a-057d-44ce-bd7a-6aaff70bc810\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n * (function() {\r\n * var board = JXG.JSXGraph.initBoard('JXGb2f2345a-057d-44ce-bd7a-6aaff70bc810', {boundingbox: [-3, 6, 5, -3], axis: true, showcopyright: false, shownavigation: false});\r\n * var checkbox = board.create('checkbox', [0, 4, 'Click me']),\r\n *     p = board.create('point', [1, 1]);\r\n *\r\n * JXG.addEvent(checkbox.rendNodeCheckbox, 'change', function() {\r\n *     if (this.Value()) {\r\n *         p.moveTo([4, 1]);\r\n *     } else {\r\n *         p.moveTo([1, 1]);\r\n *     }\r\n * }, checkbox);\r\n * })();\r\n * </script><pre>\r\n * @example\r\n *     var i1 = board.create('input', [1, 5, 'sin(x)', 'f(x)='], {cssStyle: 'width:4em', maxlength: 2});\r\n *         var c1 = board.create('checkbox', [1, 3, 'label 1'], {});\r\n *         var b1 = board.create('button', [1, 1, 'Change texts', function () {\r\n *                 i1.setText('g(x)=');\r\n *                 i1.set('cos(x)');\r\n *                 c1.setText('label 2');\r\n *                 b1.setText('Texts are changed');\r\n *             }],\r\n *             {cssStyle: 'width:200px'});\r\n *\r\n * </pre><div id=\"JXG31c6d070-354b-4f09-aab9-9aaa796f730c\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG31c6d070-354b-4f09-aab9-9aaa796f730c',\r\n *             {boundingbox: [-1, 7, 7, -1], axis: true, showcopyright: false, shownavigation: false});\r\n *         var i1 = board.create('input', [1, 5, 'sin(x)', 'f(x)='], {cssStyle: 'width:4em', maxlength: 2});\r\n *             var c1 = board.create('checkbox', [1, 3, 'label 1'], {});\r\n *             var b1 = board.create('button', [1, 1, 'Change texts', function () {\r\n *                     i1.setText('g(x)=');\r\n *                     i1.set('cos(x)');\r\n *                     c1.setText('label 2');\r\n *                     b1.setText('Texts are changed');\r\n *                 }],\r\n *                 {cssStyle: 'width:200px'});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createCheckbox = function (board, parents, attributes) {\r\n    var t,\r\n        par,\r\n        attr = Type.copyAttributes(attributes, board.options, 'checkbox');\r\n\r\n    //if (parents.length !== 3) {\r\n    //throw new Error(\"JSXGraph: Can't create checkbox with parent types '\" +\r\n    //    (typeof parents[0]) + \"' and '\" + (typeof parents[1]) + \"'.\" +\r\n    //    \"\\nPossible parents are: [[x,y], label]\");\r\n    //}\r\n\r\n    par = [\r\n        parents[0],\r\n        parents[1],\r\n        '<span style=\"display:inline\">' +\r\n            '<input type=\"checkbox\" /><label for=\"\"></label>' +\r\n            \"</span>\"\r\n    ];\r\n\r\n    // 1. Create checkbox element with empty label\r\n    t = board.create(\"text\", par, attr);\r\n    t.type = Type.OBJECT_TYPE_CHECKBOX;\r\n\r\n    t.rendNodeCheckbox = t.rendNode.childNodes[0].childNodes[0];\r\n    t.rendNodeLabel = t.rendNode.childNodes[0].childNodes[1];\r\n\r\n    t.rendNodeTag = t.rendNodeCheckbox; // Needed for unified treatment in setAttribute\r\n    t.rendNodeTag.disabled = !!attr.disabled;\r\n\r\n    t.rendNodeCheckbox.id = t.rendNode.id + \"_checkbox\";\r\n    t.rendNodeLabel.id = t.rendNode.id + \"_label\";\r\n    t.rendNodeLabel.setAttribute(\"for\", t.rendNodeCheckbox.id);\r\n\r\n    // 2. Set parents[2] (string|function) as label of the checkbox element.\r\n    // abstract.js selects the correct DOM element for the update\r\n    t.setText(parents[2]);\r\n\r\n    // This sets the font-size of the checkbox itself\r\n    t.visPropOld.fontsize = '0px';\r\n    board.renderer.updateTextStyle(t, false);\r\n\r\n    t.rendNodeCheckbox.checked = attr.checked;\r\n\r\n    t._value = attr.checked;\r\n\r\n    /**\r\n     * Returns the value of the checkbox element\r\n     * @name Value\r\n     * @memberOf Checkbox.prototype\r\n     * @function\r\n     * @returns {String} value of the checkbox.\r\n     */\r\n    t.Value = function () {\r\n        return this._value;\r\n    };\r\n\r\n     /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    t.update = function () {\r\n        if (this.needsUpdate) {\r\n            JXG.Text.prototype.update.call(this);\r\n            this._value = this.rendNodeCheckbox.checked;\r\n        }\r\n        return this;\r\n    };\r\n\r\n    Env.addEvent(t.rendNodeCheckbox, \"change\", priv.CheckboxChangeEventHandler, t);\r\n\r\n    return t;\r\n};\r\n\r\nJXG.registerElement(\"checkbox\", JXG.createCheckbox);\r\n\r\n// export default {\r\n//     createCheckbox: JXG.createCheckbox\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, window: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview In this file the Text element is defined.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Env from \"../utils/env.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * @class\r\n * @ignore\r\n */\r\nvar priv = {\r\n    /**\r\n    * @class\r\n    * @ignore\r\n    */\r\n\r\n    InputInputEventHandler: function (evt) {\r\n        this._value = this.rendNodeInput.value;\r\n        this.board.update();\r\n    }\r\n};\r\n\r\n/**\r\n * @class This element is used to provide a constructor for special texts containing a\r\n * HTML form input element.\r\n * For this element, the attribute \"display\" has to have the value 'html' (which is the default).\r\n *\r\n * <p><b>Setting a CSS class:</b> The attribute <tt>cssClass</tt> affects the HTML div element that contains the input element. To change the CSS properties of the HTML input element a selector of the form\r\n * <tt>.myinput > input { ... }</tt> has to be used. See the analog example for buttons:\r\n * {@link Button}.\r\n *\r\n * <p><b>Access the input element with JavaScript:</b>\r\n * The underlying HTML button element can be accessed through the sub-object 'rendNodeInput', e.g. to\r\n * add event listeners.\r\n *\r\n * @pseudo\r\n * @name Input\r\n * @augments Text\r\n * @constructor\r\n * @type JXG.Text\r\n *\r\n * @param {number,function_number,function_String_String,function} x,y,value,label Parent elements for input elements.\r\n *   <p>\r\n *   x and y are the coordinates of the lower left corner of the text box. The position of the text is fixed,\r\n *   x and y are numbers. The position is variable if x or y are functions.\r\n *   <p>\r\n *   The default value of the input element must be given as string.\r\n *   <p>\r\n *   The label of the input element may be given as string or function.\r\n *\r\n * @example\r\n *  // Create an input element at position [1,4].\r\n *  var input = board.create('input', [0, 1, 'sin(x)*x', 'f(x)='], {cssStyle: 'width: 100px'});\r\n *  var f = board.jc.snippet(input.Value(), true, 'x', false);\r\n *  var graph = board.create('functiongraph',[f,\r\n *          function() {\r\n *            var c = new JXG.Coords(JXG.COORDS_BY_SCREEN,[0,0],board);\r\n *            return c.usrCoords[1];\r\n *          },\r\n *          function() {\r\n *            var c = new JXG.Coords(JXG.COORDS_BY_SCREEN,[board.canvasWidth,0],board);\r\n *            return c.usrCoords[1];\r\n *          }\r\n *        ]);\r\n *\r\n *  board.create('text', [1, 3, '&lt;button onclick=\"updateGraph()\"&gt;Update graph&lt;/button&gt;']);\r\n *\r\n *  var updateGraph = function() {\r\n *      graph.Y = board.jc.snippet(input.Value(), true, 'x', false);\r\n *      graph.updateCurve();\r\n *      board.update();\r\n *  }\r\n * </pre><div class=\"jxgbox\" id=\"JXGc70f55f1-21ba-4719-a37d-a93ae2943faa\" style=\"width: 500px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *   var t1_board = JXG.JSXGraph.initBoard('JXGc70f55f1-21ba-4719-a37d-a93ae2943faa', {boundingbox: [-3, 6, 5, -3], axis: true, showcopyright: false, shownavigation: false});\r\n *   var input = t1_board.create('input', [1, 4, 'sin(x)*x', 'f(x)='], {cssStyle: 'width: 100px'});\r\n *   var f = t1_board.jc.snippet(input.Value(), true, 'x', false);\r\n *   var graph = t1_board.create('functiongraph',[f,\r\n *          function() {\r\n *            var c = new JXG.Coords(JXG.COORDS_BY_SCREEN,[0,0],t1_board);\r\n *            return c.usrCoords[1];\r\n *          },\r\n *          function() {\r\n *            var c = new JXG.Coords(JXG.COORDS_BY_SCREEN,[t1_board.canvasWidth,0],t1_board);\r\n *            return c.usrCoords[1];\r\n *          }\r\n *        ]);\r\n *\r\n *  t1_board.create('text', [1, 3, '<button onclick=\"updateGraph()\">Update graph</button>']);\r\n *\r\n *  var updateGraph = function() {\r\n *      graph.Y = t1_board.jc.snippet(input.Value(), true, 'x', false);\r\n *      graph.updateCurve();\r\n *      t1_board.update();\r\n *  }\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Add the `keyup` event to an input field\r\n * var A = board.create('point', [3, -2]);\r\n * var i = board.create('input', [-4, -4, \"1\", \"x \"]);\r\n *\r\n * i.rendNodeInput.addEventListener(\"keyup\", ( function () {\r\n *    var x = parseFloat(this.value);\r\n *    if (!isNaN(x)) {\r\n * \t   A.moveTo([x, 3], 100);\r\n *    }\r\n * }));\r\n *\r\n * </pre><div id=\"JXG81c84fa7-3f36-4874-9e0f-d4b9e93e755b\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG81c84fa7-3f36-4874-9e0f-d4b9e93e755b',\r\n *             {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false});\r\n *     var A = board.create('point', [3, -2]);\r\n *     var i = board.create('input', [-4, -4, \"1\", \"x \"]);\r\n *\r\n *     i.rendNodeInput.addEventListener(\"keyup\", ( function () {\r\n *        var x = parseFloat(this.value);\r\n *        if (!isNaN(x)) {\r\n *     \t    A.moveTo([x, 3], 100);\r\n *        }\r\n *     }));\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Add the `change` event to an input field\r\n * var A = board.create('point', [3, -2]);\r\n * var i = board.create('input', [-4, -4, \"1\", \"x \"]);\r\n *\r\n * i.rendNodeInput.addEventListener(\"change\", ( function () {\r\n *    var x = parseFloat(i.Value());\r\n *    A.moveTo([x, 2], 100);\r\n * }));\r\n *\r\n * </pre><div id=\"JXG51c4d78b-a7ad-4c34-a983-b3ddae6192d7\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG51c4d78b-a7ad-4c34-a983-b3ddae6192d7',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var A = board.create('point', [3, -2]);\r\n *     var i = board.create('input', [-4, -4, \"1\", \"x \"]);\r\n *\r\n *     i.rendNodeInput.addEventListener(\"change\", ( function () {\r\n *        var x = parseFloat(i.Value());\r\n *        A.moveTo([x, 2], 100);\r\n *     }));\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // change the width of an input field\r\n *  let s = board.create('slider', [[-3, 3], [2, 3], [50, 100, 300]]);\r\n *  let inp = board.create('input', [-6, 1, 'Math.sin(x)*x', 'f(x)='],{cssStyle:()=>'width:'+s.Value()+'px'});\r\n *\r\n * </pre><div id=\"JXG51c4d78b-a7ad-4c34-a983-b3ddae6192d7-1\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG51c4d78b-a7ad-4c34-a983-b3ddae6192d7-1',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *  let s = board.create('slider', [[-3, 3], [2, 3], [50, 100, 300]]);\r\n *  let inp = board.create('input', [-6, 1, 'Math.sin(x)*x', 'f(x)='],{cssStyle:()=>'width:'+s.Value()+'px'});\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *   Apply CSS classes to label and input tag\r\n *     &lt;style&gt;\r\n *         div.JXGtext_inp {\r\n *             font-weight: bold;\r\n *         }\r\n *\r\n *         // Label\r\n *         div.JXGtext_inp > span > span {\r\n *             padding: 3px;\r\n *         }\r\n *\r\n *         // Input field\r\n *         div.JXGtext_inp > span > input {\r\n *             width: 100px;\r\n *             border: solid 4px red;\r\n *             border-radius: 25px;\r\n *         }\r\n *     &lt;/style&gt;\r\n *\r\n * var inp = board.create('input', [-6, 1, 'x', 'y'], {\r\n *      CssClass: 'JXGtext_inp', HighlightCssClass: 'JXGtext_inp'\r\n * });\r\n *\r\n * </pre>\r\n *         <style>\r\n *             div.JXGtext_inp {\r\n *                 font-weight: bold;\r\n *             }\r\n *\r\n *             div.JXGtext_inp > span > span {\r\n *                 padding: 3px;\r\n *             }\r\n *\r\n *             div.JXGtext_inp > span > input {\r\n *                 width: 100px;\r\n *                 border: solid 4px red;\r\n *                 border-radius: 25px;\r\n *             }\r\n *         </style>\r\n * <div id=\"JXGa3642ebd-a7dc-41ac-beb2-0c9e705ab8b4\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGa3642ebd-a7dc-41ac-beb2-0c9e705ab8b4',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *         var inp = board.create('input', [-6, 1, 'x', 'y'], {CssClass: 'JXGtext_inp', HighlightCssClass: 'JXGtext_inp'});\r\n *\r\n *     })();\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createInput = function (board, parents, attributes) {\r\n    var t,\r\n        par,\r\n        attr = Type.copyAttributes(attributes, board.options, 'input');\r\n\r\n    par = [\r\n        parents[0],\r\n        parents[1],\r\n        '<span style=\"display:inline; white-space:nowrap; padding:0px;\">' +\r\n        '<label></label><input type=\"text\" maxlength=\"' +\r\n        attr.maxlength +\r\n        '\" style=\"width:100%\" />' +\r\n        \"</span>\"\r\n    ];\r\n\r\n    // 1. Create input element with empty label\r\n    t = board.create(\"text\", par, attr);\r\n    t.type = Type.OBJECT_TYPE_INPUT;\r\n\r\n    t.rendNodeLabel = t.rendNode.childNodes[0].childNodes[0];\r\n    t.rendNodeInput = t.rendNode.childNodes[0].childNodes[1];\r\n    t.rendNodeInput.value = parents[2];\r\n    t.rendNodeTag = t.rendNodeInput; // Needed for unified treatment in setAttribute\r\n    t.rendNodeTag.disabled = !!attr.disabled;\r\n    t.rendNodeLabel.id = t.rendNode.id + \"_label\";\r\n    t.rendNodeInput.id = t.rendNode.id + \"_input\";\r\n    t.rendNodeInput.setAttribute(\"aria-labelledby\", t.rendNodeLabel.id);\r\n\r\n    // 2. Set parents[3] (string|function) as label of the input element.\r\n    // abstract.js selects the correct DOM element for the update\r\n    t.setText(parents[3]);\r\n\r\n    t._value = parents[2];\r\n\r\n    // 3.  capture keydown events on the input, and do not let them propagate.  The problem is that\r\n    // elevation controls on view3D use left and right, so editing the input triggers 3D pan.\r\n    t.rendNodeInput.addEventListener(\"keydown\", (event) => {\r\n        // only trap left-and-right in case user wants input editing events\r\n        if (event.key === 'ArrowLeft' || event.key === 'ArrowRight') {\r\n            event.stopPropagation();\r\n        }\r\n    });\r\n\r\n\r\n\r\n\r\n    /**\r\n    * @class\r\n    * @ignore\r\n    */\r\n    t.update = function () {\r\n        if (this.needsUpdate) {\r\n            JXG.Text.prototype.update.call(this);\r\n            this._value = this.rendNodeInput.value;\r\n        }\r\n        return this;\r\n    };\r\n\r\n    /**\r\n     * Returns the value (content) of the input element\r\n     * @name Value\r\n     * @memberOf Input.prototype\r\n     * @function\r\n     * @returns {String} content of the input field.\r\n     */\r\n    t.Value = function () {\r\n        return this._value;\r\n    };\r\n\r\n    /**\r\n     * Sets value of the input element.\r\n     * @name set\r\n     * @memberOf Input.prototype\r\n     * @function\r\n     *\r\n     * @param {String} val\r\n     * @returns {JXG.GeometryElement} Reference to the element.\r\n     *\r\n     * @example\r\n     *         var i1 = board.create('input', [-3, 4, 'sin(x)', 'f(x)='], {cssStyle: 'width:4em', maxlength: 2});\r\n     *         var c1 = board.create('checkbox', [-3, 2, 'label 1'], {});\r\n     *         var b1 = board.create('button', [-3, -1, 'Change texts', function () {\r\n     *                 i1.setText('g(x)');\r\n     *                 i1.set('cos(x)');\r\n     *                 c1.setText('label 2');\r\n     *                 b1.setText('Texts are changed');\r\n     *             }],\r\n     *             {cssStyle: 'width:400px'});\r\n     *\r\n     * </pre><div id=\"JXG11cac8ff-2354-47e7-9da4-eb298e53de05\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXG11cac8ff-2354-47e7-9da4-eb298e53de05',\r\n     *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n     *             var i1 = board.create('input', [-3, 4, 'sin(x)', 'f(x)='], {cssStyle: 'width:4em', maxlength: 2});\r\n     *             var c1 = board.create('checkbox', [-3, 2, 'label 1'], {});\r\n     *             var b1 = board.create('button', [-3, -1, 'Change texts', function () {\r\n     *                     i1.setText('g(x)');\r\n     *                     i1.set('cos(x)');\r\n     *                     c1.setText('label 2');\r\n     *                     b1.setText('Texts are changed');\r\n     *                 }],\r\n     *                 {cssStyle: 'width:400px'});\r\n     *\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     */\r\n\r\n    /**\r\n    * @class\r\n    * @ignore\r\n    */\r\n\r\n    t.set = function (val) {\r\n        this._value = val;\r\n        this.rendNodeInput.value = val;\r\n        return this;\r\n    };\r\n\r\n    Env.addEvent(t.rendNodeInput, \"input\", priv.InputInputEventHandler, t);\r\n    Env.addEvent(\r\n        t.rendNodeInput,\r\n        \"mousedown\",\r\n        function (evt) {\r\n            if (Type.exists(evt.stopPropagation)) {\r\n                evt.stopPropagation();\r\n            }\r\n        },\r\n        t\r\n    );\r\n    Env.addEvent(\r\n        t.rendNodeInput,\r\n        \"touchstart\",\r\n        function (evt) {\r\n            if (Type.exists(evt.stopPropagation)) {\r\n                evt.stopPropagation();\r\n            }\r\n        },\r\n        t\r\n    );\r\n    Env.addEvent(\r\n        t.rendNodeInput,\r\n        \"pointerdown\",\r\n        function (evt) {\r\n            if (Type.exists(evt.stopPropagation)) {\r\n                evt.stopPropagation();\r\n            }\r\n        },\r\n        t\r\n    );\r\n\r\n    // This sets the font-size of the input HTML element\r\n    t.visPropOld.fontsize = '0px';\r\n    board.renderer.updateTextStyle(t, false);\r\n\r\n    return t;\r\n};\r\n\r\nJXG.registerElement(\"input\", JXG.createInput);\r\n\r\n// export default {\r\n//     createInput: JXG.createInput\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, window: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview In this file the Text element is defined.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Env from \"../utils/env.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\nvar priv = {\r\n    ButtonClickEventHandler: function () {\r\n        if (this._handler) {\r\n            this._handler();\r\n        }\r\n        this.board.update();\r\n    }\r\n};\r\n\r\n/**\r\n * @class A text element that contains an HTML button tag.\r\n * For this element, the attribute \"display\" has to have the value 'html' (which is the default).\r\n *\r\n * <p><b>Setting a CSS class:</b> The attribute <tt>cssClass</tt> affects the HTML div element that contains the button element. To change the CSS properties of the HTML button element a selector of the form\r\n * <tt>.mybutton > button { ... }</tt> has to be used. See the example below.\r\n *\r\n * <p><b>Access the button element with JavaScript:</b>\r\n * The underlying HTML button element can be accessed through the sub-object 'rendNodeButton', e.g. to\r\n * add event listeners.\r\n *\r\n * @pseudo\r\n * @name Button\r\n * @augments Text\r\n * @constructor\r\n * @type JXG.Text\r\n *\r\n * @param {number,function_number,function_String,function_function} x,y,label,handler Parent elements for button elements.\r\n *  <p>\r\n *  x and y are the coordinates of the lower left corner of the text box.\r\n *   The position of the text is fixed,\r\n *  x and y are numbers. The position is variable if x or y are functions.\r\n *  <p>\r\n *  The label of the input element may be given  as string.\r\n *  <p>\r\n *  The (optional) handler function which is called when the button is pressed.\r\n *\r\n * @example\r\n *  var p = board.create('point', [0.5, 0.5], {id: 'p1'});\r\n *\r\n *  // Create a button element at position [1,2].\r\n *  var button1 = board.create('button', [1, 2, 'Change Y with JavaScript', function() {\r\n *      p.moveTo([p.X(), p.Y() + 0.5], 100);\r\n *  }], {});\r\n *\r\n *  // Create a button element at position [1,4].\r\n *  var button2 = board.create('button', [1, 4, 'Change Y with JessieCode',\r\n *      \"$('p1').Y = $('p1').Y() - 0.5;\"\r\n *  ], {});\r\n *\r\n * </pre><div class=\"jxgbox\" id=\"JXGf19b1bce-dd00-4e35-be97-ff1817d11514\" style=\"width: 500px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *  var t1_board = JXG.JSXGraph.initBoard('JXGf19b1bce-dd00-4e35-be97-ff1817d11514', {boundingbox: [-3, 6, 5, -3], axis: true, showcopyright: false, shownavigation: false});\r\n *  var p = t1_board.create('point', [0, -1], {id: 'p1'});\r\n *\r\n *  // Create a button element at position [1,2].\r\n *  var button1 = t1_board.create('button', [1, 2, 'Change Y with JavaScript', function() {\r\n *      p.moveTo([p.X(), p.Y() + 0.5], 100);\r\n *  }], {});\r\n *\r\n *  // Create a button element at position [1,4].\r\n *  var button2 = t1_board.create('button', [1, 4, 'Change Y with JessieCode',\r\n *      \"$('p1').Y = $('p1').Y() - 0.5;\"\r\n *  ], {});\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // A toggle button\r\n * var butt = board.create('button', [-2, -2, 'Off', function() {\r\n *   var txt;\r\n *   butt.value = !butt.value;\r\n *   if (butt.value) {\r\n *   \ttxt = 'On';\r\n *   } else {\r\n *   \ttxt = 'Off';\r\n *   }\r\n * \tbutt.rendNodeButton.innerHTML = txt;\r\n * }]);\r\n *\r\n * // Set initial value for the button\r\n * if (!JXG.exists(butt.value)) {\r\n * \tbutt.value = false;\r\n * }\r\n *\r\n * var p = board.create('point', [2, -2], {\r\n * \tvisible: () => butt.value\r\n * });\r\n *\r\n *\r\n *\r\n * </pre><div id=\"JXGa1eaab8f-c73b-4660-96ce-4ca17bcac4d6\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGa1eaab8f-c73b-4660-96ce-4ca17bcac4d6',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var butt = board.create('button', [-2, -2, 'Off', function() {\r\n *       var txt;\r\n *       butt.value = !butt.value;\r\n *       if (butt.value) {\r\n *       \ttxt = 'On';\r\n *       } else {\r\n *       \ttxt = 'Off';\r\n *       }\r\n *     \tbutt.rendNodeButton.innerHTML = txt;\r\n *     }]);\r\n *\r\n *     // Set initial value for the button\r\n *     if (!JXG.exists(butt.value)) {\r\n *     \tbutt.value = false;\r\n *     }\r\n *\r\n *     var p = board.create('point', [2, -2], {\r\n *     \tvisible: () => butt.value\r\n *     });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var i1 = board.create('input', [-3, 4, 'sin(x)', 'f(x)='], {cssStyle: 'width:4em', maxlength: 2});\r\n * var c1 = board.create('checkbox', [-3, 2, 'label 1'], {});\r\n * var b1 = board.create('button', [-3, -1, 'Change texts', function () {\r\n *         i1.setText('g(x)');\r\n *         i1.set('cos(x)');\r\n *         c1.setText('label 2');\r\n *         b1.setText('Texts are changed');\r\n *     }],\r\n *     {cssStyle: 'width:200px'});\r\n *\r\n * </pre><div id=\"JXG11cac8ff-2354-47e7-9da4-eb928e53de05\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG11cac8ff-2354-47e7-9da4-eb928e53de05',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *             var i1 = board.create('input', [-3, 4, 'sin(x)', 'f(x)='], {cssStyle: 'width:4em', maxlength: 2});\r\n *             var c1 = board.create('checkbox', [-3, 2, 'label 1'], {});\r\n *             var b1 = board.create('button', [-3, -1, 'Change texts', function () {\r\n *                     i1.setText('g(x)');\r\n *                     i1.set('cos(x)');\r\n *                     c1.setText('label 2');\r\n *                     b1.setText('Texts are changed');\r\n *                 }],\r\n *                 {cssStyle: 'width:200px'});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Set the CSS class of the button\r\n *\r\n * // CSS:\r\n * &lt;style&gt;\r\n * .mybutton > button {\r\n *   background-color: #04AA6D;\r\n *   border: none;\r\n *   color: white;\r\n *   padding: 1px 3px;\r\n *   text-align: center;\r\n *   text-decoration: none;\r\n *   display: inline-block;\r\n *   font-size: 16px;\r\n * }\r\n * &lt;/style&gt;\r\n *\r\n * // JavaScript:\r\n * var button = board.create('button',\r\n *     [1, 4, 'answers', function () {}],\r\n *     {cssClass:'mybutton', highlightCssClass: 'mybutton'});\r\n *\r\n * </pre>\r\n * <style>\r\n * .mybutton > button {\r\n *   background-color: #04AA6D;\r\n *   border: none;\r\n *   color: white;\r\n *   padding: 1px 3px;\r\n *   text-align: center;\r\n *   text-decoration: none;\r\n *   display: inline-block;\r\n *   font-size: 16px;\r\n * }\r\n * </style>\r\n * <div id=\"JXG2da6cf73-8c2e-495c-bd31-42de43b71cf8\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG2da6cf73-8c2e-495c-bd31-42de43b71cf8',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *       var button = board.create('button', [1, 4, 'answers', function () {\r\n *       }], {cssClass:'mybutton', highlightCssClass: 'mybutton'});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createButton = function (board, parents, attributes) {\r\n    var t,\r\n        par,\r\n        attr = Type.copyAttributes(attributes, board.options, 'button');\r\n\r\n    //if (parents.length < 3) {\r\n    //throw new Error(\"JSXGraph: Can't create button with parent types '\" +\r\n    //    (typeof parents[0]) + \"' and '\" + (typeof parents[1]) + \"'.\" +\r\n    //    \"\\nPossible parents are: [x, y, label, handler]\");\r\n    //}\r\n\r\n    // 1. Create empty button\r\n    par = [parents[0], parents[1], '<button type=\"button\" style=\"width:100%; height:100%;\" tabindex=\"0\"></button>'];\r\n    t = board.create(\"text\", par, attr);\r\n    t.type = Type.OBJECT_TYPE_BUTTON;\r\n\r\n    t.rendNodeButton = t.rendNode.childNodes[0];\r\n    t.rendNodeButton.id = t.rendNode.id + \"_button\";\r\n\r\n    t.rendNodeTag = t.rendNodeButton; // Needed for unified treatment in setAttribute\r\n    t.rendNodeTag.disabled = !!attr.disabled;\r\n\r\n    // 2. Set parents[2] (string|function) as content of the button.\r\n    // abstract.js selects the correct DOM element for the update\r\n    t.setText(parents[2]);\r\n\r\n    // This sets the font size of the button text\r\n    t.visPropOld.fontsize = '0px';\r\n    board.renderer.updateTextStyle(t, false);\r\n\r\n    if (parents[3]) {\r\n        if (Type.isString(parents[3])) {\r\n            t._jc = new JXG.JessieCode();\r\n            t._jc.use(board);\r\n            t._handler = function () {\r\n                t._jc.parse(parents[3]);\r\n            };\r\n        } else {\r\n            t._handler = parents[3];\r\n        }\r\n    }\r\n\r\n    Env.addEvent(t.rendNodeButton, \"click\", priv.ButtonClickEventHandler, t);\r\n    Env.addEvent(\r\n        t.rendNodeButton,\r\n        \"mousedown\",\r\n        function (evt) {\r\n            if (Type.exists(evt.stopPropagation)) {\r\n                evt.stopPropagation();\r\n            }\r\n        },\r\n        t\r\n    );\r\n    Env.addEvent(\r\n        t.rendNodeButton,\r\n        \"touchstart\",\r\n        function (evt) {\r\n            if (Type.exists(evt.stopPropagation)) {\r\n                evt.stopPropagation();\r\n            }\r\n        },\r\n        t\r\n    );\r\n    Env.addEvent(\r\n        t.rendNodeButton,\r\n        \"pointerdown\",\r\n        function (evt) {\r\n            if (Type.exists(evt.stopPropagation)) {\r\n                evt.stopPropagation();\r\n            }\r\n        },\r\n        t\r\n    );\r\n\r\n    return t;\r\n};\r\n\r\nJXG.registerElement(\"button\", JXG.createButton);\r\n\r\n// export default {\r\n//     createButton: JXG.createButton\r\n// };\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview Implementation of vector fields and slope fields.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * @class  A vector field on a plane can be visualized as a collection of arrows\r\n * with given magnitudes and directions, each attached to a point on the plane.\r\n * <p>\r\n * Plot a vector field either given by two functions f1(x, y) and f2(x,y) or by a function f(x, y) returning an array of size 2.\r\n *\r\n * @pseudo\r\n * @name Vectorfield\r\n * @augments JXG.Curve\r\n * @constructor\r\n * @type JXG.Curve\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * Parameter options:\r\n * @param {Array|Function|String} F Either an array containing two functions f1(x, y) and f2(x, y) or function f(x, y) returning an array of length 2.\r\n * @param {Array} xData Array of length 3 containing start value for x, number of steps, end value of x. The vector field will contain\r\n * (number of steps) + 1 vectors in direction of x.\r\n * @param {Array} yData Array of length 3 containing start value for y, number of steps, end value of y. The vector field will contain\r\n * (number of steps) + 1 vectors in direction of y.\r\n *\r\n * @example\r\n * // Defining functions\r\n * var fx = (x, y) => Math.sin(y);\r\n * var fy = (x, y) => Math.cos(x);\r\n *\r\n * var field = board.create('vectorfield', [\r\n *         [fx, fy],    // Defining function\r\n *         [-6, 25, 6], // Horizontal mesh\r\n *         [-5, 20, 5], // Vertical mesh\r\n *     ]);\r\n *\r\n * </pre><div id=\"JXGa2040e30-48ea-47d4-9840-bd24cd49150b\" class=\"jxgbox\" style=\"width: 500px; height: 500px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGa2040e30-48ea-47d4-9840-bd24cd49150b',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     // Defining functions\r\n *     var fx = (x, y) => Math.sin(y);\r\n *     var fy = (x, y) => Math.cos(x);\r\n *\r\n *     var field = board.create('vectorfield', [\r\n *             [fx, fy],    // Defining function\r\n *             [-6, 25, 6], // Horizontal mesh\r\n *             [-5, 20, 5], // Vertical mesh\r\n *         ]);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Slider to control length of vectors\r\n * var s = board.create('slider', [[-3, 7], [3, 7], [0, 0.33, 1]], {name: 'length'});\r\n * // Slider to control number of steps\r\n * var stepsize = board.create('slider', [[-3, 6], [3, 6], [1, 20, 100]], {name: 'steps', snapWidth: 1});\r\n *\r\n * // Defining functions\r\n * var fx = (x, y) => 0.2 * y;\r\n * var fy = (x, y) => 0.2 * (Math.cos(x) - 2) * Math.sin(x);\r\n *\r\n * var field = board.create('vectorfield', [\r\n *         [fx, fy],        // Defining function\r\n *         [-6, () => stepsize.Value(), 6], // Horizontal mesh\r\n *         [-5, () => stepsize.Value(), 5], // Vertical mesh\r\n *     ], {\r\n *         highlightStrokeColor: JXG.palette.blue, // Make highlighting invisible\r\n *\r\n *         scale: () => s.Value(), // Scaling of vectors\r\n *\r\n *         arrowHead: {\r\n *             enabled: true,\r\n *             size: 8,  // Pixel length of arrow head\r\n *             angle: Math.PI / 16\r\n *         }\r\n * });\r\n *\r\n * </pre><div id=\"JXG9196337e-66f0-4d09-8065-11d88c4ff140\" class=\"jxgbox\" style=\"width: 500px; height: 500px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG9196337e-66f0-4d09-8065-11d88c4ff140',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     // Slider to control length of vectors\r\n *     var s = board.create('slider', [[-3, 7], [3, 7], [0, 0.33, 1]], {name: 'length'});\r\n *     // Slider to control number of steps\r\n *     var stepsize = board.create('slider', [[-3, 6], [3, 6], [1, 20, 100]], {name: 'steps', snapWidth: 1});\r\n *\r\n *     // Defining functions\r\n *     var fx = (x, y) => 0.2 * y;\r\n *     var fy = (x, y) => 0.2 * (Math.cos(x) - 2) * Math.sin(x);\r\n *\r\n *     var field = board.create('vectorfield', [\r\n *             [fx, fy],        // Defining function\r\n *             [-6, () => stepsize.Value(), 6], // Horizontal mesh\r\n *             [-5, () => stepsize.Value(), 5], // Vertical mesh\r\n *         ], {\r\n *             highlightStrokeColor: JXG.palette.blue, // Make highlighting invisible\r\n *\r\n *             scale: () => s.Value(), // Scaling of vectors\r\n *\r\n *             arrowHead: {\r\n *                 enabled: true,\r\n *                 size: 8,  // Pixel length of arrow head\r\n *                 angle: Math.PI / 16\r\n *             }\r\n *     });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createVectorField = function (board, parents, attributes) {\r\n    var el, attr;\r\n\r\n    if (!(parents.length >= 3 &&\r\n        (Type.isArray(parents[0]) || Type.isFunction(parents[0]) || Type.isString(parents[0])) &&\r\n        (Type.isArray(parents[1]) && parents[1].length === 3) &&\r\n        (Type.isArray(parents[2]) && parents[2].length === 3)\r\n    )) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create vector field with parent types \" +\r\n            \"'\" + typeof parents[0] + \"', \" +\r\n            \"'\" + typeof parents[1] + \"', \" +\r\n            \"'\" + typeof parents[2] + \"'.\"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'vectorfield');\r\n\r\n    /**\r\n     * @type {JXG.Curve}\r\n     * @ignore\r\n     */\r\n    el = board.create('curve', [[], []], attr);\r\n    el.elType = 'vectorfield';\r\n\r\n    /**\r\n     * Set the defining functions of vector field.\r\n     * @memberOf Vectorfield\r\n     * @name setF\r\n     * @function\r\n     * @param {Array|Function} func Either an array containing two functions f1(x, y) and f2(x, y) or function f(x, y) returning an array of length 2.\r\n     * @returns {Object} Reference to the vector field object.\r\n     *\r\n     * @example\r\n     * field.setF([(x, y) => Math.sin(y), (x, y) => Math.cos(x)]);\r\n     * board.update();\r\n     *\r\n     */\r\n    el.setF = function (func, varnames) {\r\n        var f0, f1;\r\n        if (Type.isArray(func)) {\r\n            f0 = Type.createFunction(func[0], this.board, varnames);\r\n            f1 = Type.createFunction(func[1], this.board, varnames);\r\n            /**\r\n             * @ignore\r\n             */\r\n            this.F = function (x, y) { return [f0(x, y), f1(x, y)]; };\r\n        } else {\r\n            this.F = Type.createFunction(func, el.board, varnames);\r\n        }\r\n        return this;\r\n    };\r\n\r\n    el.setF(parents[0], 'x, y');\r\n    el.xData = parents[1];\r\n    el.yData = parents[2];\r\n\r\n    el.updateDataArray = function () {\r\n        var x, y, i, j,\r\n            scale = this.evalVisProp('scale'),\r\n            start_x = Type.evaluate(this.xData[0]),\r\n            steps_x = Type.evaluate(this.xData[1]),\r\n            end_x = Type.evaluate(this.xData[2]),\r\n            delta_x = (end_x - start_x) / steps_x,\r\n\r\n            start_y = Type.evaluate(this.yData[0]),\r\n            steps_y = Type.evaluate(this.yData[1]),\r\n            end_y = Type.evaluate(this.yData[2]),\r\n            delta_y = (end_y - start_y) / steps_y,\r\n            v, theta, phi1, phi2,\r\n\r\n            showArrow = this.evalVisProp('arrowhead.enabled'),\r\n            leg, leg_x, leg_y, alpha;\r\n\r\n\r\n        if (showArrow) {\r\n            // Arrow head style\r\n            leg = this.evalVisProp('arrowhead.size');\r\n            leg_x = leg / board.unitX;\r\n            leg_y = leg / board.unitY;\r\n            alpha = this.evalVisProp('arrowhead.angle');\r\n        }\r\n\r\n        this.dataX = [];\r\n        this.dataY = [];\r\n\r\n        for (i = 0, x = start_x; i <= steps_x; x += delta_x, i++) {\r\n            for (j = 0, y = start_y; j <= steps_y; y += delta_y, j++) {\r\n                v = this.F(x, y);\r\n                v[0] *= scale;\r\n                v[1] *= scale;\r\n\r\n                Type.concat(this.dataX, [x, x + v[0], NaN]);\r\n                Type.concat(this.dataY, [y, y + v[1], NaN]);\r\n\r\n                if (showArrow && Math.abs(v[0]) + Math.abs(v[1]) > 0.0) {\r\n                    // Arrow head\r\n                    theta = Math.atan2(v[1], v[0]);\r\n                    phi1 = theta + alpha;\r\n                    phi2 = theta - alpha;\r\n                    Type.concat(this.dataX, [x + v[0] - Math.cos(phi1) * leg_x, x + v[0], x + v[0] - Math.cos(phi2) * leg_x, NaN]);\r\n                    Type.concat(this.dataY, [y + v[1] - Math.sin(phi1) * leg_y, y + v[1], y + v[1] - Math.sin(phi2) * leg_y, NaN]);\r\n                }\r\n            }\r\n        }\r\n    };\r\n\r\n    el.methodMap = Type.deepCopy(el.methodMap, {\r\n        setF: \"setF\"\r\n    });\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"vectorfield\", JXG.createVectorField);\r\n\r\n/**\r\n * @class A slope field is a graphical representation of the solutions\r\n * to a first-order differential equation of a scalar function.\r\n * <p>\r\n * Plot a slope field given by a function f(x, y) returning a number.\r\n *\r\n * @pseudo\r\n * @name Slopefield\r\n * @augments Vectorfield\r\n * @constructor\r\n * @type JXG.Curve\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * Parameter options:\r\n * @param {Function|String} F Function f(x, y) returning a number.\r\n * @param {Array} xData Array of length 3 containing start value for x, number of steps, end value of x. The slope field will contain\r\n * (number of steps) + 1 vectors in direction of x.\r\n * @param {Array} yData Array of length 3 containing start value for y, number of steps, end value of y. The slope field will contain\r\n * (number of steps) + 1 vectors in direction of y.\r\n * @example\r\n * var field = board.create('slopefield', [\r\n *     (x, y) => x * x - x - 2,\r\n *     [-6, 25, 6], // Horizontal mesh\r\n *     [-5, 20, 5]  // Vertical mesh\r\n * ]);\r\n *\r\n * </pre><div id=\"JXG8a2ee562-eea1-4ce0-91ca-46b71fc7543d\" class=\"jxgbox\" style=\"width: 500px; height: 500px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG8a2ee562-eea1-4ce0-91ca-46b71fc7543d',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var field = board.create('slopefield', [\r\n *         (x, y) => x * x - x - 2,\r\n *         [-6, 25, 6], [-5, 20, 5]\r\n *     ]);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * // Slider to control length of vectors\r\n * var s = board.create('slider', [[-3, 7], [3, 7], [0, 0.33, 1]], {name: 'length'});\r\n * // Slider to control number of steps\r\n * var stepsize = board.create('slider', [[-3, 6], [3, 6], [1, 20, 100]], {name: 'steps', snapWidth: 1});\r\n *\r\n * var field = board.create('slopefield', [\r\n *     (x, y) => x * x - y * y,\r\n *     [-6, () => stepsize.Value(), 6],\r\n *     [-5, () => stepsize.Value(), 5]],\r\n *     {\r\n *         strokeWidth: 1.5,\r\n *         highlightStrokeWidth: 0.5,\r\n *         highlightStrokeColor: JXG.palette.blue,\r\n *\r\n *         scale: () => s.Value(),\r\n *\r\n *         arrowHead: {\r\n *             enabled: false,\r\n *             size: 8,\r\n *             angle: Math.PI / 16\r\n *         }\r\n *     });\r\n *\r\n * </pre><div id=\"JXG1ec9e4d7-6094-4d2b-b72f-4efddd514f55\" class=\"jxgbox\" style=\"width: 500px; height: 500px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG1ec9e4d7-6094-4d2b-b72f-4efddd514f55',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     // Slider to control length of vectors\r\n *     var s = board.create('slider', [[-3, 7], [3, 7], [0, 0.33, 1]], {name: 'length'});\r\n *     // Slider to control number of steps\r\n *     var stepsize = board.create('slider', [[-3, 6], [3, 6], [1, 20, 100]], {name: 'steps', snapWidth: 1});\r\n *\r\n *     var field = board.create('slopefield', [\r\n *         (x, y) => x * x - y * y,\r\n *         [-6, () => stepsize.Value(), 6],\r\n *         [-5, () => stepsize.Value(), 5]],\r\n *         {\r\n *             strokeWidth: 1.5,\r\n *             highlightStrokeWidth: 0.5,\r\n *             highlightStrokeColor: JXG.palette.blue,\r\n *\r\n *             scale: () => s.Value(),\r\n *\r\n *             arrowHead: {\r\n *                 enabled: false,\r\n *                 size: 8,\r\n *                 angle: Math.PI / 16\r\n *             }\r\n *         });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createSlopeField = function (board, parents, attributes) {\r\n    var el, f, attr;\r\n\r\n    if (!(parents.length >= 3 &&\r\n        (Type.isFunction(parents[0]) || Type.isString(parents[0])) &&\r\n        (Type.isArray(parents[1]) && parents[1].length === 3) &&\r\n        (Type.isArray(parents[2]) && parents[2].length === 3)\r\n    )) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create slope field with parent types \" +\r\n            \"'\" + typeof parents[0] + \"', \" +\r\n            \"'\" + typeof parents[1] + \"', \" +\r\n            \"'\" + typeof parents[2] + \"'.\"\r\n        );\r\n    }\r\n\r\n    f = Type.createFunction(parents[0], board, 'x, y');\r\n    parents[0] = function (x, y) {\r\n        var z = f(x, y),\r\n            nrm = Math.sqrt(1 + z * z);\r\n        return [1 / nrm, z / nrm];\r\n    };\r\n    attr = Type.copyAttributes(attributes, board.options, 'slopefield');\r\n    /**\r\n     * @type {JXG.Curve}\r\n     * @ignore\r\n     */\r\n    el = board.create('vectorfield', parents, attr);\r\n    el.elType = 'slopefield';\r\n\r\n    /**\r\n     * Set the defining functions of slope field.\r\n     * @name Slopefield#setF\r\n     * @function\r\n     * @param {Function} func Function f(x, y) returning a number.\r\n     * @returns {Object} Reference to the slope field object.\r\n     *\r\n     * @example\r\n     * field.setF((x, y) => x * x + y * y);\r\n     * board.update();\r\n     *\r\n     */\r\n    el.setF = function (func, varnames) {\r\n        var f = Type.createFunction(func, el.board, varnames);\r\n\r\n        /**\r\n         * @ignore\r\n         */\r\n        this.F = function (x, y) {\r\n            var z = f(x, y),\r\n                nrm = Math.sqrt(1 + z * z);\r\n            return [1 / nrm, z / nrm];\r\n        };\r\n    };\r\n\r\n    el.methodMap = Type.deepCopy(el.methodMap, {\r\n        setF: \"setF\"\r\n    });\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"slopefield\", JXG.createSlopeField);\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview Implementation of smart labels..\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * @class Customized text elements for displaying measurements of JSXGraph elements,\r\n * Examples are length of a\r\n * segment, perimeter or area of a circle or polygon (including polygonal chain),\r\n * slope of a line, value of an angle, and coordinates of a point.\r\n * <p>\r\n * If additionally a text, or a function is supplied and the content is not the empty string,\r\n * that text is displayed instead of the measurement.\r\n * <p>\r\n * Smartlabels use custom made CSS layouts defined in jsxgraph.css. Therefore, the inclusion of the file jsxgraph.css is mandatory or\r\n * the CSS classes have to be replaced by other classes.\r\n * <p>\r\n * The default attributes for smartlabels are defined for each type of measured element in the following sub-objects.\r\n * This is a deviation from the usual JSXGraph attribute usage.\r\n * <ul>\r\n *  <li> <tt>JXG.Options.smartlabelangle</tt> for smartlabels of angle objects\r\n *  <li> <tt>JXG.Options.smartlabelcircle</tt> for smartlabels of circle objects\r\n *  <li> <tt>JXG.Options.smartlabelline</tt> for smartlabels of line objects\r\n *  <li> <tt>JXG.Options.smartlabelpoint</tt> for smartlabels of point objects.\r\n *  <li> <tt>JXG.Options.smartlabelpolygon</tt> for smartlabels of polygon objects.\r\n * </ul>\r\n *\r\n *\r\n * @pseudo\r\n * @name Smartlabel\r\n * @augments JXG.Text\r\n * @constructor\r\n * @type JXG.Text\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.GeometryElement} Parent parent object: point, line, circle, polygon, angle.\r\n * @param {String|Function} Txt Optional text. In case, this content is not the empty string,\r\n *  the measurement is overwritten by this text.\r\n *\r\n * @example\r\n * var p1 = board.create('point', [3, 4], {showInfobox: false, withLabel: false});\r\n * board.create('smartlabel', [p1], {digits: 1, unit: 'm', dir: 'col', useMathJax: false});\r\n *\r\n * </pre><div id=\"JXG30cd1f9e-7e78-48f3-91a2-9abd466a754f\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG30cd1f9e-7e78-48f3-91a2-9abd466a754f',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p1 = board.create('point', [3, 4], {showInfobox: false, withLabel: false});\r\n *     board.create('smartlabel', [p1], {digits: 1, unit: 'cm', dir: 'col', useMathJax: false});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var s1 = board.create('line', [[-7, 2], [6, -6]], {point1: {visible:true}, point2: {visible:true}});\r\n * board.create('smartlabel', [s1], {unit: 'm', measure: 'length', prefix: 'L = ', useMathJax: false});\r\n * board.create('smartlabel', [s1], {unit: 'm',  measure: 'slope', prefix: '&Delta; = ', useMathJax: false});\r\n *\r\n *\r\n * </pre><div id=\"JXGfb4423dc-ee3a-4122-a186-82123019a835\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGfb4423dc-ee3a-4122-a186-82123019a835',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var s1 = board.create('line', [[-7, 2], [6, -6]], {point1: {visible:true}, point2: {visible:true}});\r\n *     board.create('smartlabel', [s1], {unit: 'm', measure: 'length', prefix: 'L = ', useMathJax: false});\r\n *     board.create('smartlabel', [s1], {unit: 'm',  measure: 'slope', prefix: '&Delta; = ', useMathJax: false});\r\n *\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var c1 = board.create('circle', [[0, 1], [4, 1]], {point2: {visible: true}});\r\n * board.create('smartlabel', [c1], {unit: 'm', measure: 'perimeter', prefix: 'U = ', useMathJax: false});\r\n * board.create('smartlabel', [c1], {unit: 'm', measure: 'area', prefix: 'A = ', useMathJax: false});\r\n * board.create('smartlabel', [c1], {unit: 'm', measure: 'radius', prefix: 'R = ', useMathJax: false});\r\n *\r\n *\r\n * </pre><div id=\"JXG763c4700-8273-4eb7-9ed9-1dc6c2c52e93\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG763c4700-8273-4eb7-9ed9-1dc6c2c52e93',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var c1 = board.create('circle', [[0, 1], [4, 1]], {point2: {visible: true}});\r\n *     board.create('smartlabel', [c1], {unit: 'm', measure: 'perimeter', prefix: 'U = ', useMathJax: false});\r\n *     board.create('smartlabel', [c1], {unit: 'm', measure: 'area', prefix: 'A = ', useMathJax: false});\r\n *     board.create('smartlabel', [c1], {unit: 'm', measure: 'radius', prefix: 'R = ', useMathJax: false});\r\n *\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var p2 = board.create('polygon', [[-6, -5], [7, -7], [-4, 3]], {});\r\n * board.create('smartlabel', [p2], {\r\n *     unit: 'm',\r\n *     measure: 'area',\r\n *     prefix: 'A = ',\r\n *     cssClass: 'smart-label-pure smart-label-polygon',\r\n *     highlightCssClass: 'smart-label-pure smart-label-polygon',\r\n *     useMathJax: false\r\n * });\r\n * board.create('smartlabel', [p2, () => 'X: ' + p2.vertices[0].X().toFixed(1)], {\r\n *     measure: 'perimeter',\r\n *     cssClass: 'smart-label-outline smart-label-polygon',\r\n *     highlightCssClass: 'smart-label-outline smart-label-polygon',\r\n *     useMathJax: false\r\n * });\r\n *\r\n * </pre><div id=\"JXG376425ac-b4e5-41f2-979c-6ff32a01e9c8\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG376425ac-b4e5-41f2-979c-6ff32a01e9c8',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p2 = board.create('polygon', [[-6, -5], [7, -7], [-4, 3]], {});\r\n *     board.create('smartlabel', [p2], {\r\n *         unit: 'm',\r\n *         measure: 'area',\r\n *         prefix: 'A = ',\r\n *         cssClass: 'smart-label-pure smart-label-polygon',\r\n *         highlightCssClass: 'smart-label-pure smart-label-polygon',\r\n *         useMathJax: false\r\n *     });\r\n *     board.create('smartlabel', [p2, () => 'X: ' + p2.vertices[0].X().toFixed(1)], {\r\n *         measure: 'perimeter',\r\n *         cssClass: 'smart-label-outline smart-label-polygon',\r\n *         highlightCssClass: 'smart-label-outline smart-label-polygon',\r\n *         useMathJax: false\r\n *     });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var a1 = board.create('angle', [[1, -1], [1, 2], [1, 5]], {name: '&beta;', withLabel: false});\r\n * var sma = board.create('smartlabel', [a1], {digits: 1, prefix: a1.name + '=', unit: '°', useMathJax: false});\r\n *\r\n * </pre><div id=\"JXG48d6d1ae-e04a-45f4-a743-273976712c0b\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG48d6d1ae-e04a-45f4-a743-273976712c0b',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var a1 = board.create('angle', [[1, -1], [1, 2], [1, 5]], {name: '&beta;', withLabel: false});\r\n *     var sma = board.create('smartlabel', [a1], {digits: 1, prefix: a1.name + '=', unit: '°', useMathJax: false});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createSmartLabel = function (board, parents, attributes) {\r\n    var el, attr,\r\n        p, user_supplied_text,\r\n        getTextFun, txt_fun;\r\n\r\n    if (parents.length === 0 || (\r\n        [Const.OBJECT_CLASS_POINT, Const.OBJECT_CLASS_LINE,Const.OBJECT_CLASS_CIRCLE].indexOf(parents[0].elementClass) < 0 &&\r\n        [Const.OBJECT_TYPE_POLYGON, Const.OBJECT_TYPE_ANGLE].indexOf(parents[0].type) < 0\r\n        )\r\n    ) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create smartlabel with parent types \" +\r\n                \"'\" + typeof parents[0] + \"', \" +\r\n                \"'\" + typeof parents[1] + \"'.\"\r\n        );\r\n    }\r\n\r\n    p = parents[0];\r\n    user_supplied_text = parents[1] || '';\r\n\r\n    if (p.elementClass === Const.OBJECT_CLASS_POINT) {\r\n        attr = Type.copyAttributes(attributes, board.options, 'smartlabelpoint');\r\n\r\n    } else if (p.elementClass === Const.OBJECT_CLASS_LINE) {\r\n        attr = Type.copyAttributes(attributes, board.options, 'smartlabelline');\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        attr.rotate = function () {\r\n            return (Math.atan(p.getSlope()) * 180 / Math.PI + 360) % 360;\r\n        };\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        attr.visible = function () { return (p.L() < 1.5) ? false : true; };\r\n\r\n    } else if (p.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n        attr = Type.copyAttributes(attributes, board.options, 'smartlabelcircle');\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        attr.visible = function () { return (p.Radius() < 1.5) ? false : true; };\r\n\r\n    } else if (p.type === Const.OBJECT_TYPE_POLYGON) {\r\n        attr = Type.copyAttributes(attributes, board.options, 'smartlabelpolygon');\r\n    } else if (p.type === Const.OBJECT_TYPE_ANGLE) {\r\n        attr = Type.copyAttributes(attributes, board.options, 'smartlabelangle');\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        attr.rotate = function () {\r\n            var c1 = p.center.coords.usrCoords,\r\n                c2 = p.getLabelAnchor().usrCoords,\r\n                v = (Math.atan2(c2[2] - c1[2], c2[1] - c1[1]) * 180 / Math.PI + 360) % 360;\r\n            return (v > 90 && v < 270) ? v + 180 : v;\r\n        };\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        attr.anchorX = function () {\r\n            var c1 = p.center.coords.usrCoords,\r\n                c2 = p.getLabelAnchor().usrCoords,\r\n                v = (Math.atan2(c2[2] - c1[2], c2[1] - c1[1]) * 180 / Math.PI + 360) % 360;\r\n            return (v > 90 && v < 270) ? 'right' : 'left';\r\n        };\r\n    }\r\n\r\n    getTextFun = function (el, p, elType, mType) {\r\n        var measure;\r\n        switch (mType) {\r\n            case 'length':\r\n                /**\r\n                 * @ignore\r\n                 */\r\n                measure = function () { return p.L(); };\r\n                break;\r\n            case 'slope':\r\n                /**\r\n                 * @ignore\r\n                 */\r\n                measure = function () { return p.Slope(); };\r\n                break;\r\n            case 'area':\r\n                /**\r\n                 * @ignore\r\n                 */\r\n                measure = function () { return p.Area(); };\r\n                break;\r\n            case 'radius':\r\n                /**\r\n                 * @ignore\r\n                 */\r\n                measure = function () { return p.Radius(); };\r\n                break;\r\n            case 'perimeter':\r\n                /**\r\n                 * @ignore\r\n                 */\r\n                measure = function () { return p.Perimeter(); };\r\n                break;\r\n            case 'rad':\r\n                /**\r\n                 * @ignore\r\n                 */\r\n                measure = function () { return p.Value(); };\r\n                break;\r\n            case 'deg':\r\n                /**\r\n                 * @ignore\r\n                 */\r\n                measure = function () { return p.Value() * 180 / Math.PI; };\r\n                break;\r\n            default:\r\n                /**\r\n                 * @ignore\r\n                 */\r\n                measure = function () { return 0.0; };\r\n        }\r\n\r\n        return function () {\r\n            var str = '',\r\n                val,\r\n                txt = Type.evaluate(user_supplied_text),\r\n                digits = el.evalVisProp('digits'),\r\n                u = el.evalVisProp('unit'),\r\n                pre = el.evalVisProp('prefix'),\r\n                suf = el.evalVisProp('suffix'),\r\n                mj = el.evalVisProp('usemathjax') || el.evalVisProp('usekatex');\r\n\r\n            if (txt === '') {\r\n                if (el.useLocale()) {\r\n                    val = el.formatNumberLocale(measure(), digits);\r\n                } else {\r\n                    val = Type.toFixed(measure(), digits);\r\n                }\r\n                if (mj) {\r\n                    str = ['\\\\(', pre, val, '\\\\,', u, suf, '\\\\)'].join('');\r\n                } else {\r\n                    str = [pre, val, u, suf].join('');\r\n                }\r\n            } else {\r\n                str = txt;\r\n            }\r\n            return str;\r\n        };\r\n    };\r\n\r\n    if (p.elementClass === Const.OBJECT_CLASS_POINT) {\r\n        el = board.create('text', [\r\n            function () { return p.X(); },\r\n            function () { return p.Y(); },\r\n            ''\r\n        ], attr);\r\n\r\n        txt_fun = function () {\r\n            var str = '',\r\n                txt = Type.evaluate(user_supplied_text),\r\n                digits = el.evalVisProp('digits'),\r\n                u = el.evalVisProp('unit'),\r\n                pre = el.evalVisProp('prefix'),\r\n                suf = el.evalVisProp('suffix'),\r\n                dir = el.evalVisProp('dir'),\r\n                mj = el.evalVisProp('usemathjax') || el.evalVisProp('usekatex'),\r\n                x, y;\r\n\r\n            if (el.useLocale()) {\r\n                x = el.formatNumberLocale(p.X(), digits);\r\n                y = el.formatNumberLocale(p.Y(), digits);\r\n            } else {\r\n                x = Type.toFixed(p.X(), digits);\r\n                y = Type.toFixed(p.Y(), digits);\r\n            }\r\n\r\n            if (txt === '') {\r\n                if (dir === 'row') {\r\n                    if (mj) {\r\n                        str = ['\\\\(', pre, x, '\\\\,', u, ' / ', y, '\\\\,', u, suf, '\\\\)'].join('');\r\n                    } else {\r\n                        str = [pre, x, ' ', u, ' / ', y, ' ', u, suf].join('');\r\n                    }\r\n                } else if (dir.indexOf('col') === 0) { // Starts with 'col'\r\n                    if (mj) {\r\n                        str = ['\\\\(', pre, '\\\\left(\\\\array{', x, '\\\\,', u, '\\\\\\\\ ', y, '\\\\,', u, '}\\\\right)', suf, '\\\\)'].join('');\r\n                    } else {\r\n                        str = [pre, x, ' ', u, '<br />', y, ' ', u, suf].join('');\r\n                    }\r\n                }\r\n            } else {\r\n                str = txt;\r\n            }\r\n            return str;\r\n        };\r\n\r\n    } else if (p.elementClass === Const.OBJECT_CLASS_LINE) {\r\n\r\n        if (attr.measure === 'length') {\r\n            el = board.create('text', [\r\n                function () { return (p.point1.X() + p.point2.X()) * 0.5; },\r\n                function () { return (p.point1.Y() + p.point2.Y()) * 0.5; },\r\n                ''\r\n            ], attr);\r\n            txt_fun = getTextFun(el, p, 'line', 'length');\r\n\r\n        } else if (attr.measure === 'slope') {\r\n            el = board.create('text', [\r\n                function () { return (p.point1.X() * 0.25 + p.point2.X() * 0.75); },\r\n                function () { return (p.point1.Y() * 0.25 + p.point2.Y() * 0.75); },\r\n                ''\r\n            ], attr);\r\n            txt_fun = getTextFun(el, p, 'line', 'slope');\r\n        }\r\n\r\n    } else if (p.elementClass === Const.OBJECT_CLASS_CIRCLE) {\r\n        if (attr.measure === 'radius') {\r\n            el = board.create('text', [\r\n                function () { return p.center.X() + p.Radius() * 0.5; },\r\n                function () { return p.center.Y(); },\r\n                ''\r\n            ], attr);\r\n            txt_fun = getTextFun(el, p, 'circle', 'radius');\r\n\r\n        } else if (attr.measure === 'area') {\r\n            el = board.create('text', [\r\n                function () { return p.center.X(); },\r\n                function () { return p.center.Y() + p.Radius() * 0.5; },\r\n                ''\r\n            ], attr);\r\n            txt_fun = getTextFun(el, p, 'circle', 'area');\r\n\r\n        } else if (attr.measure === 'circumference' || attr.measure === 'perimeter') {\r\n            el = board.create('text', [\r\n                function () { return p.getLabelAnchor(); },\r\n                ''\r\n            ], attr);\r\n            txt_fun = getTextFun(el, p, 'circle', 'perimeter');\r\n\r\n        }\r\n    } else if (p.type === Const.OBJECT_TYPE_POLYGON) {\r\n        if (attr.measure === 'area') {\r\n            el = board.create('text', [\r\n                function () { return p.getTextAnchor(); },\r\n                ''\r\n            ], attr);\r\n            txt_fun = getTextFun(el, p, 'polygon', 'area');\r\n\r\n        } else if (attr.measure === 'perimeter') {\r\n            el = board.create('text', [\r\n                function () {\r\n                    var last = p.borders.length - 1;\r\n                    if (last >= 0) {\r\n                        return [\r\n                            (p.borders[last].point1.X() + p.borders[last].point2.X()) * 0.5,\r\n                            (p.borders[last].point1.Y() + p.borders[last].point2.Y()) * 0.5\r\n                        ];\r\n                    } else {\r\n                        return p.getTextAnchor();\r\n                    }\r\n                },\r\n                ''\r\n            ], attr);\r\n            txt_fun = getTextFun(el, p, 'polygon', 'perimeter');\r\n        }\r\n\r\n    } else if (p.type === Const.OBJECT_TYPE_ANGLE) {\r\n        el = board.create('text', [\r\n            function () {\r\n                return p.getLabelAnchor();\r\n            },\r\n            ''\r\n        ], attr);\r\n        txt_fun = getTextFun(el, p, 'angle', attr.measure);\r\n    }\r\n\r\n    if (Type.exists(el)) {\r\n        el.setText(txt_fun);\r\n        p.addChild(el);\r\n        el.setParents([p]);\r\n    }\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"smartlabel\", JXG.createSmartLabel);\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Michael Gerhaeuser,\r\n        Carsten Miller,\r\n        Bianca Valentin,\r\n        Alfred Wassermann,\r\n        Peter Wilfahrt\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, window: true*/\r\n/*jslint nomen: true, plusplus: true*/\r\n\r\n/**\r\n * @fileoverview In this file the ForeignObject element is defined.\r\n */\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"./constants.js\";\r\nimport Coords from \"./coords.js\";\r\nimport GeometryElement from \"./element.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport CoordsElement from \"./coordselement.js\";\r\n\r\n/**\r\n * Construct and handle SVG foreignObjects.\r\n *\r\n * @class Creates a new foreignObject object. Do not use this constructor to create a foreignObject. Use {@link JXG.Board#create} with\r\n * type {@link foreignobject} instead.\r\n * @augments JXG.GeometryElement\r\n * @augments JXG.CoordsElement\r\n * @param {string|JXG.Board} board The board the new foreignObject is drawn on.\r\n * @param {Array} coordinates An array with the user coordinates of the foreignObject.\r\n * @param {Object} attributes An object containing visual and - optionally - a name and an id.\r\n * @param {string|function} url An URL string or a function returning an URL string.\r\n * @param  {Array} size Array containing width and height of the foreignObject in user coordinates.\r\n *\r\n */\r\nJXG.ForeignObject = function (board, coords, attributes, content, size) {\r\n    this.constructor(\r\n        board,\r\n        attributes,\r\n        Const.OBJECT_TYPE_FOREIGNOBJECT,\r\n        Const.OBJECT_CLASS_OTHER\r\n    );\r\n    this.element = this.board.select(attributes.anchor);\r\n    this.coordsConstructor(coords);\r\n\r\n    this._useUserSize = false;\r\n\r\n    /**\r\n     * Array of length two containing [width, height] of the foreignObject in pixel.\r\n     * @type Array\r\n     */\r\n    this.size = [1, 1];\r\n    if (Type.exists(size) && size.length > 0) {\r\n        this._useUserSize = true;\r\n\r\n        this.W = Type.createFunction(size[0], this.board, \"\");\r\n        this.H = Type.createFunction(size[1], this.board, \"\");\r\n        this.addParentsFromJCFunctions([this.W, this.H]);\r\n\r\n        this.usrSize = [this.W(), this.H()];\r\n    }\r\n\r\n    // this.size = [Math.abs(this.usrSize[0] * board.unitX), Math.abs(this.usrSize[1] * board.unitY)];\r\n\r\n    /**\r\n     * 'href' of the foreignObject.\r\n     * @type {string}\r\n     */\r\n    this.content = content;\r\n\r\n    this.elType = 'foreignobject';\r\n\r\n    // span contains the anchor point and the two vectors\r\n    // spanning the foreignObject rectangle.\r\n    // this.span = [\r\n    //     this.coords.usrCoords.slice(0),\r\n    //     [this.coords.usrCoords[0], this.W(), 0],\r\n    //     [this.coords.usrCoords[0], 0, this.H()]\r\n    // ];\r\n    //this.parent = board.select(attributes.anchor);\r\n\r\n    this.id = this.board.setId(this, 'Im');\r\n\r\n    this.board.renderer.drawForeignObject(this);\r\n    this.board.finalizeAdding(this);\r\n\r\n    this.methodMap = JXG.deepCopy(this.methodMap, {\r\n        addTransformation: \"addTransform\",\r\n        trans: \"addTransform\",\r\n        W: \"W\",\r\n        Width: \"W\",\r\n        H: \"H\",\r\n        Height: \"H\"\r\n    });\r\n};\r\n\r\nJXG.ForeignObject.prototype = new GeometryElement();\r\nType.copyPrototypeMethods(JXG.ForeignObject, CoordsElement, 'coordsConstructor');\r\n\r\nJXG.extend(\r\n    JXG.ForeignObject.prototype,\r\n    /** @lends JXG.ForeignObject.prototype */ {\r\n        /**\r\n         * Checks whether (x,y) is over or near the image;\r\n         * @param {Number} x Coordinate in x direction, screen coordinates.\r\n         * @param {Number} y Coordinate in y direction, screen coordinates.\r\n         * @returns {Boolean} True if (x,y) is over the image, False otherwise.\r\n         */\r\n        hasPoint: function (x, y) {\r\n            var dx, dy, r, type, prec, c, v, p, dot,\r\n                len = this.transformations.length;\r\n\r\n            if (Type.isObject(this.evalVisProp('precision'))) {\r\n                type = this.board._inputDevice;\r\n                prec = this.evalVisProp('precision.' + type);\r\n            } else {\r\n                // 'inherit'\r\n                prec = this.board.options.precision.hasPoint;\r\n            }\r\n\r\n            // Easy case: no transformation\r\n            if (len === 0) {\r\n                dx = x - this.coords.scrCoords[1];\r\n                dy = this.coords.scrCoords[2] - y;\r\n                r = prec;\r\n\r\n                return dx >= -r && dx - this.size[0] <= r && dy >= -r && dy - this.size[1] <= r;\r\n            }\r\n\r\n            // foreignObject is transformed\r\n            c = new Coords(Const.COORDS_BY_SCREEN, [x, y], this.board);\r\n            // v is the vector from anchor point to the drag point\r\n            c = c.usrCoords;\r\n            v = [c[0] - this.span[0][0], c[1] - this.span[0][1], c[2] - this.span[0][2]];\r\n            dot = Mat.innerProduct; // shortcut\r\n\r\n            // Project the drag point to the sides.\r\n            p = dot(v, this.span[1]);\r\n            if (0 <= p && p <= dot(this.span[1], this.span[1])) {\r\n                p = dot(v, this.span[2]);\r\n\r\n                if (0 <= p && p <= dot(this.span[2], this.span[2])) {\r\n                    return true;\r\n                }\r\n            }\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * Recalculate the coordinates of lower left corner and the width and height.\r\n         *\r\n         * @returns {JXG.ForeignObject} A reference to the element\r\n         * @private\r\n         */\r\n        update: function (fromParent) {\r\n            if (!this.needsUpdate) {\r\n                return this;\r\n            }\r\n            this.updateCoords(fromParent);\r\n            this.updateSize();\r\n            // this.updateSpan();\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Send an update request to the renderer.\r\n         * @private\r\n         */\r\n        updateRenderer: function () {\r\n            return this.updateRendererGeneric('updateForeignObject');\r\n        },\r\n\r\n        /**\r\n         * Updates the internal arrays containing size of the foreignObject.\r\n         * @returns {JXG.ForeignObject} A reference to the element\r\n         * @private\r\n         */\r\n        updateSize: function () {\r\n            var bb = [0, 0];\r\n\r\n            if (this._useUserSize) {\r\n                this.usrSize = [this.W(), this.H()];\r\n                this.size = [\r\n                    Math.abs(this.usrSize[0] * this.board.unitX),\r\n                    Math.abs(this.usrSize[1] * this.board.unitY)\r\n                ];\r\n            } else {\r\n                if (this.rendNode.hasChildNodes()) {\r\n                    bb = this.rendNode.childNodes[0].getBoundingClientRect();\r\n                    this.size = [bb.width, bb.height];\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Update the anchor point of the foreignObject, i.e. the lower left corner\r\n         * and the two vectors which span the rectangle.\r\n         * @returns {JXG.ForeignObject} A reference to the element\r\n         * @private\r\n         *\r\n         */\r\n        updateSpan: function () {\r\n            var i,\r\n                j,\r\n                len = this.transformations.length,\r\n                v = [];\r\n\r\n            if (len === 0) {\r\n                this.span = [\r\n                    [this.Z(), this.X(), this.Y()],\r\n                    [this.Z(), this.W(), 0],\r\n                    [this.Z(), 0, this.H()]\r\n                ];\r\n            } else {\r\n                // v contains the three defining corners of the rectangle/image\r\n                v[0] = [this.Z(), this.X(), this.Y()];\r\n                v[1] = [this.Z(), this.X() + this.W(), this.Y()];\r\n                v[2] = [this.Z(), this.X(), this.Y() + this.H()];\r\n\r\n                // Transform the three corners\r\n                for (i = 0; i < len; i++) {\r\n                    for (j = 0; j < 3; j++) {\r\n                        v[j] = Mat.matVecMult(this.transformations[i].matrix, v[j]);\r\n                    }\r\n                }\r\n                // Normalize the vectors\r\n                for (j = 0; j < 3; j++) {\r\n                    v[j][1] /= v[j][0];\r\n                    v[j][2] /= v[j][0];\r\n                    v[j][0] /= v[j][0];\r\n                }\r\n                // Compute the two vectors spanning the rectangle\r\n                // by subtracting the anchor point.\r\n                for (j = 1; j < 3; j++) {\r\n                    v[j][0] -= v[0][0];\r\n                    v[j][1] -= v[0][1];\r\n                    v[j][2] -= v[0][2];\r\n                }\r\n                this.span = v;\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        addTransform: function (transform) {\r\n            var i;\r\n\r\n            if (Type.isArray(transform)) {\r\n                for (i = 0; i < transform.length; i++) {\r\n                    this.transformations.push(transform[i]);\r\n                }\r\n            } else {\r\n                this.transformations.push(transform);\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        // Documented in element.js\r\n        getParents: function () {\r\n            var p = [this.url, [this.Z(), this.X(), this.Y()], this.usrSize];\r\n\r\n            if (this.parents.length !== 0) {\r\n                p = this.parents;\r\n            }\r\n\r\n            return p;\r\n        },\r\n\r\n        /**\r\n         * Set the width and height of the foreignObject. After setting a new size,\r\n         * board.update() or foreignobject.fullUpdate()\r\n         * has to be called to make the change visible.\r\n         * @param  {numbe|function|string} width  Number, function or string\r\n         *                            that determines the new width of the foreignObject\r\n         * @param  {number|function|string} height Number, function or string\r\n         *                            that determines the new height of the foreignObject\r\n         * @returns {JXG.ForeignObject} A reference to the element\r\n         *\r\n         */\r\n        setSize: function (width, height) {\r\n            this.W = Type.createFunction(width, this.board, \"\");\r\n            this.H = Type.createFunction(height, this.board, \"\");\r\n            this._useUserSize = true;\r\n            this.addParentsFromJCFunctions([this.W, this.H]);\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Returns the width of the foreignObject in user coordinates.\r\n         * @returns {number} width of the image in user coordinates\r\n         */\r\n        W: function () {}, // Needed for docs, defined in constructor\r\n\r\n        /**\r\n         * Returns the height of the foreignObject in user coordinates.\r\n         * @returns {number} height of the image in user coordinates\r\n         */\r\n        H: function () {} // Needed for docs, defined in constructor\r\n    }\r\n);\r\n\r\n/**\r\n * @class Display any HTML content in an SVG foreignObject container - even below other elements.\r\n * <p>\r\n * Instead of board.create('foreignobject') the shortcut board.create('fo') may be used.\r\n *\r\n * <p style=\"background-color:#dddddd; padding:10px\"><b>NOTE:</b> In Safari up to version 15, a foreignObject does not obey the layer structure\r\n * if it contains &lt;video&gt; or &lt;iframe&gt; tags, as well as elements which are\r\n * positioned with <tt>position:absolute|relative|fixed</tt>. In this  case, the foreignobject will be\r\n * \"above\" the JSXGraph construction.\r\n * </p>\r\n *\r\n * @pseudo\r\n * @name ForeignObject\r\n * @augments JXG.ForeignObject\r\n * @constructor\r\n * @type JXG.ForeignObject\r\n *\r\n * @param {String} content HTML content of the foreignObject. May also be &lt;video&gt; or &lt;iframe&gt;\r\n * @param {Array} position Position of the foreignObject given by [x, y] in user coordinates. Same as for images.\r\n * @param {Array} [size] (Optional) argument size of the foreignObject in user coordinates. If not given, size is specified by the HTML attributes\r\n * or CSS properties of the content.\r\n *\r\n * @see Image\r\n *\r\n * @example\r\n * var p = board.create('point', [1, 7], {size: 16});\r\n * var fo = board.create('foreignobject', [\r\n *     '&lt;video width=\"300\" height=\"200\" src=\"https://eucbeniki.sio.si/vega2/278/Video_metanje_oge_.mp4\" type=\"html5video\" controls&gt;',\r\n *     [0, -3], [9, 6]],\r\n *     {layer: 8, fixed: true}\r\n *  );\r\n *\r\n * </pre><div id=\"JXG0c122f2c-3671-4a28-80a9-f4c523eeda89\" class=\"jxgbox\" style=\"width: 500px; height: 500px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG0c122f2c-3671-4a28-80a9-f4c523eeda89',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p = board.create('point', [1, 7], {size: 16});\r\n *     var fo = board.create('foreignobject', [\r\n *         '<video width=\"300\" height=\"200\" src=\"https://eucbeniki.sio.si/vega2/278/Video_metanje_oge_.mp4\" type=\"html5video\" controls>',\r\n *         [0, -3], [9, 6]],\r\n *         {layer: 8, fixed: true}\r\n *      );\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var p = board.create('point', [1, 7], {size: 16});\r\n * var fo = board.create('fo', [\r\n *     '&lt;div style=\"background-color:blue; color: yellow; padding:20px; width:200px; height:50px; \"&gt;Hello&lt;/div&gt;',\r\n *     [-7, -6]],\r\n *     {layer: 1, fixed: false}\r\n *  );\r\n *\r\n * </pre><div id=\"JXG1759c868-1a4a-4767-802c-91f84902e3ec\" class=\"jxgbox\" style=\"width: 500px; height: 500px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG1759c868-1a4a-4767-802c-91f84902e3ec',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var p = board.create('point', [1, 7], {size: 16});\r\n *     var fo = board.create('foreignobject', [\r\n *         '<div style=\"background-color:blue; color: yellow; padding:20px; width:200px; height:50px; \">Hello</div>',\r\n *         [-7, -6]],\r\n *         {layer: 1, fixed: false}\r\n *      );\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * board.renderer.container.style.backgroundColor = 'lightblue';\r\n * var points = [];\r\n * points.push( board.create('point', [-2, 3.5], {fixed:false,color: 'yellow', size: 6,name:'6 am'}) );\r\n * points.push( board.create('point', [0, 3.5],  {fixed:false,color: 'yellow', size: 6,name:'12 pm'}) );\r\n * points.push( board.create('point', [2, 3.5],  {fixed:false,color: 'yellow', size: 6,name:'6 pm'}) );\r\n *\r\n * var fo = board.create('fo', [\r\n *     '&lt;video width=\"100%\" height=\"100%\" src=\"https://benedu.net/moodle/aaimg/ajx_img/astro/tr/1vd.mp4\" type=\"html5video\" controls&gt;',\r\n *     [-6, -4], [12, 8]],\r\n *     {layer: 0, fixed: true}\r\n *  );\r\n *\r\n * var f = JXG.Math.Numerics.lagrangePolynomial(points);\r\n * var graph = board.create('functiongraph', [f, -10, 10], {fixed:true,strokeWidth:3, layer: 8});\r\n *\r\n * </pre><div id=\"JXGc3fc5520-13aa-4f66-abaa-42e9dc3fbf3f\" class=\"jxgbox\" style=\"width: 500px; height: 500px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGc3fc5520-13aa-4f66-abaa-42e9dc3fbf3f',\r\n *             {boundingbox: [-6,4,6,-4], axis: true, showcopyright: false, shownavigation: false});\r\n *     board.renderer.container.style.backgroundColor = 'lightblue';\r\n *     var points = [];\r\n *     points.push( board.create('point', [-2, 3.5], {fixed:false,color: 'yellow', size: 6,name:'6 am'}) );\r\n *     points.push( board.create('point', [0, 3.5],  {fixed:false,color: 'yellow', size: 6,name:'12 pm'}) );\r\n *     points.push( board.create('point', [2, 3.5],  {fixed:false,color: 'yellow', size: 6,name:'6 pm'}) );\r\n *\r\n *     var fo = board.create('fo', [\r\n *         '<video width=\"100%\" height=\"100%\" src=\"https://benedu.net/moodle/aaimg/ajx_img/astro/tr/1vd.mp4\" type=\"html5video\" controls>',\r\n *         [-6, -4], [12, 8]],\r\n *         {layer: 0, fixed: true}\r\n *      );\r\n *\r\n *     var f = JXG.Math.Numerics.lagrangePolynomial(points);\r\n *     var graph = board.create('functiongraph', [f, -10, 10], {fixed:true,strokeWidth:3, layer: 8});\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * Video \"24-hour time-lapse in Cascais, Portugal. Produced by Nuno Miguel Duarte\" adapted from\r\n * <a href=\"https://www.pbslearningmedia.org/resource/buac18-k2-sci-ess-sunposition/changing-position-of-the-sun-in-the-sky/\">https://www.pbslearningmedia.org/resource/buac18-k2-sci-ess-sunposition/changing-position-of-the-sun-in-the-sky/</a>,\r\n * ©2016 Nuno Miguel Duarte.\r\n *\r\n */\r\nJXG.createForeignObject = function (board, parents, attributes) {\r\n    var attr,\r\n        fo,\r\n        content = parents[0],\r\n        coords = parents[1],\r\n        size = [];\r\n\r\n    if (parents.length >= 2) {\r\n        size = parents[2];\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'foreignobject');\r\n    fo = CoordsElement.create(JXG.ForeignObject, board, coords, attr, content, size);\r\n    if (!fo) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create foreignObject with parent types '\" +\r\n                typeof parents[0] +\r\n                \"' and '\" +\r\n                typeof parents[1] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [string, [x, y], [w, h]], [string, [x, y]], [element,transformation]\"\r\n        );\r\n    }\r\n\r\n    return fo;\r\n};\r\n\r\nJXG.registerElement(\"foreignobject\", JXG.createForeignObject);\r\nJXG.registerElement(\"fo\", JXG.createForeignObject);\r\n\r\nexport default JXG.ForeignObject;\r\n// export default {\r\n//     ForeignObject: JXG.ForeignObject,\r\n//     createForeignobject: JXG.createForeignObject\r\n// };\r\n","/*global JXG:true, define: true*/\r\n\r\nimport JXG from \"./jxg.js\";\r\nimport Options from \"./options.js\";\r\n\r\nJXG.extend(Options, {\r\n    // infobox: {\r\n    //     // strokeColor: 'black',\r\n    //     // useKatex: false,\r\n    //     // useMathjax: false\r\n    // },\r\n\r\n    axes3d: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Position of the main axes in a View3D element. Possible values are\r\n         * 'center', 'border' or 'none'. This attribute is immutable, i.e.\r\n         * can not be changed during the lifetime of the construction.\r\n         *\r\n         * @type String\r\n         * @name View3D#axesPosition\r\n         * @default 'center'\r\n         */\r\n        axesPosition: \"center\", // Possible values: 'center', 'border', 'none'\r\n\r\n        // Main axes\r\n        /**\r\n         * Attributes of the centered 3D x-axis.\r\n         *\r\n         * @type Line3D\r\n         * @name View3D#xAxis\r\n         * @see View3D#axesPosition\r\n         */\r\n        xAxis: { visible: true, point2: { name: \"x\" }, strokeColor: JXG.palette.red },\r\n\r\n        /**\r\n         * Attributes of the centered 3D y-axis.\r\n         *\r\n         * @type Line3D\r\n         * @name View3D#yAxis\r\n         * @see View3D#axesPosition\r\n         */\r\n        yAxis: { visible: true, point2: { name: \"y\" }, strokeColor: JXG.palette.green },\r\n\r\n        /**\r\n         * Attributes of the centered 3D z-axis.\r\n         *\r\n         * @type Line3D\r\n         * @name View3D#zAxis\r\n         * @see View3D#axesPosition\r\n         */\r\n        zAxis: { visible: true, point2: { name: \"z\" }, strokeColor: JXG.palette.blue },\r\n\r\n        /**\r\n         * Attributes of the 3D x-axis at the border.\r\n         *\r\n         * @type Line3D\r\n         * @name View3D#xAxisBorder\r\n         * @see View3D#axesPosition\r\n         * @default <pre>{\r\n         *   name: 'x',\r\n         *   withLabel: false,\r\n         *   label: {\r\n         *       position: '50% left',\r\n         *       offset: [30, 0],\r\n         *       fontsize: 15\r\n         *   },\r\n         *   strokeWidth: 1,\r\n         *   lastArrow: false,\r\n         *   ticks3d: {\r\n         *       label: {\r\n         *           anchorX: 'middle',\r\n         *           anchorY: 'middle'\r\n         *       }\r\n         *   }\r\n         *}\r\n         *</pre>\r\n         */\r\n        xAxisBorder: {\r\n            name: 'x',\r\n            visible: 'ìnherit',\r\n            withLabel: false,\r\n            label: {\r\n                position: '50% left',\r\n                offset: [30, 0],\r\n                fontsize: 15\r\n            },\r\n            strokeWidth: 1,\r\n            lastArrow: false,\r\n            ticks3d: {\r\n                visible: 'ìnherit',\r\n                label: {\r\n                    anchorX: 'middle',\r\n                    anchorY: 'middle'\r\n                }\r\n\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Attributes of the 3D y-axis at the border.\r\n         *\r\n         * @type Line3D\r\n         * @name View3D#yAxisBorder\r\n         * @see View3D#axesPosition\r\n         * @default <pre>{\r\n         *   name: 'x',\r\n         *   withLabel: false,\r\n         *   label: {\r\n         *       position: '50% right',\r\n         *       offset: [0, -30],\r\n         *       fontsize: 15\r\n         *   },\r\n         *   strokeWidth: 1,\r\n         *   lastArrow: false,\r\n         *   ticks3d: {\r\n         *       label: {\r\n         *           anchorX: 'middle',\r\n         *       }\r\n         *   }\r\n         *}\r\n         *</pre>\r\n         */\r\n        yAxisBorder: {\r\n            name: 'y',\r\n            visible: 'ìnherit',\r\n            withLabel: false,\r\n            label: {\r\n                position: '50% right',\r\n                offset: [0, -30],\r\n                fontsize: 15\r\n            },\r\n            strokeWidth: 1,\r\n            lastArrow: false,\r\n            ticks3d: {\r\n                visible: 'ìnherit',\r\n                label: {\r\n                    anchorX: 'middle'\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Attributes of the 3D z-axis at the border.\r\n         *\r\n         * @type Line3D\r\n         * @name View3D#zAxisBorder\r\n         * @see View3D#axesPosition\r\n         * @default <pre>{\r\n         *   name: 'z',\r\n         *   withLabel: false,\r\n         *   label: {\r\n         *       position: '50% right',\r\n         *       offset: [30, 0],\r\n         *       fontsize: 15\r\n         *   },\r\n         *   strokeWidth: 1,\r\n         *   lastArrow: false,\r\n         *   ticks3d: {\r\n         *       label: {\r\n         *           anchorX: 'middle',\r\n         *           anchorY: 'middle'\r\n         *       }\r\n         *   }\r\n         *}\r\n         *</pre>\r\n         */\r\n        zAxisBorder: {\r\n            name: 'z',\r\n            visible: 'ìnherit',\r\n            withLabel: false,\r\n            label: {\r\n                position: '50% right',\r\n                offset: [30, 0],\r\n                fontsize: 15\r\n            },\r\n            strokeWidth: 1,\r\n            lastArrow: false,\r\n            ticks3d: {\r\n                visible: 'ìnherit',\r\n                label: {\r\n                    anchorX: 'middle',\r\n                    anchorY: 'middle'\r\n                }\r\n            }\r\n        },\r\n\r\n        // Planes\r\n        /**\r\n         * Attributes of the 3D plane orthogonal to the x-axis at the \"rear\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#xPlaneRear\r\n         */\r\n        xPlaneRear: {\r\n            visible: true,\r\n            layer: 0,\r\n            strokeWidth: 1,\r\n            strokeColor: '#dddddd',\r\n            fillColor: '#dddddd',\r\n            mesh3d: { layer: 1 }\r\n        },\r\n\r\n        /**\r\n         * Attributes of the 3D plane orthogonal to the y-axis at the \"rear\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#yPlaneRear\r\n         */\r\n        yPlaneRear: {\r\n            visible: true,\r\n            strokeWidth: 1,\r\n            strokeColor: '#dddddd',\r\n            fillColor: '#dddddd',\r\n            layer: 0,\r\n            mesh3d: { layer: 1 }\r\n        },\r\n\r\n        /**\r\n         * Attributes of the 3D plane orthogonal to the z-axis at the \"rear\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#zPlaneRear\r\n         */\r\n        zPlaneRear: {\r\n            visible: true,\r\n            strokeWidth: 1,\r\n            strokeColor: '#dddddd',\r\n            fillColor: '#dddddd',\r\n            layer: 0,\r\n            mesh3d: { layer: 1 }\r\n        },\r\n\r\n        /**\r\n         * Attributes of the 3D plane orthogonal to the x-axis at the \"front\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#xPlaneFront\r\n         */\r\n        xPlaneFront: {\r\n            visible: false,\r\n            strokeWidth: 1,\r\n            strokeColor: '#dddddd',\r\n            fillColor: '#dddddd',\r\n            layer: 0,\r\n            mesh3d: { layer: 1 }\r\n        },\r\n        /**\r\n         * Attributes of the 3D plane orthogonal to the y-axis at the \"front\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#yPlaneFront\r\n         */\r\n        yPlaneFront: {\r\n            visible: false,\r\n            strokeWidth: 1,\r\n            strokeColor: '#dddddd',\r\n            fillColor: '#dddddd',\r\n            layer: 0,\r\n            mesh3d: { layer: 1 }\r\n        },\r\n        /**\r\n         * Attributes of the 3D plane orthogonal to the z-axis at the \"front\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#zPlaneFront\r\n         */\r\n        zPlaneFront: {\r\n            visible: false,\r\n            strokeWidth: 1,\r\n            strokeColor: '#dddddd',\r\n            fillColor: '#dddddd',\r\n            layer: 0,\r\n            mesh3d: { layer: 1 }\r\n        },\r\n\r\n        // Axes on the planes\r\n        /**\r\n         * Attributes of the 3D y-axis on the 3D plane orthogonal to the x-axis at the \"rear\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#xPlaneRearYAxis\r\n         */\r\n        xPlaneRearYAxis: {\r\n            visible: 'inherit',\r\n            strokeColor: \"#888888\",\r\n            strokeWidth: 1\r\n        },\r\n        /**\r\n         * Attributes of the 3D z-axis on the 3D plane orthogonal to the x-axis at the \"rear\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#xPlaneRearZAxis\r\n         */\r\n        xPlaneRearZAxis: {\r\n            visible: 'inherit',\r\n            strokeColor: \"#888888\",\r\n            strokeWidth: 1\r\n        },\r\n        /**\r\n         * Attributes of the 3D y-axis on the 3D plane orthogonal to the x-axis at the \"front\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#xPlaneFrontYAxis\r\n         */\r\n        xPlaneFrontYAxis: {\r\n            visible: 'inherit',\r\n            strokeColor: \"#888888\",\r\n            strokeWidth: 1\r\n        },\r\n        /**\r\n         * Attributes of the 3D z-axis on the 3D plane orthogonal to the x-axis at the \"front\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#xPlaneFrontZAxis\r\n         */\r\n        xPlaneFrontZAxis: {\r\n            visible: 'inherit',\r\n            strokeColor: \"#888888\",\r\n            strokeWidth: 1\r\n        },\r\n\r\n        /**\r\n         * Attributes of the 3D x-axis on the 3D plane orthogonal to the y-axis at the \"rear\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#yPlaneRearXAxis\r\n         */\r\n        yPlaneRearXAxis: {\r\n            visible: 'inherit',\r\n            strokeColor: \"#888888\",\r\n            strokeWidth: 1\r\n        },\r\n        /**\r\n         * Attributes of the 3D z-axis on the 3D plane orthogonal to the y-axis at the \"rear\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#yPlaneRearZAxis\r\n         */\r\n        yPlaneRearZAxis: {\r\n            visible: 'inherit',\r\n            strokeColor: \"#888888\",\r\n            strokeWidth: 1\r\n        },\r\n        /**\r\n         * Attributes of the 3D x-axis on the 3D plane orthogonal to the y-axis at the \"front\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#yPlaneFrontXAxis\r\n         */\r\n        yPlaneFrontXAxis: {\r\n            visible: 'inherit',\r\n            strokeColor: \"#888888\",\r\n            strokeWidth: 1\r\n        },\r\n        /**\r\n         * Attributes of the 3D z-axis on the 3D plane orthogonal to the y-axis at the \"front\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#yPlaneFrontZAxis\r\n         */\r\n        yPlaneFrontZAxis: {\r\n            visible: 'inherit',\r\n            strokeColor: \"#888888\",\r\n            strokeWidth: 1\r\n        },\r\n\r\n        /**\r\n         * Attributes of the 3D x-axis on the 3D plane orthogonal to the z-axis at the \"rear\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#zPlaneRearXAxis\r\n         */\r\n        zPlaneRearXAxis: {\r\n            visible: 'inherit',\r\n            strokeColor: \"#888888\",\r\n            strokeWidth: 1\r\n        },\r\n        /**\r\n         * Attributes of the 3D y-axis on the 3D plane orthogonal to the z-axis at the \"rear\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#zPlaneRearYAxis\r\n         */\r\n        zPlaneRearYAxis: {\r\n            visible: 'inherit',\r\n            strokeColor: \"#888888\",\r\n            strokeWidth: 1\r\n        },\r\n        /**\r\n         * Attributes of the 3D x-axis on the 3D plane orthogonal to the z-axis at the \"front\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#zPlaneFrontXAxis\r\n         */\r\n        zPlaneFrontXAxis: {\r\n            visible: 'inherit',\r\n            strokeColor: \"#888888\",\r\n            strokeWidth: 1\r\n        },\r\n        /**\r\n         * Attributes of the 3D y-axis on the 3D plane orthogonal to the z-axis at the \"front\" of the cube.\r\n         * @type Plane3D\r\n         * @name View3D#zPlaneFrontYAxis\r\n         */\r\n        zPlaneFrontYAxis: {\r\n            visible: 'inherit',\r\n            strokeColor: \"#888888\",\r\n            strokeWidth: 1\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    axis3d: {\r\n        highlight: false,\r\n        fixed: true,\r\n        strokeColor: \"black\",\r\n        strokeWidth: 1,\r\n        tabindex: null,\r\n\r\n        point1: { visible: false, name: \"\", withLabel: false },\r\n        point2: { visible: false, name: \"\", withLabel: false, label: { visible: true } }\r\n    },\r\n\r\n    circle3d: {\r\n\r\n        layer: 12,\r\n        point: { visible: false, name: \"\" },\r\n        needsRegularUpdate: true\r\n\r\n    },\r\n\r\n    curve3d: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        layer: 12,\r\n        highlight: false,\r\n        tabindex: -1,\r\n        strokeWidth: 1,\r\n        numberPointsHigh: 200,\r\n        needsRegularUpdate: true\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    face3d: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        transitionProperties: [],\r\n        layer: 12,\r\n        highlight: false,\r\n        tabindex: null,\r\n        strokeWidth: 1,\r\n        fillColor: JXG.palette.yellow,\r\n        fillOpacity: 0.4,\r\n        needsRegularUpdate: true,\r\n\r\n        /**\r\n         * Shading of faces. For this, the HSL color scheme is used.\r\n         * Two types are possible: either by 'angle' or by 'zIndex'.\r\n         * By default (i.e. type:'angle'), the angle between the camera axis and the normal of the\r\n         * face determines the lightness value of the HSL color. Otherwise, the\r\n         * zIndex of the face determines the lightness value of the HSL color.\r\n         *\r\n         * @type Object\r\n         * @name Face3D#shader\r\n         * @see View3D#depthOrder\r\n         * @default <pre>{\r\n         *  enabled: false,\r\n         *  type: 'angle',   // 'angle', otherwise zIndex\r\n         *  hue: 60,         // yellow\r\n         *  saturation: 90,\r\n         *  minLightness: 30,\r\n         *  maxLightness: 90\r\n         * }</pre>\r\n         *\r\n         * @example\r\n         *         var view = board.create(\r\n         *             'view3d',\r\n         *             [[-5, -3], [8, 8],\r\n         *             [[-3, 3], [-3, 3], [-3, 3]]],\r\n         *             {\r\n         *                 projection: 'central',\r\n         *                 trackball: { enabled: true },\r\n         *                 depthOrder: {\r\n         *                     enabled: true\r\n         *                 },\r\n         *                 xPlaneRear: { visible: false },\r\n         *                 yPlaneRear: { visible: false },\r\n         *                 zPlaneRear: { fillOpacity: 0.2, visible: true }\r\n         *             }\r\n         *         );\r\n         *\r\n         *         let rho = 1.6180339887;\r\n         *         let vertexList = [\r\n         *             [0, -1, -rho], [0, +1, -rho], [0, -1, rho], [0, +1, rho],\r\n         *             [1, rho, 0], [-1, rho, 0], [1, -rho, 0], [-1, -rho, 0],\r\n         *             [-rho, 0, 1], [-rho, 0, -1], [rho, 0, 1], [rho, 0, -1]\r\n         *         ];\r\n         *         let faceArray = [\r\n         *             [4, 1, 11],\r\n         *             [11, 1, 0],\r\n         *             [6, 11, 0],\r\n         *             [0, 1, 9],\r\n         *             [11, 10, 4],\r\n         *             [9, 1, 5],\r\n         *             [8, 9, 5],\r\n         *             [5, 3, 8],\r\n         *             [6, 10, 11],\r\n         *             [2, 3, 10],\r\n         *             [2, 10, 6],\r\n         *             [8, 3, 2],\r\n         *             [3, 4, 10],\r\n         *             [7, 8, 2],\r\n         *             [9, 8, 7],\r\n         *             [0, 9, 7],\r\n         *             [4, 3, 5],\r\n         *             [5, 1, 4],\r\n         *             [0, 7, 6],\r\n         *             [7, 2, 6]\r\n         *         ];\r\n         *         var ico = view.create('polyhedron3d', [vertexList, faceArray], {\r\n         *             fillColorArray: [],\r\n         *             fillOpacity: 1,\r\n         *             strokeWidth: 0.1,\r\n         *             layer: 12,\r\n         *             shader: {\r\n         *                 enabled: true,\r\n         *                 type: 'angle',\r\n         *                 hue: 0,\r\n         *                 saturation: 90,\r\n         *                 minlightness: 60,\r\n         *                 maxLightness: 80\r\n         *             }\r\n         *         });\r\n         *\r\n         * </pre><div id=\"JXGbf32b040-affb-4e03-a05b-abfe953f614d\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGbf32b040-affb-4e03-a05b-abfe953f614d',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false,\r\n         *                pan: {enabled: false}, zoom: {enabled: false}});\r\n         *             var view = board.create(\r\n         *                 'view3d',\r\n         *                 [[-5, -3], [8, 8],\r\n         *                 [[-3, 3], [-3, 3], [-3, 3]]],\r\n         *                 {\r\n         *                     projection: 'central',\r\n         *                     trackball: { enabled: true },\r\n         *                     depthOrder: {\r\n         *                         enabled: true\r\n         *                     },\r\n         *                     xPlaneRear: { visible: false },\r\n         *                     yPlaneRear: { visible: false },\r\n         *                     zPlaneRear: { fillOpacity: 0.2, visible: true }\r\n         *                 }\r\n         *             );\r\n         *\r\n         *             let rho = 1.6180339887;\r\n         *             let vertexList = [\r\n         *                 [0, -1, -rho], [0, +1, -rho], [0, -1, rho], [0, +1, rho],\r\n         *                 [1, rho, 0], [-1, rho, 0], [1, -rho, 0], [-1, -rho, 0],\r\n         *                 [-rho, 0, 1], [-rho, 0, -1], [rho, 0, 1], [rho, 0, -1]\r\n         *             ];\r\n         *             let faceArray = [\r\n         *                 [4, 1, 11],\r\n         *                 [11, 1, 0],\r\n         *                 [6, 11, 0],\r\n         *                 [0, 1, 9],\r\n         *                 [11, 10, 4],\r\n         *                 [9, 1, 5],\r\n         *                 [8, 9, 5],\r\n         *                 [5, 3, 8],\r\n         *                 [6, 10, 11],\r\n         *                 [2, 3, 10],\r\n         *                 [2, 10, 6],\r\n         *                 [8, 3, 2],\r\n         *                 [3, 4, 10],\r\n         *                 [7, 8, 2],\r\n         *                 [9, 8, 7],\r\n         *                 [0, 9, 7],\r\n         *                 [4, 3, 5],\r\n         *                 [5, 1, 4],\r\n         *                 [0, 7, 6],\r\n         *                 [7, 2, 6]\r\n         *             ];\r\n         *             var ico = view.create('polyhedron3d', [vertexList, faceArray], {\r\n         *                 fillColorArray: [],\r\n         *                 fillOpacity: 1,\r\n         *                 strokeWidth: 0.1,\r\n         *                 layer: 12,\r\n         *                 shader: {\r\n         *                     enabled: true,\r\n         *                     type: 'angle',\r\n         *                     hue: 0,\r\n         *                     saturation: 90,\r\n         *                     minlightness: 60,\r\n         *                     maxLightness: 80\r\n         *                 }\r\n         *             });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        shader: {\r\n            enabled: false,\r\n            type: 'angle',   // 'angle', otherwise zIndex\r\n            hue: 60,         // yellow\r\n            saturation: 90,\r\n            minLightness: 30,\r\n            maxLightness: 90\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    intersectionline3d: {\r\n        point1: { visible: false, name: \"\" }, // Used in point/point\r\n        point2: { visible: false, name: \"\" }\r\n    },\r\n\r\n    line3d: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        layer: 12,\r\n        strokeWidth: 1,\r\n        strokeColor: \"black\",\r\n        fixed: true,\r\n        tabindex: null,\r\n        // gradient: \"linear\",\r\n        // gradientSecondColor: \"#ffffff\",\r\n        needsRegularUpdate: true,\r\n\r\n        /**\r\n         * Attributes of the defining point in case the line is defined by [point, vector, [range]]\r\n         * @type Point3D\r\n         * @name Line3D#point\r\n         * @default <pre>visible: false, name: \"\"</pre>\r\n         */\r\n        point: { visible: false, name: \"\" }, // Used in cases of point/direction/range\r\n\r\n        /**\r\n         * Attributes of the first point in case the line is defined by [point, point].\r\n         * @type Point3D\r\n         * @name Line3D#point1\r\n         * @default <pre>visible: false, name: \"\"</pre>\r\n         */\r\n        point1: { visible: false, name: \"\" }, // Used in point/point\r\n\r\n        /**\r\n         * Attributes of the second point in case the line is defined by [point, point].\r\n         * @type Point3D\r\n         * @name Line3D#point2\r\n         * @default <pre>visible: false, name: \"\"</pre>\r\n         */\r\n        point2: { visible: false, name: \"\" },\r\n\r\n        /**\r\n         * If the 3D line is defined by two points and if this attribute is true,\r\n         * the 3D line stretches infinitely in direction of its first point.\r\n         * Otherwise it ends at point1.\r\n         *\r\n         * @name Line3D#straightFirst\r\n         * @see Line3D#straightLast\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        straightFirst: false,\r\n\r\n\r\n        /**\r\n         * If the 3D line is defined by two points and if this attribute is true,\r\n         * the 3D line stretches infinitely in direction of its second point.\r\n         * Otherwise it ends at point2.\r\n         *\r\n         * @name Line3D#straightLast\r\n         * @see Line3D#straightFirst\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        straightLast: false\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    mesh3d: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        layer: 12,\r\n        strokeWidth: 1,\r\n        strokeColor: \"#9a9a9a\",\r\n        strokeOpacity: 0.6,\r\n        highlight: false,\r\n        tabindex: null,\r\n        needsRegularUpdate: true,\r\n\r\n        /**\r\n         * Step width of the mesh in the direction of the first spanning vector.\r\n         * @type {Number}\r\n         * @name Mesh3D#stepWidthU\r\n         * @default 1\r\n         *\r\n         */\r\n        stepWidthU: 1,\r\n\r\n        /**\r\n         * Step width of the mesh in the direction of the second spanning vector.\r\n         *\r\n         * @type {Number}\r\n         * @name Mesh3D#stepWidthV\r\n         * @default 1\r\n         *\r\n         */\r\n        stepWidthV: 1\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    plane3d: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        layer: 12,\r\n        strokeWidth: 0,\r\n        strokeColor: \"black\",\r\n        strokeOpacity: 1,\r\n        highlight: false,\r\n        tabindex: null,\r\n        needsRegularUpdate: true,\r\n        visible: true,\r\n\r\n        gradient: \"linear\",\r\n        gradientSecondColor: \"#ffffff\",\r\n        gradientAngle: Math.PI,\r\n        fillColor: \"#a7a7a7\",\r\n        fillOpacity: 0.6,\r\n\r\n        /**\r\n         * Optional 3D mesh of a finite plane.\r\n         * It is not available if the plane is infinite (at initialization time) in any direction.\r\n         *\r\n         * @type Mesh3D\r\n         * @name Plane3D#mesh3d\r\n         * @default see {@link Mesh3D}\r\n         */\r\n        mesh3d: {\r\n            visible: 'inherit'\r\n        },\r\n\r\n        /**\r\n         * If the second parameter and the third parameter are given as arrays or functions and threePoints:true\r\n         * then the second and third parameter are interpreted as point coordinates and not as directions, i.e.\r\n         * the plane is defined by three points.\r\n         *\r\n         * @name Plane3D#threePoints\r\n         * @type Boolean\r\n         * @default false\r\n         */\r\n        threePoints: false,\r\n\r\n        /**\r\n         * Attributes of the defining point in case the plane is defined by [point, direction1, direction2, [range1, [range2]]].\r\n         * @type Point3D\r\n         * @name Plane3D#point\r\n         * @default <pre>visible: false, name: \"\", fixed: true</pre>\r\n         */\r\n        point: { visible: false, name: \"\", fixed: true },\r\n\r\n        /**\r\n         * Attributes of the first point in case the plane is defined by [point, point, point].\r\n         * @type Point3D\r\n         * @name Plane3D#point1\r\n         * @default <pre>visible: false, name: \"\"</pre>\r\n         */\r\n        point1: { visible: false, name: \"\" }, // Used in point/point/point\r\n\r\n        /**\r\n         * Attributes of the second point in case the plane is defined by [point, point, point].\r\n         * @type Point3D\r\n         * @name Plane3D#point2\r\n         * @default <pre>visible: false, name: \"\"</pre>\r\n         */\r\n        point2: { visible: false, name: \"\" }, // Used in point/point/point\r\n\r\n        /**\r\n         * Attributes of the third point in case the plane is defined by [point, point, point].\r\n         * @type Point3D\r\n         * @name Plane3D#point3\r\n         * @default <pre>visible: false, name: \"\"</pre>\r\n         */\r\n        point3: { visible: false, name: \"\" } // Used in point/point/point\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    point3d: {\r\n        layer: 13,\r\n        infoboxDigits: \"auto\",\r\n        strokeWidth: 0,\r\n        gradient: \"radial\",\r\n        gradientSecondColor: \"#555555\",\r\n        fillColor: \"yellow\",\r\n        highlightStrokeColor: \"#555555\",\r\n        gradientFX: 0.7,\r\n        gradientFY: 0.3,\r\n        needsRegularUpdate: true\r\n    },\r\n\r\n    polygon3d: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        layer: 12,\r\n        highlight: false,\r\n        tabindex: -1,\r\n        strokeWidth: 1,\r\n        fillColor: 'none',\r\n        needsRegularUpdate: true\r\n\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    polyhedron3d: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Color array to define fill colors of faces cyclically.\r\n         * Alternatively, the fill color can be defined for each face individually.\r\n         *\r\n         * @type Array\r\n         * @name Polyhedron3D#fillColorArray\r\n         * @default ['white', 'black']\r\n         */\r\n        fillColorArray: ['white', 'black'],\r\n\r\n        needsRegularUpdate: true\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    sphere3d: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        layer: 12,\r\n        highlight: false,\r\n\r\n        strokeWidth: 1,\r\n        strokeColor: '#00ff80',\r\n        fillColor: 'white',\r\n        gradient: 'radial',\r\n        gradientSecondColor: '#00ff80',\r\n        gradientFX: 0.7,\r\n        gradientFY: 0.3,\r\n        fillOpacity: 0.4,\r\n        needsRegularUpdate: true\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    surface3d: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        layer: 12,\r\n        highlight: false,\r\n        tabindex: -1,\r\n        strokeWidth: 1,\r\n\r\n        /**\r\n         * Number of intervals the mesh is divided into in direction of parameter u.\r\n         * @type Number\r\n         * @name ParametricSurface3D#stepsU\r\n         */\r\n        stepsU: 30,\r\n\r\n        /**\r\n         * Number of intervals the mesh is divided into in direction of parameter v.\r\n         * @type Number\r\n         * @name ParametricSurface3D#stepsV\r\n         */\r\n        stepsV: 30,\r\n\r\n        needsRegularUpdate: true\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    text3d: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        withLabel: false,\r\n        needsRegularUpdate: true\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    ticks3d: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        visible: true,\r\n\r\n        ticksDistance: 1,\r\n        majorHeight: 10,\r\n        minorTicks: 0,\r\n        tickEndings: [0, 1],\r\n        drawLabels: true,\r\n        needsRegularUpdate: true,\r\n\r\n        label: {\r\n            visible: true,\r\n            withLabel: false\r\n        }\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    vectorfield3d: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        /**\r\n         * Scaling factor of the vectors. This in contrast to slope fields, where this attribute sets the vector to the given length.\r\n         * @name scale\r\n         * @memberOf Vectorfield3D.prototype\r\n         * @type {Number|Function}\r\n         * @see Slopefield.scale\r\n         * @default 1\r\n         */\r\n        scale: 1,\r\n\r\n        /**\r\n         * Customize arrow heads of vectors. Be careful! If enabled this will slow down the performance.\r\n         * Fields are:\r\n         * <ul>\r\n         *  <li> enabled: Boolean\r\n         *  <li> size: length of the arrow head legs (in pixel)\r\n         *  <li> angle: angle of the arrow head legs In radians.\r\n         * </ul>\r\n         * @name arrowhead\r\n         * @memberOf Vectorfield3D.prototype\r\n         * @type {Object}\r\n         * @default <tt>{enabled: true, size: 5, angle: Math.PI * 0.125}</tt>\r\n         */\r\n        arrowhead: {\r\n            enabled: true,\r\n            size: 5,\r\n            angle: Math.PI * 0.125\r\n        },\r\n        needsRegularUpdate: true\r\n\r\n        /**#@-*/\r\n    },\r\n\r\n    view3d: {\r\n        /**#@+\r\n         * @visprop\r\n         */\r\n\r\n        needsRegularUpdate: true,\r\n\r\n        /**\r\n         * When this attribute is enabled, elements closer to the screen are drawn\r\n         * over elements further from the screen within the 3D layer. This affects\r\n         * all elements which are in one of the layer specified in the sub-attribute 'layers'.\r\n         * <p>\r\n         * For each layer this depth ordering is done independently.\r\n         * Sub-attributes:\r\n         *      <ul>\r\n         *          <li><tt>enabled</tt>: false/true\r\n         *          <li><tt>layers</tt>: [12, 13]\r\n         *      </ul>\r\n         *\r\n         * @name View3D#depthOrder\r\n         * @type Object\r\n         * @default <pre>{\r\n         *   enabled: false,\r\n         *   layers: [12, 13]\r\n         * }\r\n         * </pre>\r\n         */\r\n        depthOrder: {\r\n            enabled: false,\r\n            layers: [12, 13]\r\n        },\r\n\r\n        /**\r\n         * Choose the projection type to be used: `parallel` or `central`.\r\n         * <ul>\r\n         * <li> `parallel` is parallel projection, also called orthographic projection\r\n         * <li> `central` is central projection, also called perspective projection\r\n         * </ul>\r\n         *\r\n         *\r\n         * @name View3D#projection\r\n         * @type String\r\n         * @default 'parallel'\r\n         * @example\r\n         *         var bound = [-5, 5];\r\n         *         var view = board.create('view3d',\r\n         *             [[-6, -3], [8, 8],\r\n         *             [bound, bound, bound]],\r\n         *             {\r\n         *                 projection: 'parallel'\r\n         *             });\r\n         *\r\n         * </pre><div id=\"JXG80d81b13-c604-4841-bdf6-62996440088a\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG80d81b13-c604-4841-bdf6-62996440088a',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n         *             var bound = [-5, 5];\r\n         *             var view = board.create('view3d',\r\n         *                 [[-6, -3], [8, 8],\r\n         *                 [bound, bound, bound]],\r\n         *                 {\r\n         *                     projection: 'parallel'\r\n         *                 });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         * @example\r\n         *         var bound = [-5, 5];\r\n         *         var view = board.create('view3d',\r\n         *             [[-6, -3], [8, 8],\r\n         *             [bound, bound, bound]],\r\n         *             {\r\n         *                 projection: 'central'\r\n         *             });\r\n         *\r\n         * </pre><div id=\"JXGdb7b7c99-631c-41d0-99bf-c0a8d0138218\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGdb7b7c99-631c-41d0-99bf-c0a8d0138218',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n         *             var bound = [-5, 5];\r\n         *             var view = board.create('view3d',\r\n         *                 [[-6, -3], [8, 8],\r\n         *                 [bound, bound, bound]],\r\n         *                 {\r\n         *                     projection: 'central'\r\n         *                 });\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        projection: 'parallel',\r\n\r\n        /**\r\n         * Allow vertical dragging of objects, i.e. in direction of the z-axis.\r\n         * Subobjects are\r\n         * <ul>\r\n         *  <li>enabled: true\r\n         *  <li>key: 'shift'\r\n         * </ul>\r\n         * <p>\r\n         * Possible values for attribute <i>key</i>: 'shift' or 'ctrl'.\r\n         *\r\n         * @name View3D#verticalDrag\r\n         * @type Object\r\n         * @default <tt>{enabled: true, key: 'shift'}</tt>\r\n         */\r\n        verticalDrag: {\r\n            enabled: true,\r\n            key: 'shift'\r\n        },\r\n\r\n        /**\r\n         * Specify the user handling of the azimuth.\r\n         * <ul>\r\n         *  <li><tt>pointer</tt> sub-attributes:\r\n         *      <ul>\r\n         *          <li><tt>enabled</tt>: Boolean that specifies whether pointer navigation is allowed by azimuth.\r\n         *          <li><tt>speed</tt>: Number indicating how many passes the range of the az_slider makes when the cursor crosses the entire board once in the horizontal direction.\r\n         *          <li><tt>outside</tt>: Boolean that specifies whether the pointer navigation is continued when the cursor leaves the board.\r\n         *          <li><tt>button</tt>: Which button of the pointer should be used? (<tt>'-1'</tt> (=no button), <tt>'0'</tt> or <tt>'2'</tt>)\r\n         *          <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)\r\n         *      </ul>\r\n         *  <li><tt>keyboard</tt> sub-attributes:\r\n         *      <ul>\r\n         *          <li><tt>enabled</tt>: Boolean that specifies whether the keyboard (left/right arrow keys) can be used to navigate the board.\r\n         *          <li><tt>step</tt>: Size of the step per keystroke.\r\n         *          <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)\r\n         *      </ul>\r\n         *  <li><tt>continuous</tt>: Boolean that specifies whether the az_slider starts again from the beginning when its end is reached.\r\n         *  <li><tt>slider</tt> attributes of the az_slider ({@link Slider}) with additional\r\n         *      <ul>\r\n         *          <li><tt>min</tt>: Minimum value.\r\n         *          <li><tt>max</tt>: Maximum value.\r\n         *          <li><tt>start</tt>: Start value.\r\n         *      </ul>\r\n         *      'min' and 'max' are used only if trackball is not enabled.\r\n         *     Additionally, the attributes 'slider.point1.pos' and 'slider.point2.pos' control the position of the slider. Possible\r\n         *     values are 'auto' or an array [x, y] of length 2 for the position in user coordinates (or a function returning such an array).\r\n         * </ul>\r\n         *\r\n         * @name View3D#az\r\n         * @type Object\r\n         * @default <pre>{\r\n         *      pointer: {enabled: true, speed: 1, outside: true, button: -1, key: 'none'},\r\n         *      keyboard: {enabled: true, step: 10, key: 'ctrl'},\r\n         *      continuous: true,\r\n         *      slider: {\r\n         *          visible: true,\r\n         *          style: 6,\r\n         *          point1: {\r\n         *              pos: 'auto',\r\n         *              frozen: false\r\n         *          },\r\n         *          point2: {\r\n         *              pos: 'auto',\r\n         *              frozen: false\r\n         *          },\r\n         *          min: 0,\r\n         *          max: 2 * Math.PI,\r\n         *          start: 1.0\r\n         *      },\r\n         * }</pre>\r\n         *\r\n         * @example\r\n         *     var bound = [-4, 6];\r\n         *     var view = board.create('view3d',\r\n         *         [[-4, -3], [8, 8],\r\n         *         [bound, bound, bound]],\r\n         *         {\r\n         *             projection: 'parallel',\r\n         *             az: {\r\n         *                 slider: {visible: true, start: 0.75 * Math.PI}\r\n         *             }\r\n         *         });\r\n         *\r\n         * </pre><div id=\"JXG4c381f21-f043-4419-941d-75f384c026d0\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG4c381f21-f043-4419-941d-75f384c026d0',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n         *         var bound = [-4, 6];\r\n         *         var view = board.create('view3d',\r\n         *             [[-4, -3], [8, 8],\r\n         *             [bound, bound, bound]],\r\n         *             {\r\n         *                 projection: 'parallel',\r\n         *                 az: {\r\n         *                     slider: {visible: true, start: 0.75 * Math.PI}\r\n         *                 }\r\n         *             });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        az: {\r\n            pointer: {\r\n                enabled: true,\r\n                speed: 1,\r\n                outside: true,\r\n                button: -1,\r\n                key: 'none'\r\n            },\r\n            keyboard: {\r\n                enabled: true,\r\n                step: 10,\r\n                key: 'ctrl'\r\n            },\r\n            continuous: true,\r\n            slider: {\r\n                visible: 'inherit',\r\n                style: 6,\r\n                point1: {\r\n                    pos: 'auto',\r\n                    frozen: false\r\n                },\r\n                point2: {\r\n                    pos: 'auto',\r\n                    frozen: false\r\n                },\r\n                min: 0,\r\n                max: 2 * Math.PI,\r\n                start: 1.0\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Specify the user handling of the elevation.\r\n         * <ul>\r\n         *  <li><tt>pointer</tt> sub-attributes:\r\n         *      <ul>\r\n         *          <li><tt>enabled</tt>: Boolean that specifies whether pointer navigation is allowed by elevation.\r\n         *          <li><tt>speed</tt>: Number indicating how many passes the range of the el_slider makes when the cursor crosses the entire board once in the horizontal direction.\r\n         *          <li><tt>outside</tt>: Boolean that specifies whether the pointer navigation is continued when the cursor leaves the board.\r\n         *          <li><tt>button</tt>: Which button of the pointer should be used? (<tt>'-1'</tt> (=no button), <tt>'0'</tt> or <tt>'2'</tt>)\r\n         *          <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)\r\n         *      </ul>\r\n         *  <li><tt>keyboard</tt> sub-attributes:\r\n         *      <ul>\r\n         *          <li><tt>enabled</tt>: Boolean that specifies whether the keyboard (up/down arrow keys) can be used to navigate the board.\r\n         *          <li><tt>step</tt>: Size of the step per keystroke.\r\n         *          <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)\r\n         *      </ul>\r\n         *  <li><tt>continuous</tt>: Boolean that specifies whether the el_slider starts again from the beginning when its end is reached.\r\n         *  <li><tt>slider</tt> attributes of the el_slider ({@link Slider}) with additional\r\n         *      <ul>\r\n         *          <li><tt>min</tt>: Minimum value.\r\n         *          <li><tt>max</tt>: Maximum value.\r\n         *          <li><tt>start</tt>: Start value.\r\n         *      </ul>\r\n         *     'min' and 'max' are used only if trackball is not enabled.\r\n         *     Additionally, the attributes 'slider.point1.pos' and 'slider.point2.pos' control the position of the slider. Possible\r\n         *     values are 'auto' or an array [x, y] of length 2 for the position in user coordinates (or a function returning such an array).\r\n         * </ul>\r\n         *\r\n         * @name View3D#el\r\n         * @type Object\r\n         * @default <pre>{\r\n         *      pointer: {enabled: true, speed: 1, outside: true, button: -1, key: 'none'},\r\n         *      keyboard: {enabled: true, step: 10, key: 'ctrl'},\r\n         *      continuous: true,\r\n         *      slider: {\r\n         *          visible: true,\r\n         *          style: 6,\r\n         *          point1: {\r\n         *              pos: 'auto',\r\n         *              frozen: false\r\n         *          },\r\n         *          point2: {\r\n         *              pos: 'auto',\r\n         *              frozen: false\r\n         *          },\r\n         *          min: 0,\r\n         *          max: 2 * Math.PI,\r\n         *          start: 0.3\r\n         *      },\r\n         * }<pre>\r\n         * @example\r\n         *     var bound = [-4, 6];\r\n         *     var view = board.create('view3d',\r\n         *         [[-4, -3], [8, 8],\r\n         *         [bound, bound, bound]],\r\n         *         {\r\n         *             projection: 'parallel',\r\n         *             el: {\r\n         *                 slider: {visible: true}\r\n         *             }\r\n         *         });\r\n         *\r\n         * </pre><div id=\"JXG8926f733-c42e-466b-853c-74feb795e879\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXG8926f733-c42e-466b-853c-74feb795e879',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n         *         var bound = [-4, 6];\r\n         *         var view = board.create('view3d',\r\n         *             [[-4, -3], [8, 8],\r\n         *             [bound, bound, bound]],\r\n         *             {\r\n         *                 projection: 'parallel',\r\n         *                 el: {\r\n         *                     slider: {visible: true}\r\n         *                 }\r\n         *             });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        el: {\r\n            pointer: {\r\n                enabled: true,\r\n                speed: 1,\r\n                outside: true,\r\n                button: -1,\r\n                key: 'none'\r\n            },\r\n            keyboard: {\r\n                enabled: true,\r\n                step: 10,\r\n                key: 'ctrl'\r\n            },\r\n            continuous: true,\r\n            slider: {\r\n                visible: 'inherit',\r\n                style: 6,\r\n                point1: {\r\n                    frozen: false,\r\n                    pos: 'auto'\r\n                },\r\n                point2: {\r\n                    frozen: false,\r\n                    pos: 'auto'\r\n                },\r\n                min: 0,\r\n                max: 2 * Math.PI,\r\n                start: 0.3\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Specify the user handling of the bank angle.\r\n         * <ul>\r\n         *  <li><tt>pointer</tt> sub-attributes:\r\n         *      <ul>\r\n         *          <li><tt>enabled</tt>: Boolean that specifies whether pointer navigation is allowed by elevation.\r\n         *          <li><tt>speed</tt>: Number indicating how many passes the range of the el_slider makes when the cursor crosses the entire board once in the horizontal direction.\r\n         *          <li><tt>outside</tt>: Boolean that specifies whether the pointer navigation is continued when the cursor leaves the board.\r\n         *          <li><tt>button</tt>: Which button of the pointer should be used? (<tt>'-1'</tt> (=no button), <tt>'0'</tt> or <tt>'2'</tt>)\r\n         *          <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)\r\n         *      </ul>\r\n         *  <li><tt>keyboard</tt> sub-attributes:\r\n         *      <ul>\r\n         *          <li><tt>enabled</tt>: Boolean that specifies whether the keyboard ('<', '>' keys) can be used to navigate the board.\r\n         *          <li><tt>step</tt>: Size of the step per keystroke.\r\n         *          <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)\r\n         *      </ul>\r\n         *  <li><tt>continuous</tt>: Boolean that specifies whether the el_slider starts again from the beginning when its end is reached.\r\n         *  <li><tt>slider</tt> attributes of the el_slider ({@link Slider}) with additional\r\n         *      <ul>\r\n         *          <li><tt>min</tt>: Minimum value.\r\n         *          <li><tt>max</tt>: Maximum value.\r\n         *          <li><tt>start</tt>: Start value.\r\n         *      </ul>\r\n         *      'min' and 'max' are used only if trackball is not enabled.\r\n         *     Additionally, the attributes 'slider.point1.pos' and 'slider.point2.pos' control the position of the slider. Possible\r\n         *     values are 'auto' or an array [x, y] of length 2 for the position in user coordinates (or a function returning such an array).\r\n         * </ul>\r\n         *\r\n         * @name View3D#bank\r\n         * @type Object\r\n         * @default <pre>{\r\n         *      pointer: {enabled: true, speed: 1, outside: true, button: -1, key: 'none'},\r\n         *      keyboard: {enabled: true, step: 10, key: 'ctrl'},\r\n         *      continuous: true,\r\n         *      slider: {\r\n         *          visible: true,\r\n         *          style: 6,\r\n         *          point1: {\r\n         *              pos: 'auto',\r\n         *              frozen: false\r\n         *          },\r\n         *          point2: {\r\n         *              pos: 'auto',\r\n         *              frozen: false\r\n         *          },\r\n         *          min: 0,\r\n         *          max: 2 * Math.PI,\r\n         *          start: 0.3\r\n         *      },\r\n         * }<pre>\r\n         * @example\r\n         *     var bound = [-4, 6];\r\n         *     var view = board.create('view3d',\r\n         *         [[-4, -3], [8, 8],\r\n         *         [bound, bound, bound]],\r\n         *         {\r\n         *             projection: 'parallel',\r\n         *             bank: {\r\n         *                 slider: {visible: true}\r\n         *             }\r\n         *         });\r\n         *\r\n         * </pre><div id=\"JXGb67811ea-c1e3-4d1e-b13c-3537b3436f6c\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         *         var board = JXG.JSXGraph.initBoard('JXGb67811ea-c1e3-4d1e-b13c-3537b3436f6c',\r\n         *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n         *         var bound = [-4, 6];\r\n         *         var view = board.create('view3d',\r\n         *             [[-4, -3], [8, 8],\r\n         *             [bound, bound, bound]],\r\n         *             {\r\n         *                 projection: 'parallel',\r\n         *                 bank: {\r\n         *                     slider: {visible: true}\r\n         *                 }\r\n         *             });\r\n         *\r\n         *     })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        bank: {\r\n            pointer: {\r\n                enabled: true,\r\n                speed: 0.08,\r\n                outside: true,\r\n                button: -1,\r\n                key: 'none'\r\n            },\r\n            keyboard: {\r\n                enabled: true,\r\n                step: 10,\r\n                key: 'ctrl'\r\n            },\r\n            continuous: true,\r\n            slider: {\r\n                visible: 'inherit',\r\n                style: 6,\r\n                point1: {\r\n                    frozen: false,\r\n                    pos: 'auto'\r\n                },\r\n                point2: {\r\n                    frozen: false,\r\n                    pos: 'auto'\r\n                },\r\n                min: -Math.PI,\r\n                max:  Math.PI,\r\n                start: 0.0\r\n            }\r\n        },\r\n\r\n        /**\r\n         * Enable user handling by a virtual trackball that allows to move the 3D scene\r\n         * with 3 degrees of freedom. If not enabled, direct user dragging (i.e. in the JSXGraph board, not manipulating the sliders) will only have\r\n         * two degrees of freedom. This means, the z-axis will always be projected to a vertical 2D line.\r\n         * <p>\r\n         * Sub-attributes:\r\n         *      <ul>\r\n         *          <li><tt>enabled</tt>: Boolean that specifies whether pointer navigation is allowed by elevation.\r\n         *          <li><tt>outside</tt>: Boolean that specifies whether the pointer navigation is continued when the cursor leaves the board.\r\n         *          <li><tt>button</tt>: Which button of the pointer should be used? (<tt>'-1'</tt> (=no button), <tt>'0'</tt> or <tt>'2'</tt>)\r\n         *          <li><tt>key</tt>: Should an additional key be pressed? (<tt>'none'</tt>, <tt>'shift'</tt> or <tt>'ctrl'</tt>)\r\n         *      </ul>\r\n         *\r\n         * @name View3D#trackball\r\n         * @type Object\r\n         * @default <pre>{\r\n         *   enabled: false,\r\n         *   outside: true,\r\n         *   button: -1,\r\n         *   key: 'none'\r\n         * }\r\n         * </pre>\r\n         */\r\n        trackball: {\r\n            enabled: false,\r\n            outside: true,\r\n            button: -1,\r\n            key: 'none'\r\n        },\r\n\r\n        /**\r\n         * Distance of the camera to the center of the view.\r\n         * If set to 'auto', r will be calculated automatically.\r\n         *\r\n         * @type {Number|String}\r\n         * @default 'auto'\r\n         */\r\n        r: 'auto',\r\n\r\n        /**\r\n         * Field of View defines the angle of view (in radians) of the camera, determining how much of the scene is captured within the frame.\r\n         *\r\n         * @type Number\r\n         * @default 2/5*Math.PI\r\n         */\r\n        fov: 1 / 5 * 2 * Math.PI,\r\n\r\n        /**\r\n         * Fixed values for the view, which can be changed using keyboard keys `picture-up` and `picture-down`.\r\n         * Array of the form: [[el0, az0, r0], [el1, az1, r1, ...[eln, azn, rn]]\r\n         *\r\n         * @name View3D#values\r\n         * @type Array\r\n         * @default <tt>{[[0, 1.57], [0.78, 0.62], [0, 0], [5.49, 0.62], [4.71, 0], [3.93, 0.62], [3.14, 0], [2.36, 0.62], [1.57, 1.57]]}<tt>\r\n         */\r\n        values: [\r\n            [0, 1.57],\r\n            [0.78, 0.62],\r\n            [0, 0],\r\n            [5.49, 0.62],\r\n            [4.71, 0],\r\n            [3.93, 0.62],\r\n            [3.14, 0],\r\n            [2.36, 0.62],\r\n            [1.57, 1.57]\r\n        ],\r\n\r\n        infobox: {\r\n            // strokeColor: '#888888',\r\n            strokeColor: '#000000',\r\n            fontSize: 16,\r\n            useKatex: false,\r\n            useMathjax: false,\r\n            intl: {\r\n                enabled: true,\r\n                options: {\r\n                    minimumFractionDigits: 2,\r\n                    maximumFractionDigits: 3\r\n                }\r\n            }\r\n        },\r\n\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        _currentView: -1\r\n\r\n        /**#@-*/\r\n    }\r\n});\r\n\r\nexport default JXG.Options;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*\r\n    Some functionalities in this file were developed as part of a software project\r\n    with students. We would like to thank all contributors for their help:\r\n\r\n    Winter semester 2023/2024:\r\n        Lars Hofmann\r\n        Leonhard Iser\r\n        Vincent Kulicke\r\n        Laura Rinas\r\n */\r\n\r\n/*global JXG:true, define: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Coords from \"../base/coords.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Numerics from \"../math/numerics.js\";\r\nimport Env from \"../utils/env.js\";\r\nimport GeometryElement from \"../base/element.js\";\r\nimport Composition from \"../base/composition.js\";\r\n\r\n/**\r\n * 3D view inside a JXGraph board.\r\n *\r\n * @class Creates a new 3D view. Do not use this constructor to create a 3D view. Use {@link JXG.Board#create} with\r\n * type {@link View3D} instead.\r\n *\r\n * @augments JXG.GeometryElement\r\n * @param {Array} parents Array consisting of lower left corner [x, y] of the view inside the board, [width, height] of the view\r\n * and box size [[x1, x2], [y1,y2], [z1,z2]]. If the view's azimuth=0 and elevation=0, the 3D view will cover a rectangle with lower left corner\r\n * [x,y] and side lengths [w, h] of the board.\r\n */\r\nJXG.View3D = function (board, parents, attributes) {\r\n    this.constructor(board, attributes, Const.OBJECT_TYPE_VIEW3D, Const.OBJECT_CLASS_3D);\r\n\r\n    /**\r\n     * An associative array containing all geometric objects belonging to the view.\r\n     * Key is the id of the object and value is a reference to the object.\r\n     * @type Object\r\n     * @private\r\n     */\r\n    this.objects = {};\r\n\r\n    /**\r\n     * An array containing all the elements in the view that are sorted due to their depth order.\r\n     * @Type Object\r\n     * @private\r\n     */\r\n    this.depthOrdered = {};\r\n\r\n    /**\r\n     * TODO: why deleted?\r\n     * An array containing all geometric objects in this view in the order of construction.\r\n     * @type Array\r\n     * @private\r\n     */\r\n    // this.objectsList = [];\r\n\r\n    /**\r\n     * An associative array / dictionary to store the objects of the board by name. The name of the object is the key and value is a reference to the object.\r\n     * @type Object\r\n     * @private\r\n     */\r\n    this.elementsByName = {};\r\n\r\n    /**\r\n     * Default axes of the 3D view, contains the axes of the view or null.\r\n     *\r\n     * @type {Object}\r\n     * @default null\r\n     */\r\n    this.defaultAxes = null;\r\n\r\n    /**\r\n     * The Tait-Bryan angles specifying the view box orientation\r\n     */\r\n    this.angles = {\r\n        az: null,\r\n        el: null,\r\n        bank: null\r\n    };\r\n\r\n    /**\r\n     * @type {Array}\r\n     * The view box orientation matrix\r\n     */\r\n    this.matrix3DRot = [\r\n        [1, 0, 0, 0],\r\n        [0, 1, 0, 0],\r\n        [0, 0, 1, 0],\r\n        [0, 0, 0, 1]\r\n    ];\r\n\r\n    // Used for z-index computation\r\n    this.matrix3DRotShift = [\r\n        [1, 0, 0, 0],\r\n        [0, 1, 0, 0],\r\n        [0, 0, 1, 0],\r\n        [0, 0, 0, 1]\r\n    ];\r\n\r\n    /**\r\n     * @type  {Array}\r\n     * @private\r\n     */\r\n    // 3D-to-2D transformation matrix\r\n    this.matrix3D = [\r\n        [1, 0, 0, 0],\r\n        [0, 1, 0, 0],\r\n        [0, 0, 1, 0]\r\n    ];\r\n\r\n    /**\r\n     * The 4×4 matrix that maps box coordinates to camera coordinates. These\r\n     * coordinate systems fit into the View3D coordinate atlas as follows.\r\n     * <ul>\r\n     * <li><b>World coordinates.</b> The coordinates used to specify object\r\n     * positions in a JSXGraph scene.</li>\r\n     * <li><b>Box coordinates.</b> The world coordinates translated to put the\r\n     * center of the view box at the origin.\r\n     * <li><b>Camera coordinates.</b> The coordinate system where the\r\n     * <code>x</code>, <code>y</code> plane is the screen, the origin is the\r\n     * center of the screen, and the <code>z</code> axis points out of the\r\n     * screen, toward the viewer.\r\n     * <li><b>Focal coordinates.</b> The camera coordinates translated to put\r\n     * the origin at the focal point, which is set back from the screen by the\r\n     * focal distance.</li>\r\n     * </ul>\r\n     * The <code>boxToCam</code> transformation is exposed to help 3D elements\r\n     * manage their 2D representations in central projection mode. To map world\r\n     * coordinates to focal coordinates, use the\r\n     * {@link JXG.View3D#worldToFocal} method.\r\n     * @type {Array}\r\n     */\r\n    this.boxToCam = [];\r\n\r\n    /**\r\n     * @type array\r\n     * @private\r\n     */\r\n    // Lower left corner [x, y] of the 3D view if elevation and azimuth are set to 0.\r\n    this.llftCorner = parents[0];\r\n\r\n    /**\r\n     * Width and height [w, h] of the 3D view if elevation and azimuth are set to 0.\r\n     * @type array\r\n     * @private\r\n     */\r\n    this.size = parents[1];\r\n\r\n    /**\r\n     * Bounding box (cube) [[x1, x2], [y1,y2], [z1,z2]] of the 3D view\r\n     * @type array\r\n     */\r\n    this.bbox3D = parents[2];\r\n\r\n    /**\r\n     * The distance from the camera to the origin. In other words, the\r\n     * radius of the sphere where the camera sits.\r\n     * @type Number\r\n     */\r\n    this.r = -1;\r\n\r\n    /**\r\n     * The distance from the camera to the screen. Computed automatically from\r\n     * the `fov` property.\r\n     * @type Number\r\n     */\r\n    this.focalDist = -1;\r\n\r\n    /**\r\n     * Type of projection.\r\n     * @type String\r\n     */\r\n    // Will be set in update().\r\n    this.projectionType = 'parallel';\r\n\r\n    /**\r\n     * Whether trackball navigation is currently enabled.\r\n     * @type String\r\n     */\r\n    this.trackballEnabled = false;\r\n\r\n    this.timeoutAzimuth = null;\r\n\r\n    this.zIndexMin = Infinity;\r\n    this.zIndexMax = -Infinity;\r\n\r\n    this.id = this.board.setId(this, 'V');\r\n    this.board.finalizeAdding(this);\r\n    this.elType = 'view3d';\r\n\r\n    this.methodMap = Type.deepCopy(this.methodMap, {\r\n        // TODO\r\n    });\r\n};\r\nJXG.View3D.prototype = new GeometryElement();\r\n\r\nJXG.extend(\r\n    JXG.View3D.prototype, /** @lends JXG.View3D.prototype */ {\r\n\r\n    /**\r\n     * Creates a new 3D element of type elementType.\r\n     * @param {String} elementType Type of the element to be constructed given as a string e.g. 'point3d' or 'surface3d'.\r\n     * @param {Array} parents Array of parent elements needed to construct the element e.g. coordinates for a 3D point or two\r\n     * 3D points to construct a line. This highly depends on the elementType that is constructed. See the corresponding JXG.create*\r\n     * methods for a list of possible parameters.\r\n     * @param {Object} [attributes] An object containing the attributes to be set. This also depends on the elementType.\r\n     * Common attributes are name, visible, strokeColor.\r\n     * @returns {Object} Reference to the created element. This is usually a GeometryElement3D, but can be an array containing\r\n     * two or more elements.\r\n     */\r\n    create: function (elementType, parents, attributes) {\r\n        var prefix = [],\r\n            el;\r\n\r\n        if (elementType.indexOf('3d') > 0) {\r\n            // is3D = true;\r\n            prefix.push(this);\r\n        }\r\n        el = this.board.create(elementType, prefix.concat(parents), attributes);\r\n\r\n        return el;\r\n    },\r\n\r\n    /**\r\n     * Select a single or multiple elements at once.\r\n     * @param {String|Object|function} str The name, id or a reference to a JSXGraph 3D element in the 3D view. An object will\r\n     * be used as a filter to return multiple elements at once filtered by the properties of the object.\r\n     * @param {Boolean} onlyByIdOrName If true (default:false) elements are only filtered by their id, name or groupId.\r\n     * The advanced filters consisting of objects or functions are ignored.\r\n     * @returns {JXG.GeometryElement3D|JXG.Composition}\r\n     * @example\r\n     * // select the element with name A\r\n     * view.select('A');\r\n     *\r\n     * // select all elements with strokecolor set to 'red' (but not '#ff0000')\r\n     * view.select({\r\n     *   strokeColor: 'red'\r\n     * });\r\n     *\r\n     * // select all points on or below the x/y plane and make them black.\r\n     * view.select({\r\n     *   elType: 'point3d',\r\n     *   Z: function (v) {\r\n     *     return v <= 0;\r\n     *   }\r\n     * }).setAttribute({color: 'black'});\r\n     *\r\n     * // select all elements\r\n     * view.select(function (el) {\r\n     *   return true;\r\n     * });\r\n     */\r\n    select: function (str, onlyByIdOrName) {\r\n        var flist,\r\n            olist,\r\n            i,\r\n            l,\r\n            s = str;\r\n\r\n        if (s === null) {\r\n            return s;\r\n        }\r\n\r\n        if (Type.isString(s) && s !== '') {\r\n            // It's a string, most likely an id or a name.\r\n            // Search by ID\r\n            if (Type.exists(this.objects[s])) {\r\n                s = this.objects[s];\r\n                // Search by name\r\n            } else if (Type.exists(this.elementsByName[s])) {\r\n                s = this.elementsByName[s];\r\n                // // Search by group ID\r\n                // } else if (Type.exists(this.groups[s])) {\r\n                //     s = this.groups[s];\r\n            }\r\n\r\n        } else if (\r\n            !onlyByIdOrName &&\r\n            (Type.isFunction(s) || (Type.isObject(s) && !Type.isFunction(s.setAttribute)))\r\n        ) {\r\n            // It's a function or an object, but not an element\r\n            flist = Type.filterElements(this.objectsList, s);\r\n\r\n            olist = {};\r\n            l = flist.length;\r\n            for (i = 0; i < l; i++) {\r\n                olist[flist[i].id] = flist[i];\r\n            }\r\n            s = new Composition(olist);\r\n\r\n        } else if (\r\n            Type.isObject(s) &&\r\n            Type.exists(s.id) &&\r\n            !Type.exists(this.objects[s.id])\r\n        ) {\r\n            // It's an element which has been deleted (and still hangs around, e.g. in an attractor list)\r\n            s = null;\r\n        }\r\n\r\n        return s;\r\n    },\r\n\r\n    // set the Tait-Bryan angles to specify the current view rotation matrix\r\n    setAnglesFromRotation: function () {\r\n        var rem = this.matrix3DRot, // rotation remaining after angle extraction\r\n            rBank, cosBank, sinBank,\r\n            cosEl, sinEl,\r\n            cosAz, sinAz;\r\n\r\n        // extract bank by rotating the view box z axis onto the camera yz plane\r\n        rBank = Math.sqrt(rem[1][3] * rem[1][3] + rem[2][3] * rem[2][3]);\r\n        if (rBank > Mat.eps) {\r\n            cosBank = rem[2][3] / rBank;\r\n            sinBank = rem[1][3] / rBank;\r\n        } else {\r\n            // if the z axis is pointed almost exactly at the screen, we\r\n            // keep the current bank value\r\n            cosBank = Math.cos(this.angles.bank);\r\n            sinBank = Math.sin(this.angles.bank);\r\n        }\r\n        rem = Mat.matMatMult([\r\n            [1, 0, 0, 0],\r\n            [0, cosBank, -sinBank, 0],\r\n            [0, sinBank, cosBank, 0],\r\n            [0, 0, 0, 1]\r\n        ], rem);\r\n        this.angles.bank = Math.atan2(sinBank, cosBank);\r\n\r\n        // extract elevation by rotating the view box z axis onto the camera\r\n        // y axis\r\n        cosEl = rem[2][3];\r\n        sinEl = rem[3][3];\r\n        rem = Mat.matMatMult([\r\n            [1, 0, 0, 0],\r\n            [0, 1, 0, 0],\r\n            [0, 0, cosEl, sinEl],\r\n            [0, 0, -sinEl, cosEl]\r\n        ], rem);\r\n        this.angles.el = Math.atan2(sinEl, cosEl);\r\n\r\n        // extract azimuth\r\n        cosAz = -rem[1][1];\r\n        sinAz = rem[3][1];\r\n        this.angles.az = Math.atan2(sinAz, cosAz);\r\n        if (this.angles.az < 0) this.angles.az += 2 * Math.PI;\r\n\r\n        this.setSlidersFromAngles();\r\n    },\r\n\r\n    anglesHaveMoved: function () {\r\n        return (\r\n            this._hasMoveAz || this._hasMoveEl ||\r\n            Math.abs(this.angles.az - this.az_slide.Value()) > Mat.eps ||\r\n            Math.abs(this.angles.el - this.el_slide.Value()) > Mat.eps ||\r\n            Math.abs(this.angles.bank - this.bank_slide.Value()) > Mat.eps\r\n        );\r\n    },\r\n\r\n    getAnglesFromSliders: function () {\r\n        this.angles.az = this.az_slide.Value();\r\n        this.angles.el = this.el_slide.Value();\r\n        this.angles.bank = this.bank_slide.Value();\r\n    },\r\n\r\n    setSlidersFromAngles: function () {\r\n        this.az_slide.setValue(this.angles.az);\r\n        this.el_slide.setValue(this.angles.el);\r\n        this.bank_slide.setValue(this.angles.bank);\r\n    },\r\n\r\n    // return the rotation matrix specified by the current Tait-Bryan angles\r\n    getRotationFromAngles: function () {\r\n        var a, e, b, f,\r\n            cosBank, sinBank,\r\n            mat = [\r\n                [1, 0, 0, 0],\r\n                [0, 1, 0, 0],\r\n                [0, 0, 1, 0],\r\n                [0, 0, 0, 1]\r\n            ];\r\n\r\n        // mat projects homogeneous 3D coords in View3D\r\n        // to homogeneous 2D coordinates in the board\r\n        a = this.angles.az;\r\n        e = this.angles.el;\r\n        b = this.angles.bank;\r\n        f = -Math.sin(e);\r\n\r\n        mat[1][1] = -Math.cos(a);\r\n        mat[1][2] = Math.sin(a);\r\n        mat[1][3] = 0;\r\n\r\n        mat[2][1] = f * Math.sin(a);\r\n        mat[2][2] = f * Math.cos(a);\r\n        mat[2][3] = Math.cos(e);\r\n\r\n        mat[3][1] = Math.cos(e) * Math.sin(a);\r\n        mat[3][2] = Math.cos(e) * Math.cos(a);\r\n        mat[3][3] = Math.sin(e);\r\n\r\n        cosBank = Math.cos(b);\r\n        sinBank = Math.sin(b);\r\n        mat = Mat.matMatMult([\r\n            [1, 0, 0, 0],\r\n            [0, cosBank, sinBank, 0],\r\n            [0, -sinBank, cosBank, 0],\r\n            [0, 0, 0, 1]\r\n        ], mat);\r\n\r\n        return mat;\r\n\r\n        /* this code, originally from `_updateCentralProjection`, is an\r\n         * alternate implementation of the azimuth-elevation matrix\r\n         * computation above. using this implementation instead of the\r\n         * current one might lead to simpler code in a future refactoring\r\n        var a, e, up,\r\n            ax, ay, az, v, nrm,\r\n            eye, d,\r\n            func_sphere;\r\n\r\n        // finds the point on the unit sphere with the given azimuth and\r\n        // elevation, and returns its affine coordinates\r\n        func_sphere = function (az, el) {\r\n            return [\r\n                Math.cos(az) * Math.cos(el),\r\n                -Math.sin(az) * Math.cos(el),\r\n                Math.sin(el)\r\n            ];\r\n        };\r\n\r\n        a = this.az_slide.Value() + (3 * Math.PI * 0.5); // Sphere\r\n        e = this.el_slide.Value();\r\n\r\n        // create an up vector and an eye vector which are 90 degrees out of phase\r\n        up = func_sphere(a, e + Math.PI / 2);\r\n        eye = func_sphere(a, e);\r\n        d = [eye[0], eye[1], eye[2]];\r\n\r\n        nrm = Mat.norm(d, 3);\r\n        az = [d[0] / nrm, d[1] / nrm, d[2] / nrm];\r\n\r\n        nrm = Mat.norm(up, 3);\r\n        v = [up[0] / nrm, up[1] / nrm, up[2] / nrm];\r\n\r\n        ax = Mat.crossProduct(v, az);\r\n        ay = Mat.crossProduct(az, ax);\r\n\r\n        this.matrix3DRot[1] = [0, ax[0], ax[1], ax[2]];\r\n        this.matrix3DRot[2] = [0, ay[0], ay[1], ay[2]];\r\n        this.matrix3DRot[3] = [0, az[0], az[1], az[2]];\r\n         */\r\n    },\r\n\r\n    /**\r\n     * Project 2D point (x,y) to the virtual trackpad sphere,\r\n     * see Bell's virtual trackpad, and return z-component of the\r\n     * number.\r\n     *\r\n     * @param {Number} r\r\n     * @param {Number} x\r\n     * @param {Number} y\r\n     * @returns Number\r\n     * @private\r\n     */\r\n    _projectToSphere: function (r, x, y) {\r\n        var d = Mat.hypot(x, y),\r\n            t, z;\r\n\r\n        if (d < r * 0.7071067811865475) { // Inside sphere\r\n            z = Math.sqrt(r * r - d * d);\r\n        } else {                          // On hyperbola\r\n            t = r / 1.414213562373095;\r\n            z = t * t / d;\r\n        }\r\n        return z;\r\n    },\r\n\r\n    /**\r\n     * Determine 4x4 rotation matrix with Bell's virtual trackball.\r\n     *\r\n     * @returns {Array} 4x4 rotation matrix\r\n     * @private\r\n     */\r\n    updateProjectionTrackball: function (Pref) {\r\n        var R = 100,\r\n            dx, dy, dr2,\r\n            p1, p2, x, y, theta, t, d,\r\n            c, s, n,\r\n            mat = [\r\n                [1, 0, 0, 0],\r\n                [0, 1, 0, 0],\r\n                [0, 0, 1, 0],\r\n                [0, 0, 0, 1]\r\n            ];\r\n\r\n        if (!Type.exists(this._trackball)) {\r\n            return this.matrix3DRot;\r\n        }\r\n\r\n        dx = this._trackball.dx;\r\n        dy = this._trackball.dy;\r\n        dr2 = dx * dx + dy * dy;\r\n        if (dr2 > Mat.eps) {\r\n            // // Method by Hanson, \"The rolling ball\", Graphics Gems III, p.51\r\n            // // Rotation axis:\r\n            // //     n = (-dy/dr, dx/dr, 0)\r\n            // // Rotation angle around n:\r\n            // //     theta = atan(dr / R) approx dr / R\r\n            // dr = Math.sqrt(dr2);\r\n            // c = R / Math.hypot(R, dr);  // cos(theta)\r\n            // t = 1 - c;                  // 1 - cos(theta)\r\n            // s = dr / Math.hypot(R, dr); // sin(theta)\r\n            // n = [-dy / dr, dx / dr, 0];\r\n\r\n            // Bell virtual trackpad, see\r\n            // https://opensource.apple.com/source/X11libs/X11libs-60/mesa/Mesa-7.8.2/progs/util/trackball.c.auto.html\r\n            // http://scv.bu.edu/documentation/presentations/visualizationworkshop08/materials/opengl/trackball.c.\r\n            // See also Henriksen, Sporring, Hornaek, \"Virtual Trackballs revisited\".\r\n            //\r\n            R = (this.size[0] * this.board.unitX + this.size[1] * this.board.unitY) * 0.25;\r\n            x = this._trackball.x;\r\n            y = this._trackball.y;\r\n\r\n            p2 = [x, y, this._projectToSphere(R, x, y)];\r\n            x -= dx;\r\n            y -= dy;\r\n            p1 = [x, y, this._projectToSphere(R, x, y)];\r\n\r\n            n = Mat.crossProduct(p1, p2);\r\n            d = Mat.hypot(n[0], n[1], n[2]);\r\n            n[0] /= d;\r\n            n[1] /= d;\r\n            n[2] /= d;\r\n\r\n            t = Geometry.distance(p2, p1, 3) / (2 * R);\r\n            t = (t > 1.0) ? 1.0 : t;\r\n            t = (t < -1.0) ? -1.0 : t;\r\n            theta = 2.0 * Math.asin(t);\r\n            c = Math.cos(theta);\r\n            t = 1 - c;\r\n            s = Math.sin(theta);\r\n\r\n            // Rotation by theta about the axis n. See equation 9.63 of\r\n            //\r\n            //   Ian Richard Cole. \"Modeling CPV\" (thesis). Loughborough\r\n            //   University. https://hdl.handle.net/2134/18050\r\n            //\r\n            mat[1][1] = c + n[0] * n[0] * t;\r\n            mat[2][1] = n[1] * n[0] * t + n[2] * s;\r\n            mat[3][1] = n[2] * n[0] * t - n[1] * s;\r\n\r\n            mat[1][2] = n[0] * n[1] * t - n[2] * s;\r\n            mat[2][2] = c + n[1] * n[1] * t;\r\n            mat[3][2] = n[2] * n[1] * t + n[0] * s;\r\n\r\n            mat[1][3] = n[0] * n[2] * t + n[1] * s;\r\n            mat[2][3] = n[1] * n[2] * t - n[0] * s;\r\n            mat[3][3] = c + n[2] * n[2] * t;\r\n        }\r\n\r\n        mat = Mat.matMatMult(mat, this.matrix3DRot);\r\n        return mat;\r\n    },\r\n\r\n    updateAngleSliderBounds: function () {\r\n        var az_smax, az_smin,\r\n            el_smax, el_smin, el_cover,\r\n            el_smid, el_equiv, el_flip_equiv,\r\n            el_equiv_loss, el_flip_equiv_loss, el_interval_loss,\r\n            bank_smax, bank_smin;\r\n\r\n        // update stored trackball toggle\r\n        this.trackballEnabled = this.evalVisProp('trackball.enabled');\r\n\r\n        // set slider bounds\r\n        if (this.trackballEnabled) {\r\n            this.az_slide.setMin(0);\r\n            this.az_slide.setMax(2 * Math.PI);\r\n            this.el_slide.setMin(-0.5 * Math.PI);\r\n            this.el_slide.setMax(0.5 * Math.PI);\r\n            this.bank_slide.setMin(-Math.PI);\r\n            this.bank_slide.setMax(Math.PI);\r\n        } else {\r\n            this.az_slide.setMin(this.visProp.az.slider.min);\r\n            this.az_slide.setMax(this.visProp.az.slider.max);\r\n            this.el_slide.setMin(this.visProp.el.slider.min);\r\n            this.el_slide.setMax(this.visProp.el.slider.max);\r\n            this.bank_slide.setMin(this.visProp.bank.slider.min);\r\n            this.bank_slide.setMax(this.visProp.bank.slider.max);\r\n        }\r\n\r\n        // get new slider bounds\r\n        az_smax = this.az_slide._smax;\r\n        az_smin = this.az_slide._smin;\r\n        el_smax = this.el_slide._smax;\r\n        el_smin = this.el_slide._smin;\r\n        bank_smax = this.bank_slide._smax;\r\n        bank_smin = this.bank_slide._smin;\r\n\r\n        // wrap and restore angle values\r\n        if (this.trackballEnabled) {\r\n            // if we're upside-down, flip the bank angle to reach the same\r\n            // orientation with an elevation between -pi/2 and pi/2\r\n            el_cover = Mat.mod(this.angles.el, 2 * Math.PI);\r\n            if (0.5 * Math.PI < el_cover && el_cover < 1.5 * Math.PI) {\r\n                this.angles.el = Math.PI - el_cover;\r\n                this.angles.az = Mat.wrap(this.angles.az + Math.PI, az_smin, az_smax);\r\n                this.angles.bank = Mat.wrap(this.angles.bank + Math.PI, bank_smin, bank_smax);\r\n            }\r\n\r\n            // wrap the azimuth and bank angle\r\n            this.angles.az = Mat.wrap(this.angles.az, az_smin, az_smax);\r\n            this.angles.el = Mat.wrap(this.angles.el, el_smin, el_smax);\r\n            this.angles.bank = Mat.wrap(this.angles.bank, bank_smin, bank_smax);\r\n        } else {\r\n            // wrap and clamp the elevation into the slider range. if\r\n            // flipping the elevation gets us closer to the slider interval,\r\n            // do that, inverting the azimuth and bank angle to compensate\r\n            el_interval_loss = function (t) {\r\n                if (t < el_smin) {\r\n                    return el_smin - t;\r\n                } else if (el_smax < t) {\r\n                    return t - el_smax;\r\n                } else {\r\n                    return 0;\r\n                }\r\n            };\r\n            el_smid = 0.5 * (el_smin + el_smax);\r\n            el_equiv = Mat.wrap(\r\n                this.angles.el,\r\n                el_smid - Math.PI,\r\n                el_smid + Math.PI\r\n            );\r\n            el_flip_equiv = Mat.wrap(\r\n                Math.PI - this.angles.el,\r\n                el_smid - Math.PI,\r\n                el_smid + Math.PI\r\n            );\r\n            el_equiv_loss = el_interval_loss(el_equiv);\r\n            el_flip_equiv_loss = el_interval_loss(el_flip_equiv);\r\n            if (el_equiv_loss <= el_flip_equiv_loss) {\r\n                this.angles.el = Mat.clamp(el_equiv, el_smin, el_smax);\r\n            } else {\r\n                this.angles.el = Mat.clamp(el_flip_equiv, el_smin, el_smax);\r\n                this.angles.az = Mat.wrap(this.angles.az + Math.PI, az_smin, az_smax);\r\n                this.angles.bank = Mat.wrap(this.angles.bank + Math.PI, bank_smin, bank_smax);\r\n            }\r\n\r\n            // wrap and clamp the azimuth and bank angle into the slider range\r\n            this.angles.az = Mat.wrapAndClamp(this.angles.az, az_smin, az_smax, 2 * Math.PI);\r\n            this.angles.bank = Mat.wrapAndClamp(this.angles.bank, bank_smin, bank_smax, 2 * Math.PI);\r\n\r\n            // since we're using `clamp`, angles may have changed\r\n            this.matrix3DRot = this.getRotationFromAngles();\r\n        }\r\n\r\n        // restore slider positions\r\n        this.setSlidersFromAngles();\r\n    },\r\n\r\n    /**\r\n     * @private\r\n     * @returns {Array}\r\n     */\r\n    _updateCentralProjection: function () {\r\n        var zf = 20, // near clip plane\r\n            zn = 8, // far clip plane\r\n\r\n            // See https://www.mathematik.uni-marburg.de/~thormae/lectures/graphics1/graphics_6_1_eng_web.html\r\n            // bbox3D is always at the world origin, i.e. T_obj is the unit matrix.\r\n            // All vectors contain affine coordinates and have length 3\r\n            // The matrices are of size 4x4.\r\n            r, A;\r\n\r\n        // set distance from view box center to camera\r\n        r = this.evalVisProp('r');\r\n        if (r === 'auto') {\r\n            r = Mat.hypot(\r\n                this.bbox3D[0][0] - this.bbox3D[0][1],\r\n                this.bbox3D[1][0] - this.bbox3D[1][1],\r\n                this.bbox3D[2][0] - this.bbox3D[2][1]\r\n            ) * 1.01;\r\n        }\r\n\r\n        // compute camera transformation\r\n        // this.boxToCam = this.matrix3DRot.map((row) => row.slice());\r\n        this.boxToCam = this.matrix3DRot.map(function (row) { return row.slice(); });\r\n        this.boxToCam[3][0] = -r;\r\n\r\n        // compute focal distance and clip space transformation\r\n        this.focalDist = 1 / Math.tan(0.5 * this.evalVisProp('fov'));\r\n        A = [\r\n            [0, 0, 0, -1],\r\n            [0, this.focalDist, 0, 0],\r\n            [0, 0, this.focalDist, 0],\r\n            [2 * zf * zn / (zn - zf), 0, 0, (zf + zn) / (zn - zf)]\r\n        ];\r\n\r\n        return Mat.matMatMult(A, this.boxToCam);\r\n    },\r\n\r\n    // Update 3D-to-2D transformation matrix with the actual azimuth and elevation angles.\r\n    update: function () {\r\n        var r = this.r,\r\n            stretch = [\r\n                [1, 0, 0, 0],\r\n                [0, -r, 0, 0],\r\n                [0, 0, -r, 0],\r\n                [0, 0, 0, 1]\r\n            ],\r\n            mat2D, objectToClip, size,\r\n            dx, dy;\r\n            // objectsList;\r\n\r\n        if (\r\n            !Type.exists(this.el_slide) ||\r\n            !Type.exists(this.az_slide) ||\r\n            !Type.exists(this.bank_slide) ||\r\n            !this.needsUpdate\r\n        ) {\r\n            this.needsUpdate = false;\r\n            return this;\r\n        }\r\n\r\n        mat2D = [\r\n            [1, 0, 0],\r\n            [0, 1, 0],\r\n            [0, 0, 1]\r\n        ];\r\n\r\n        this.projectionType = this.evalVisProp('projection').toLowerCase();\r\n\r\n        // override angle slider bounds when trackball navigation is enabled\r\n        if (this.trackballEnabled !== this.evalVisProp('trackball.enabled')) {\r\n            this.updateAngleSliderBounds();\r\n        }\r\n\r\n        if (this._hasMoveTrackball) {\r\n            // The trackball has been moved since the last update, so we do\r\n            // trackball navigation. When the trackball is enabled, a drag\r\n            // event is interpreted as a trackball movement unless it's\r\n            // caught by something else, like point dragging. When the\r\n            // trackball is disabled, the trackball movement flag should\r\n            // never be set\r\n            this.matrix3DRot = this.updateProjectionTrackball();\r\n            this.setAnglesFromRotation();\r\n        } else if (this.anglesHaveMoved()) {\r\n            // The trackball hasn't been moved since the last up date, but\r\n            // the Tait-Bryan angles have been, so we do angle navigation\r\n            this.getAnglesFromSliders();\r\n            this.matrix3DRot = this.getRotationFromAngles();\r\n        }\r\n\r\n        /**\r\n         * The translation that moves the center of the view box to the origin.\r\n         */\r\n        this.shift = [\r\n            [1, 0, 0, 0],\r\n            [-0.5 * (this.bbox3D[0][0] + this.bbox3D[0][1]), 1, 0, 0],\r\n            [-0.5 * (this.bbox3D[1][0] + this.bbox3D[1][1]), 0, 1, 0],\r\n            [-0.5 * (this.bbox3D[2][0] + this.bbox3D[2][1]), 0, 0, 1]\r\n        ];\r\n\r\n        switch (this.projectionType) {\r\n            case 'central': // Central projection\r\n\r\n                // Add a final transformation to scale and shift the projection\r\n                // on the board, usually called viewport.\r\n                size = 2 * 0.4;\r\n                mat2D[1][1] = this.size[0] / size; // w / d_x\r\n                mat2D[2][2] = this.size[1] / size; // h / d_y\r\n                mat2D[1][0] = this.llftCorner[0] + mat2D[1][1] * 0.5 * size; // llft_x\r\n                mat2D[2][0] = this.llftCorner[1] + mat2D[2][2] * 0.5 * size; // llft_y\r\n                // The transformations this.matrix3D and mat2D can not be combined at this point,\r\n                // since the projected vectors have to be normalized in between in project3DTo2D\r\n                this.viewPortTransform = mat2D;\r\n                objectToClip = this._updateCentralProjection();\r\n                // this.matrix3D is a 4x4 matrix\r\n                this.matrix3D = Mat.matMatMult(objectToClip, this.shift);\r\n                break;\r\n\r\n            case 'parallel': // Parallel projection\r\n            default:\r\n                // Add a final transformation to scale and shift the projection\r\n                // on the board, usually called viewport.\r\n                dx = this.bbox3D[0][1] - this.bbox3D[0][0];\r\n                dy = this.bbox3D[1][1] - this.bbox3D[1][0];\r\n                mat2D[1][1] = this.size[0] / dx; // w / d_x\r\n                mat2D[2][2] = this.size[1] / dy; // h / d_y\r\n                mat2D[1][0] = this.llftCorner[0] + mat2D[1][1] * 0.5 * dx; // llft_x\r\n                mat2D[2][0] = this.llftCorner[1] + mat2D[2][2] * 0.5 * dy; // llft_y\r\n\r\n                // Combine all transformations, this.matrix3D is a 3x4 matrix\r\n                this.matrix3D = Mat.matMatMult(\r\n                    mat2D,\r\n                    Mat.matMatMult(Mat.matMatMult(this.matrix3DRot, stretch), this.shift).slice(0, 3)\r\n                );\r\n        }\r\n\r\n        // Used for zIndex in dept ordering in subsequent update methods of the\r\n        // 3D elements and in view3d.updateRenderer\r\n        this.matrix3DRotShift = Mat.matMatMult(this.matrix3DRot, this.shift);\r\n\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * Compares 3D elements according to their z-Index.\r\n     * @param {JXG.GeometryElement3D} a\r\n     * @param {JXG.GeometryElement3D} b\r\n     * @returns Number\r\n     */\r\n    compareDepth: function (a, b) {\r\n        // return a.zIndex - b.zIndex;\r\n        // if (a.type !== Const.OBJECT_TYPE_PLANE3D && b.type !== Const.OBJECT_TYPE_PLANE3D) {\r\n        //     return a.zIndex - b.zIndex;\r\n        // } else if (a.type === Const.OBJECT_TYPE_PLANE3D) {\r\n        //     let bHesse = Mat.innerProduct(a.point.coords, a.normal, 4);\r\n        //     let po = Mat.innerProduct(b.coords, a.normal, 4);\r\n        //     let pos = Mat.innerProduct(this.boxToCam[3], a.normal, 4);\r\n        // console.log(this.boxToCam[3])\r\n        //     return pos - po;\r\n        // } else if (b.type === Const.OBJECT_TYPE_PLANE3D) {\r\n        //     let bHesse = Mat.innerProduct(b.point.coords, b.normal, 4);\r\n        //     let po = Mat.innerProduct(a.coords, a.normal, 4);\r\n        //     let pos = Mat.innerProduct(this.boxToCam[3], b.normal, 4);\r\n        //     console.log('b', pos, po, bHesse)\r\n        //     return -pos;\r\n        // }\r\n        return a.zIndex - b.zIndex;\r\n    },\r\n\r\n    updateZIndices: function() {\r\n        var id, el;\r\n        for (id in this.objects) {\r\n            if (this.objects.hasOwnProperty(id)) {\r\n                el = this.objects[id];\r\n                // Update zIndex of less frequent objects line3d and polygon3d\r\n                // The other elements (point3d, face3d) do this in their update method.\r\n                if ((el.type === Const.OBJECT_TYPE_LINE3D ||\r\n                    el.type === Const.OBJECT_TYPE_POLYGON3D\r\n                    ) &&\r\n                    Type.exists(el.element2D) &&\r\n                    el.element2D.evalVisProp('visible')\r\n                ) {\r\n                    el.updateZIndex();\r\n                }\r\n            }\r\n        }\r\n    },\r\n\r\n    updateShaders: function() {\r\n        var id, el, v;\r\n        for (id in this.objects) {\r\n            if (this.objects.hasOwnProperty(id)) {\r\n                el = this.objects[id];\r\n                if (Type.exists(el.shader)) {\r\n                    v = el.shader();\r\n                    if (v < this.zIndexMin) {\r\n                        this.zIndexMin = v;\r\n                    } else if (v > this.zIndexMax) {\r\n                        this.zIndexMax = v;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    },\r\n\r\n    updateDepthOrdering: function () {\r\n        var id, el,\r\n            i, j, l, layers, lay;\r\n\r\n        // Collect elements for depth ordering layer-wise\r\n        layers = this.evalVisProp('depthorder.layers');\r\n        for (i = 0; i < layers.length; i++) {\r\n            this.depthOrdered[layers[i]] = [];\r\n        }\r\n\r\n        for (id in this.objects) {\r\n            if (this.objects.hasOwnProperty(id)) {\r\n                el = this.objects[id];\r\n                if ((el.type === Const.OBJECT_TYPE_FACE3D ||\r\n                    el.type === Const.OBJECT_TYPE_LINE3D ||\r\n                    // el.type === Const.OBJECT_TYPE_PLANE3D ||\r\n                    el.type === Const.OBJECT_TYPE_POINT3D ||\r\n                    el.type === Const.OBJECT_TYPE_POLYGON3D\r\n                    ) &&\r\n                    Type.exists(el.element2D) &&\r\n                    el.element2D.evalVisProp('visible')\r\n                ) {\r\n                    lay = el.element2D.evalVisProp('layer');\r\n                    if (layers.indexOf(lay) >= 0) {\r\n                        this.depthOrdered[lay].push(el);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        if (this.board.renderer && this.board.renderer.type === 'svg') {\r\n            for (i = 0; i < layers.length; i++) {\r\n                lay = layers[i];\r\n                this.depthOrdered[lay].sort(this.compareDepth.bind(this));\r\n                // DEBUG\r\n                // if (this.depthOrdered[lay].length > 0) {\r\n                //     for (let k = 0; k < this.depthOrdered[lay].length; k++) {\r\n                //         let o = this.depthOrdered[lay][k]\r\n                //         console.log(o.visProp.fillcolor, o.zIndex)\r\n                //     }\r\n                // }\r\n                l = this.depthOrdered[lay];\r\n                for (j = 0; j < l.length; j++) {\r\n                    this.board.renderer.setLayer(l[j].element2D, lay);\r\n                }\r\n                // this.depthOrdered[lay].forEach((el) => this.board.renderer.setLayer(el.element2D, lay));\r\n                // Attention: forEach prevents deleting an element\r\n            }\r\n        }\r\n\r\n        return this;\r\n    },\r\n\r\n    updateRenderer: function () {\r\n        if (!this.needsUpdate) {\r\n            return this;\r\n        }\r\n\r\n        // console.time('update')\r\n        // Handle depth ordering\r\n        this.depthOrdered = {};\r\n\r\n        if (this.shift !== undefined && this.evalVisProp('depthorder.enabled')) {\r\n            // Update the zIndices of certain element types.\r\n            // We do it here in updateRenderer, because the elements' positions\r\n            // are meanwhile updated.\r\n            this.updateZIndices();\r\n\r\n            this.updateShaders();\r\n\r\n            if (this.board.renderer && this.board.renderer.type === 'svg') {\r\n                // For SVG we update the DOM order\r\n                // In canvas we sort the elements in board.updateRendererCanvas\r\n                this.updateDepthOrdering();\r\n            }\r\n        }\r\n        // console.timeEnd('update')\r\n\r\n        this.needsUpdate = false;\r\n        return this;\r\n    },\r\n\r\n    removeObject: function (object, saveMethod) {\r\n        var i, el;\r\n\r\n        // this.board.removeObject(object, saveMethod);\r\n        if (Type.isArray(object)) {\r\n            for (i = 0; i < object.length; i++) {\r\n                this.removeObject(object[i]);\r\n            }\r\n            return this;\r\n        }\r\n\r\n        object = this.select(object);\r\n\r\n        // // If the object which is about to be removed unknown or a string, do nothing.\r\n        // // it is a string if a string was given and could not be resolved to an element.\r\n        if (!Type.exists(object) || Type.isString(object)) {\r\n            return this;\r\n        }\r\n\r\n        try {\r\n            // Remove all children.\r\n            for (el in object.childElements) {\r\n                if (object.childElements.hasOwnProperty(el)) {\r\n                    this.removeObject(object.childElements[el]);\r\n                }\r\n            }\r\n\r\n            delete this.objects[object.id];\r\n        } catch (e) {\r\n            JXG.debug('View3D ' + object.id + ': Could not be removed: ' + e);\r\n        }\r\n\r\n        // this.update();\r\n\r\n        this.board.removeObject(object, saveMethod);\r\n\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * Map world coordinates to focal coordinates. These coordinate systems\r\n     * are explained in the {@link JXG.View3D#boxToCam} matrix\r\n     * documentation.\r\n     *\r\n     * @param {Array} pWorld A world space point, in homogeneous coordinates.\r\n     * @param {Boolean} [homog=true] Whether to return homogeneous coordinates.\r\n     * If false, projects down to ordinary coordinates.\r\n     */\r\n    worldToFocal: function (pWorld, homog = true) {\r\n        var k,\r\n            pView = Mat.matVecMult(this.boxToCam, Mat.matVecMult(this.shift, pWorld));\r\n        pView[3] -= pView[0] * this.focalDist;\r\n        if (homog) {\r\n            return pView;\r\n        } else {\r\n            for (k = 1; k < 4; k++) {\r\n                pView[k] /= pView[0];\r\n            }\r\n            return pView.slice(1, 4);\r\n        }\r\n    },\r\n\r\n    /**\r\n     * Project 3D coordinates to 2D board coordinates\r\n     * The 3D coordinates are provides as three numbers x, y, z or one array of length 3.\r\n     *\r\n     * @param  {Number|Array} x\r\n     * @param  {Number[]} y\r\n     * @param  {Number[]} z\r\n     * @returns {Array} Array of length 3 containing the projection on to the board\r\n     * in homogeneous user coordinates.\r\n     */\r\n    project3DTo2D: function (x, y, z) {\r\n        var vec, w;\r\n        if (arguments.length === 3) {\r\n            vec = [1, x, y, z];\r\n        } else {\r\n            // Argument is an array\r\n            if (x.length === 3) {\r\n                // vec = [1].concat(x);\r\n                vec = x.slice();\r\n                vec.unshift(1);\r\n            } else {\r\n                vec = x;\r\n            }\r\n        }\r\n\r\n        w = Mat.matVecMult(this.matrix3D, vec);\r\n\r\n        switch (this.projectionType) {\r\n            case 'central':\r\n                w[1] /= w[0];\r\n                w[2] /= w[0];\r\n                w[3] /= w[0];\r\n                w[0] /= w[0];\r\n                return Mat.matVecMult(this.viewPortTransform, w.slice(0, 3));\r\n\r\n            case 'parallel':\r\n            default:\r\n                return w;\r\n        }\r\n    },\r\n\r\n    /**\r\n     * We know that v2d * w0 = mat * (1, x, y, d)^T where v2d = (1, b, c, h)^T with unknowns w0, h, x, y.\r\n     * Setting R = mat^(-1) gives\r\n     *   1/ w0 * (1, x, y, d)^T = R * v2d.\r\n     * The first and the last row of this equation allows to determine 1/w0 and h.\r\n     *\r\n     * @param {Array} mat\r\n     * @param {Array} v2d\r\n     * @param {Number} d\r\n     * @returns Array\r\n     * @private\r\n     */\r\n    _getW0: function (mat, v2d, d) {\r\n        var R = Mat.inverse(mat),\r\n            R1 = R[0][0] + v2d[1] * R[0][1] + v2d[2] * R[0][2],\r\n            R2 = R[3][0] + v2d[1] * R[3][1] + v2d[2] * R[3][2],\r\n            w, h, det;\r\n\r\n        det = d * R[0][3] - R[3][3];\r\n        w = (R2 * R[0][3] - R1 * R[3][3]) / det;\r\n        h = (R2 - R1 * d) / det;\r\n        return [1 / w, h];\r\n    },\r\n\r\n    /**\r\n     * Project a 2D coordinate to the plane defined by point \"foot\"\r\n     * and the normal vector `normal`.\r\n     *\r\n     * @param  {JXG.Point} point2d\r\n     * @param  {Array} normal Normal of plane\r\n     * @param  {Array} foot Foot point of plane\r\n     * @returns {Array} of length 4 containing the projected\r\n     * point in homogeneous coordinates.\r\n     */\r\n    project2DTo3DPlane: function (point2d, normal, foot) {\r\n        var mat, rhs, d, le, sol,\r\n            f = foot.slice(1) || [0, 0, 0],\r\n            n = normal.slice(1),\r\n            v2d, w0, res;\r\n\r\n        le = Mat.norm(n, 3);\r\n        d = Mat.innerProduct(f, n, 3) / le;\r\n\r\n        if (this.projectionType === 'parallel') {\r\n            mat = this.matrix3D.slice(0, 3);     // Copy each row by reference\r\n            mat.push([0, n[0], n[1], n[2]]);\r\n\r\n            // 2D coordinates of point\r\n            rhs = point2d.coords.usrCoords.slice();\r\n            rhs.push(d);\r\n            try {\r\n                // Prevent singularity in case elevation angle is zero\r\n                if (mat[2][3] === 1.0) {\r\n                    mat[2][1] = mat[2][2] = Mat.eps * 0.001;\r\n                }\r\n                sol = Mat.Numerics.Gauss(mat, rhs);\r\n            } catch (e) {\r\n                sol = [0, NaN, NaN, NaN];\r\n            }\r\n        } else {\r\n            mat = this.matrix3D;\r\n\r\n            // 2D coordinates of point:\r\n            rhs = point2d.coords.usrCoords.slice();\r\n\r\n            v2d = Mat.Numerics.Gauss(this.viewPortTransform, rhs);\r\n            res = this._getW0(mat, v2d, d);\r\n            w0 = res[0];\r\n            rhs = [\r\n                v2d[0] * w0,\r\n                v2d[1] * w0,\r\n                v2d[2] * w0,\r\n                res[1] * w0\r\n            ];\r\n            try {\r\n                // Prevent singularity in case elevation angle is zero\r\n                if (mat[2][3] === 1.0) {\r\n                    mat[2][1] = mat[2][2] = Mat.eps * 0.001;\r\n                }\r\n\r\n                sol = Mat.Numerics.Gauss(mat, rhs);\r\n                sol[1] /= sol[0];\r\n                sol[2] /= sol[0];\r\n                sol[3] /= sol[0];\r\n                // sol[3] = d;\r\n                sol[0] /= sol[0];\r\n            } catch (err) {\r\n                sol = [0, NaN, NaN, NaN];\r\n            }\r\n        }\r\n\r\n        return sol;\r\n    },\r\n\r\n    /**\r\n     * Project a point on the screen to the nearest point, in screen\r\n     * distance, on a line segment in 3d space. The inputs must be in\r\n     * ordinary coordinates, but the output is in homogeneous coordinates.\r\n     *\r\n     * @param {Array} pScr The screen coordinates of the point to project.\r\n     * @param {Array} end0 The world space coordinates of one end of the\r\n     * line segment.\r\n     * @param {Array} end1 The world space coordinates of the other end of\r\n     * the line segment.\r\n     *\r\n     * @returns Homogeneous coordinates of the projection\r\n     */\r\n    projectScreenToSegment: function (pScr, end0, end1) {\r\n        var end0_2d = this.project3DTo2D(end0).slice(1, 3),\r\n            end1_2d = this.project3DTo2D(end1).slice(1, 3),\r\n            dir_2d = [\r\n                end1_2d[0] - end0_2d[0],\r\n                end1_2d[1] - end0_2d[1]\r\n            ],\r\n            dir_2d_norm_sq = Mat.innerProduct(dir_2d, dir_2d),\r\n            diff = [\r\n                pScr[0] - end0_2d[0],\r\n                pScr[1] - end0_2d[1]\r\n            ],\r\n            s = Mat.innerProduct(diff, dir_2d) / dir_2d_norm_sq, // screen-space affine parameter\r\n            mid, mid_2d, mid_diff, m,\r\n\r\n            t, // view-space affine parameter\r\n            t_clamped, // affine parameter clamped to range\r\n            t_clamped_co;\r\n\r\n        if (this.projectionType === 'central') {\r\n            mid = [\r\n                0.5 * (end0[0] + end1[0]),\r\n                0.5 * (end0[1] + end1[1]),\r\n                0.5 * (end0[2] + end1[2])\r\n            ];\r\n            mid_2d = this.project3DTo2D(mid).slice(1, 3);\r\n            mid_diff = [\r\n                mid_2d[0] - end0_2d[0],\r\n                mid_2d[1] - end0_2d[1]\r\n            ];\r\n            m = Mat.innerProduct(mid_diff, dir_2d) / dir_2d_norm_sq;\r\n\r\n            // the view-space affine parameter s is related to the\r\n            // screen-space affine parameter t by a Möbius transformation,\r\n            // which is determined by the following relations:\r\n            //\r\n            // s | t\r\n            // -----\r\n            // 0 | 0\r\n            // m | 1/2\r\n            // 1 | 1\r\n            //\r\n            t = (1 - m) * s / ((1 - 2 * m) * s + m);\r\n        } else {\r\n            t = s;\r\n        }\r\n\r\n        t_clamped = Math.min(Math.max(t, 0), 1);\r\n        t_clamped_co = 1 - t_clamped;\r\n        return [\r\n            1,\r\n            t_clamped_co * end0[0] + t_clamped * end1[0],\r\n            t_clamped_co * end0[1] + t_clamped * end1[1],\r\n            t_clamped_co * end0[2] + t_clamped * end1[2]\r\n        ];\r\n    },\r\n\r\n    /**\r\n     * Project a 2D coordinate to a new 3D position by keeping\r\n     * the 3D x, y coordinates and changing only the z coordinate.\r\n     * All horizontal moves of the 2D point are ignored.\r\n     *\r\n     * @param {JXG.Point} point2d\r\n     * @param {Array} base_c3d\r\n     * @returns {Array} of length 4 containing the projected\r\n     * point in homogeneous coordinates.\r\n     */\r\n    project2DTo3DVertical: function (point2d, base_c3d) {\r\n        var pScr = point2d.coords.usrCoords.slice(1, 3),\r\n            end0 = [base_c3d[1], base_c3d[2], this.bbox3D[2][0]],\r\n            end1 = [base_c3d[1], base_c3d[2], this.bbox3D[2][1]];\r\n\r\n        return this.projectScreenToSegment(pScr, end0, end1);\r\n    },\r\n\r\n    /**\r\n     * Limit 3D coordinates to the bounding cube.\r\n     *\r\n     * @param {Array} c3d 3D coordinates [x,y,z]\r\n     * @returns Array [Array, Boolean] containing [coords, corrected]. coords contains the updated 3D coordinates,\r\n     * correct is true if the coords have been changed.\r\n     */\r\n    project3DToCube: function (c3d) {\r\n        var cube = this.bbox3D,\r\n            isOut = false;\r\n\r\n        if (c3d[1] < cube[0][0]) {\r\n            c3d[1] = cube[0][0];\r\n            isOut = true;\r\n        }\r\n        if (c3d[1] > cube[0][1]) {\r\n            c3d[1] = cube[0][1];\r\n            isOut = true;\r\n        }\r\n        if (c3d[2] < cube[1][0]) {\r\n            c3d[2] = cube[1][0];\r\n            isOut = true;\r\n        }\r\n        if (c3d[2] > cube[1][1]) {\r\n            c3d[2] = cube[1][1];\r\n            isOut = true;\r\n        }\r\n        if (c3d[3] <= cube[2][0]) {\r\n            c3d[3] = cube[2][0];\r\n            isOut = true;\r\n        }\r\n        if (c3d[3] >= cube[2][1]) {\r\n            c3d[3] = cube[2][1];\r\n            isOut = true;\r\n        }\r\n\r\n        return [c3d, isOut];\r\n    },\r\n\r\n    /**\r\n     * Intersect a ray with the bounding cube of the 3D view.\r\n     * @param {Array} p 3D coordinates [w,x,y,z]\r\n     * @param {Array} dir 3D direction vector of the line (array of length 3 or 4)\r\n     * @param {Number} r direction of the ray (positive if r > 0, negative if r < 0).\r\n     * @returns Affine ratio of the intersection of the line with the cube.\r\n     */\r\n    intersectionLineCube: function (p, dir, r) {\r\n        var r_n, i, r0, r1, d;\r\n\r\n        d = (dir.length === 3) ? dir : dir.slice(1);\r\n\r\n        r_n = r;\r\n        for (i = 0; i < 3; i++) {\r\n            if (d[i] !== 0) {\r\n                r0 = (this.bbox3D[i][0] - p[i + 1]) / d[i];\r\n                r1 = (this.bbox3D[i][1] - p[i + 1]) / d[i];\r\n                if (r < 0) {\r\n                    r_n = Math.max(r_n, Math.min(r0, r1));\r\n                } else {\r\n                    r_n = Math.min(r_n, Math.max(r0, r1));\r\n                }\r\n            }\r\n        }\r\n        return r_n;\r\n    },\r\n\r\n    /**\r\n     * Test if coordinates are inside of the bounding cube.\r\n     * @param {array} p 3D coordinates [[w],x,y,z] of a point.\r\n     * @returns Boolean\r\n     */\r\n    isInCube: function (p, polyhedron) {\r\n        var q;\r\n        if (p.length === 4) {\r\n            if (p[0] === 0) {\r\n                return false;\r\n            }\r\n            q = p.slice(1);\r\n        }\r\n        return (\r\n            q[0] > this.bbox3D[0][0] - Mat.eps &&\r\n            q[0] < this.bbox3D[0][1] + Mat.eps &&\r\n            q[1] > this.bbox3D[1][0] - Mat.eps &&\r\n            q[1] < this.bbox3D[1][1] + Mat.eps &&\r\n            q[2] > this.bbox3D[2][0] - Mat.eps &&\r\n            q[2] < this.bbox3D[2][1] + Mat.eps\r\n        );\r\n    },\r\n\r\n    /**\r\n     *\r\n     * @param {JXG.Plane3D} plane1\r\n     * @param {JXG.Plane3D} plane2\r\n     * @param {Number} d Right hand side of Hesse normal for plane2 (it can be adjusted)\r\n     * @returns {Array} of length 2 containing the coordinates of the defining points of\r\n     * of the intersection segment, or false if there is no intersection\r\n     */\r\n    intersectionPlanePlane: function (plane1, plane2, d) {\r\n        var ret = [false, false],\r\n            p, q, r, w,\r\n            dir;\r\n\r\n        d = d || plane2.d;\r\n\r\n        // Get one point of the intersection of the two planes\r\n        w = Mat.crossProduct(plane1.normal.slice(1), plane2.normal.slice(1));\r\n        w.unshift(0);\r\n\r\n        p = Mat.Geometry.meet3Planes(\r\n            plane1.normal,\r\n            plane1.d,\r\n            plane2.normal,\r\n            d,\r\n            w,\r\n            0\r\n        );\r\n\r\n        // Get the direction of the intersecting line of the two planes\r\n        dir = Mat.Geometry.meetPlanePlane(\r\n            plane1.vec1,\r\n            plane1.vec2,\r\n            plane2.vec1,\r\n            plane2.vec2\r\n        );\r\n\r\n        // Get the bounding points of the intersecting segment\r\n        r = this.intersectionLineCube(p, dir, Infinity);\r\n        q = Mat.axpy(r, dir, p);\r\n        if (this.isInCube(q)) {\r\n            ret[0] = q;\r\n        }\r\n        r = this.intersectionLineCube(p, dir, -Infinity);\r\n        q = Mat.axpy(r, dir, p);\r\n        if (this.isInCube(q)) {\r\n            ret[1] = q;\r\n        }\r\n\r\n        return ret;\r\n    },\r\n\r\n    intersectionPlaneFace: function (plane, face) {\r\n        var ret = [],\r\n            j, t,\r\n            p, crds,\r\n            p1, p2, c,\r\n            f, le, x1, y1, x2, y2,\r\n            dir, vec, w,\r\n            mat = [], b = [], sol;\r\n\r\n        w = Mat.crossProduct(plane.normal.slice(1), face.normal.slice(1));\r\n        w.unshift(0);\r\n\r\n        // Get one point of the intersection of the two planes\r\n        p = Geometry.meet3Planes(\r\n            plane.normal,\r\n            plane.d,\r\n            face.normal,\r\n            face.d,\r\n            w,\r\n            0\r\n        );\r\n\r\n        // Get the direction the intersecting line of the two planes\r\n        dir = Geometry.meetPlanePlane(\r\n            plane.vec1,\r\n            plane.vec2,\r\n            face.vec1,\r\n            face.vec2\r\n        );\r\n\r\n        f = face.polyhedron.faces[face.faceNumber];\r\n        crds = face.polyhedron.coords;\r\n        le = f.length;\r\n        for (j = 1; j <= le; j++) {\r\n            p1 = crds[f[j - 1]];\r\n            p2 = crds[f[j % le]];\r\n            vec = [0, p2[1] - p1[1], p2[2] - p1[2], p2[3] - p1[3]];\r\n\r\n            x1 = Math.random();\r\n            y1 = Math.random();\r\n            x2 = Math.random();\r\n            y2 = Math.random();\r\n            mat = [\r\n                [x1 * dir[1] + y1 * dir[3], x1 * (-vec[1]) + y1 * (-vec[3])],\r\n                [x2 * dir[2] + y2 * dir[3], x2 * (-vec[2]) + y2 * (-vec[3])]\r\n            ];\r\n            b = [\r\n                x1 * (p1[1] - p[1]) + y1 * (p1[3] - p[3]),\r\n                x2 * (p1[2] - p[2]) + y2 * (p1[3] - p[3])\r\n            ];\r\n\r\n            sol = Numerics.Gauss(mat, b);\r\n            t = sol[1];\r\n            if (t > -Mat.eps && t < 1 + Mat.eps) {\r\n                c = [1, p1[1] + t * vec[1], p1[2] + t * vec[2], p1[3] + t * vec[3]];\r\n                ret.push(c);\r\n            }\r\n        }\r\n\r\n        return ret;\r\n    },\r\n\r\n    // TODO:\r\n    // - handle non-closed polyhedra\r\n    // - handle intersections in vertex, edge, plane\r\n    intersectionPlanePolyhedron: function(plane, phdr) {\r\n        var i, j, seg,\r\n            p, first, pos, pos_akt,\r\n            eps = 1e-12,\r\n            points = [],\r\n            x = [],\r\n            y = [],\r\n            z = [];\r\n\r\n        for (i = 0; i < phdr.numberFaces; i++) {\r\n            if (phdr.def.faces[i].length < 3) {\r\n                // We skip intersection with points or lines\r\n                continue;\r\n            }\r\n\r\n            // seg will be an array consisting of two points\r\n            // that span the intersecting segment of the plane\r\n            // and the face.\r\n            seg = this.intersectionPlaneFace(plane, phdr.faces[i]);\r\n\r\n            // Plane intersects the face in less than 2 points\r\n            if (seg.length < 2) {\r\n                continue;\r\n            }\r\n\r\n            if (seg[0].length === 4 && seg[1].length === 4) {\r\n                // This test is necessary to filter out intersection lines which are\r\n                // identical to intersections of axis planes (they would occur twice),\r\n                // i.e. edges of bbox3d.\r\n                for (j = 0; j < points.length; j++) {\r\n                    if (\r\n                        (Geometry.distance(seg[0], points[j][0], 4) < eps &&\r\n                            Geometry.distance(seg[1], points[j][1], 4) < eps) ||\r\n                        (Geometry.distance(seg[0], points[j][1], 4) < eps &&\r\n                            Geometry.distance(seg[1], points[j][0], 4) < eps)\r\n                    ) {\r\n                        break;\r\n                    }\r\n                }\r\n                if (j === points.length) {\r\n                    points.push(seg.slice());\r\n                }\r\n            }\r\n        }\r\n\r\n        // Handle the case that the intersection is the empty set.\r\n        if (points.length === 0) {\r\n            return { X: x, Y: y, Z: z };\r\n        }\r\n\r\n        // Concatenate the intersection points to a polygon.\r\n        // If all went well, each intersection should appear\r\n        // twice in the list.\r\n        // __Attention:__ each face has to be planar!!!\r\n        // Otherwise the algorithm will fail.\r\n        first = 0;\r\n        pos = first;\r\n        i = 0;\r\n        do {\r\n            p = points[pos][i];\r\n            if (p.length === 4) {\r\n                x.push(p[1]);\r\n                y.push(p[2]);\r\n                z.push(p[3]);\r\n            }\r\n            i = (i + 1) % 2;\r\n            p = points[pos][i];\r\n\r\n            pos_akt = pos;\r\n            for (j = 0; j < points.length; j++) {\r\n                if (j !== pos && Geometry.distance(p, points[j][0]) < eps) {\r\n                    pos = j;\r\n                    i = 0;\r\n                    break;\r\n                }\r\n                if (j !== pos && Geometry.distance(p, points[j][1]) < eps) {\r\n                    pos = j;\r\n                    i = 1;\r\n                    break;\r\n                }\r\n            }\r\n            if (pos === pos_akt) {\r\n                console.log('Error face3d intersection update: did not find next', pos, i);\r\n                break;\r\n            }\r\n        } while (pos !== first);\r\n        x.push(x[0]);\r\n        y.push(y[0]);\r\n        z.push(z[0]);\r\n\r\n        return { X: x, Y: y, Z: z };\r\n    },\r\n\r\n    /**\r\n     * Generate mesh for a surface / plane.\r\n     * Returns array [dataX, dataY] for a JSXGraph curve's updateDataArray function.\r\n     * @param {Array|Function} func\r\n     * @param {Array} interval_u\r\n     * @param {Array} interval_v\r\n     * @returns Array\r\n     * @private\r\n     *\r\n     * @example\r\n     *  var el = view.create('curve', [[], []]);\r\n     *  el.updateDataArray = function () {\r\n     *      var steps_u = this.evalVisProp('stepsu'),\r\n     *           steps_v = this.evalVisProp('stepsv'),\r\n     *           r_u = Type.evaluate(this.range_u),\r\n     *           r_v = Type.evaluate(this.range_v),\r\n     *           func, ret;\r\n     *\r\n     *      if (this.F !== null) {\r\n     *          func = this.F;\r\n     *      } else {\r\n     *          func = [this.X, this.Y, this.Z];\r\n     *      }\r\n     *      ret = this.view.getMesh(func,\r\n     *          r_u.concat([steps_u]),\r\n     *          r_v.concat([steps_v]));\r\n     *\r\n     *      this.dataX = ret[0];\r\n     *      this.dataY = ret[1];\r\n     *  };\r\n     *\r\n     */\r\n    getMesh: function (func, interval_u, interval_v) {\r\n        var i_u, i_v, u, v,\r\n            c2d, delta_u, delta_v,\r\n            p = [0, 0, 0],\r\n            steps_u = Type.evaluate(interval_u[2]),\r\n            steps_v = Type.evaluate(interval_v[2]),\r\n            dataX = [],\r\n            dataY = [];\r\n\r\n        delta_u = (Type.evaluate(interval_u[1]) - Type.evaluate(interval_u[0])) / steps_u;\r\n        delta_v = (Type.evaluate(interval_v[1]) - Type.evaluate(interval_v[0])) / steps_v;\r\n\r\n        for (i_u = 0; i_u <= steps_u; i_u++) {\r\n            u = interval_u[0] + delta_u * i_u;\r\n            for (i_v = 0; i_v <= steps_v; i_v++) {\r\n                v = interval_v[0] + delta_v * i_v;\r\n                if (Type.isFunction(func)) {\r\n                    p = func(u, v);\r\n                } else {\r\n                    p = [func[0](u, v), func[1](u, v), func[2](u, v)];\r\n                }\r\n                c2d = this.project3DTo2D(p);\r\n                dataX.push(c2d[1]);\r\n                dataY.push(c2d[2]);\r\n            }\r\n            dataX.push(NaN);\r\n            dataY.push(NaN);\r\n        }\r\n\r\n        for (i_v = 0; i_v <= steps_v; i_v++) {\r\n            v = interval_v[0] + delta_v * i_v;\r\n            for (i_u = 0; i_u <= steps_u; i_u++) {\r\n                u = interval_u[0] + delta_u * i_u;\r\n                if (Type.isFunction(func)) {\r\n                    p = func(u, v);\r\n                } else {\r\n                    p = [func[0](u, v), func[1](u, v), func[2](u, v)];\r\n                }\r\n                c2d = this.project3DTo2D(p);\r\n                dataX.push(c2d[1]);\r\n                dataY.push(c2d[2]);\r\n            }\r\n            dataX.push(NaN);\r\n            dataY.push(NaN);\r\n        }\r\n\r\n        return [dataX, dataY];\r\n    },\r\n\r\n    /**\r\n     *\r\n     */\r\n    animateAzimuth: function () {\r\n        var s = this.az_slide._smin,\r\n            e = this.az_slide._smax,\r\n            sdiff = e - s,\r\n            newVal = this.az_slide.Value() + 0.1;\r\n\r\n        this.az_slide.position = (newVal - s) / sdiff;\r\n        if (this.az_slide.position > 1) {\r\n            this.az_slide.position = 0.0;\r\n        }\r\n        this.board._change3DView = true;\r\n        this.board.update();\r\n        this.board._change3DView = false;\r\n\r\n        this.timeoutAzimuth = setTimeout(function () {\r\n            this.animateAzimuth();\r\n        }.bind(this), 200);\r\n    },\r\n\r\n    /**\r\n     *\r\n     */\r\n    stopAzimuth: function () {\r\n        clearTimeout(this.timeoutAzimuth);\r\n        this.timeoutAzimuth = null;\r\n    },\r\n\r\n    /**\r\n     * Check if vertical dragging is enabled and which action is needed.\r\n     * Default is shiftKey.\r\n     *\r\n     * @returns Boolean\r\n     * @private\r\n     */\r\n    isVerticalDrag: function () {\r\n        var b = this.board,\r\n            key;\r\n        if (!this.evalVisProp('verticaldrag.enabled')) {\r\n            return false;\r\n        }\r\n        key = '_' + this.evalVisProp('verticaldrag.key') + 'Key';\r\n        return b[key];\r\n    },\r\n\r\n    /**\r\n     * Sets camera view to the given values.\r\n     *\r\n     * @param {Number} az Value of azimuth.\r\n     * @param {Number} el Value of elevation.\r\n     * @param {Number} [r] Value of radius.\r\n     *\r\n     * @returns {Object} Reference to the view.\r\n     */\r\n    setView: function (az, el, r) {\r\n        r = r || this.r;\r\n\r\n        this.az_slide.setValue(az);\r\n        this.el_slide.setValue(el);\r\n        this.r = r;\r\n        this.board.update();\r\n\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * Changes view to the next view stored in the attribute `values`.\r\n     *\r\n     * @see View3D#values\r\n     *\r\n     * @returns {Object} Reference to the view.\r\n     */\r\n    nextView: function () {\r\n        var views = this.evalVisProp('values'),\r\n            n = this.visProp._currentview;\r\n\r\n        n = (n + 1) % views.length;\r\n        this.setCurrentView(n);\r\n\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * Changes view to the previous view stored in the attribute `values`.\r\n     *\r\n     * @see View3D#values\r\n     *\r\n     * @returns {Object} Reference to the view.\r\n     */\r\n    previousView: function () {\r\n        var views = this.evalVisProp('values'),\r\n            n = this.visProp._currentview;\r\n\r\n        n = (n + views.length - 1) % views.length;\r\n        this.setCurrentView(n);\r\n\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * Changes view to the determined view stored in the attribute `values`.\r\n     *\r\n     * @see View3D#values\r\n     *\r\n     * @param {Number} n Index of view in attribute `values`.\r\n     * @returns {Object} Reference to the view.\r\n     */\r\n    setCurrentView: function (n) {\r\n        var views = this.evalVisProp('values');\r\n\r\n        if (n < 0 || n >= views.length) {\r\n            n = ((n % views.length) + views.length) % views.length;\r\n        }\r\n\r\n        this.setView(views[n][0], views[n][1], views[n][2]);\r\n        this.visProp._currentview = n;\r\n\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * Controls the navigation in az direction using either the keyboard or a pointer.\r\n     *\r\n     * @private\r\n     *\r\n     * @param {event} evt either the keydown or the pointer event\r\n     * @returns view\r\n     */\r\n    _azEventHandler: function (evt) {\r\n        var smax = this.az_slide._smax,\r\n            smin = this.az_slide._smin,\r\n            speed = (smax - smin) / this.board.canvasWidth * (this.evalVisProp('az.pointer.speed')),\r\n            delta = evt.movementX,\r\n            az = this.az_slide.Value(),\r\n            el = this.el_slide.Value();\r\n\r\n        // Doesn't allow navigation if another moving event is triggered\r\n        if (this.board.mode === this.board.BOARD_MODE_DRAG) {\r\n            return this;\r\n        }\r\n\r\n        // Calculate new az value if keyboard events are triggered\r\n        // Plus if right-button, minus if left-button\r\n        if (this.evalVisProp('az.keyboard.enabled')) {\r\n            if (evt.key === 'ArrowRight') {\r\n                az = az + this.evalVisProp('az.keyboard.step') * Math.PI / 180;\r\n            } else if (evt.key === 'ArrowLeft') {\r\n                az = az - this.evalVisProp('az.keyboard.step') * Math.PI / 180;\r\n            }\r\n        }\r\n\r\n        if (this.evalVisProp('az.pointer.enabled') && (delta !== 0) && evt.key == null) {\r\n            az += delta * speed;\r\n        }\r\n\r\n        // Project the calculated az value to a usable value in the interval [smin,smax]\r\n        // Use modulo if continuous is true\r\n        if (this.evalVisProp('az.continuous')) {\r\n            az = Mat.wrap(az, smin, smax);\r\n        } else {\r\n            if (az > 0) {\r\n                az = Math.min(smax, az);\r\n            } else if (az < 0) {\r\n                az = Math.max(smin, az);\r\n            }\r\n        }\r\n\r\n        this.setView(az, el);\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * Controls the navigation in el direction using either the keyboard or a pointer.\r\n     *\r\n     * @private\r\n     *\r\n     * @param {event} evt either the keydown or the pointer event\r\n     * @returns view\r\n     */\r\n    _elEventHandler: function (evt) {\r\n        var smax = this.el_slide._smax,\r\n            smin = this.el_slide._smin,\r\n            speed = (smax - smin) / this.board.canvasHeight * this.evalVisProp('el.pointer.speed'),\r\n            delta = evt.movementY,\r\n            az = this.az_slide.Value(),\r\n            el = this.el_slide.Value();\r\n\r\n        // Doesn't allow navigation if another moving event is triggered\r\n        if (this.board.mode === this.board.BOARD_MODE_DRAG) {\r\n            return this;\r\n        }\r\n\r\n        // Calculate new az value if keyboard events are triggered\r\n        // Plus if down-button, minus if up-button\r\n        if (this.evalVisProp('el.keyboard.enabled')) {\r\n            if (evt.key === 'ArrowUp') {\r\n                el = el - this.evalVisProp('el.keyboard.step') * Math.PI / 180;\r\n            } else if (evt.key === 'ArrowDown') {\r\n                el = el + this.evalVisProp('el.keyboard.step') * Math.PI / 180;\r\n            }\r\n        }\r\n\r\n        if (this.evalVisProp('el.pointer.enabled') && (delta !== 0) && evt.key == null) {\r\n            el += delta * speed;\r\n        }\r\n\r\n        // Project the calculated el value to a usable value in the interval [smin,smax]\r\n        // Use modulo if continuous is true and the trackball is disabled\r\n        if (this.evalVisProp('el.continuous') && !this.trackballEnabled) {\r\n            el = Mat.wrap(el, smin, smax);\r\n        } else {\r\n            if (el > 0) {\r\n                el = Math.min(smax, el);\r\n            } else if (el < 0) {\r\n                el = Math.max(smin, el);\r\n            }\r\n        }\r\n\r\n        this.setView(az, el);\r\n\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * Controls the navigation in bank direction using either the keyboard or a pointer.\r\n     *\r\n     * @private\r\n     *\r\n     * @param {event} evt either the keydown or the pointer event\r\n     * @returns view\r\n     */\r\n    _bankEventHandler: function (evt) {\r\n        var smax = this.bank_slide._smax,\r\n            smin = this.bank_slide._smin,\r\n            step, speed,\r\n            delta = evt.deltaY,\r\n            bank = this.bank_slide.Value();\r\n\r\n        // Doesn't allow navigation if another moving event is triggered\r\n        if (this.board.mode === this.board.BOARD_MODE_DRAG) {\r\n            return this;\r\n        }\r\n\r\n        // Calculate new bank value if keyboard events are triggered\r\n        // Plus if down-button, minus if up-button\r\n        if (this.evalVisProp('bank.keyboard.enabled')) {\r\n            step = this.evalVisProp('bank.keyboard.step') * Math.PI / 180;\r\n            if (evt.key === '.' || evt.key === '<') {\r\n                bank -= step;\r\n            } else if (evt.key === ',' || evt.key === '>') {\r\n                bank += step;\r\n            }\r\n        }\r\n\r\n        if (this.evalVisProp('bank.pointer.enabled') && (delta !== 0) && evt.key == null) {\r\n            speed = (smax - smin) / this.board.canvasHeight * this.evalVisProp('bank.pointer.speed');\r\n            bank += delta * speed;\r\n\r\n            // prevent the pointer wheel from scrolling the page\r\n            evt.preventDefault();\r\n        }\r\n\r\n        // Project the calculated bank value to a usable value in the interval [smin,smax]\r\n        if (this.evalVisProp('bank.continuous')) {\r\n            // in continuous mode, wrap value around slider range\r\n            bank = Mat.wrap(bank, smin, smax);\r\n        } else {\r\n            // in non-continuous mode, clamp value to slider range\r\n            bank = Mat.clamp(bank, smin, smax);\r\n        }\r\n\r\n        this.bank_slide.setValue(bank);\r\n        this.board.update();\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * Controls the navigation using either virtual trackball.\r\n     *\r\n     * @private\r\n     *\r\n     * @param {event} evt either the keydown or the pointer event\r\n     * @returns view\r\n     */\r\n    _trackballHandler: function (evt) {\r\n        var pos = this.board.getMousePosition(evt),\r\n            x, y, center;\r\n\r\n        center = new Coords(Const.COORDS_BY_USER, [this.llftCorner[0] + this.size[0] * 0.5, this.llftCorner[1] + this.size[1] * 0.5], this.board);\r\n        x = pos[0] - center.scrCoords[1];\r\n        y = pos[1] - center.scrCoords[2];\r\n        this._trackball = {\r\n            dx: evt.movementX,\r\n            dy: -evt.movementY,\r\n            x: x,\r\n            y: -y\r\n        };\r\n        this.board.update();\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * Event handler for pointer down event. Triggers handling of all 3D navigation.\r\n     *\r\n     * @private\r\n     * @param {event} evt\r\n     * @returns view\r\n     */\r\n    pointerDownHandler: function (evt) {\r\n        var neededButton, neededKey, target;\r\n\r\n        this._hasMoveAz = false;\r\n        this._hasMoveEl = false;\r\n        this._hasMoveBank = false;\r\n        this._hasMoveTrackball = false;\r\n\r\n        if (this.board.mode !== this.board.BOARD_MODE_NONE) {\r\n            return;\r\n        }\r\n\r\n        this.board._change3DView = true;\r\n\r\n        if (this.evalVisProp('trackball.enabled')) {\r\n            neededButton = this.evalVisProp('trackball.button');\r\n            neededKey = this.evalVisProp('trackball.key');\r\n\r\n            // Move events for virtual trackball\r\n            if (\r\n                (neededButton === -1 || neededButton === evt.button) &&\r\n                (neededKey === 'none' || (neededKey.indexOf('shift') > -1 && evt.shiftKey) || (neededKey.indexOf('ctrl') > -1 && evt.ctrlKey))\r\n            ) {\r\n                // If outside is true then the event listener is bound to the document, otherwise to the div\r\n                target = (this.evalVisProp('trackball.outside')) ? document : this.board.containerObj;\r\n                Env.addEvent(target, 'pointermove', this._trackballHandler, this);\r\n                this._hasMoveTrackball = true;\r\n            }\r\n        } else {\r\n            if (this.evalVisProp('az.pointer.enabled')) {\r\n                neededButton = this.evalVisProp('az.pointer.button');\r\n                neededKey = this.evalVisProp('az.pointer.key');\r\n\r\n                // Move events for azimuth\r\n                if (\r\n                    (neededButton === -1 || neededButton === evt.button) &&\r\n                    (neededKey === 'none' || (neededKey.indexOf('shift') > -1 && evt.shiftKey) || (neededKey.indexOf('ctrl') > -1 && evt.ctrlKey))\r\n                ) {\r\n                    // If outside is true then the event listener is bound to the document, otherwise to the div\r\n                    target = (this.evalVisProp('az.pointer.outside')) ? document : this.board.containerObj;\r\n                    Env.addEvent(target, 'pointermove', this._azEventHandler, this);\r\n                    this._hasMoveAz = true;\r\n                }\r\n            }\r\n\r\n            if (this.evalVisProp('el.pointer.enabled')) {\r\n                neededButton = this.evalVisProp('el.pointer.button');\r\n                neededKey = this.evalVisProp('el.pointer.key');\r\n\r\n                // Events for elevation\r\n                if (\r\n                    (neededButton === -1 || neededButton === evt.button) &&\r\n                    (neededKey === 'none' || (neededKey.indexOf('shift') > -1 && evt.shiftKey) || (neededKey.indexOf('ctrl') > -1 && evt.ctrlKey))\r\n                ) {\r\n                    // If outside is true then the event listener is bound to the document, otherwise to the div\r\n                    target = (this.evalVisProp('el.pointer.outside')) ? document : this.board.containerObj;\r\n                    Env.addEvent(target, 'pointermove', this._elEventHandler, this);\r\n                    this._hasMoveEl = true;\r\n                }\r\n            }\r\n\r\n            if (this.evalVisProp('bank.pointer.enabled')) {\r\n                neededButton = this.evalVisProp('bank.pointer.button');\r\n                neededKey = this.evalVisProp('bank.pointer.key');\r\n\r\n                // Events for bank\r\n                if (\r\n                    (neededButton === -1 || neededButton === evt.button) &&\r\n                    (neededKey === 'none' || (neededKey.indexOf('shift') > -1 && evt.shiftKey) || (neededKey.indexOf('ctrl') > -1 && evt.ctrlKey))\r\n                ) {\r\n                    // If `outside` is true, we bind the event listener to\r\n                    // the document. otherwise, we bind it to the div. we\r\n                    // register the event listener as active so it can\r\n                    // prevent the pointer wheel from scrolling the page\r\n                    target = (this.evalVisProp('bank.pointer.outside')) ? document : this.board.containerObj;\r\n                    Env.addEvent(target, 'wheel', this._bankEventHandler, this, { passive: false });\r\n                    this._hasMoveBank = true;\r\n                }\r\n            }\r\n        }\r\n        Env.addEvent(document, 'pointerup', this.pointerUpHandler, this);\r\n    },\r\n\r\n    /**\r\n     * Event handler for pointer up event. Triggers handling of all 3D navigation.\r\n     *\r\n     * @private\r\n     * @param {event} evt\r\n     * @returns view\r\n     */\r\n    pointerUpHandler: function (evt) {\r\n        var target;\r\n\r\n        if (this._hasMoveAz) {\r\n            target = (this.evalVisProp('az.pointer.outside')) ? document : this.board.containerObj;\r\n            Env.removeEvent(target, 'pointermove', this._azEventHandler, this);\r\n            this._hasMoveAz = false;\r\n        }\r\n        if (this._hasMoveEl) {\r\n            target = (this.evalVisProp('el.pointer.outside')) ? document : this.board.containerObj;\r\n            Env.removeEvent(target, 'pointermove', this._elEventHandler, this);\r\n            this._hasMoveEl = false;\r\n        }\r\n        if (this._hasMoveBank) {\r\n            target = (this.evalVisProp('bank.pointer.outside')) ? document : this.board.containerObj;\r\n            Env.removeEvent(target, 'wheel', this._bankEventHandler, this);\r\n            this._hasMoveBank = false;\r\n        }\r\n        if (this._hasMoveTrackball) {\r\n            target = (this.evalVisProp('trackball.outside')) ? document : this.board.containerObj;\r\n            Env.removeEvent(target, 'pointermove', this._trackballHandler, this);\r\n            this._hasMoveTrackball = false;\r\n        }\r\n        Env.removeEvent(document, 'pointerup', this.pointerUpHandler, this);\r\n        this.board._change3DView = false;\r\n\r\n    }\r\n});\r\n\r\n/**\r\n * @class A View3D element provides the container and the methods to create and display 3D elements.\r\n * @pseudo\r\n * @description  A View3D element provides the container and the methods to create and display 3D elements.\r\n * It is contained in a JSXGraph board.\r\n * <p>\r\n * It is advisable to disable panning of the board by setting the board attribute \"pan\":\r\n * <pre>\r\n *   pan: {enabled: false}\r\n * </pre>\r\n * Otherwise users will not be able to rotate the scene with their fingers on a touch device.\r\n * <p>\r\n * The start position of the camera can be adjusted by the attributes {@link View3D#az}, {@link View3D#el}, and {@link View3D#bank}.\r\n *\r\n * @name View3D\r\n * @augments JXG.View3D\r\n * @constructor\r\n * @type Object\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Array_Array_Array} lower,dim,cube  Here, lower is an array of the form [x, y] and\r\n * dim is an array of the form [w, h].\r\n * The arrays [x, y] and [w, h] define the 2D frame into which the 3D cube is\r\n * (roughly) projected. If the view's azimuth=0 and elevation=0, the 3D view will cover a rectangle with lower left corner\r\n * [x,y] and side lengths [w, h] of the board.\r\n * The array 'cube' is of the form [[x1, x2], [y1, y2], [z1, z2]]\r\n * which determines the coordinate ranges of the 3D cube.\r\n *\r\n * @example\r\n *     var bound = [-4, 6];\r\n *     var view = board.create('view3d',\r\n *         [[-4, -3], [8, 8],\r\n *         [bound, bound, bound]],\r\n *         {\r\n *             projection: 'parallel',\r\n *             trackball: {enabled:true},\r\n *         });\r\n *\r\n *     var curve = view.create('curve3d', [\r\n *         (t) => (2 + Math.cos(3 * t)) * Math.cos(2 * t),\r\n *         (t) => (2 + Math.cos(3 * t)) * Math.sin(2 * t),\r\n *         (t) => Math.sin(3 * t),\r\n *         [-Math.PI, Math.PI]\r\n *     ], { strokeWidth: 4 });\r\n *\r\n * </pre><div id=\"JXG9b327a6c-1bd6-4e40-a502-59d024dbfd1b\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG9b327a6c-1bd6-4e40-a502-59d024dbfd1b',\r\n *             {boundingbox: [-8, 8, 8,-8], pan: {enabled: false}, axis: false, showcopyright: false, shownavigation: false});\r\n *         var bound = [-4, 6];\r\n *         var view = board.create('view3d',\r\n *             [[-4, -3], [8, 8],\r\n *             [bound, bound, bound]],\r\n *             {\r\n *                 projection: 'parallel',\r\n *                 trackball: {enabled:true},\r\n *             });\r\n *\r\n *         var curve = view.create('curve3d', [\r\n *             (t) => (2 + Math.cos(3 * t)) * Math.cos(2 * t),\r\n *             (t) => (2 + Math.cos(3 * t)) * Math.sin(2 * t),\r\n *             (t) => Math.sin(3 * t),\r\n *             [-Math.PI, Math.PI]\r\n *         ], { strokeWidth: 4 });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *     var bound = [-4, 6];\r\n *     var view = board.create('view3d',\r\n *         [[-4, -3], [8, 8],\r\n *         [bound, bound, bound]],\r\n *         {\r\n *             projection: 'central',\r\n *             trackball: {enabled:true},\r\n *\r\n *             xPlaneRear: { visible: false },\r\n *             yPlaneRear: { visible: false }\r\n *\r\n *         });\r\n *\r\n *     var curve = view.create('curve3d', [\r\n *         (t) => (2 + Math.cos(3 * t)) * Math.cos(2 * t),\r\n *         (t) => (2 + Math.cos(3 * t)) * Math.sin(2 * t),\r\n *         (t) => Math.sin(3 * t),\r\n *         [-Math.PI, Math.PI]\r\n *     ], { strokeWidth: 4 });\r\n *\r\n * </pre><div id=\"JXG0dc2493d-fb2f-40d5-bdb8-762ba0ad2007\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG0dc2493d-fb2f-40d5-bdb8-762ba0ad2007',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});\r\n *         var bound = [-4, 6];\r\n *         var view = board.create('view3d',\r\n *             [[-4, -3], [8, 8],\r\n *             [bound, bound, bound]],\r\n *             {\r\n *                 projection: 'central',\r\n *                 trackball: {enabled:true},\r\n *\r\n *                 xPlaneRear: { visible: false },\r\n *                 yPlaneRear: { visible: false }\r\n *\r\n *             });\r\n *\r\n *         var curve = view.create('curve3d', [\r\n *             (t) => (2 + Math.cos(3 * t)) * Math.cos(2 * t),\r\n *             (t) => (2 + Math.cos(3 * t)) * Math.sin(2 * t),\r\n *             (t) => Math.sin(3 * t),\r\n *             [-Math.PI, Math.PI]\r\n *         ], { strokeWidth: 4 });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n* @example\r\n *     var bound = [-4, 6];\r\n *     var view = board.create('view3d',\r\n *         [[-4, -3], [8, 8],\r\n *         [bound, bound, bound]],\r\n *         {\r\n *             projection: 'central',\r\n *             trackball: {enabled:true},\r\n *\r\n *             // Main axes\r\n *             axesPosition: 'border',\r\n *\r\n *             // Axes at the border\r\n *             xAxisBorder: { ticks3d: { ticksDistance: 2} },\r\n *             yAxisBorder: { ticks3d: { ticksDistance: 2} },\r\n *             zAxisBorder: { ticks3d: { ticksDistance: 2} },\r\n *\r\n *             // No axes on planes\r\n *             xPlaneRearYAxis: {visible: false},\r\n *             xPlaneRearZAxis: {visible: false},\r\n *             yPlaneRearXAxis: {visible: false},\r\n *             yPlaneRearZAxis: {visible: false},\r\n *             zPlaneRearXAxis: {visible: false},\r\n *             zPlaneRearYAxis: {visible: false}\r\n *         });\r\n *\r\n *     var curve = view.create('curve3d', [\r\n *         (t) => (2 + Math.cos(3 * t)) * Math.cos(2 * t),\r\n *         (t) => (2 + Math.cos(3 * t)) * Math.sin(2 * t),\r\n *         (t) => Math.sin(3 * t),\r\n *         [-Math.PI, Math.PI]\r\n *     ], { strokeWidth: 4 });\r\n *\r\n * </pre><div id=\"JXG586f3551-335c-47e9-8d72-835409f6a103\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG586f3551-335c-47e9-8d72-835409f6a103',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});\r\n *         var bound = [-4, 6];\r\n *         var view = board.create('view3d',\r\n *             [[-4, -3], [8, 8],\r\n *             [bound, bound, bound]],\r\n *             {\r\n *                 projection: 'central',\r\n *                 trackball: {enabled:true},\r\n *\r\n *                 // Main axes\r\n *                 axesPosition: 'border',\r\n *\r\n *                 // Axes at the border\r\n *                 xAxisBorder: { ticks3d: { ticksDistance: 2} },\r\n *                 yAxisBorder: { ticks3d: { ticksDistance: 2} },\r\n *                 zAxisBorder: { ticks3d: { ticksDistance: 2} },\r\n *\r\n *                 // No axes on planes\r\n *                 xPlaneRearYAxis: {visible: false},\r\n *                 xPlaneRearZAxis: {visible: false},\r\n *                 yPlaneRearXAxis: {visible: false},\r\n *                 yPlaneRearZAxis: {visible: false},\r\n *                 zPlaneRearXAxis: {visible: false},\r\n *                 zPlaneRearYAxis: {visible: false}\r\n *             });\r\n *\r\n *         var curve = view.create('curve3d', [\r\n *             (t) => (2 + Math.cos(3 * t)) * Math.cos(2 * t),\r\n *             (t) => (2 + Math.cos(3 * t)) * Math.sin(2 * t),\r\n *             (t) => Math.sin(3 * t),\r\n *             [-Math.PI, Math.PI]\r\n *         ], { strokeWidth: 4 });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *     var bound = [-4, 6];\r\n *     var view = board.create('view3d',\r\n *         [[-4, -3], [8, 8],\r\n *         [bound, bound, bound]],\r\n *         {\r\n *             projection: 'central',\r\n *             trackball: {enabled:true},\r\n *\r\n *             axesPosition: 'none'\r\n *         });\r\n *\r\n *     var curve = view.create('curve3d', [\r\n *         (t) => (2 + Math.cos(3 * t)) * Math.cos(2 * t),\r\n *         (t) => (2 + Math.cos(3 * t)) * Math.sin(2 * t),\r\n *         (t) => Math.sin(3 * t),\r\n *         [-Math.PI, Math.PI]\r\n *     ], { strokeWidth: 4 });\r\n *\r\n * </pre><div id=\"JXG9a9467e1-f189-4c8c-adb2-d4f49bc7fa26\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG9a9467e1-f189-4c8c-adb2-d4f49bc7fa26',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});\r\n *         var bound = [-4, 6];\r\n *         var view = board.create('view3d',\r\n *             [[-4, -3], [8, 8],\r\n *             [bound, bound, bound]],\r\n *             {\r\n *                 projection: 'central',\r\n *                 trackball: {enabled:true},\r\n *\r\n *                 axesPosition: 'none'\r\n *             });\r\n *\r\n *         var curve = view.create('curve3d', [\r\n *             (t) => (2 + Math.cos(3 * t)) * Math.cos(2 * t),\r\n *             (t) => (2 + Math.cos(3 * t)) * Math.sin(2 * t),\r\n *             (t) => Math.sin(3 * t),\r\n *             [-Math.PI, Math.PI]\r\n *         ], { strokeWidth: 4 });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *     var bound = [-4, 6];\r\n *     var view = board.create('view3d',\r\n *         [[-4, -3], [8, 8],\r\n *         [bound, bound, bound]],\r\n *         {\r\n *             projection: 'central',\r\n *             trackball: {enabled:true},\r\n *\r\n *             // Main axes\r\n *             axesPosition: 'border',\r\n *\r\n *             // Axes at the border\r\n *             xAxisBorder: { ticks3d: { ticksDistance: 2} },\r\n *             yAxisBorder: { ticks3d: { ticksDistance: 2} },\r\n *             zAxisBorder: { ticks3d: { ticksDistance: 2} },\r\n *\r\n *             xPlaneRear: {\r\n *                 fillColor: '#fff',\r\n *                 mesh3d: {visible: false}\r\n *             },\r\n *             yPlaneRear: {\r\n *                 fillColor: '#fff',\r\n *                 mesh3d: {visible: false}\r\n *             },\r\n *             zPlaneRear: {\r\n *                 fillColor: '#fff',\r\n *                 mesh3d: {visible: false}\r\n *             },\r\n *             xPlaneFront: {\r\n *                 visible: true,\r\n *                 fillColor: '#fff',\r\n *                 mesh3d: {visible: false}\r\n *             },\r\n *             yPlaneFront: {\r\n *                 visible: true,\r\n *                 fillColor: '#fff',\r\n *                 mesh3d: {visible: false}\r\n *             },\r\n *             zPlaneFront: {\r\n *                 visible: true,\r\n *                 fillColor: '#fff',\r\n *                 mesh3d: {visible: false}\r\n *             },\r\n *\r\n *             // No axes on planes\r\n *             xPlaneRearYAxis: {visible: false},\r\n *             xPlaneRearZAxis: {visible: false},\r\n *             yPlaneRearXAxis: {visible: false},\r\n *             yPlaneRearZAxis: {visible: false},\r\n *             zPlaneRearXAxis: {visible: false},\r\n *             zPlaneRearYAxis: {visible: false},\r\n *             xPlaneFrontYAxis: {visible: false},\r\n *             xPlaneFrontZAxis: {visible: false},\r\n *             yPlaneFrontXAxis: {visible: false},\r\n *             yPlaneFrontZAxis: {visible: false},\r\n *             zPlaneFrontXAxis: {visible: false},\r\n *             zPlaneFrontYAxis: {visible: false}\r\n *\r\n *         });\r\n *\r\n *     var curve = view.create('curve3d', [\r\n *         (t) => (2 + Math.cos(3 * t)) * Math.cos(2 * t),\r\n *         (t) => (2 + Math.cos(3 * t)) * Math.sin(2 * t),\r\n *         (t) => Math.sin(3 * t),\r\n *         [-Math.PI, Math.PI]\r\n *     ], { strokeWidth: 4 });\r\n *\r\n * </pre><div id=\"JXGbd41a4e3-1bf7-4764-b675-98b01667103b\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGbd41a4e3-1bf7-4764-b675-98b01667103b',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});\r\n *         var bound = [-4, 6];\r\n *         var view = board.create('view3d',\r\n *             [[-4, -3], [8, 8],\r\n *             [bound, bound, bound]],\r\n *             {\r\n *                 projection: 'central',\r\n *                 trackball: {enabled:true},\r\n *\r\n *                 // Main axes\r\n *                 axesPosition: 'border',\r\n *\r\n *                 // Axes at the border\r\n *                 xAxisBorder: { ticks3d: { ticksDistance: 2} },\r\n *                 yAxisBorder: { ticks3d: { ticksDistance: 2} },\r\n *                 zAxisBorder: { ticks3d: { ticksDistance: 2} },\r\n *\r\n *                 xPlaneRear: {\r\n *                     fillColor: '#fff',\r\n *                     mesh3d: {visible: false}\r\n *                 },\r\n *                 yPlaneRear: {\r\n *                     fillColor: '#fff',\r\n *                     mesh3d: {visible: false}\r\n *                 },\r\n *                 zPlaneRear: {\r\n *                     fillColor: '#fff',\r\n *                     mesh3d: {visible: false}\r\n *                 },\r\n *                 xPlaneFront: {\r\n *                     visible: true,\r\n *                     fillColor: '#fff',\r\n *                     mesh3d: {visible: false}\r\n *                 },\r\n *                 yPlaneFront: {\r\n *                     visible: true,\r\n *                     fillColor: '#fff',\r\n *                     mesh3d: {visible: false}\r\n *                 },\r\n *                 zPlaneFront: {\r\n *                     visible: true,\r\n *                     fillColor: '#fff',\r\n *                     mesh3d: {visible: false}\r\n *                 },\r\n *\r\n *                 // No axes on planes\r\n *                 xPlaneRearYAxis: {visible: false},\r\n *                 xPlaneRearZAxis: {visible: false},\r\n *                 yPlaneRearXAxis: {visible: false},\r\n *                 yPlaneRearZAxis: {visible: false},\r\n *                 zPlaneRearXAxis: {visible: false},\r\n *                 zPlaneRearYAxis: {visible: false},\r\n *                 xPlaneFrontYAxis: {visible: false},\r\n *                 xPlaneFrontZAxis: {visible: false},\r\n *                 yPlaneFrontXAxis: {visible: false},\r\n *                 yPlaneFrontZAxis: {visible: false},\r\n *                 zPlaneFrontXAxis: {visible: false},\r\n *                 zPlaneFrontYAxis: {visible: false}\r\n *\r\n *             });\r\n *\r\n *         var curve = view.create('curve3d', [\r\n *             (t) => (2 + Math.cos(3 * t)) * Math.cos(2 * t),\r\n *             (t) => (2 + Math.cos(3 * t)) * Math.sin(2 * t),\r\n *             (t) => Math.sin(3 * t),\r\n *             [-Math.PI, Math.PI]\r\n *         ], { strokeWidth: 4 });\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *  var bound = [-5, 5];\r\n *  var view = board.create('view3d',\r\n *      [[-6, -3],\r\n *       [8, 8],\r\n *       [bound, bound, bound]],\r\n *      {\r\n *          // Main axes\r\n *          axesPosition: 'center',\r\n *          xAxis: { strokeColor: 'blue', strokeWidth: 3},\r\n *\r\n *          // Planes\r\n *          xPlaneRear: { fillColor: 'yellow',  mesh3d: {visible: false}},\r\n *          yPlaneFront: { visible: true, fillColor: 'blue'},\r\n *\r\n *          // Axes on planes\r\n *          xPlaneRearYAxis: {strokeColor: 'red'},\r\n *          xPlaneRearZAxis: {strokeColor: 'red'},\r\n *\r\n *          yPlaneFrontXAxis: {strokeColor: 'blue'},\r\n *          yPlaneFrontZAxis: {strokeColor: 'blue'},\r\n *\r\n *          zPlaneFrontXAxis: {visible: false},\r\n *          zPlaneFrontYAxis: {visible: false}\r\n *      });\r\n *\r\n * </pre><div id=\"JXGdd06d90e-be5d-4531-8f0b-65fc30b1a7c7\" class=\"jxgbox\" style=\"width: 500px; height: 500px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGdd06d90e-be5d-4531-8f0b-65fc30b1a7c7',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});\r\n *         var bound = [-5, 5];\r\n *         var view = board.create('view3d',\r\n *             [[-6, -3], [8, 8],\r\n *             [bound, bound, bound]],\r\n *             {\r\n *                 // Main axes\r\n *                 axesPosition: 'center',\r\n *                 xAxis: { strokeColor: 'blue', strokeWidth: 3},\r\n *                 // Planes\r\n *                 xPlaneRear: { fillColor: 'yellow',  mesh3d: {visible: false}},\r\n *                 yPlaneFront: { visible: true, fillColor: 'blue'},\r\n *                 // Axes on planes\r\n *                 xPlaneRearYAxis: {strokeColor: 'red'},\r\n *                 xPlaneRearZAxis: {strokeColor: 'red'},\r\n *                 yPlaneFrontXAxis: {strokeColor: 'blue'},\r\n *                 yPlaneFrontZAxis: {strokeColor: 'blue'},\r\n *                 zPlaneFrontXAxis: {visible: false},\r\n *                 zPlaneFrontYAxis: {visible: false}\r\n *             });\r\n *     })();\r\n *\r\n * </script><pre>\r\n * @example\r\n * var bound = [-5, 5];\r\n * var view = board.create('view3d',\r\n *     [[-6, -3], [8, 8],\r\n *     [bound, bound, bound]],\r\n *     {\r\n *         projection: 'central',\r\n *         az: {\r\n *             slider: {\r\n *                 visible: true,\r\n *                 point1: {\r\n *                     pos: [5, -4]\r\n *                 },\r\n *                 point2: {\r\n *                     pos: [5, 4]\r\n *                 },\r\n *                 label: {anchorX: 'middle'}\r\n *             }\r\n *         },\r\n *         el: {\r\n *             slider: {\r\n *                 visible: true,\r\n *                 point1: {\r\n *                     pos: [6, -5]\r\n *                 },\r\n *                 point2: {\r\n *                     pos: [6, 3]\r\n *                 },\r\n *                 label: {anchorX: 'middle'}\r\n *             }\r\n *         },\r\n *         bank: {\r\n *             slider: {\r\n *                 visible: true,\r\n *                 point1: {\r\n *                     pos: [7, -6]\r\n *                 },\r\n *                 point2: {\r\n *                     pos: [7, 2]\r\n *                 },\r\n *                 label: {anchorX: 'middle'}\r\n *             }\r\n *         }\r\n *     });\r\n *\r\n *\r\n * </pre><div id=\"JXGe181cc55-271b-419b-84fd-622326fd1d1a\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGe181cc55-271b-419b-84fd-622326fd1d1a',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});\r\n *     var bound = [-5, 5];\r\n *     var view = board.create('view3d',\r\n *         [[-6, -3], [8, 8],\r\n *         [bound, bound, bound]],\r\n *         {\r\n *             projection: 'central',\r\n *             az: {\r\n *                 slider: {\r\n *                     visible: true,\r\n *                     point1: {\r\n *                         pos: [5, -4]\r\n *                     },\r\n *                     point2: {\r\n *                         pos: [5, 4]\r\n *                     },\r\n *                     label: {anchorX: 'middle'}\r\n *                 }\r\n *             },\r\n *             el: {\r\n *                 slider: {\r\n *                     visible: true,\r\n *                     point1: {\r\n *                         pos: [6, -5]\r\n *                     },\r\n *                     point2: {\r\n *                         pos: [6, 3]\r\n *                     },\r\n *                     label: {anchorX: 'middle'}\r\n *                 }\r\n *             },\r\n *             bank: {\r\n *                 slider: {\r\n *                     visible: true,\r\n *                     point1: {\r\n *                         pos: [7, -6]\r\n *                     },\r\n *                     point2: {\r\n *                         pos: [7, 2]\r\n *                     },\r\n *                     label: {anchorX: 'middle'}\r\n *                 }\r\n *             }\r\n *         });\r\n *\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n *\r\n */\r\nJXG.createView3D = function (board, parents, attributes) {\r\n    var view, attr, attr_az, attr_el, attr_bank,\r\n        x, y, w, h,\r\n        p1, p2, v,\r\n        coords = parents[0], // llft corner\r\n        size = parents[1]; // [w, h]\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'view3d');\r\n    view = new JXG.View3D(board, parents, attr);\r\n    view.defaultAxes = view.create('axes3d', [], attr);\r\n\r\n    x = coords[0];\r\n    y = coords[1];\r\n    w = size[0];\r\n    h = size[1];\r\n\r\n    attr_az = Type.copyAttributes(attr, board.options, 'view3d', 'az', 'slider');\r\n    attr_az.name = 'az';\r\n\r\n    attr_el = Type.copyAttributes(attr, board.options, 'view3d', 'el', 'slider');\r\n    attr_el.name = 'el';\r\n\r\n    attr_bank = Type.copyAttributes(attr, board.options, 'view3d', 'bank', 'slider');\r\n    attr_bank.name = 'bank';\r\n\r\n    v = Type.evaluate(attr_az.point1.pos);\r\n    if (!Type.isArray(v)) {\r\n        // 'auto'\r\n        p1 = [x - 1, y - 2];\r\n    } else {\r\n        p1 = v;\r\n    }\r\n    v = Type.evaluate(attr_az.point2.pos);\r\n    if (!Type.isArray(v)) {\r\n        // 'auto'\r\n        p2 = [x + w + 1, y - 2];\r\n    } else {\r\n        p2 = v;\r\n    }\r\n\r\n    /**\r\n     * Slider to adapt azimuth angle\r\n     * @name JXG.View3D#az_slide\r\n     * @type {Slider}\r\n     */\r\n    view.az_slide = board.create(\r\n        'slider',\r\n        [\r\n            p1, p2,\r\n            [\r\n                Type.evaluate(attr_az.min),\r\n                Type.evaluate(attr_az.start),\r\n                Type.evaluate(attr_az.max)\r\n            ]\r\n        ],\r\n        attr_az\r\n    );\r\n    view.inherits.push(view.az_slide);\r\n    view.az_slide.elType = 'view3d_slider'; // Used in board.prepareUpdate()\r\n\r\n    v = Type.evaluate(attr_el.point1.pos);\r\n    if (!Type.isArray(v)) {\r\n        // 'auto'\r\n        p1 = [x - 1, y];\r\n    } else {\r\n        p1 = v;\r\n    }\r\n    v = Type.evaluate(attr_el.point2.pos);\r\n    if (!Type.isArray(v)) {\r\n        // 'auto'\r\n        p2 = [x - 1, y + h];\r\n    } else {\r\n        p2 = v;\r\n    }\r\n\r\n    /**\r\n     * Slider to adapt elevation angle\r\n     *\r\n     * @name JXG.View3D#el_slide\r\n     * @type {Slider}\r\n     */\r\n    view.el_slide = board.create(\r\n        'slider',\r\n        [\r\n            p1, p2,\r\n            [\r\n                Type.evaluate(attr_el.min),\r\n                Type.evaluate(attr_el.start),\r\n                Type.evaluate(attr_el.max)]\r\n        ],\r\n        attr_el\r\n    );\r\n    view.inherits.push(view.el_slide);\r\n    view.el_slide.elType = 'view3d_slider'; // Used in board.prepareUpdate()\r\n\r\n    v = Type.evaluate(attr_bank.point1.pos);\r\n    if (!Type.isArray(v)) {\r\n        // 'auto'\r\n        p1 = [x - 1, y + h + 2];\r\n    } else {\r\n        p1 = v;\r\n    }\r\n    v = Type.evaluate(attr_bank.point2.pos);\r\n    if (!Type.isArray(v)) {\r\n        // 'auto'\r\n        p2 = [x + w + 1, y + h + 2];\r\n    } else {\r\n        p2 = v;\r\n    }\r\n\r\n    /**\r\n     * Slider to adjust bank angle\r\n     *\r\n     * @name JXG.View3D#bank_slide\r\n     * @type {Slider}\r\n     */\r\n    view.bank_slide = board.create(\r\n        'slider',\r\n        [\r\n            p1, p2,\r\n            [\r\n                Type.evaluate(attr_bank.min),\r\n                Type.evaluate(attr_bank.start),\r\n                Type.evaluate(attr_bank.max)\r\n            ]\r\n        ],\r\n        attr_bank\r\n    );\r\n    view.inherits.push(view.bank_slide);\r\n    view.bank_slide.elType = 'view3d_slider'; // Used in board.prepareUpdate()\r\n\r\n    // Set special infobox attributes of view3d.infobox\r\n    // Using setAttribute() is not possible here, since we have to\r\n    // avoid a call of board.update().\r\n    // The drawback is that we can not use shortcuts\r\n    view.board.infobox.visProp = Type.merge(view.board.infobox.visProp, attr.infobox);\r\n\r\n    // 3d infobox: drag direction and coordinates\r\n    view.board.highlightInfobox = function (x, y, el) {\r\n        var d, i, c3d, foot,\r\n            pre = '',\r\n            brd = el.board,\r\n            arr, infobox,\r\n            p = null;\r\n\r\n        if (this.mode === this.BOARD_MODE_DRAG) {\r\n            // Drag direction is only shown during dragging\r\n            if (view.isVerticalDrag()) {\r\n                pre = '<span style=\"color:black; font-size:200%\">\\u21C5 &nbsp;</span>';\r\n            } else {\r\n                pre = '<span style=\"color:black; font-size:200%\">\\u21C4 &nbsp;</span>';\r\n            }\r\n        }\r\n\r\n        // Search 3D parent\r\n        for (i = 0; i < el.parents.length; i++) {\r\n            p = brd.objects[el.parents[i]];\r\n            if (p.is3D) {\r\n                break;\r\n            }\r\n        }\r\n\r\n        if (p && Type.exists(p.element2D)) {\r\n            foot = [1, 0, 0, p.coords[3]];\r\n            view._w0 = Mat.innerProduct(view.matrix3D[0], foot, 4);\r\n\r\n            c3d = view.project2DTo3DPlane(p.element2D, [1, 0, 0, 1], foot);\r\n            if (!view.isInCube(c3d)) {\r\n                view.board.highlightCustomInfobox('', p);\r\n                return;\r\n            }\r\n            d = p.evalVisProp('infoboxdigits');\r\n            infobox = view.board.infobox;\r\n            if (d === 'auto') {\r\n                if (infobox.useLocale()) {\r\n                    arr = [pre, '(', infobox.formatNumberLocale(p.X()), ' | ', infobox.formatNumberLocale(p.Y()), ' | ', infobox.formatNumberLocale(p.Z()), ')'];\r\n                } else {\r\n                    arr = [pre, '(', Type.autoDigits(p.X()), ' | ', Type.autoDigits(p.Y()), ' | ', Type.autoDigits(p.Z()), ')'];\r\n                }\r\n\r\n            } else {\r\n                if (infobox.useLocale()) {\r\n                    arr = [pre, '(', infobox.formatNumberLocale(p.X(), d), ' | ', infobox.formatNumberLocale(p.Y(), d), ' | ', infobox.formatNumberLocale(p.Z(), d), ')'];\r\n                } else {\r\n                    arr = [pre, '(', Type.toFixed(p.X(), d), ' | ', Type.toFixed(p.Y(), d), ' | ', Type.toFixed(p.Z(), d), ')'];\r\n                }\r\n            }\r\n            view.board.highlightCustomInfobox(arr.join(''), p);\r\n        } else {\r\n            view.board.highlightCustomInfobox('(' + x + ', ' + y + ')', el);\r\n        }\r\n    };\r\n\r\n    // Hack needed to enable addEvent for view3D:\r\n    view.BOARD_MODE_NONE = 0x0000;\r\n\r\n    // Add events for the keyboard navigation\r\n    Env.addEvent(board.containerObj, 'keydown', function (event) {\r\n        var neededKey,\r\n            catchEvt = false;\r\n\r\n        // this.board._change3DView = true;\r\n        if (view.evalVisProp('el.keyboard.enabled') &&\r\n            (event.key === 'ArrowUp' || event.key === 'ArrowDown')\r\n        ) {\r\n            neededKey = view.evalVisProp('el.keyboard.key');\r\n            if (neededKey === 'none' ||\r\n                (neededKey.indexOf('shift') > -1 && event.shiftKey) ||\r\n                (neededKey.indexOf('ctrl') > -1 && event.ctrlKey)) {\r\n                view._elEventHandler(event);\r\n                catchEvt = true;\r\n            }\r\n\r\n        }\r\n\r\n        if (view.evalVisProp('az.keyboard.enabled') &&\r\n            (event.key === 'ArrowLeft' || event.key === 'ArrowRight')\r\n        ) {\r\n            neededKey = view.evalVisProp('az.keyboard.key');\r\n            if (neededKey === 'none' ||\r\n                (neededKey.indexOf('shift') > -1 && event.shiftKey) ||\r\n                (neededKey.indexOf('ctrl') > -1 && event.ctrlKey)\r\n            ) {\r\n                view._azEventHandler(event);\r\n                catchEvt = true;\r\n            }\r\n        }\r\n\r\n        if (view.evalVisProp('bank.keyboard.enabled') && (event.key === ',' || event.key === '<' || event.key === '.' || event.key === '>')) {\r\n            neededKey = view.evalVisProp('bank.keyboard.key');\r\n            if (neededKey === 'none' || (neededKey.indexOf('shift') > -1 && event.shiftKey) || (neededKey.indexOf('ctrl') > -1 && event.ctrlKey)) {\r\n                view._bankEventHandler(event);\r\n                catchEvt = true;\r\n            }\r\n        }\r\n\r\n        if (event.key === 'PageUp') {\r\n            view.nextView();\r\n            catchEvt = true;\r\n        } else if (event.key === 'PageDown') {\r\n            view.previousView();\r\n            catchEvt = true;\r\n        }\r\n\r\n        if (catchEvt) {\r\n            // We stop event handling only in the case if the keypress could be\r\n            // used for the 3D view. If this is not done, input fields et al\r\n            // can not be used any more.\r\n            event.preventDefault();\r\n        }\r\n        this.board._change3DView = false;\r\n\r\n    }, view);\r\n\r\n    // Add events for the pointer navigation\r\n    Env.addEvent(board.containerObj, 'pointerdown', view.pointerDownHandler, view);\r\n\r\n    // Initialize view rotation matrix\r\n    view.getAnglesFromSliders();\r\n    view.matrix3DRot = view.getRotationFromAngles();\r\n\r\n    // override angle slider bounds when trackball navigation is enabled\r\n    view.updateAngleSliderBounds();\r\n\r\n    view.board.update();\r\n\r\n    return view;\r\n};\r\n\r\nJXG.registerElement(\"view3d\", JXG.createView3D);\r\n\r\nexport default JXG.View3D;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*global JXG:true, define: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Constructs a new GeometryElement3D object.\r\n * @class This is the basic class for 3D geometry elements like Point3D and Line3D.\r\n * @constructor\r\n * @augments JXG.GeometryElement\r\n *\r\n * @param {string} elType\r\n */\r\nJXG.GeometryElement3D = function (view, elType) {\r\n    this.elType = elType;\r\n\r\n    /**\r\n     * Pointer to the view3D in which the element is constructed\r\n     * @type JXG.View3D\r\n     * @private\r\n     */\r\n    this.view = view;\r\n\r\n    this.id = this.view.board.setId(this, elType);\r\n\r\n    /**\r\n     * Link to the 2D element(s) used to visualize the 3D element\r\n     * in a view. In case, there are several 2D elements, it is an array.\r\n     *\r\n     * @type Array\r\n     * @description JXG.GeometryElement,Array\r\n     * @private\r\n     *\r\n     * @example\r\n     *   p.element2D;\r\n     */\r\n    this.element2D = null;\r\n\r\n    /**\r\n     * If this property exists (and is true) the element is a 3D element.\r\n     *\r\n     * @type Boolean\r\n     * @private\r\n     */\r\n    this.is3D = true;\r\n\r\n    this.zIndex = 0.0;\r\n\r\n    this.view.objects[this.id] = this;\r\n\r\n    if (this.name !== \"\") {\r\n        this.view.elementsByName[this.name] = this;\r\n    }\r\n};\r\n\r\nJXG.extend(JXG.GeometryElement3D.prototype, {\r\n\r\n    setAttr2D: function(attr3D) {\r\n        var attr2D = attr3D;\r\n\r\n        attr2D.name = this.name;\r\n        attr2D.element3d = this;\r\n        attr2D.id = null; // The 2D element's id may not be controlled by the user.\r\n\r\n        return attr2D;\r\n    },\r\n\r\n    // Documented in element.js\r\n    setAttribute: function(attr) {\r\n        var i, key, value, arg, pair,\r\n        attributes = {};\r\n\r\n        // Normalize the user input\r\n        for (i = 0; i < arguments.length; i++) {\r\n            arg = arguments[i];\r\n            if (Type.isString(arg)) {\r\n                // pairRaw is string of the form 'key:value'\r\n                pair = arg.split(\":\");\r\n                attributes[Type.trim(pair[0])] = Type.trim(pair[1]);\r\n            } else if (!Type.isArray(arg)) {\r\n                // pairRaw consists of objects of the form {key1:value1,key2:value2,...}\r\n                JXG.extend(attributes, arg);\r\n            } else {\r\n                // pairRaw consists of array [key,value]\r\n                attributes[arg[0]] = arg[1];\r\n            }\r\n        }\r\n\r\n        for (i in attributes) {\r\n            if (attributes.hasOwnProperty(i)) {\r\n                key = i.replace(/\\s+/g, \"\").toLowerCase();\r\n                value = attributes[i];\r\n                switch (key) {\r\n                    case \"numberpointshigh\":\r\n                    case \"stepsu\":\r\n                    case \"stepsv\":\r\n                        if (Type.exists(this.visProp[key]) &&\r\n                        (!JXG.Validator[key] ||\r\n                            (JXG.Validator[key] && JXG.Validator[key](value)) ||\r\n                            (JXG.Validator[key] &&\r\n                                Type.isFunction(value) &&\r\n                                JXG.Validator[key](value())))\r\n                        ) {\r\n                            value =\r\n                                value.toLowerCase && value.toLowerCase() === \"false\"\r\n                                    ? false\r\n                                    : value;\r\n                            this._set(key, value);\r\n                        }\r\n                    break;\r\n                    default:\r\n                        if (Type.exists(this.element2D)) {\r\n                            this.element2D.setAttribute(attributes);\r\n                        }\r\n                }\r\n            }\r\n        }\r\n    },\r\n\r\n    // Documented in element.js\r\n    getAttribute: function(key) {\r\n        var result;\r\n        key = key.toLowerCase();\r\n\r\n        switch (key) {\r\n            case \"numberpointshigh\":\r\n            case \"stepsu\":\r\n            case \"stepsv\":\r\n                result = this.visProp[key];\r\n                break;\r\n            default:\r\n                if (Type.exists(this.element2D)) {\r\n                    result = this.element2D.getAttribute(key);\r\n                }\r\n                break;\r\n        }\r\n\r\n        return result;\r\n    },\r\n\r\n    // Documented in element.js\r\n    getAttributes: function() {\r\n        var attr = {},\r\n            i, key,\r\n            attr3D = ['numberpointshigh', 'stepsu', 'stepsv'],\r\n            le = attr3D.length;\r\n\r\n        if (Type.exists(this.element2D)) {\r\n            attr = Type.merge(this.element2D.getAttributes());\r\n        }\r\n\r\n        for (i = 0; i < le; i++) {\r\n            key = attr3D[i];\r\n            if (Type.exists(this.visProp[key])) {\r\n                attr[key] = this.visProp[key];\r\n            }\r\n        }\r\n\r\n        return attr;\r\n    },\r\n\r\n    // /**\r\n    //  * Add transformations to this element.\r\n    //  * @param {JXG.GeometryElement} el\r\n    //  * @param {JXG.Transformation|Array} transform Either one {@link JXG.Transformation}\r\n    //  * or an array of {@link JXG.Transformation}s.\r\n    //  * @returns {JXG.CoordsElement} Reference to itself.\r\n    //  */\r\n    addTransformGeneric: function (el, transform) {\r\n        var i,\r\n            list = Type.isArray(transform) ? transform : [transform],\r\n            len = list.length;\r\n\r\n        // There is only one baseElement possible\r\n        if (this.transformations.length === 0) {\r\n            this.baseElement = el;\r\n        }\r\n\r\n        for (i = 0; i < len; i++) {\r\n            this.transformations.push(list[i]);\r\n        }\r\n\r\n        return this;\r\n    },\r\n\r\n    /**\r\n     * Set position of the 2D element. This is a\r\n     * callback function, executed in {@link JXG.GeometryElement#setPosition}.\r\n     * @param {JXG.Transform} t transformation\r\n     * @private\r\n     * @see JXG.GeometryElement#setPosition\r\n     */\r\n    setPosition2D: function(t) {\r\n        /* stub */\r\n    },\r\n\r\n    /**\r\n     * Project a 3D point to this element and update point.position.\r\n     * @param {Array} p 3D position of the point (array of length 3)\r\n     * @param {Array} params Changed in place to the new of the point in terms of the elements functions X, Y, Z.\r\n     * For example for a surface, params will contain values (u,v) such that the new 3D position\r\n     * p = [X(u, v), Z(u, v), Z(u, v)].\r\n     * @returns {Array} 3D coordinates of the projected point with homogeneous coordinates of the form [1, x, y, z].\r\n     */\r\n    projectCoords: function(p, params) {\r\n        /* stub */\r\n    },\r\n\r\n    // Documented in element.js\r\n    remove: function() {}\r\n\r\n});\r\n\r\nexport default JXG.GeometryElement3D;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*global JXG:true, define: true*/\r\n\r\n/**\r\n * Create axes and rear and front walls of the\r\n * view3d bounding box bbox3D.\r\n */\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * @class A container element that creates the axes and rear and front planes of a 3D view.\r\n * @pseudo\r\n * @description This element \"axes3d\" is used to create\r\n *  <ul>\r\n *   <li> 3D coordinate axes (either \"axesPosition:'border'\" or \"axesPosition:'center'\")\r\n *   <li> A point3d \"O\" (origin) if \"axesPosition:'center'\"\r\n *   <li> Rear and front planes in all three directions of the view3d element.\r\n *   <li> Coordinate axes on the rear and front planes\r\n *  </ul>\r\n *\r\n * @name Axes3D\r\n * @constructor\r\n * @type Object\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n *\r\n */\r\nJXG.createAxes3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n    directions = [\"x\", \"y\", \"z\"],\r\n    suffixAxis = \"Axis\",\r\n    sides = [\"Rear\", \"Front\"],\r\n    rear = [0, 0, 0],           // x, y, z\r\n    front = [0, 0, 0],          // x, y, z\r\n    i, j, k, i1, i2, attr, pos,\r\n    dir, dir1, len,\r\n    from, to, vec1, vec2,\r\n    range1, range2,\r\n    na, na_parent,\r\n    ticks_attr,\r\n    axes = {};\r\n\r\n    if (Type.exists(view.bbox3D)) {\r\n        for (i = 0; i < directions.length; i++) {\r\n            rear[i] = view.bbox3D[i][0];\r\n            front[i] = view.bbox3D[i][1];\r\n        }\r\n    } else {\r\n        for (i = 0; i < directions.length; i++) {\r\n            rear[i] = parents[1][i];\r\n            front[i] = parents[2][1];\r\n        }\r\n    }\r\n\r\n    // Main 3D axes\r\n    attr = Type.copyAttributes(attributes, board.options, 'axes3d');\r\n    // Position of the main axes can not be changed during run time\r\n    pos = attr.axesposition;\r\n\r\n    for (i = 0; i < directions.length; i++) {\r\n        // Run through ['x', 'y', 'z']\r\n        dir = directions[i];\r\n        na = dir + suffixAxis;\r\n\r\n        if (pos === 'center') {\r\n            // Axes centered\r\n            from = [0, 0, 0];\r\n            to = [0, 0, 0];\r\n            to[i] = front[i];\r\n            axes[na] = view.create(\"axis3d\", [from, to], attr[na.toLowerCase()]);\r\n            axes[na].view = view;\r\n        } else if (pos === 'border') {\r\n            // Axes bordered\r\n            na += 'Border';\r\n            from = rear.slice();\r\n            to = front.slice();\r\n            if (dir === 'z') {\r\n                from[1] = front[1];\r\n                to[0] = rear[0];\r\n            } else if (dir === 'x') {\r\n                from = [rear[0], front[1], rear[2]];\r\n                to = [front[0], front[1], rear[2]];\r\n            } else {\r\n                from = [front[0], rear[1], rear[2]];\r\n                to = [front[0], front[1], rear[2]];\r\n            }\r\n            to[i] = front[i];\r\n            // attr[na.toLowerCase()].lastArrow = false;\r\n            axes[na] = view.create(\"axis3d\", [from, to], attr[na.toLowerCase()]);\r\n            axes[na].view = view;\r\n\r\n            ticks_attr = attr[na.toLowerCase()].ticks3d;\r\n            ticks_attr.element3d = true;  // Needed to avoid update during change of view\r\n            len = front[i] - rear[i];\r\n            if (dir === 'x') {\r\n                axes[na + \"Ticks\"] = view.create(\"ticks3d\", [from, [1, 0, 0], len, [0, 1, 0]], ticks_attr);\r\n            } else if (dir === 'y') {\r\n                axes[na + \"Ticks\"] = view.create(\"ticks3d\", [from, [0, 1, 0], len, [1, 0, 0]], ticks_attr);\r\n            } else {\r\n                axes[na + \"Ticks\"] = view.create(\"ticks3d\", [from, [0, 0, 1], len, [0, 1, 0]], ticks_attr);\r\n            }\r\n            axes[na + \"Ticks\"].view = view;\r\n        }\r\n    }\r\n\r\n    if (pos === 'center') {\r\n        // Origin (2D point)\r\n        axes.O = view.create(\r\n            \"intersection\",\r\n            [axes[directions[0] + suffixAxis], axes[directions[1] + suffixAxis]],\r\n            {\r\n                name: \"\",\r\n                visible: false,\r\n                withLabel: false\r\n            }\r\n        );\r\n        axes.O.view = view;\r\n    } else {\r\n        axes.O = null;\r\n    }\r\n\r\n    // Front and rear planes\r\n    for (i = 0; i < directions.length; i++) {\r\n        // Run through ['x', 'y', 'z']\r\n        i1 = (i + 1) % 3;\r\n        i2 = (i + 2) % 3;\r\n\r\n        dir = directions[i];\r\n        for (j = 0; j < sides.length; j++) {\r\n            // Run through ['Rear', 'Front']\r\n            // attr = Type.copyAttributes(attributes, board.options, 'axes3d');\r\n\r\n            na = dir + \"Plane\" + sides[j];\r\n\r\n            from = [0, 0, 0];\r\n            from[i] = j === 0 ? rear[i] : front[i];\r\n            vec1 = [0, 0, 0];\r\n            vec2 = [0, 0, 0];\r\n            vec1[i1] = 1;\r\n            vec2[i2] = 1;\r\n            range1 = [rear[i1], front[i1]];\r\n            range2 = [rear[i2], front[i2]];\r\n\r\n            attr = Type.copyAttributes(attributes, board.options, \"axes3d\", na);\r\n            axes[na] = view.create(\"plane3d\", [from, vec1, vec2, range1, range2], attr);\r\n            axes[na].elType = 'axisplane3d';\r\n        }\r\n    }\r\n\r\n    // Axes on front and rear planes\r\n    for (i = 0; i < directions.length; i++) {\r\n        // Run through ['x', 'y', 'z']\r\n        dir = directions[i];\r\n        for (j = 0; j < sides.length; j++) {\r\n            for (k = 1; k <= 2; k++) {\r\n                i1 = (i + k) % 3;\r\n                dir1 = directions[i1];\r\n                na = dir + \"Plane\" + sides[j] + dir1.toUpperCase() + 'Axis';\r\n                na_parent = dir + \"Plane\" + sides[j];\r\n\r\n                from = [0, 0, 0];\r\n                to = [0, 0, 0];\r\n                from[i] = to[i] = j === 0 ? rear[i] : front[i];\r\n\r\n                from[i1] = rear[i1];\r\n                to[i1] = front[i1];\r\n\r\n                attr = Type.copyAttributes(attributes, board.options, \"axes3d\", na);\r\n                axes[na] = view.create(\"axis3d\", [from, to], attr);\r\n                axes[na].view = view;\r\n                axes[na_parent].addChild(axes[na]);\r\n                axes[na_parent].element2D.inherits.push(axes[na]); // TODO: Access of element2D is not nice\r\n            }\r\n        }\r\n    }\r\n\r\n    return axes;\r\n};\r\nJXG.registerElement(\"axes3d\", JXG.createAxes3D);\r\n\r\n/**\r\n * @class A 3D axis element is a line together with optional ticks and labels.\r\n * @pseudo\r\n * @description Simple element 3d axis as used with \"axesPosition:center\". No ticks and no label (yet).\r\n * <p>\r\n * At the time being, the input arrays are NOT dynamic, i.e. can not be given as functions.\r\n *\r\n * @name Axis3D\r\n * @augments Arrow\r\n * @constructor\r\n * @type Object\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Array_Array} start,end Two arrays of length 3 for the start point and the end point of the axis.\r\n *\r\n */\r\nJXG.createAxis3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        attr,\r\n        start = parents[1],\r\n        end = parents[2],\r\n        el_start,\r\n        el_end,\r\n        el;\r\n\r\n    // Use 2D points to create axis\r\n    attr = Type.copyAttributes(attributes.point1, board.options, \"axis3d\", 'point1');\r\n    attr.element3d = true;  // Needed to avoid update during change of view\r\n    el_start = view.create(\r\n        \"point\",\r\n        [\r\n            (function (xx, yy, zz) {\r\n                return function () {\r\n                    return view.project3DTo2D(xx, yy, zz)[1];\r\n                };\r\n            })(start[0], start[1], start[2]),\r\n            (function (xx, yy, zz) {\r\n                return function () {\r\n                    return view.project3DTo2D(xx, yy, zz)[2];\r\n                };\r\n            })(start[0], start[1], start[2])\r\n        ],\r\n        attr\r\n    );\r\n\r\n    attr = Type.copyAttributes(attributes.point2, board.options, \"axis3d\", 'point2');\r\n    attr.element3d = true;  // Needed to avoid update during change of view\r\n    el_end = view.create(\r\n        \"point\",\r\n        [\r\n            (function (xx, yy, zz) {\r\n                return function () {\r\n                    return view.project3DTo2D(xx, yy, zz)[1];\r\n                };\r\n            })(end[0], end[1], end[2]),\r\n            (function (xx, yy, zz) {\r\n                return function () {\r\n                    return view.project3DTo2D(xx, yy, zz)[2];\r\n                };\r\n            })(end[0], end[1], end[2])\r\n        ],\r\n        attr\r\n    );\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'axis3d');\r\n    attr.element3d = true;  // Needed to avoid update during change of view\r\n    el = view.create(\"arrow\", [el_start, el_end], attr);\r\n\r\n    return el;\r\n};\r\nJXG.registerElement(\"axis3d\", JXG.createAxis3D);\r\n\r\n/**\r\n * @class Display a rectangular mesh on a 3D plane element.\r\n * @pseudo\r\n * @description Create a (rectangular) mesh - i.e. grid lines - on a plane3D element.\r\n * <p>\r\n * At the time being, the mesh is not connected to the plane. The connecting element is simply the\r\n * parameter point.\r\n *\r\n * @name Mesh3D\r\n * @augments Curve\r\n * @constructor\r\n * @type Object\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Array_Array_Array_Array_Array} point,direction1,direction2,range1,range2 point is an array of length 3\r\n * determining the starting point of the grid. direction1 and direction2 are arrays of length 3 for the directions of the grid.\r\n * range1 and range2 (arrays of length 2) give the respective ranges.\r\n * All parameters can be supplied as functions returning an appropriate data type.\r\n *\r\n */\r\nJXG.createMesh3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        attr, el;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'mesh3d');\r\n    attr.element3d = true;  // Needed to avoid update during change of view\r\n    el = view.create(\"curve\", [[], []], attr);\r\n\r\n    el.point = parents[1];\r\n    el.direction1 = parents[2];\r\n    el.direction2 = parents[3];\r\n    el.range1 = parents[4];\r\n    el.range2 = parents[5];\r\n\r\n    /**\r\n     * @ignore\r\n     */\r\n    el.updateDataArray = function () {\r\n        var range1 = Type.evaluate(this.range1),\r\n            range2 = Type.evaluate(this.range2),\r\n            s1 = range1[0],\r\n            e1 = range1[1],\r\n            s2 = range2[0],\r\n            e2 = range2[1],\r\n            l1, l2, res, i,\r\n            v1 = [0, 0, 0],\r\n            v2 = [0, 0, 0],\r\n            step_u = this.evalVisProp('stepwidthu'),\r\n            step_v = this.evalVisProp('stepwidthv'),\r\n            q = [0, 0, 0];\r\n\r\n        this.dataX = [];\r\n        this.dataY = [];\r\n\r\n        if (Type.isFunction(this.point)) {\r\n            q = this.point();\r\n        } else {\r\n            if (Type.isPoint3D(this.point)) {\r\n                q = this.point.coords;\r\n            } else {\r\n                for (i = 0; i < this.point.length; i++) {\r\n                    q[i] = Type.evaluate(this.point[i]);\r\n                }\r\n            }\r\n        }\r\n        if (Type.isFunction(this.direction1)) {\r\n            v1 = Type.evaluate(this.direction1);\r\n        } else {\r\n            for (i = 0; i < this.direction1.length; i++) {\r\n                v1[i] = Type.evaluate(this.direction1[i]);\r\n            }\r\n        }\r\n        if (Type.isFunction(this.direction2)) {\r\n            v2 = Type.evaluate(this.direction2);\r\n        } else {\r\n            for (i = 0; i < this.direction2.length; i++) {\r\n                v2[i] = Type.evaluate(this.direction2[i]);\r\n            }\r\n        }\r\n        if (q.length === 4) {\r\n            q = q.slice(1);\r\n        }\r\n        if (v1.length === 4) {\r\n            v1 = v1.slice(1);\r\n        }\r\n        if (v2.length === 4) {\r\n            v2 = v2.slice(1);\r\n        }\r\n\r\n        l1 = JXG.Math.norm(v1, 3);\r\n        l2 = JXG.Math.norm(v2, 3);\r\n        for (i = 0; i < 3; i++) {\r\n            v1[i] /= l1;\r\n            v2[i] /= l2;\r\n        }\r\n\r\n        // sol = Mat.Geometry.getPlaneBounds(v1, v2, q, s1, e1);\r\n        // if (sol !== null) {\r\n        //     s1 = sol[0];\r\n        //     e1 = sol[1];\r\n        //     s2 = sol[2];\r\n        //     e2 = sol[3];\r\n        // }\r\n\r\n        res = view.getMesh(\r\n            [\r\n                function (u, v) {\r\n                    return q[0] + u * v1[0] + v * v2[0];\r\n                },\r\n                function (u, v) {\r\n                    return q[1] + u * v1[1] + v * v2[1];\r\n                },\r\n                function (u, v) {\r\n                    return q[2] + u * v1[2] + v * v2[2];\r\n                }\r\n            ],\r\n            [Math.ceil(s1), Math.floor(e1), (Math.ceil(e1) - Math.floor(s1)) / step_u],\r\n            [Math.ceil(s2), Math.floor(e2), (Math.ceil(e2) - Math.floor(s2)) / step_v]\r\n        );\r\n        this.dataX = res[0];\r\n        this.dataY = res[1];\r\n    };\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"mesh3d\", JXG.createMesh3D);\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Aaron Fenyes,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*global JXG:true, define: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Mat from '../math/math.js';\r\nimport Geometry from '../math/geometry.js';\r\n\r\n/**\r\n * In 3D space, a circle consists of all points on a given plane with a given distance from a given point. The given point is called the center, and the given distance is called the radius.\r\n * A circle can be constructed by providing a center, a normal vector, and a radius (given as a number or function).\r\n * @class Creates a new 3D circle object. Do not use this constructor to create a 3D circle. Use {@link JXG.View3D#create} with\r\n * type {@link Circle3D} instead.\r\n * @constructor\r\n * @augments JXG.Curve3D\r\n * @augments JXG.GeometryElement\r\n * @param {JXG.View3D} view The 3D view the circle is drawn on.\r\n * @param {JXG.Point} center The center of the circle.\r\n * @param {Array} normal A normal vector of the plane the circle lies in. Must be either an array of three numbers or an array of three functions returning numbers.\r\n * @param {Number|Function} radius The radius of the circle.\r\n * @param {Object} attributes\r\n * @see JXG.Board#generateName\r\n */\r\nJXG.Circle3D = function (view, center, normal, radius, attributes) {\r\n    var altFrame1, that;\r\n\r\n    this.constructor(view.board, attributes, Const.OBJECT_TYPE_CIRCLE3D, Const.OBJECT_CLASS_3D);\r\n    this.constructor3D(view, 'circle3d');\r\n\r\n    /**\r\n     * The circle's center. Do not set this parameter directly, as that will break JSXGraph's update system.\r\n     * @type JXG.Point3D\r\n     */\r\n    this.center = this.board.select(center);\r\n\r\n    this.normalFunc = normal;\r\n\r\n    /**\r\n     * A normal vector of the plane the circle lies in. Do not set this parameter directly, as that will break JSXGraph's update system.\r\n     * @type Array\r\n     * @private\r\n     *\r\n     * @see updateNormal\r\n     */\r\n    this.normal = [0, 0, 0, 0];\r\n\r\n    /**\r\n     * The circle's underlying Curve3D.\r\n     */\r\n    this.curve;\r\n\r\n    /**\r\n     * The first vector in an orthonormal frame for the plane the circle lies in.\r\n     * Do not set this parameter directly, as that will break JSXGraph's update system.\r\n     * @type Array\r\n     * @private\r\n     *\r\n     * @see updateFrame\r\n     */\r\n    this.frame1;\r\n\r\n    /**\r\n     * The second vector in an orthonormal frame for the plane the circle lies in.\r\n     * Do not set this parameter directly, as that will break JSXGraph's update system.\r\n     * @type Array\r\n     * @private\r\n     *\r\n     * @see updateFrame\r\n     */\r\n    this.frame2;\r\n\r\n    // place the circle or its center---whichever is newer---in the scene tree\r\n    if (Type.exists(this.center._is_new)) {\r\n        this.addChild(this.center);\r\n        delete this.center._is_new;\r\n    } else {\r\n        this.center.addChild(this);\r\n    }\r\n\r\n    // Converts JessieCode syntax into JavaScript syntax and generally ensures that the radius is a function\r\n    this.updateRadius = Type.createFunction(radius, this.board);\r\n    this.addParentsFromJCFunctions([this.updateRadius]);\r\n\r\n    // initialize normal\r\n    this.updateNormal();\r\n\r\n    // initialize the first frame vector by taking the cross product with\r\n    // [1, 0, 0] or [-0.5, sqrt(3)/2, 0]---whichever is further away on the unit\r\n    // sphere. every vector is at least 60 degrees from one of these, which\r\n    // should be good enough to make the frame vector numerically accurate\r\n    this.frame1 = Mat.crossProduct(this.normal.slice(1), [1, 0, 0]);\r\n    this.frame1.unshift(0);\r\n    altFrame1 = Mat.crossProduct(this.normal.slice(1), [-0.5, 0.8660254037844386, 0]); // [1/2, sqrt(3)/2, 0]\r\n    altFrame1.unshift(0);\r\n    if (Mat.norm(altFrame1) > Mat.norm(this.frame1)) {\r\n        this.frame1 = altFrame1;\r\n    }\r\n\r\n    // initialize the second frame vector\r\n    this.frame2 = Mat.crossProduct(this.normal.slice(1), this.frame1.slice(1));\r\n    this.frame2.unshift(0);\r\n\r\n    // scale both frame vectors to unit length\r\n    this.normalizeFrame();\r\n\r\n    // create the underlying curve\r\n    that = this;\r\n    this.curve = view.create(\r\n        'curve3d',\r\n        [\r\n            function(t) {\r\n                var r = that.Radius(),\r\n                    s = Math.sin(t),\r\n                    c = Math.cos(t);\r\n\r\n                return [\r\n                    that.center.coords[1] + r * (c * that.frame1[1] + s * that.frame2[1]),\r\n                    that.center.coords[2] + r * (c * that.frame1[2] + s * that.frame2[2]),\r\n                    that.center.coords[3] + r * (c * that.frame1[3] + s * that.frame2[3])\r\n                ];\r\n            },\r\n            [0, 2 * Math.PI] // parameter range\r\n        ],\r\n        attributes\r\n    );\r\n};\r\nJXG.Circle3D.prototype = new JXG.GeometryElement();\r\nType.copyPrototypeMethods(JXG.Circle3D, JXG.GeometryElement3D, 'constructor3D');\r\n\r\nJXG.extend(\r\n    JXG.Circle3D.prototype,\r\n    /** @lends JXG.Circle3D.prototype */ {\r\n\r\n        // Already documented in element3d.js\r\n        update: function () {\r\n            if (this.needsUpdate) {\r\n                this.updateNormal()\r\n                    .updateFrame();\r\n\r\n                this.curve.visProp.visible = !isNaN(this.Radius()); // TODO\r\n            }\r\n            return this;\r\n        },\r\n\r\n        // Already documented in element3d.js\r\n        updateRenderer: function () {\r\n            this.needsUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set a new radius, then update the board.\r\n         * @param {String|Number|function} r A string, function or number describing the new radius\r\n         * @returns {JXG.Circle3D} Reference to this sphere\r\n         */\r\n        setRadius: function (r) {\r\n            this.updateRadius = Type.createFunction(r, this.board);\r\n            this.addParentsFromJCFunctions([this.updateRadius]);\r\n            this.board.update();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Calculates the radius of the circle.\r\n         * @param {String|Number|function} [value] Set new radius\r\n         * @returns {Number} The radius of the circle\r\n         */\r\n        Radius: function (value) {\r\n            if (Type.exists(value)) {\r\n                this.setRadius(value);\r\n                return this.Radius();\r\n            }\r\n\r\n            return Math.abs(this.updateRadius());\r\n        },\r\n\r\n        normalizeFrame: function () {\r\n            // normalize frame\r\n            var len1 = Mat.norm(this.frame1),\r\n                len2 = Mat.norm(this.frame2),\r\n                i;\r\n\r\n            for (i = 0; i < 4; i++) {\r\n                this.frame1[i] /= len1;\r\n                this.frame2[i] /= len2;\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        updateNormal: function () {\r\n            // evaluate normal direction\r\n            var i, len,\r\n                eps = 1.e-12;\r\n\r\n            this.normal = Type.evaluate(this.normalFunc);\r\n\r\n            // scale normal to unit length\r\n            len = Mat.norm(this.normal);\r\n            if (Math.abs(len) > eps) {\r\n                for (i = 0; i < 4; i++) {\r\n                    this.normal[i] /= len;\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        updateFrame: function () {\r\n            this.frame1 = Mat.crossProduct(this.frame2.slice(1), this.normal.slice(1));\r\n            this.frame1.unshift(0);\r\n            this.frame2 = Mat.crossProduct(this.normal.slice(1), this.frame1.slice(1));\r\n            this.frame2.unshift(0);\r\n            this.normalizeFrame();\r\n\r\n            return this;\r\n        },\r\n\r\n        // Already documented in element3d.js\r\n        projectCoords: function (p, params) {\r\n            // we have to call `this.curve.projectCoords`, i.e. the curve's projectCoords rather\r\n            // than the circle's, to make `this` refer to the curve within the\r\n            // call.\r\n            return this.curve.projectCoords(p, params);\r\n        }\r\n\r\n        // projectScreenCoords: function (pScr, params) {\r\n        //     // we have to call `this.curve.projectScreenCoords` from the curve,\r\n        //     // rather than the circle, to make `this` refer to the curve within\r\n        //     // the call\r\n        //     return this.curve.projectScreenCoords(pScr, params);\r\n        // }\r\n    }\r\n);\r\n\r\n/**\r\n * @class A circle in 3D can be defined by various combinations of points and numbers.\r\n * @pseudo\r\n * @description In 3D space, a circle consists of all points on a given plane with a given distance from a given point. The given point is called the center, and the given distance is called the radius.\r\n * A circle can be constructed by providing a center, a normal vector, and a radius (given as a number or function).\r\n * <p>\r\n * If the radius has a negative value, its absolute value is taken. If the radius evaluates to NaN,\r\n * the circle is not displayed. This is convenient for constructing an intersection circle, which is empty when its parents do not intersect.\r\n * @name Circle3D\r\n * @augments JXG.Circle3D\r\n * @constructor\r\n * @type JXG.Circle3D\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point,Array,Function_Array,Function_Number,Function} center,normal,radius The center must be given as a {@link JXG.Point}, array or function (see {@link JXG.providePoints}).\r\n * The normal vector can be given as an array of four numbers (i.e. homogeneous coordinates [0, x, y, z]) or a function returning an array of length 4\r\n * and the radius can be given as a number (which will create a circle with a fixed radius) or a function.\r\n * <p>\r\n * If the radius is supplied as a number or the output of a function, its absolute value is taken. When the radius evaluates to NaN, the circle does not display.\r\n */\r\nJXG.createCircle3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        attr = Type.copyAttributes(attributes, board.options, 'circle3d'),\r\n        center = Type.providePoints3D(view, [parents[1]], attributes, 'circle3d', ['point'])[0],\r\n        normal = parents[2],\r\n        radius = parents[3],\r\n        el;\r\n\r\n    // Create element\r\n    el = new JXG.Circle3D(view, center, normal, radius, attr);\r\n\r\n    // Update scene tree\r\n    el.curve.addParents([el]);\r\n    el.addChild(el.curve);\r\n\r\n    el.update();\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"circle3d\", JXG.createCircle3D);\r\n\r\n/**\r\n * @class The circle that is the intersection of two elements (plane3d or sphere3d) in 3D.\r\n *\r\n * @pseudo\r\n * @name IntersectionCircle3D\r\n * @augments JXG.Circle3D\r\n * @constructor\r\n * @type JXG.Circle3D\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Sphere3D_JXG.Sphere3D|JXG.Plane3D} el1,el2 The result will be the intersection of el1 and el2.\r\n * @example\r\n * // Create the intersection circle of two spheres\r\n * var view = board.create(\r\n *     'view3d',\r\n *     [[-6, -3], [8, 8],\r\n *     [[0, 3], [0, 3], [0, 3]]],\r\n *     {\r\n *         xPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *         yPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *         zPlaneRear: {fillOpacity: 0.2, gradient: null}\r\n *     }\r\n * );\r\n * var a1 = view.create('point3d', [-1, 0, 0]);\r\n * var a2 = view.create('point3d', [1, 0, 0]);\r\n *\r\n * var s1 = view.create(\r\n *    'sphere3d',\r\n *     [a1, 2],\r\n *     {fillColor: '#00ff80'}\r\n * );\r\n * var s2 = view.create(\r\n *    'sphere3d',\r\n *     [a2, 2],\r\n *     {fillColor: '#ff0000'}\r\n * );\r\n *\r\n * var i = view.create('intersectioncircle3d', [s1, s2]);\r\n *\r\n * </pre><div id=\"JXG64ede949-8dd6-44d0-b2a9-248a479d3a5d\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG64ede949-8dd6-44d0-b2a9-248a479d3a5d',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});\r\n *         var view = board.create(\r\n *            'view3d',\r\n *            [[-6, -3], [8, 8],\r\n *            [[0, 3], [0, 3], [0, 3]]],\r\n *            {\r\n *                xPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *                yPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *                zPlaneRear: {fillOpacity: 0.2, gradient: null}\r\n *            }\r\n *        );\r\n *        var a1 = view.create('point3d', [-1, 0, 0]);\r\n *        var a2 = view.create('point3d', [1, 0, 0]);\r\n *\r\n *        var s1 = view.create(\r\n *           'sphere3d',\r\n *            [a1, 2],\r\n *            {fillColor: '#00ff80'}\r\n *        );\r\n *        var p2 = view.create(\r\n *           'sphere3d',\r\n *            [a2, 2],\r\n *            {fillColor: '#ff0000'}\r\n *        );\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createIntersectionCircle3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        el1 = parents[1],\r\n        el2 = parents[2],\r\n        ixnCircle, center, func,\r\n        attr = Type.copyAttributes(attributes, board.options, 'intersectioncircle3d');\r\n\r\n    func = Geometry.intersectionFunction3D(view, el1, el2);\r\n    center = view.create('point3d', func[0], { visible: false });\r\n    ixnCircle = view.create('circle3d', [center, func[1], func[2]], attr);\r\n\r\n    try {\r\n        el1.addChild(ixnCircle);\r\n        el2.addChild(ixnCircle);\r\n    } catch (e) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create 'intersection' with parent types '\" +\r\n            typeof parents[1] +\r\n            \"' and '\" +\r\n            typeof parents[2] +\r\n            \"'.\"\r\n        );\r\n    }\r\n\r\n    ixnCircle.type = Const.OBJECT_TYPE_INTERSECTION_CIRCLE3D;\r\n    ixnCircle.elType = 'intersectioncircle3d';\r\n    ixnCircle.setParents([el1.id, el2.id]);\r\n\r\n    return ixnCircle;\r\n};\r\n\r\nJXG.registerElement('intersectioncircle3d', JXG.createIntersectionCircle3D);\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*global JXG:true, define: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\n\r\n/**\r\n * A 3D point is the basic geometric element.\r\n * @class Creates a new 3D point object. Do not use this constructor to create a 3D point. Use {@link JXG.View3D#create} with\r\n * type {@link Point3D} instead.\r\n * @augments JXG.GeometryElement3D\r\n * @augments JXG.GeometryElement\r\n * @param {JXG.View3D} view The 3D view the point is drawn on.\r\n * @param {Function|Array} F Array of numbers, array of functions or function returning an array with defines the user coordinates of the point.\r\n * @param {JXG.GeometryElement3D} slide Object the 3D point should be bound to. If null, the point is a free point.\r\n * @param {Object} attributes An object containing visual properties like in {@link JXG.Options#point3d} and\r\n * {@link JXG.Options#elements}, and optional a name and an id.\r\n * @see JXG.Board#generateName\r\n */\r\nJXG.Point3D = function (view, F, slide, attributes) {\r\n    this.constructor(view.board, attributes, Const.OBJECT_TYPE_POINT3D, Const.OBJECT_CLASS_3D);\r\n    this.constructor3D(view, 'point3d');\r\n\r\n    this.board.finalizeAdding(this);\r\n\r\n    // add the new point to its view's point list\r\n    // if (view.visProp.depthorderpoints) {\r\n    //     view.points.push(this);\r\n    // }\r\n\r\n    /**\r\n     * Homogeneous coordinates of a Point3D, i.e. array of length 4 containing numbers: [w, x, y, z].\r\n     * Usually, w=1 for finite points and w=0 for points which are infinitely far.\r\n     * If coordinates of the point are supplied as functions, they are resolved in {@link Point3D#updateCoords} into numbers.\r\n     *\r\n     * @example\r\n     *   p.coords;\r\n     *\r\n     * @name Point3D#coords\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.coords = [0, 0, 0, 0];\r\n    this.initialCoords = [0, 0, 0, 0];\r\n\r\n    /**\r\n     * Function or array of functions or array of numbers defining the coordinates of the point, used in {@link updateCoords}.\r\n     *\r\n     * @name Point3D#F\r\n     * @function\r\n     * @private\r\n     *\r\n     * @see updateCoords\r\n     */\r\n    this.F = F;\r\n\r\n    /**\r\n     * Optional slide element, i.e. element the Point3D lives on.\r\n     *\r\n     * @example\r\n     *   p.slide;\r\n     *\r\n     * @name Point3D#slide\r\n     * @type JXG.GeometryElement3D\r\n     * @default null\r\n     * @private\r\n     *\r\n     */\r\n    this.slide = slide;\r\n\r\n    /**\r\n     * In case, the point is a glider, store the preimage of the coordinates in terms of the parametric definition of the host element.\r\n     * That is, if the host element `slide` is a curve, and the coordinates of the point are equal to `p` and `u = this.position[0]`, then\r\n     * `p = [slide.X(u), slide.Y(u), slide.Z(u)]`.\r\n     *\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.position = [];\r\n\r\n    /**\r\n     * An array of coordinates for moveTo().  An in-progress move can be updated or cancelled by updating or clearing this array.  Use moveTo() instead of\r\n     * accessing this array directly.\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.movePath = [];\r\n    this.moveCallback = null;\r\n    this.moveInterval = null;\r\n\r\n\r\n    this._c2d = null;\r\n\r\n    this.methodMap = Type.deepCopy(this.methodMap, {\r\n        // TODO\r\n    });\r\n};\r\n\r\nJXG.Point3D.prototype = new JXG.GeometryElement();\r\nType.copyPrototypeMethods(JXG.Point3D, JXG.GeometryElement3D, 'constructor3D');\r\n\r\nJXG.extend(\r\n    JXG.Point3D.prototype,\r\n    /** @lends JXG.Point3D.prototype */ {\r\n\r\n        /**\r\n         * Get x-coordinate of a 3D point.\r\n         *\r\n         * @name X\r\n         * @memberOf Point3D\r\n         * @function\r\n         * @returns {Number}\r\n         *\r\n         * @example\r\n         *   p.X();\r\n         */\r\n        X: function () {\r\n            return this.coords[1];\r\n        },\r\n\r\n        /**\r\n         * Get y-coordinate of a 3D point.\r\n         *\r\n         * @name Y\r\n         * @memberOf Point3D\r\n         * @function\r\n         * @returns Number\r\n         *\r\n         * @example\r\n         *   p.Y();\r\n         */\r\n        Y: function () {\r\n            return this.coords[2];\r\n        },\r\n\r\n        /**\r\n         * Get z-coordinate of a 3D point.\r\n         *\r\n         * @name Z\r\n         * @memberOf Point3D\r\n         * @function\r\n         * @returns Number\r\n         *\r\n         * @example\r\n         *   p.Z();\r\n         */\r\n        Z: function () {\r\n            return this.coords[3];\r\n        },\r\n\r\n        /**\r\n         * Get w-coordinate of a 3D point.\r\n         *\r\n         * @name W\r\n         * @memberOf Point3D\r\n         * @function\r\n         * @returns Number\r\n         *\r\n         * @example\r\n         *   p.W();\r\n         */\r\n        W: function () {\r\n            return this.coords[0];\r\n        },\r\n\r\n        /**\r\n         * Update the array {@link JXG.Point3D#coords} containing the homogeneous coords.\r\n         *\r\n         * @name updateCoords\r\n         * @memberOf Point3D\r\n         * @function\r\n         * @returns {Object} Reference to the Point3D object\r\n         * @private\r\n         * @see GeometryElement3D#update()\r\n         * @example\r\n         *    p.updateCoords();\r\n         */\r\n        updateCoords: function () {\r\n            var i,\r\n                s = 0;\r\n\r\n            if (Type.isFunction(this.F)) {\r\n                this.coords = Type.evaluate(this.F);\r\n                if (this.coords.length === 3) {\r\n                    this.coords.unshift(1);\r\n                }\r\n            } else {\r\n                if (this.F.length === 3) {\r\n                    this.coords[0] = 1;\r\n                    s = 1;\r\n                }\r\n                for (i = 0; i < this.F.length; i++) {\r\n                    // Attention: if F is array of numbers, coords may not be updated.\r\n                    // Otherwise, dragging will not work anymore.\r\n                    if (Type.isFunction(this.F[i])) {\r\n                        this.coords[s + i] = Type.evaluate(this.F[i]);\r\n                    }\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Initialize the coords array.\r\n         *\r\n         * @private\r\n         * @returns {Object} Reference to the Point3D object\r\n         */\r\n        initCoords: function () {\r\n            var i,\r\n                s = 0;\r\n\r\n\r\n            if (Type.isFunction(this.F)) {\r\n                this.coords = Type.evaluate(this.F);\r\n                if (this.coords.length === 3) {\r\n                    this.coords.unshift(1);\r\n                }\r\n            } else {\r\n                if (this.F.length === 3) {\r\n                    this.coords[0] = 1;\r\n                    s = 1;\r\n                }\r\n                for (i = 0; i < this.F.length; i++) {\r\n                    this.coords[s + i] = Type.evaluate(this.F[i]);\r\n                }\r\n            }\r\n            this.initialCoords = this.coords.slice();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Normalize homogeneous coordinates such the the first coordinate (the w-coordinate is equal to 1 or 0)-\r\n         *\r\n         * @name normalizeCoords\r\n         * @memberOf Point3D\r\n         * @function\r\n         * @returns {Object} Reference to the Point3D object\r\n         * @private\r\n         * @example\r\n         *    p.normalizeCoords();\r\n         */\r\n        normalizeCoords: function () {\r\n            if (Math.abs(this.coords[0]) > 1.e-14) {\r\n                this.coords[1] /= this.coords[0];\r\n                this.coords[2] /= this.coords[0];\r\n                this.coords[3] /= this.coords[0];\r\n                this.coords[0] = 1.0;\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the position of a 3D point.\r\n         *\r\n         * @name setPosition\r\n         * @memberOf Point3D\r\n         * @function\r\n         * @param {Array} coords 3D coordinates. Either of the form [x,y,z] (Euclidean) or [w,x,y,z] (homogeneous).\r\n         * @param {Boolean} [noevent] If true, no events are triggered (TODO)\r\n         * @returns {Object} Reference to the Point3D object\r\n         *\r\n         * @example\r\n         *    p.setPosition([1, 3, 4]);\r\n         */\r\n        setPosition: function (coords, noevent) {\r\n            var c = this.coords;\r\n            // oc = this.coords.slice(); // Copy of original values\r\n\r\n            if (coords.length === 3) {\r\n                // Euclidean coordinates\r\n                c[0] = 1.0;\r\n                c[1] = coords[0];\r\n                c[2] = coords[1];\r\n                c[3] = coords[2];\r\n            } else {\r\n                // Homogeneous coordinates (normalized)\r\n                c[0] = coords[0];\r\n                c[1] = coords[1];\r\n                c[2] = coords[2];\r\n                c[3] = coords[2];\r\n                this.normalizeCoords();\r\n            }\r\n\r\n            // console.log(el.emitter, !noevent, oc[0] !== c[0] || oc[1] !== c[1] || oc[2] !== c[2] || oc[3] !== c[3]);\r\n            // Not yet working TODO\r\n            // if (el.emitter && !noevent &&\r\n            //     (oc[0] !== c[0] || oc[1] !== c[1] || oc[2] !== c[2] || oc[3] !== c[3])) {\r\n            //     this.triggerEventHandlers(['update3D'], [oc]);\r\n            // }\r\n            return this;\r\n        },\r\n\r\n        // /**\r\n        //  * Add transformations to this element.\r\n        //  * @param {JXG.GeometryElement} el\r\n        //  * @param {JXG.Transformation|Array} transform Either one {@link JXG.Transformation}\r\n        //  * or an array of {@link JXG.Transformation}s.\r\n        //  * @returns {JXG.CoordsElement} Reference to itself.\r\n        //  */\r\n        addTransform: function (el, transform) {\r\n            this.addTransformGeneric(el, transform);\r\n            return this;\r\n        },\r\n\r\n        updateTransform: function () {\r\n            var c, i;\r\n\r\n            if (this.transformations.length === 0 || this.baseElement === null) {\r\n                return this;\r\n            }\r\n\r\n            if (this === this.baseElement) {\r\n                c = this.initialCoords;\r\n            } else {\r\n                c = this.baseElement.coords;\r\n            }\r\n            for (i = 0; i < this.transformations.length; i++) {\r\n                this.transformations[i].update();\r\n                c = Mat.matVecMult(this.transformations[i].matrix, c);\r\n            }\r\n            this.coords = c;\r\n\r\n            return this;\r\n        },\r\n\r\n        // Already documented in JXG.GeometryElement\r\n        update: function (drag) {\r\n            var c3d,         // Homogeneous 3D coordinates\r\n                foot, res;\r\n\r\n            if (\r\n                this.element2D.draggable() &&\r\n                Geometry.distance(this._c2d, this.element2D.coords.usrCoords) !== 0\r\n            ) {\r\n                // Update is called from board.updateElements, e.g. after manipulating a\r\n                // a slider or dragging a point.\r\n                // Usually this followed by an update call using the other branch below.\r\n                if (this.view.isVerticalDrag()) {\r\n                    // Drag the point in its vertical to the xy plane\r\n                    // If the point is outside of bbox3d,\r\n                    // c3d is already corrected.\r\n                    c3d = this.view.project2DTo3DVertical(this.element2D, this.coords);\r\n                } else {\r\n                    // Drag the point in its xy plane\r\n                    foot = [1, 0, 0, this.coords[3]];\r\n                    c3d = this.view.project2DTo3DPlane(this.element2D, [1, 0, 0, 1], foot);\r\n                }\r\n\r\n                if (c3d[0] !== 0) {\r\n                    // Check if c3d is inside of view.bbox3d\r\n                    // Otherwise, the coords are now corrected.\r\n                    res = this.view.project3DToCube(c3d);\r\n                    this.coords = res[0];\r\n\r\n                    if (res[1]) {\r\n                        // The 3D coordinates have been corrected, now\r\n                        // also correct the 2D element.\r\n                        this.element2D.coords.setCoordinates(\r\n                            Const.COORDS_BY_USER,\r\n                            this.view.project3DTo2D(this.coords)\r\n                        );\r\n                    }\r\n                    if (this.slide) {\r\n                        this.coords = this.slide.projectCoords([1, this.X(), this.Y(), this.Z()], this.position);\r\n                        this.element2D.coords.setCoordinates(\r\n                            Const.COORDS_BY_USER,\r\n                            this.view.project3DTo2D(this.coords)\r\n                        );\r\n                    }\r\n                }\r\n\r\n            } else {\r\n                // Update 2D point from its 3D view, e.g. when rotating the view\r\n                this.updateCoords()\r\n                    .updateTransform();\r\n\r\n                if (this.slide) {\r\n                    this.coords = this.slide.projectCoords([1, this.X(), this.Y(), this.Z()], this.position);\r\n                }\r\n                c3d = this.coords;\r\n                this.element2D.coords.setCoordinates(\r\n                    Const.COORDS_BY_USER,\r\n                    this.view.project3DTo2D(c3d)\r\n                );\r\n                // this.zIndex = Mat.matVecMult(this.view.matrix3DRotShift, c3d)[3];\r\n                this.zIndex = Mat.innerProduct(this.view.matrix3DRotShift[3], c3d);\r\n            }\r\n            this._c2d = this.element2D.coords.usrCoords.slice();\r\n\r\n            return this;\r\n        },\r\n\r\n        // Already documented in JXG.GeometryElement\r\n        updateRenderer: function () {\r\n            this.needsUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Check whether a point's position is finite, i.e. the first entry is not zero.\r\n         * @returns {Boolean} True if the first entry of the coordinate vector is not zero; false otherwise.\r\n         */\r\n        testIfFinite: function () {\r\n            return Math.abs(this.coords[0]) > 1.e-12 ? true : false;\r\n            // return Type.cmpArrays(this.coords, [0, 0, 0, 0]);\r\n        },\r\n\r\n        /**\r\n         * Calculate the distance from one point to another. If one of the points is on the plane at infinity, return positive infinity.\r\n         * @param {JXG.Point3D} pt The point to which the distance is calculated.\r\n         * @returns {Number} The distance\r\n         */\r\n        distance: function (pt) {\r\n            var eps_sq = 1e-12,\r\n                c_this = this.coords,\r\n                c_pt = pt.coords;\r\n\r\n            if (c_this[0] * c_this[0] > eps_sq && c_pt[0] * c_pt[0] > eps_sq) {\r\n                return Mat.hypot(\r\n                    c_pt[1] - c_this[1],\r\n                    c_pt[2] - c_this[2],\r\n                    c_pt[3] - c_this[3]\r\n                );\r\n            } else {\r\n                return Number.POSITIVE_INFINITY;\r\n            }\r\n        },\r\n\r\n\r\n\r\n        /**\r\n        * Starts an animated point movement towards the given coordinates <tt>where</tt>.\r\n        * The animation is done after <tt>time</tt> milliseconds.\r\n        * If the second parameter is not given or is equal to 0, coordinates are changed without animation.\r\n        * @param {Array} where Array containing the target coordinate in cartesian or homogenous form.\r\n        * @param {Number} [time] Number of milliseconds the animation should last.\r\n        * @param {Object} [options] Optional settings for the animation\r\n        * @param {function} [options.callback] A function that is called as soon as the animation is finished.\r\n        * @param {String} [options.effect='<>'|'>'|'<'] animation effects like speed fade in and out. possible values are\r\n        * '<>' for speed increase on start and slow down at the end (default), '<' for speed up, '>' for slow down, and '--' for constant speed during\r\n        * the whole animation.\r\n        * @see JXG.Point3D#moveAlong\r\n        * @see JXG.Point#moveTo\r\n        * @example\r\n        * // visit a coordinate, then use callback to visit a second coordinate.\r\n        * const board = JXG.JSXGraph.initBoard('jxgbox')\r\n        * var view = board.create(\r\n        *     'view3d',\r\n        *     [[-6, -3], [8, 8],\r\n        *     [[-3, 3], [-3, 3], [-3, 3]]]);\r\n        *\r\n        *  let A = view.create('point3d', [0, 0, 0]);\r\n        *\r\n        *  // move A with callbacks\r\n        *  board.create('button', [-4, 4.3, 'callbacks', () => {\r\n        *    A.moveTo([3, 3, 3], 3000,\r\n        *       {\r\n        *          callback: () => A.moveTo([-3, -3, -3], 3000, {\r\n        *              callback: () => A.moveTo([0, 0, 0],1000), effect: '<'\r\n        *          }),\r\n        *          effect: '>'\r\n        *       })\r\n        *     }])\r\n        *\r\n        *   // move A with async/await\r\n        *   board.create('button', [-3, 4.3, 'async/await', async () => {\r\n        *       await A.moveTo([3, 3, 3], 3000, { effect: '>' });\r\n        *       await A.moveTo([-3, -3, -3], 3000, { effect: '<' });\r\n        *       A.moveTo([0, 0, 0],1000)\r\n        *   }])\r\n        *  </pre><div id=\"JXG0f35a50e-e99d-11e8-a1ca-cba3b0c2aad4\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n        * <script type=\"text/javascript\">\r\n        * {\r\n        * const board = JXG.JSXGraph.initBoard('JXG0f35a50e-e99d-11e8-a1ca-cba3b0c2aad4')\r\n        * var view = board.create(\r\n        *     'view3d',\r\n        *     [[-6, -3], [8, 8],\r\n        *     [[-3, 3], [-3, 3], [-3, 3]]]);\r\n        *\r\n        * let A = view.create('point3d', [0, 0, 0]);\r\n        *  // move A with callbacks\r\n        *  board.create('button', [-4, 4.3, 'callbacks', () => {\r\n        *    A.moveTo([3, 3, 3], 3000,\r\n        *       {\r\n        *          callback: () => A.moveTo([-3, -3, -3], 3000, {\r\n        *              callback: () => A.moveTo([0, 0, 0],1000), effect: '<'\r\n        *          }),\r\n        *          effect: '>'\r\n        *       })\r\n        *     }])\r\n        *\r\n        *   // move A with async/await\r\n        *   board.create('button', [-1, 4.3, 'async/await', async () => {\r\n        *       await A.moveTo([3, 3, 3], 3000, { effect: '>' });\r\n        *       await A.moveTo([-3, -3, -3], 3000, { effect: '<' });\r\n        *       A.moveTo([0, 0, 0],1000)\r\n        *   }])\r\n        * }\r\n        * </script><pre>\r\n        */\r\n        moveTo: function (where, time, options) {\r\n            options = options || {};\r\n\r\n            var i,\r\n                steps = Math.ceil(time / this.board.attr.animationdelay),\r\n                X = where[0],\r\n                Y = where[1],\r\n                Z = where[2],\r\n                dX = this.coords[1] - X,\r\n                dY = this.coords[2] - Y,\r\n                dZ = this.coords[3] - Z,\r\n                doneCallback = () => { },\r\n                stepFun;\r\n\r\n            if (options.callback)\r\n                doneCallback = options.callback;  // unload\r\n\r\n\r\n            /** @ignore */\r\n            stepFun = function (i) {\r\n                var x = i / steps;  // absolute progress of the animatin\r\n\r\n                if (options.effect) {\r\n                    if (options.effect === \"<>\") {\r\n                        return Math.pow(Math.sin((x * Math.PI) / 2), 2);\r\n                    }\r\n                    if (options.effect === \"<\") {   // cubic ease in\r\n                        return x * x * x;\r\n                    }\r\n                    if (options.effect === \">\") {   // cubic ease out\r\n                        return 1 - Math.pow(1 - x, 3);\r\n                    }\r\n                    if (options.effect === \"==\") {\r\n                        return i / steps;       // linear\r\n                    }\r\n                    throw new Error(\"valid effects are '==', '<>', '>', and '<'.\");\r\n                }\r\n                return i / steps;  // default\r\n            };\r\n\r\n            // immediate move, no time\r\n            if (\r\n                !Type.exists(time) ||\r\n                time === 0\r\n                // check for tiny move, is this necessary?\r\n                // Math.abs(where.usrCoords[0] - this.coords.usrCoords[0]) > Mat.eps\r\n            ) {\r\n                this.setPosition([X, Y, Z], true);  // no event here\r\n                return this.board.update(this);\r\n            }\r\n\r\n            // In case there is no callback and we are already at the endpoint we can stop here\r\n            if (\r\n                !Type.exists(options.callback) &&\r\n                Math.abs(dX) < Mat.eps &&\r\n                Math.abs(dY) < Mat.eps &&\r\n                Math.abs(dZ) < Mat.eps\r\n            ) {\r\n                return this;\r\n            }\r\n\r\n            this.animationPath = [];\r\n            for (i = steps; i >= 0; i--) {\r\n                this.animationPath[steps - i] = [\r\n                    X + dX * stepFun(i),\r\n                    Y + dY * stepFun(i),\r\n                    Z + dZ * stepFun(i)\r\n                ];\r\n            }\r\n\r\n            return this.moveAlong(this.animationPath, time,\r\n                { callback: doneCallback });\r\n\r\n        },\r\n\r\n        /**\r\n         * Move along a path defined by an array of coordinates\r\n         * @param {number[][]} [traversePath] Array of path coordinates (either cartesian or homogenous).\r\n         * @param {number} [time] Number of milliseconds the animation should last.\r\n         * @param {Object} [options] 'callback' and 'interpolate'.  see {@link JXG.CoordsElement#moveAlong},\r\n         * @example\r\n         *const board = JXG.JSXGraph.initBoard('jxgbox')\r\n         *var view = board.create(\r\n         *    'view3d',\r\n         *    [[-6, -3], [8, 8],\r\n         *    [[-3, 3], [-3, 3], [-3, 3]]]);\r\n         *\r\n         * board.create('button', [-4, 4.5, 'start', () => {\r\n         *      let A = view.create('point3d', [0, 0, 0]);\r\n         *      A.moveAlong([[3, 3, 3], [-2, -1, -2], [-1, -1, -1], [-1, -2, 1]], 3000,\r\n         *         { callback: () => board.create('text', [-4, 4, 'done!']) })\r\n         *}])\r\n         *\r\n         * </pre><div id=\"JXGa45032e5-a517-4f1d-868a-abc698d344cf\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n         * <script type=\"text/javascript\">\r\n         *     (function() {\r\n         * const board = JXG.JSXGraph.initBoard(\"JXGa45032e5-a517-4f1d-868a-abc698d344cf\")\r\n         * var view = board.create(\r\n         *     'view3d',\r\n         *     [[-6, -3], [8, 8],\r\n         *     [[-3, 3], [-3, 3], [-3, 3]]]);\r\n         *\r\n         * board.create('button', [-4, 4.5, 'start', () => {\r\n         *      let A = view.create('point3d', [0, 0, 0]);\r\n         *      A.moveAlong([[3, 3, 3], [-2, -1, -2], [-1, -1, -1], [-1, -2, 1]], 3000,\r\n         *       { callback: () => board.create('text', [-4, 4, 'done!']) })\r\n         * }])\r\n         *\r\n         * })();\r\n         *\r\n         * </script><pre>\r\n         *\r\n         */\r\n        moveAlong: function (traversePath, time, options) {\r\n            let stepTime = time/traversePath.length;   // will be same as this.board.attr.animationdelay if called by MoveTo\r\n\r\n\r\n            // unload the options\r\n            if (Type.isObject(options)) {\r\n                if ('callback' in options)\r\n                    this.moveCallback = options.callback;\r\n                // TODO:add interpolation using Neville.  How?  easiest is add interpolation to path before start\r\n                // if ('interpolate' in options) interpolate = options.interpolate;\r\n            }\r\n\r\n\r\n            if (this.movePath.length > 0) {         // existing move in progress\r\n                this.movePath = traversePath;       // set the new path and return ??\r\n                return;                             // promise is still outstanding\r\n            }\r\n\r\n            // no move currently in progress\r\n            this.movePath = traversePath;           // set the new path and return a promise\r\n            return new Promise((resolve, reject) => {\r\n                this.moveInterval = setInterval(() => {\r\n                    if (this.movePath.length > 0) {\r\n                        let coord = this.movePath.shift();\r\n                        this.setPosition(coord, true);  // no events during transit\r\n                        this.board.update(this);\r\n                    }\r\n                    if (this.movePath.length === 0) {   // now shorter than previous test\r\n                        clearInterval(this.moveInterval);\r\n                        resolve();\r\n                        if (Type.isFunction(this.moveCallback)) {\r\n                            this.moveCallback(); // invoke the callback\r\n                        }\r\n                    }\r\n                }, stepTime);\r\n            });\r\n        },\r\n\r\n\r\n\r\n\r\n        // Not yet working\r\n        __evt__update3D: function (oc) { }\r\n    }\r\n);\r\n\r\n/**\r\n * @class A Point3D object is defined by three coordinates [x,y,z], or a function returning an array with three numbers.\r\n * Alternatively, all numbers can also be provided as functions returning a number.\r\n *\r\n * @pseudo\r\n * @name Point3D\r\n * @augments JXG.Point3D\r\n * @constructor\r\n * @throws {Exception} If the element cannot be constructed with the given parent\r\n * objects an exception is thrown.\r\n * @param {number,function_number,function_number,function_JXG.GeometryElement3D} x,y,z,[slide=undefined] The coordinates are given as x, y, z consisting of numbers or functions.\r\n * If an optional 3D element \"slide\" is supplied, the point is a glider on that element. At the time of version v1.11, only elements of type line3d are supperted as glider hosts.\r\n * @param {array,function_JXG.GeometryElement3D} F,[slide=null] Alternatively, the coordinates can be supplied as\r\n *  <ul>\r\n *   <li>function returning an array [x,y,z] of length 3 of numbers or\r\n *   <li>array arr=[x,y,z] of length 3 consisting of numbers\r\n * </ul>\r\n * If an optional 3D element \"slide\" is supplied, the point is a glider on that element.\r\n *\r\n * @example\r\n *    var bound = [-5, 5];\r\n *    var view = board.create('view3d',\r\n *        [[-6, -3], [8, 8],\r\n *        [bound, bound, bound]],\r\n *        {});\r\n *    var p = view.create('point3d', [1, 2, 2], { name:'A', size: 5 });\r\n *    var q = view.create('point3d', function() { return [p.X(), p.Y(), p.Z() - 3]; }, { name:'B', size: 3, fixed: true });\r\n *    var w = view.create('point3d', [ () => p.X() + 3, () => p.Y(), () => p.Z() - 2], { name:'C', size: 3, fixed: true });\r\n *\r\n * </pre><div id=\"JXGb9ee8f9f-3d2b-4f73-8221-4f82c09933f1\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGb9ee8f9f-3d2b-4f73-8221-4f82c09933f1',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});\r\n *         var bound = [-5, 5];\r\n *         var view = board.create('view3d',\r\n *             [[-6, -3], [8, 8],\r\n *             [bound, bound, bound]],\r\n *             {});\r\n *         var p = view.create('point3d', [1, 2, 2], { name:'A', size: 5 });\r\n *         var q = view.create('point3d', function() { return [p.X(), p.Y(), p.Z() - 3]; }, { name:'B', size: 3 });\r\n *         var w = view.create('point3d', [ () => p.X() + 3, () => p.Y(), () => p.Z() - 2], { name:'C', size: 3, fixed: true });\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *     // Glider on sphere\r\n *     var view = board.create(\r\n *         'view3d',\r\n *         [[-6, -3], [8, 8],\r\n *         [[-3, 3], [-3, 3], [-3, 3]]],\r\n *         {\r\n *             depthOrder: {\r\n *                 enabled: true\r\n *             },\r\n *             projection: 'central',\r\n *             xPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *             yPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *             zPlaneRear: {fillOpacity: 0.2, gradient: null}\r\n *         }\r\n *     );\r\n *\r\n *     // Two points\r\n *     var center = view.create('point3d', [0, 0, 0], {withLabel: false, size: 2});\r\n *     var point = view.create('point3d', [2, 0, 0], {withLabel: false, size: 2});\r\n *\r\n *     // Sphere\r\n *     var sphere = view.create('sphere3d', [center, point], {fillOpacity: 0.8});\r\n *\r\n *     // Glider on sphere\r\n *     var glide = view.create('point3d', [2, 2, 0, sphere], {withLabel: false, color: 'red', size: 4});\r\n *     var l1 = view.create('line3d', [glide, center], { strokeWidth: 2, dash: 2 });\r\n *\r\n * </pre><div id=\"JXG672fe3c7-e6fd-48e0-9a24-22f51f2dfa71\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG672fe3c7-e6fd-48e0-9a24-22f51f2dfa71',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *         var view = board.create(\r\n *             'view3d',\r\n *             [[-6, -3], [8, 8],\r\n *             [[-3, 3], [-3, 3], [-3, 3]]],\r\n *             {\r\n *                 depthOrder: {\r\n *                     enabled: true\r\n *                 },\r\n *                 projection: 'central',\r\n *                 xPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *                 yPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *                 zPlaneRear: {fillOpacity: 0.2, gradient: null}\r\n *             }\r\n *         );\r\n *\r\n *         // Two points\r\n *         var center = view.create('point3d', [0, 0, 0], {withLabel: false, size: 2});\r\n *         var point = view.create('point3d', [2, 0, 0], {withLabel: false, size: 2});\r\n *\r\n *         // Sphere\r\n *         var sphere = view.create('sphere3d', [center, point], {fillOpacity: 0.8});\r\n *\r\n *         // Glider on sphere\r\n *         var glide = view.create('point3d', [2, 2, 0, sphere], {withLabel: false, color: 'red', size: 4});\r\n *         var l1 = view.create('line3d', [glide, center], { strokeWidth: 2, dash: 2 });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createPoint3D = function (board, parents, attributes) {\r\n    //   parents[0]: view\r\n    // followed by\r\n    //   parents[1]: function or array\r\n    // or\r\n    //   parents[1..3]: coordinates\r\n\r\n    var view = parents[0],\r\n        attr, F, slide, c2d, el,\r\n        base = null,\r\n        transform = null;\r\n\r\n    // If the last element of `parents` is a 3D object,\r\n    // the point is a glider on that element.\r\n    if (parents.length > 2 &&\r\n        Type.exists(parents[parents.length - 1].is3D) &&\r\n        !Type.isTransformationOrArray(parents[parents.length - 1])\r\n    ) {\r\n        slide = parents.pop();\r\n    } else {\r\n        slide = null;\r\n    }\r\n\r\n    if (parents.length === 2) {\r\n        // [view, array|fun] (Array [x, y, z] | function) returning [x, y, z]\r\n        F = parents[1];\r\n    } else if (parents.length === 3 &&\r\n        Type.isPoint3D(parents[1]) &&\r\n        Type.isTransformationOrArray(parents[2])\r\n    ) {\r\n        F = [0, 0, 0];\r\n        base = parents[1];\r\n        transform = parents[2];\r\n    } else if (parents.length === 4) {\r\n        // [view, x, y, z], (3 numbers | functions)\r\n        F = parents.slice(1);\r\n    } else if (parents.length === 5) {\r\n        // [view, w, x, y, z], (4 numbers | functions)\r\n        F = parents.slice(1);\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create point3d with parent types '\" +\r\n            typeof parents[1] +\r\n            \"' and '\" +\r\n            typeof parents[2] +\r\n            \"'.\" +\r\n            \"\\nPossible parent types: [[x,y,z]], [x,y,z], or [[x,y,z], slide], () => [x, y, z], or [point, transformation(s)]\"\r\n        );\r\n        //  \"\\nPossible parent types: [[x,y,z]], [x,y,z], [element,transformation]\"); // TODO\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'point3d');\r\n    el = new JXG.Point3D(view, F, slide, attr);\r\n    el.initCoords();\r\n    if (base !== null && transform !== null) {\r\n        el.addTransform(base, transform);\r\n    }\r\n\r\n    c2d = view.project3DTo2D(el.coords);\r\n\r\n    attr = el.setAttr2D(attr);\r\n    el.element2D = view.create('point', c2d, attr);\r\n    el.element2D.view = view;\r\n    el.addChild(el.element2D);\r\n    el.inherits.push(el.element2D);\r\n    el.element2D.setParents(el);\r\n\r\n    // If this point is a glider, record that in the update tree\r\n    if (el.slide) {\r\n        el.slide.addChild(el);\r\n        el.setParents(el.slide);\r\n    }\r\n    if (base) {\r\n        el.setParents(base);\r\n    }\r\n\r\n    el._c2d = el.element2D.coords.usrCoords.slice(); // Store a copy of the coordinates to detect dragging\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"point3d\", JXG.createPoint3D);\r\n\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*global JXG:true, define: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Mat from \"../math/math.js\";\r\n\r\n/**\r\n * Constructor for 3D curves.\r\n * @class Creates a new 3D curve object. Do not use this constructor to create a 3D curve. Use {@link JXG.View3D#create} with type {@link Curve3D} instead.\r\n *\r\n * @augments JXG.GeometryElement3D\r\n * @augments JXG.GeometryElement\r\n * @param {View3D} view\r\n * @param {Function} F\r\n * @param {Function} X\r\n * @param {Function} Y\r\n * @param {Function} Z\r\n * @param {Array} range\r\n * @param {Object} attributes\r\n * @see JXG.Board#generateName\r\n */\r\nJXG.Curve3D = function (view, F, X, Y, Z, range, attributes) {\r\n    this.constructor(view.board, attributes, Const.OBJECT_TYPE_CURVE3D, Const.OBJECT_CLASS_3D);\r\n    this.constructor3D(view, 'curve3d');\r\n\r\n    this.board.finalizeAdding(this);\r\n\r\n    /**\r\n     * Internal function defining the surface without applying any transformations.\r\n     * Does only exist if it or X are supplied as a function. Otherwise it is null.\r\n     *\r\n     * @function\r\n     * @private\r\n     */\r\n    this._F = F;\r\n\r\n    /**\r\n     * Function or array which maps u to x; i.e. it defines the x-coordinate of the curve\r\n     * @function\r\n     * @returns Number\r\n     * @private\r\n     */\r\n    this._X = X;\r\n\r\n    /**\r\n     * Function or array  which maps u to y; i.e. it defines the y-coordinate of the curve\r\n     * @function\r\n     * @returns Number\r\n     * @private\r\n     */\r\n    this._Y = Y;\r\n\r\n    /**\r\n     * Function or array  which maps u to z; i.e. it defines the z-coordinate of the curve\r\n     * @function\r\n     * @returns Number\r\n     * @private\r\n     */\r\n    this._Z = Z;\r\n\r\n    this.points = [];\r\n\r\n    this.numberPoints = 0;\r\n\r\n    this.dataX = null;\r\n    this.dataY = null;\r\n    this.dataZ = null;\r\n\r\n    if (this._F !== null) {\r\n        this._X = function (u) {\r\n            return this._F(u)[0];\r\n        };\r\n        this._Y = function (u) {\r\n            return this._F(u)[1];\r\n        };\r\n        this._Z = function (u) {\r\n            return this._F(u)[2];\r\n        };\r\n    } else {\r\n        if (Type.isFunction(this._X)) {\r\n            this._F = function(u) {\r\n                return [this._X(u), this._Y(u), this._Z(u)];\r\n            };\r\n        } else {\r\n            this._F = null;\r\n        }\r\n    }\r\n\r\n    this.range = range;\r\n\r\n    this.methodMap = Type.deepCopy(this.methodMap, {\r\n        // TODO\r\n    });\r\n};\r\nJXG.Curve3D.prototype = new JXG.GeometryElement();\r\nType.copyPrototypeMethods(JXG.Curve3D, JXG.GeometryElement3D, 'constructor3D');\r\n\r\nJXG.extend(\r\n    JXG.Curve3D.prototype,\r\n    /** @lends JXG.Curve3D.prototype */ {\r\n\r\n        /**\r\n         * Simple curve plotting algorithm.\r\n         *\r\n         * @returns {JXG.Curve3D} Reference to itself\r\n         */\r\n        updateCoords: function() {\r\n            var steps = this.evalVisProp('numberpointshigh'),\r\n                r, s, e, delta,\r\n                u, i,\r\n                c3d = [1, 0, 0, 0];\r\n\r\n            this.points = [];\r\n\r\n            if (Type.exists(this.dataX)) {\r\n                steps = this.dataX.length;\r\n                for (u = 0; u < steps; u++) {\r\n                    this.points.push([1, this.dataX[u], this.dataY[u], this.dataZ[u]]);\r\n                }\r\n            } else if (Type.isArray(this._X)) {\r\n                steps = this._X.length;\r\n                for (u = 0; u < steps; u++) {\r\n                    this.points.push([1, this._X[u], this._Y[u], this._Z[u]]);\r\n                }\r\n            } else {\r\n                r = Type.evaluate(this.range);\r\n                s = Type.evaluate(r[0]);\r\n                e = Type.evaluate(r[1]);\r\n                delta = (e - s) / (steps - 1);\r\n                for (i = 0, u = s; i < steps && u <= e; i++, u += delta) {\r\n                    c3d = this.F(u);\r\n                    c3d.unshift(1);\r\n                    this.points.push(c3d);\r\n                }\r\n            }\r\n            this.numberPoints = this.points.length;\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Generic function which evaluates the function term of the curve\r\n         * and applies its transformations.\r\n         * @param {Number} u\r\n         * @returns\r\n         */\r\n        evalF: function(u) {\r\n            var t, i,\r\n                c3d = [0, 0, 0, 0];\r\n\r\n            if (this.transformations.length === 0 || !Type.exists(this.baseElement)) {\r\n                if (Type.exists(this._F)) {\r\n                    c3d = this._F(u);\r\n                } else {\r\n                    c3d = [this._X[u], this._Y[u], this._Z[u]];\r\n                }\r\n                return c3d;\r\n            }\r\n\r\n            t = this.transformations;\r\n            for (i = 0; i < t.length; i++) {\r\n                t[i].update();\r\n            }\r\n            if (c3d.length === 3) {\r\n                c3d.unshift(1);\r\n            }\r\n\r\n            if (this === this.baseElement) {\r\n                if (Type.exists(this._F)) {\r\n                    c3d = this._F(u);\r\n                } else {\r\n                    c3d = [this._X[u], this._Y[u], this._Z[u]];\r\n                }\r\n            } else {\r\n                c3d = this.baseElement.evalF(u);\r\n            }\r\n            c3d.unshift(1);\r\n            c3d = Mat.matVecMult(t[0].matrix, c3d);\r\n            for (i = 1; i < t.length; i++) {\r\n                c3d = Mat.matVecMult(t[i].matrix, c3d);\r\n            }\r\n\r\n            return c3d.slice(1);\r\n        },\r\n\r\n        /**\r\n         * Function defining the curve plus applying transformations.\r\n         * @param {Number} u\r\n         * @returns Array [x, y, z] of length 3\r\n         */\r\n        F: function(u) {\r\n            return this.evalF(u);\r\n        },\r\n\r\n        /**\r\n        * Function which maps (u) to z; i.e. it defines the x-coordinate of the curve\r\n        * plus applying transformations.\r\n        * @param {Number} u\r\n        * @returns Number\r\n        */\r\n        X: function(u) {\r\n            return this.evalF(u)[0];\r\n        },\r\n\r\n        /**\r\n        * Function which maps (u) to y; i.e. it defines the y-coordinate of the curve\r\n        * plus applying transformations.\r\n        * @param {Number} u\r\n        * @returns Number\r\n        */\r\n        Y: function(u) {\r\n            return this.evalF(u)[1];\r\n        },\r\n\r\n        /**\r\n        * Function which maps (u) to z; i.e. it defines the z-coordinate of the curve\r\n        * plus applying transformations.\r\n        * @param {Number} u\r\n        * @returns Number\r\n        */\r\n        Z: function(u) {\r\n            return this.evalF(u)[2];\r\n        },\r\n\r\n        updateDataArray2D: function () {\r\n            var i, c2d,\r\n                dataX = [],\r\n                dataY = [],\r\n                len = this.points.length;\r\n\r\n            for (i = 0; i < len; i++) {\r\n                c2d = this.view.project3DTo2D(this.points[i]);\r\n                dataX.push(c2d[1]);\r\n                dataY.push(c2d[2]);\r\n            }\r\n\r\n            return { X: dataX, Y: dataY };\r\n        },\r\n\r\n        // Already documented in GeometryElement\r\n        addTransform: function (el, transform) {\r\n            this.addTransformGeneric(el, transform);\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         *\r\n         * @returns {JXG.Curve3D} Reference to itself\r\n         */\r\n        updateTransform: function () {\r\n            var t, c, i, j, len;\r\n\r\n            if (this.transformations.length === 0 || this.baseElement === null ||\r\n                Type.exists(this._F) // Transformations have only to be applied here\r\n                                     // if the curve is defined by arrays\r\n            ) {\r\n                return this;\r\n            }\r\n\r\n            t = this.transformations;\r\n            for (i = 0; i < t.length; i++) {\r\n                t[i].update();\r\n            }\r\n            len = this.baseElement.numberPoints;\r\n            for (i = 0; i < len; i++) {\r\n                if (this === this.baseElement) {\r\n                    c = this.points[i];\r\n                } else {\r\n                    c = this.baseElement.points[i];\r\n                }\r\n                for (j = 0; j < t.length; j++) {\r\n                    c = Mat.matVecMult(t[j].matrix, c);\r\n                }\r\n                this.points[i] = c;\r\n            }\r\n            this.numberPoints = len;\r\n\r\n            return this;\r\n        },\r\n\r\n        // Already documented in GeometryElement\r\n        updateDataArray: function() { /* stub */ },\r\n\r\n        // Already documented in GeometryElement\r\n        update: function () {\r\n            if (this.needsUpdate) {\r\n                this.updateDataArray();\r\n                this.updateCoords()\r\n                    .updateTransform();\r\n            }\r\n            return this;\r\n        },\r\n\r\n        // Already documented in GeometryElement\r\n        updateRenderer: function () {\r\n            this.needsUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        // Already documented in element3d.js\r\n        projectCoords: function (p, params) {\r\n            return Geometry.projectCoordsToParametric(p, this, 1, params);\r\n        }\r\n\r\n        // projectScreenCoords: function (pScr, params) {\r\n        //     this.initParamsIfNeeded(params);\r\n        //     return Geometry.projectScreenCoordsToParametric(pScr, this, params);\r\n        // }\r\n    }\r\n);\r\n\r\n/**\r\n * @class 3D Curves can be defined by mappings or by discrete data sets.\r\n * In general, a 3D curve is a mapping from R to R^3, where t maps to (x(t),y(t),z(t)).\r\n * The graph is drawn for t in the interval [a,b].\r\n * @pseudo\r\n * @description A 3D parametric curve is defined by a function\r\n *    <i>F: R<sup>1</sup> &rarr; R<sup>3</sup></i>.\r\n *\r\n * @name Curve3D\r\n * @augments Curve\r\n * @constructor\r\n * @type Object\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Function_Function_Function_Array,Function} F<sub>X</sub>,F<sub>Y</sub>,F<sub>Z</sub>,range\r\n * F<sub>X</sub>(u), F<sub>Y</sub>(u), F<sub>Z</sub>(u) are functions returning a number, range is the array containing\r\n * lower and upper bound for the range of the parameter u. range may also be a function returning an array of length two.\r\n * @param {Function_Array,Function} F,range Alternatively: F<sub>[X,Y,Z]</sub>(u) a function returning an array [x,y,z] of\r\n * numbers, range as above.\r\n * @param {Array_Array_Array} X,Y,Z Three arrays containing the coordinate points which define the curve.\r\n * @example\r\n * // create a simple curve in 3d\r\n * var bound = [-1.5, 1.5];\r\n * var view=board.create('view3d',\r\n *     [[-4, -4],[8, 8],\r\n *     [bound, bound, bound]],\r\n *     {});\r\n * var curve = view.create('curve3d', [(u)=>Math.cos(u), (u)=>Math.sin(u), (u)=>(u/Math.PI)-1,[0,2*Math.PI] ]);\r\n * </pre><div id=\"JXG0f35a50e-e99d-11e8-a1ca-04d3b0c2aad3\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG0f35a50e-e99d-11e8-a1ca-04d3b0c2aad3',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *         // create a simple curve in 3d\r\n *         var bound = [-1.5, 1.5];\r\n *         var view=board.create('view3d',\r\n *             [[-4, -4],[8, 8],\r\n *             [bound, bound, bound]],\r\n *             {});\r\n *         var curve = view.create('curve3d', [(u)=>Math.cos(u), (u)=>Math.sin(u), (u)=>(u/Math.PI)-1,[0,2*Math.PI] ]);\r\n *     })();\r\n * </script><pre>\r\n  */\r\nJXG.createCurve3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        F, X, Y, Z, range, attr, el,\r\n        mat,\r\n        base = null,\r\n        transform = null;\r\n\r\n    if (parents.length === 3) {\r\n        if (Type.isTransformationOrArray(parents[2]) && parents[1].type === Const.OBJECT_TYPE_CURVE3D) {\r\n            // [curve, transformation(s)]\r\n            // This might be adopted to the type of the base element (data plot or function)\r\n            base = parents[1];\r\n            transform = parents[2];\r\n            F = null;\r\n            X = [];\r\n            Y = [];\r\n            Z = [];\r\n        } else {\r\n            // [F, range]\r\n            F = parents[1];\r\n            range = parents[2];\r\n            X = null;\r\n            Y = null;\r\n            Z = null;\r\n        }\r\n    } else if (parents.length === 2 && Type.isArray(parents[1])) {\r\n        mat = Mat.transpose(parents[1]);\r\n        X = mat[0];\r\n        Y = mat[1];\r\n        Z = mat[2];\r\n        F = null;\r\n    } else {\r\n        // [X, Y, Z, range]\r\n        X = parents[1];\r\n        Y = parents[2];\r\n        Z = parents[3];\r\n        range = parents[4];\r\n        F = null;\r\n    }\r\n    // TODO Throw new Error\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'curve3d');\r\n    el = new JXG.Curve3D(view, F, X, Y, Z, range, attr);\r\n\r\n    attr = el.setAttr2D(attr);\r\n    el.element2D = view.create(\"curve\", [[], []], attr);\r\n    el.element2D.view = view;\r\n    if (base !== null) {\r\n        el.addTransform(base, transform);\r\n        el.addParents(base);\r\n    }\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    el.element2D.updateDataArray = function () {\r\n        var ret = el.updateDataArray2D();\r\n        this.dataX = ret.X;\r\n        this.dataY = ret.Y;\r\n    };\r\n    el.addChild(el.element2D);\r\n    el.inherits.push(el.element2D);\r\n    el.element2D.setParents(el);\r\n\r\n    el.element2D.prepareUpdate().update();\r\n    if (!board.isSuspendedUpdate) {\r\n        el.element2D.updateVisibility().updateRenderer();\r\n    }\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"curve3d\", JXG.createCurve3D);\r\n\r\n/**\r\n * @class A vector field is an assignment of a vector to each point in 3D space.\r\n * <p>\r\n * Plot a vector field either given by three functions\r\n * f1(x, y, z), f2(x, y, z), and f3(x, y, z) or by a function f(x, y, z)\r\n * returning an array of size 3.\r\n *\r\n * @pseudo\r\n * @name Vectorfield3D\r\n * @augments JXG.Curve3D\r\n * @constructor\r\n * @type JXG.Curve3D\r\n * @throws {Error} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * Parameter options:\r\n * @param {Array|Function|String} F Either an array containing three functions f1(x, y, z), f2(x, y, z),\r\n * and f3(x, y) or function f(x, y, z) returning an array of length 3.\r\n * @param {Array} xData Array of length 3 containing start value for x, number of steps,\r\n * end value of x. The vector field will contain (number of steps) + 1 vectors in direction of x.\r\n * @param {Array} yData Array of length 3 containing start value for y, number of steps,\r\n * end value of y. The vector field will contain (number of steps) + 1 vectors in direction of y.\r\n * @param {Array} zData Array of length 3 containing start value for z, number of steps,\r\n * end value of z. The vector field will contain (number of steps) + 1 vectors in direction of z.\r\n *\r\n * @example\r\n * const view = board.create('view3d',\r\n *     [\r\n *         [-6, -3],\r\n *         [8, 8],\r\n *         [[-3, 3], [-3, 3], [-3, 3]]\r\n *     ], {});\r\n *\r\n * var vf = view.create('vectorfield3d', [\r\n *     [(x, y, z) => Math.cos(y), (x, y, z) => Math.sin(x), (x, y, z) => z],\r\n *     [-2, 5, 2], // x from -2 to 2 in 5 steps\r\n *     [-2, 5, 2], // y\r\n *     [-2, 5, 2] // z\r\n * ], {\r\n *     strokeColor: 'red',\r\n *     scale: 0.5\r\n * });\r\n *\r\n * </pre><div id=\"JXG8e41c67b-3338-4428-bd0f-c69d8f6fb348\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG8e41c67b-3338-4428-bd0f-c69d8f6fb348',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false,\r\n *          pan: {\r\n *                needTwoFingers: true\r\n *           }\r\n *          });\r\n *     const view = board.create('view3d',\r\n *         [\r\n *             [-6, -3],\r\n *             [8, 8],\r\n *             [[-3, 3], [-3, 3], [-3, 3]]\r\n *         ], {});\r\n *     var vf = view.create('vectorfield3d', [\r\n *         [(x, y, z) => Math.cos(y), (x, y, z) => Math.sin(x), (x, y, z) => z],\r\n *         [-2, 5, 2], // x from -2 to 2 in 5 steps\r\n *         [-2, 5, 2], // y\r\n *         [-2, 5, 2] // z\r\n *     ], {\r\n *         strokeColor: 'red',\r\n *         scale: 0.5\r\n *     });\r\n *\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createVectorfield3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        el, attr;\r\n\r\n    if (!(parents.length >= 5 &&\r\n        (Type.isArray(parents[1]) || Type.isFunction(parents[1]) || Type.isString(parents[1])) &&\r\n        (Type.isArray(parents[2]) && parents[1].length === 3) &&\r\n        (Type.isArray(parents[3]) && parents[2].length === 3) &&\r\n        (Type.isArray(parents[4]) && parents[3].length === 3)\r\n    )) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create vector field 3D with parent types \" +\r\n            \"'\" + typeof parents[1] + \"', \" +\r\n            \"'\" + typeof parents[2] + \"', \" +\r\n            \"'\" + typeof parents[3] + \"'.\"  +\r\n            \"'\" + typeof parents[4] + \"', \"\r\n        );\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'vectorfield3d');\r\n    el = view.create('curve3d', [[], [], []], attr);\r\n\r\n    /**\r\n     * Set the defining functions of 3D vector field.\r\n     * @memberOf Vectorfield3D\r\n     * @name setF\r\n     * @function\r\n     * @param {Array|Function} func Either an array containing three functions f1(x, y, z),\r\n     * f2(x, y, z), and f3(x, y, z) or function f(x, y, z) returning an array of length 3.\r\n     * @returns {Object} Reference to the 3D vector field object.\r\n     *\r\n     * @example\r\n     * field.setF([(x, y, z) => Math.sin(y), (x, y, z) => Math.cos(x), (x, y, z) => z]);\r\n     * board.update();\r\n     *\r\n     */\r\n    el.setF = function (func, varnames) {\r\n        var f0, f1, f2;\r\n        if (Type.isArray(func)) {\r\n            f0 = Type.createFunction(func[0], this.board, varnames);\r\n            f1 = Type.createFunction(func[1], this.board, varnames);\r\n            f2 = Type.createFunction(func[2], this.board, varnames);\r\n            /**\r\n             * @ignore\r\n             */\r\n            this.F = function (x, y, z) {\r\n                return [f0(x, y, z), f1(x, y, z), f2(x, y, z)];\r\n            };\r\n        } else {\r\n            this.F = Type.createFunction(func, el.board, varnames);\r\n        }\r\n        return this;\r\n    };\r\n\r\n    el.setF(parents[1], 'x, y, z');\r\n    el.xData = parents[2];\r\n    el.yData = parents[3];\r\n    el.zData = parents[4];\r\n\r\n    el.updateDataArray = function () {\r\n        var k, i, j,\r\n            v, nrm,\r\n            x, y, z,\r\n            scale = this.evalVisProp('scale'),\r\n            start = [\r\n                Type.evaluate(this.xData[0]),\r\n                Type.evaluate(this.yData[0]),\r\n                Type.evaluate(this.zData[0])\r\n            ],\r\n            steps = [\r\n                Type.evaluate(this.xData[1]),\r\n                Type.evaluate(this.yData[1]),\r\n                Type.evaluate(this.zData[1])\r\n            ],\r\n            end = [\r\n                Type.evaluate(this.xData[2]),\r\n                Type.evaluate(this.yData[2]),\r\n                Type.evaluate(this.zData[2])\r\n            ],\r\n            delta = [\r\n                (end[0] - start[0]) / steps[0],\r\n                (end[1] - start[1]) / steps[1],\r\n                (end[2] - start[2]) / steps[2]\r\n            ],\r\n            phi, theta1, theta2, theta,\r\n            showArrow = this.evalVisProp('arrowhead.enabled'),\r\n            leg, leg_x, leg_y, leg_z, alpha;\r\n\r\n        if (showArrow) {\r\n            // Arrow head style\r\n            // leg = 8;\r\n            // alpha = Math.PI * 0.125;\r\n            leg = this.evalVisProp('arrowhead.size');\r\n            alpha = this.evalVisProp('arrowhead.angle');\r\n            leg_x = leg / board.unitX;\r\n            leg_y = leg / board.unitY;\r\n            leg_z = leg / Math.sqrt(board.unitX * board.unitY);\r\n        }\r\n\r\n        this.dataX = [];\r\n        this.dataY = [];\r\n        this.dataZ = [];\r\n        for (i = 0, x = start[0]; i <= steps[0]; x += delta[0], i++) {\r\n            for (j = 0, y = start[1]; j <= steps[1]; y += delta[1], j++) {\r\n                for (k = 0, z = start[2]; k <= steps[2]; z += delta[2], k++) {\r\n                    v = this.F(x, y, z);\r\n                    nrm = Mat.norm(v);\r\n                    if (nrm < Number.EPSILON) {\r\n                        continue;\r\n                    }\r\n\r\n                    v[0] *= scale;\r\n                    v[1] *= scale;\r\n                    v[2] *= scale;\r\n                    Type.concat(this.dataX, [x, x + v[0], NaN]);\r\n                    Type.concat(this.dataY, [y, y + v[1], NaN]);\r\n                    Type.concat(this.dataZ, [z, z + v[2], NaN]);\r\n\r\n                    if (showArrow) {\r\n                        // Arrow head\r\n                        nrm *= scale;\r\n                        phi = Math.atan2(v[1], v[0]);\r\n                        theta = Math.asin(v[2] / nrm);\r\n                        theta1 = theta - alpha;\r\n                        theta2 = theta + alpha;\r\n                        Type.concat(this.dataX, [\r\n                            x + v[0] - leg_x * Math.cos(phi) * Math.cos(theta1),\r\n                            x + v[0],\r\n                            x + v[0] - leg_x * Math.cos(phi) * Math.cos(theta2),\r\n                            NaN]);\r\n                        Type.concat(this.dataY, [\r\n                            y + v[1] - leg_y * Math.sin(phi) * Math.cos(theta1),\r\n                            y + v[1],\r\n                            y + v[1] - leg_y * Math.sin(phi) * Math.cos(theta2),\r\n                            NaN]);\r\n                        Type.concat(this.dataZ, [\r\n                            z + v[2] - leg_z * Math.sin(theta2),\r\n                            z + v[2],\r\n                            z + v[2] - leg_z * Math.sin(theta1),\r\n                            NaN]);\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    };\r\n\r\n    el.methodMap = Type.deepCopy(el.methodMap, {\r\n        setF: \"setF\"\r\n    });\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"vectorfield3D\", JXG.createVectorfield3D);\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Aaron Fenyes,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*global JXG:true, define: true*/\r\n\r\n/**\r\n * Create linear spaces of dimension at least one,\r\n * i.e. lines and planes.\r\n */\r\nimport JXG from '../jxg.js';\r\nimport Const from '../base/constants.js';\r\nimport Type from '../utils/type.js';\r\nimport Mat from '../math/math.js';\r\nimport Geometry from '../math/geometry.js';\r\n\r\n// -----------------------\r\n//  Lines\r\n// -----------------------\r\n\r\n/**\r\n * Constructor for 3D lines.\r\n * @class Creates a new 3D line object. Do not use this constructor to create a 3D line. Use {@link JXG.View3D#create} with type {@link Line3D} instead.\r\n *\r\n * @augments JXG.GeometryElement3D\r\n * @augments JXG.GeometryElement\r\n * @param {View3D} view\r\n * @param {Point3D|Array} point\r\n * @param {Array} direction\r\n * @param {Array} range\r\n * @param {Object} attributes\r\n * @see JXG.Board#generateName\r\n */\r\nJXG.Line3D = function (view, point, direction, range, attributes) {\r\n    this.constructor(view.board, attributes, Const.OBJECT_TYPE_LINE3D, Const.OBJECT_CLASS_3D);\r\n    this.constructor3D(view, 'line3d');\r\n\r\n    /**\r\n     * 3D point which - together with a direction - defines the line.\r\n     * @name point\r\n     * @memberOf Line3D\r\n     * @type Point3D\r\n     *\r\n     * @see Line3D#direction\r\n     */\r\n    this.point = point;\r\n\r\n    /**\r\n     * Direction which - together with a point - defines the line. Array of numbers or functions (of length 3) or function\r\n     * returning array of length 3.\r\n     *\r\n     * @name Line3D#direction\r\n     * @type Array|Function\r\n     * @see Line3D.point\r\n     */\r\n    this.direction = direction;\r\n\r\n    /**\r\n     * Spanning vector of the 3D line. Contains the evaluated coordinates from {@link direction}\r\n     * and {@link range}.\r\n     * The array has length 4, the first entry being 0.\r\n     *\r\n     * @name Line3D#vec\r\n     * @type {Array}\r\n     */\r\n    this.vec = [0, 0, 0, 0];\r\n\r\n    /**\r\n     * Range [r1, r2] of the line. r1, r2 can be numbers or functions.\r\n     * The 3D line goes from (point + r1 * direction) to (point + r2 * direction)\r\n     * @name Line3D#range\r\n     * @type Array\r\n     * @default [-Infinity, Infinity]\r\n     */\r\n    this.range = range || [-Infinity, Infinity];\r\n\r\n    /**\r\n     * Starting point of the 3D line\r\n     * @name Line3D#point1\r\n     * @type JXG.Point3D\r\n     * @private\r\n     */\r\n    this.point1 = null;\r\n\r\n    /**\r\n     * End point of the 3D line\r\n     * @name Line3D#point2\r\n     * @type JXG.Point3D\r\n     * @private\r\n     */\r\n    this.point2 = null;\r\n\r\n    this.board.finalizeAdding(this);\r\n\r\n    this.methodMap = Type.deepCopy(this.methodMap, {\r\n        // TODO\r\n    });\r\n};\r\nJXG.Line3D.prototype = new JXG.GeometryElement();\r\nType.copyPrototypeMethods(JXG.Line3D, JXG.GeometryElement3D, 'constructor3D');\r\n\r\nJXG.extend(\r\n    JXG.Line3D.prototype,\r\n    /** @lends JXG.Line3D.prototype */ {\r\n\r\n        /**\r\n         * Update the array {@link Line3D#vec} containing the homogeneous coords of the spanning vector.\r\n         *\r\n         * @name Line3D#updateCoords\r\n         * @function\r\n         * @returns {Object} Reference to Line3D object\r\n         * @private\r\n         */\r\n        updateCoords: function() {\r\n            var i,\r\n                s = 0;\r\n\r\n            if ((Type.exists(this.direction.view) && this.direction.type === Const.OBJECT_TYPE_LINE3D)) {\r\n                // direction is another line3D object\r\n                this.vec = this.direction.vec.slice();\r\n            } else if (Type.isFunction(this.direction)) {\r\n                this.vec = Type.evaluate(this.direction);\r\n                if (this.vec.length === 3) {\r\n                    this.vec.unshift(0);\r\n                }\r\n            } else {\r\n                if (this.direction.length === 3) {\r\n                    this.vec[0] = 0;\r\n                    s = 1;\r\n                }\r\n                for (i = 0; i < this.direction.length; i++) {\r\n                    this.vec[s + i] = Type.evaluate(this.direction[i]);\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Determine one end point of a 3D line from point, direction and range).\r\n         *\r\n         * @name Line3D#getPointCoords\r\n         * @param {Number|function} r Usually, one of the range borders.\r\n         * @private\r\n         * @returns {Array} Coordinates of length 4.\r\n         */\r\n        getPointCoords: function (r) {\r\n            var p = [],\r\n                d = [],\r\n                r0;\r\n\r\n            p = this.point.coords;\r\n            d = this.vec;\r\n\r\n            // Intersect the ray - if necessary - with the cube,\r\n            // i.e. clamp the line.\r\n            r0 = Type.evaluate(r);\r\n            r = this.view.intersectionLineCube(p, d, r0);\r\n\r\n            // Check if r is infinite. This happens\r\n            // if this.vec is the zero vector.\r\n            if (Math.abs(r) === Infinity) {\r\n                r = 0;\r\n            }\r\n            return [\r\n                p[0] + d[0] * r,\r\n                p[1] + d[1] * r,\r\n                p[2] + d[2] * r,\r\n                p[3] + d[3] * r\r\n            ];\r\n        },\r\n\r\n        addTransform: function (el, transform) {\r\n            this.point.addTransform(el.point, transform);\r\n            this.addTransformGeneric(el, transform);\r\n\r\n            return this;\r\n        },\r\n\r\n        updateTransform: function () {\r\n            var c, i;\r\n\r\n            if (this.transformations.length === 0 || this.baseElement === null) {\r\n                return this;\r\n            }\r\n\r\n            if (this === this.baseElement) {\r\n                c = this.vec;\r\n            } else {\r\n                c = this.baseElement.vec;\r\n            }\r\n            for (i = 0; i < this.transformations.length; i++) {\r\n                this.transformations[i].update();\r\n                c = Mat.matVecMult(this.transformations[i].matrix, c);\r\n            }\r\n            this.vec = c;\r\n\r\n            return this;\r\n        },\r\n\r\n        // Already documented in JXG.GeometryElement\r\n        update: function () {\r\n            if (this.needsUpdate) {\r\n                this.updateCoords()\r\n                    .updateTransform();\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the 2D position of the defining points.\r\n         *\r\n         * @name Line3D#setPosition2D\r\n         * @function\r\n         * @param {JXG.Transformation} t projective 2D transformation\r\n         * @private\r\n         */\r\n        setPosition2D: function (t) {\r\n            var j, el;\r\n\r\n            for (j = 0; j < this.parents.length; j++) {\r\n                // Run through defining 3D points\r\n                el = this.view.select(this.parents[j]);\r\n                if (el.elType === 'point3d' && el.element2D.draggable()) {\r\n                    t.applyOnce(el.element2D);\r\n                }\r\n            }\r\n            this.endpoints[0].update();\r\n            this.endpoints[1].update();\r\n        },\r\n\r\n        // Already documented in JXG.GeometryElement\r\n        updateRenderer: function () {\r\n            this.needsUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        // Already documented in element3d.js\r\n        projectCoords: function (p, params) {\r\n            var p0_coords = this.getPointCoords(0),\r\n                p1_coords = this.getPointCoords(1),\r\n                dir = [\r\n                    p1_coords[0] - p0_coords[0],\r\n                    p1_coords[1] - p0_coords[1],\r\n                    p1_coords[2] - p0_coords[2]\r\n                ],\r\n                diff = [\r\n                    p[0] - p0_coords[0],\r\n                    p[1] - p0_coords[1],\r\n                    p[2] - p0_coords[2]\r\n                ],\r\n                t = Mat.innerProduct(diff, dir) / Mat.innerProduct(dir, dir),\r\n                t_clamped = Math.min(Math.max(t, Type.evaluate(this.range[0])), Type.evaluate(this.range[1])),\r\n                c3d;\r\n\r\n            c3d = this.getPointCoords(t_clamped).slice();\r\n            params[0] = t_clamped;\r\n\r\n            return c3d;\r\n        },\r\n\r\n        // projectScreenCoords: function (pScr) {\r\n        //     var end0 = this.getPointCoords(0),\r\n        //         end1 = this.getPointCoords(1);\r\n\r\n        //     return this.view.projectScreenToSegment(pScr, end0, end1);\r\n        // },\r\n\r\n        /**\r\n         * Update the z-index of the line, i.e. the z-index of its midpoint.\r\n         * @name Line3D#updateZIndex\r\n         * @function\r\n         * @returns {Object} Reference to Line3D object\r\n         */\r\n        updateZIndex: function() {\r\n            var p1 = this.endpoints[0],\r\n                p2 = this.endpoints[1],\r\n                c3d = [1, p1.X() + p2.X(), p1.Y() + p2.Y(), p1.Z() + p2.Z()];\r\n\r\n            c3d[1] *= 0.5;\r\n            c3d[2] *= 0.5;\r\n            c3d[3] *= 0.5;\r\n            // this.zIndex = Mat.matVecMult(this.view.matrix3DRotShift, c3d)[3];\r\n            this.zIndex = Mat.innerProduct(this.view.matrix3DRotShift[3], c3d);\r\n\r\n            return this;\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * @class A line in 3D is given by two points, or one point and a direction vector.\r\n *\r\n * @description\r\n * A line in 3D is given by two points, or one point and a direction vector.\r\n * That is, there are the following two possibilities to create a Line3D object:\r\n * <ol>\r\n * <li> The 3D line is defined by two 3D points (Point3D):\r\n * The points can be either existing points or coordinate arrays of\r\n * the form [x, y, z].\r\n * <p> The 3D line is defined by a point (or coordinate array [x, y, z])\r\n * a direction given as array [x, y, z] and an optional range\r\n * given as array [s, e]. The default value for the range is [-Infinity, Infinity].\r\n * </ol>\r\n * All numbers can also be provided as functions returning a number.\r\n * The case [point, array] is ambiguous, it is not clear if 'array' contains the coordinates of a point\r\n * or of a direction. In that case, 'array' is interpreted as the coordinate array of a point,\r\n * i.e. the line is defined by two points.\r\n *\r\n * @pseudo\r\n * @name Line3D\r\n * @augments JXG.GeometryElement3D\r\n * @constructor\r\n * @type JXG.Line3D\r\n * @throws {Exception} If the element cannot be constructed with the given parent\r\n * objects an exception is thrown.\r\n * @param {JXG.Point3D,array,function_JXG.Point3D,array,function} point1,point2 First and second defining point of the line.\r\n * The attributes {@link Line3D#straightFirst} and {@link Line3D#straightLast} control if the line is displayed as\r\n * segment, ray or infinite line.\r\n * @param {JXG.Point3D,array,function_JXG.Line3D,array,function_array,function} point,direction,range The line is defined by point, direction and range.\r\n * <ul>\r\n * <li> point: Point3D or array of length 3\r\n * <li> direction: array of length 3 or function returning an array of numbers or function returning an array\r\n * <li> range: array of length 2, elements can also be functions. Use [-Infinity, Infinity] for infinite lines.\r\n * </ul>\r\n *\r\n * @example\r\n *     var bound = [-5, 5];\r\n *     var view = board.create('view3d',\r\n *         [[-6, -3], [8, 8],\r\n *         [bound, bound, bound]],\r\n *         {});\r\n *     var p = view.create('point3d', [1, 2, 2], { name:'A', size: 5 });\r\n *     // Lines through 2 points\r\n *     var l1 = view.create('line3d', [[1, 3, 3], [-3, -3, -3]], {point1: {visible: true}, point2: {visible: true} });\r\n *     var l2 = view.create('line3d', [p, l1.point1]);\r\n *\r\n *     // Line by point, direction, range\r\n *     var l3 = view.create('line3d', [p, [0, 0, 1], [-2, 4]]);\r\n *\r\n * </pre><div id='JXG05f9baa4-6059-4502-8911-6a934f823b3d' class='jxgbox' style='width: 300px; height: 300px;'></div>\r\n * <script type='text/javascript'>\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG05f9baa4-6059-4502-8911-6a934f823b3d',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *         var bound = [-5, 5];\r\n *         var view = board.create('view3d',\r\n *             [[-6, -3], [8, 8],\r\n *             [bound, bound, bound]],\r\n *             {});\r\n *         var p = view.create('point3d', [1, 2, 2], { name:'A', size: 5 });\r\n *         // Lines through 2 points\r\n *         var l1 = view.create('line3d', [[1, 3, 3], [-3, -3, -3]], {name: 'll1', point1: {visible: true}, point2: {visible: true} });\r\n *         var l2 = view.create('line3d', [p, l1.point1]);\r\n *         // Line by point, direction, range\r\n *         var l3 = view.create('line3d', [p, [0, 0, 1], [-2, 4]]);\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *     var view = board.create(\r\n *         'view3d',\r\n *         [[-6, -3], [8, 8],\r\n *         [[-3, 3], [-3, 3], [-3, 3]]],\r\n *         {\r\n *             depthOrder: {\r\n *                 enabled: true\r\n *             },\r\n *             projection: 'central',\r\n *             xPlaneRear: {fillOpacity: 0.2},\r\n *             yPlaneRear: {fillOpacity: 0.2},\r\n *             zPlaneRear: {fillOpacity: 0.2}\r\n *         }\r\n *     );\r\n *\r\n *     var A = view.create('point3d', [0, 0, 0], {size: 2});\r\n *     var B = view.create('point3d', [2, 1, 1], {size: 2});\r\n *     var C = view.create('point3d', [-2.5, 2.5, 1.5], {size: 2});\r\n *\r\n *     // Draggable line by two points\r\n *     var line1 = view.create('line3d', [A, B], {\r\n *         fixed: false,\r\n *         straightFirst: true,\r\n *         straightLast: true,\r\n *         dash: 2\r\n *     });\r\n *\r\n *     // Line by point, direction, and range\r\n *     var line2 = view.create('line3d', [C, [1, 0, 0], [-1, Infinity]], {\r\n *         strokeColor: 'blue'\r\n *     });\r\n *\r\n *     // Line by point and array\r\n *     var line3 = view.create('line3d', [C, [-2.5, -1, 1.5]], {\r\n *         point2: { visible: true},\r\n *         strokeColor: 'red'\r\n *     });\r\n *\r\n * </pre><div id=\"JXGc42dda18-0a72-45f2-8add-3b2ad7e10853\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGc42dda18-0a72-45f2-8add-3b2ad7e10853',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *         var view = board.create(\r\n *             'view3d',\r\n *             [[-6, -3], [8, 8],\r\n *             [[-3, 3], [-3, 3], [-3, 3]]],\r\n *             {\r\n *                 depthOrder: {\r\n *                     enabled: true\r\n *                 },\r\n *                 projection: 'central',\r\n *                 xPlaneRear: {fillOpacity: 0.2},\r\n *                 yPlaneRear: {fillOpacity: 0.2},\r\n *                 zPlaneRear: {fillOpacity: 0.2}\r\n *             }\r\n *         );\r\n *\r\n *         var A = view.create('point3d', [0, 0, 0], {size: 2});\r\n *         var B = view.create('point3d', [2, 1, 1], {size: 2});\r\n *         var C = view.create('point3d', [-2.5, 2.5, 1.5], {size: 2});\r\n *\r\n *         // Draggable line by two points\r\n *         var line1 = view.create('line3d', [A, B], {\r\n *             fixed: false,\r\n *             straightFirst: true,\r\n *             straightLast: true,\r\n *             dash: 2\r\n *         });\r\n *\r\n *         // Line by point, direction, and range\r\n *         var line2 = view.create('line3d', [C, [1, 0, 0], [-1, Infinity]], {\r\n *             strokeColor: 'blue'\r\n *         });\r\n *\r\n *         // Line by point and array\r\n *         var line3 = view.create('line3d', [C, [-2.5, -1, 1.5]], {\r\n *             point2: { visible: true},\r\n *             strokeColor: 'red'\r\n *         });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *  var view = board.create(\r\n *      'view3d',\r\n *      [[-6, -3], [8, 8],\r\n *      [[-3, 3], [-3, 3], [-3, 3]]],\r\n *      {\r\n *          depthOrder: {\r\n *              enabled: true\r\n *          },\r\n *          projection: 'parallel',\r\n *          xPlaneRear: { fillOpacity: 0.2 },\r\n *          yPlaneRear: { fillOpacity: 0.2 },\r\n *          zPlaneRear: { fillOpacity: 0.2 }\r\n *      }\r\n *  );\r\n *\r\n *\r\n * var A = view.create('point3d', [-2, 0, 1], { size: 2 });\r\n * var B = view.create('point3d', [-2, 0, 2], { size: 2 });\r\n * var line1 = view.create('line3d', [A, B], {\r\n *     fixed: false,\r\n *     strokeColor: 'blue',\r\n *     straightFirst: true,\r\n *     straightLast: true\r\n * });\r\n *\r\n * var C = view.create('point3d', [2, 0, 1], { size: 2 });\r\n * var line2 = view.create('line3d', [C, line1, [-Infinity, Infinity]], { strokeColor: 'red' });\r\n *\r\n * </pre><div id=\"JXGc9234445-de9b-4543-aae7-0ef2d0b540e6\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGc9234445-de9b-4543-aae7-0ef2d0b540e6',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *                 var view = board.create(\r\n *                     'view3d',\r\n *                     [[-6, -3], [8, 8],\r\n *                     [[-3, 3], [-3, 3], [-3, 3]]],\r\n *                     {\r\n *                         depthOrder: {\r\n *                             enabled: true\r\n *                         },\r\n *                         projection: 'parallel',\r\n *                         xPlaneRear: { fillOpacity: 0.2 },\r\n *                         yPlaneRear: { fillOpacity: 0.2 },\r\n *                         zPlaneRear: { fillOpacity: 0.2 }\r\n *                     }\r\n *                 );\r\n *\r\n *\r\n *                 var A = view.create('point3d', [-2, 0, 1], { size: 2 });\r\n *                 var B = view.create('point3d', [-2, 0, 2], { size: 2 });\r\n *                 var line1 = view.create('line3d', [A, B], {\r\n *                     fixed: false,\r\n *                     strokeColor: 'blue',\r\n *                     straightFirst: true,\r\n *                     straightLast: true\r\n *                 });\r\n *\r\n *                 var C = view.create('point3d', [2, 0, 1], { size: 2 });\r\n *                 var line2 = view.create('line3d', [C, line1, [-Infinity, Infinity]], { strokeColor: 'red' });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createLine3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        attr, points,\r\n        point, direction, range,\r\n        point1, point2, endpoints,\r\n        el,\r\n        base = null,\r\n        transform = null;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'line3d');\r\n\r\n    // In any case, parents[1] contains a point or point coordinates\r\n\r\n    if (parents[1].type === Const.OBJECT_TYPE_LINE3D &&\r\n        Type.isTransformationOrArray(parents[2])\r\n    ) {\r\n        base = parents[1];\r\n        transform = parents[2];\r\n\r\n        points = Type.providePoints3D(\r\n            view,\r\n            [\r\n                [0, 0, 0, 0],\r\n                [0, 0, 0, 0]\r\n            ],\r\n            attributes,\r\n            'line3d',\r\n            ['point1', 'point2']\r\n        );\r\n    }\r\n\r\n    if (base === null &&   // No transformation\r\n        (Type.isPoint3D(parents[2]) ||\r\n            ( parents.length === 3 && (Type.isArray(parents[2]) || Type.isFunction(parents[2])) )\r\n        )\r\n    ) {\r\n        // Line defined by two points; [view, point1, point2]\r\n        point1 = Type.providePoints3D(view, [parents[1]], attributes, 'line3d', ['point1'])[0];\r\n        point2 = Type.providePoints3D(view, [parents[2]], attributes, 'line3d', ['point2'])[0];\r\n        direction = function () {\r\n            return [0, point2.X() - point1.X(), point2.Y() - point1.Y(), point2.Z() - point1.Z()];\r\n        };\r\n        range = [0, 1]; // Segment by default\r\n        el = new JXG.Line3D(view, point1, direction, range, attr);\r\n        el.prepareUpdate().update();\r\n\r\n        // Create two shadow points that are the end points of the visible line.\r\n        // This is of relevance if the line has straightFirst or straightLast set to true, then\r\n        // endpoints differ from point1, point2.\r\n        // In such a case, the endpoints are the intersection of the line with the cube.\r\n        endpoints = Type.providePoints3D(\r\n            view,\r\n            [\r\n                [1, 0, 0, 0],\r\n                [1, 0, 0, 0]\r\n            ],\r\n            { visible: true },\r\n            'line3d',\r\n            ['point1', 'point2']\r\n        );\r\n\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        endpoints[0].F = function () {\r\n            var r = 0;\r\n            if (el.evalVisProp('straightfirst')) {\r\n                r = -Infinity;\r\n            }\r\n            return el.getPointCoords(r);\r\n        };\r\n\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        endpoints[1].F = function () {\r\n            var r = 1;\r\n            if (el.evalVisProp('straightlast')) {\r\n                r = Infinity;\r\n            }\r\n            return el.getPointCoords(r);\r\n        };\r\n        endpoints[0].prepareUpdate().update();\r\n        endpoints[1].prepareUpdate().update();\r\n\r\n        // The 2D line is always a segment.\r\n        attr = el.setAttr2D(attr);\r\n        attr.straightfirst = false;\r\n        attr.straightlast = false;\r\n        el.element2D = view.create('segment', [endpoints[0].element2D, endpoints[1].element2D], attr);\r\n        el.element2D.view = view;\r\n\r\n        /**\r\n         * Shadow points that determine the visible line.\r\n         * This is of relevance if the line is defined by two points and has straightFirst or straightLast set to true.\r\n         * In such a case, the shadow points are the intersection of the line with the cube.\r\n         *\r\n         * @name JXG.Point3D.endpoints\r\n         * @type Array\r\n         * @private\r\n         */\r\n        el.endpoints = endpoints;\r\n        el.addChild(endpoints[0]);\r\n        el.addChild(endpoints[1]);\r\n        // el.setParents(endpoints);\r\n        el.addParents([point1, point2]);\r\n\r\n    } else {\r\n        // Line defined by point, direction and range\r\n\r\n        // Directions are handled as arrays of length 4, i.e. with homogeneous coordinates.\r\n        if (base !== null) {\r\n            point = Type.providePoints3D(view, [[0, 0, 0]], attributes, 'line3d', ['point'])[0];\r\n            direction = [0, 0, 0, 0.0001];\r\n            range = parents[3] || [-Infinity, Infinity];\r\n        } else if (\r\n            (Type.exists(parents[2].view) && parents[2].type === Const.OBJECT_TYPE_LINE3D) || // direction given by another line\r\n            Type.isFunction(parents[2]) || (parents[2].length === 3) || (parents[2].length === 4) // direction given as function or array\r\n        ) {\r\n            point = Type.providePoints3D(view, [parents[1]], attributes, 'line3d', ['point'])[0];\r\n            direction = parents[2];\r\n            range = parents[3];\r\n        } else {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create line3d with parents of type '\" +\r\n                    typeof parents[1] + \", \"  +\r\n                    typeof parents[2] + \", \"  +\r\n                    typeof parents[3] + \"'.\"\r\n            );\r\n        }\r\n\r\n        points = Type.providePoints3D(\r\n            view,\r\n            [\r\n                [1, 0, 0, 0],\r\n                [1, 0, 0, 0]\r\n            ],\r\n            attributes,\r\n            'line3d',\r\n            ['point1', 'point2']\r\n        );\r\n\r\n        // Create a line3d with two dummy points\r\n        el = new JXG.Line3D(view, point, direction, range, attr);\r\n        el.prepareUpdate().update();\r\n\r\n        // Now set the real points which define the line\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        points[0].F = function () {\r\n            return el.getPointCoords(Type.evaluate(el.range[0]));\r\n        };\r\n        points[0].prepareUpdate().update();\r\n        point1 = points[0];\r\n\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        points[1].F = function () {\r\n            return el.getPointCoords(Type.evaluate(el.range[1]));\r\n        };\r\n        points[1].prepareUpdate().update();\r\n        point2 = points[1];\r\n\r\n        attr = el.setAttr2D(attr);\r\n        attr.straightfirst = false;\r\n        attr.straightlast = false;\r\n        el.element2D = view.create('segment', [point1.element2D, point2.element2D], attr);\r\n        el.element2D.view = view;\r\n\r\n        /**\r\n         * Array of length 2 containing the endings of the Line3D element. These are the defining points,\r\n         * the intersections of the line with the bounding box, or the endings defined by the range.\r\n         * @name Line3D#endpoints\r\n         * @type {Array}\r\n         */\r\n        el.endpoints = points;\r\n\r\n        el.addParents(point);\r\n\r\n        if (base !== null && transform !== null) {\r\n            el.addTransform(base, transform);\r\n            el.addParents(base);\r\n        }\r\n    }\r\n\r\n    el.addChild(el.element2D);\r\n    el.inherits.push(el.element2D);\r\n    el.element2D.addParents(el);\r\n\r\n    el.point1 = point1;\r\n    el.point2 = point2;\r\n    if (el.point1._is_new) {\r\n        el.addChild(el.point1);\r\n        delete el.point1._is_new;\r\n    } else {\r\n        el.point1.addChild(el);\r\n    }\r\n    if (el.point2._is_new) {\r\n        el.addChild(el.point2);\r\n        delete el.point2._is_new;\r\n    } else {\r\n        el.point2.addChild(el);\r\n    }\r\n    if (Type.exists(point)) {\r\n        if (point._is_new) {\r\n            el.addChild(point);\r\n            delete point._is_new;\r\n        } else {\r\n            point.addChild(el);\r\n        }\r\n    }\r\n\r\n    el.update();\r\n    el.element2D.prepareUpdate().update().updateRenderer();\r\n    return el;\r\n};\r\n\r\nJXG.registerElement('line3d', JXG.createLine3D);\r\n\r\n// -----------------------\r\n//  Planes\r\n// -----------------------\r\n\r\n/**\r\n * Constructor for 3D planes.\r\n * @class Creates a new 3D plane object. Do not use this constructor to create a 3D plane. Use {@link JXG.Board#create} with type {@link Plane3D} instead.\r\n *\r\n * @augments JXG.GeometryElement3D\r\n * @augments JXG.GeometryElement\r\n * @param {View3D} view\r\n * @param {Point3D|Array} point\r\n * @param {Array} direction1\r\n * @param {Array} range_u\r\n * @param {Array} direction2\r\n * @param {Array} range_v\r\n * @param {Object} attributes\r\n * @see JXG.Board#generateName\r\n */\r\nJXG.Plane3D = function (view, point, dir1, range_u, dir2, range_v, attributes) {\r\n    this.constructor(view.board, attributes, Const.OBJECT_TYPE_PLANE3D, Const.OBJECT_CLASS_3D);\r\n    this.constructor3D(view, 'plane3d');\r\n\r\n    this.board.finalizeAdding(this);\r\n\r\n    /**\r\n     * 3D point which - together with two direction vectors - defines the plane.\r\n     *\r\n     * @name point\r\n     * @memberOf Plane3D\r\n     * @type JXG.Point3D\r\n     *\r\n     * @see Plane3D#direction1\r\n     * @see Plane3D#direction2\r\n     */\r\n    this.point = point;\r\n\r\n    /**\r\n     * Two linearly independent vectors - together with a point - define the plane. Each of these direction vectors is an\r\n     * array of numbers or functions (either of length 3 or 4) or function returning array of length 3 or 4.\r\n     * Homogeneous coordinates of directions have the form [0, x, y, z].\r\n     *\r\n     * @name Plane3D#direction1\r\n     * @type Array|Function\r\n     *\r\n     * @see Plane3D.point\r\n     * @see Plane3D#direction2\r\n     */\r\n    this.direction1 = dir1;\r\n\r\n    /**\r\n     * Two linearly independent vectors - together with a point - define the plane. Each of these direction vectors is an\r\n     * array of numbers or functions (either of length 3 or 4) or function returning array of length 3 or 4.\r\n     * Homogeneous coordinates of directions have the form [0, x, y, z].\r\n     *\r\n     * @type Array|Function\r\n     * @name Plane3D#direction2\r\n     * @see Plane3D.point\r\n     * @see Plane3D#direction1\r\n     */\r\n    this.direction2 = dir2;\r\n\r\n    /**\r\n     * Range [r1, r2] of {@link direction1}. The 3D line goes from (point + r1 * direction1) to (point + r2 * direction1)\r\n     * @name Plane3D#range_u\r\n     * @type {Array}\r\n     * @default [-Infinity, Infinity]\r\n     * @default\r\n     */\r\n    this.range_u = range_u || [-Infinity, Infinity];\r\n\r\n    /**\r\n     * Range [r1, r2] of {@link direction2}. The 3D line goes from (point + r1 * direction2) to (point + r2 * direction2)\r\n     * @name Plane3D#range_v\r\n     * @type {Array}\r\n     * @type {Array}\r\n     * @default [-Infinity, Infinity]\r\n     */\r\n    this.range_v = range_v || [-Infinity, Infinity];\r\n\r\n    /**\r\n     * Spanning vector 1 of the 3D plane. Contains the evaluated coordinates from {@link direction1} and {@link range1}.\r\n     * and is of length 4, the first entry being 0, i.e. homogenous coordinates.\r\n     *\r\n     * @name Plane3D#vec1\r\n     * @type Array\r\n     * @private\r\n     *\r\n     * @see Plane3D#updateCoords\r\n     */\r\n    this.vec1 = [0, 0, 0, 0];\r\n\r\n    /**\r\n     * Spanning vector 2 of the 3D plane. Contains the evaluated coordinates from {@link Plane3D#direction2} and {@link Plane3D#range2}\r\n     * and is of length 4, the first entry being 0, i.e. homogenous coordinates.\r\n     *\r\n     * @name Plane3D#vec2\r\n     * @type Array\r\n     * @private\r\n     *\r\n     * @see Plane3D#updateCoords\r\n     */\r\n    this.vec2 = [0, 0, 0, 0];\r\n\r\n    /**\r\n     * Mesh (grid) element of the plane.\r\n     *\r\n     * @name Plane3D#mesh3d\r\n     * @type Mesh3D\r\n     * @private\r\n     */\r\n    this.mesh3d = null;\r\n\r\n    /**\r\n     * Normal vector of the plane. Left hand side of the Hesse normal form.\r\n     * @name Plane3D#normal\r\n     * @type Array\r\n     * @private\r\n     *\r\n     * @see Plane3D.updateNormal\r\n     *\r\n     */\r\n    this.normal = [0, 0, 0, 0];\r\n\r\n    /**\r\n     * Right hand side of the Hesse normal form.\r\n     * @name Plane3D#d\r\n     * @type Array\r\n     * @private\r\n     *\r\n     * @see Plane3D.updateNormal\r\n     *\r\n     */\r\n    this.d = 0;\r\n\r\n    this.updateCoords();\r\n    this.updateNormal();\r\n\r\n    this.methodMap = Type.deepCopy(this.methodMap, {\r\n        // TODO\r\n    });\r\n};\r\nJXG.Plane3D.prototype = new JXG.GeometryElement();\r\nType.copyPrototypeMethods(JXG.Plane3D, JXG.GeometryElement3D, 'constructor3D');\r\n\r\nJXG.extend(\r\n    JXG.Plane3D.prototype,\r\n    /** @lends JXG.Plane3D.prototype */ {\r\n\r\n        /**\r\n         * Get coordinate array [x, y, z] of a point on the plane for parameters (u, v).\r\n         *\r\n         * @name Plane3D#F\r\n         * @function\r\n         * @param {Number} u\r\n         * @param {Number} v\r\n         * @returns Array of length 3.\r\n         */\r\n        F: function (u, v) {\r\n            var i, v1, v2, l1, l2;\r\n\r\n            v1 = this.vec1.slice();\r\n            v2 = this.vec2.slice();\r\n            l1 = Mat.norm(v1, 3);\r\n            l2 = Mat.norm(v2, 3);\r\n            for (i = 0; i < 3; i++) {\r\n                v1[i] /= l1;\r\n                v2[i] /= l2;\r\n            }\r\n\r\n            return [\r\n                this.point.X() + u * v1[0] + v * v2[0],\r\n                this.point.Y() + u * v1[1] + v * v2[1],\r\n                this.point.Z() + u * v1[2] + v * v2[2]\r\n            ];\r\n        },\r\n\r\n        /**\r\n         * Get x-coordinate of a point on the plane for parameters (u, v).\r\n         *\r\n         * @name Plane3D#X\r\n         * @function\r\n         * @param {Number} u\r\n         * @param {Number} v\r\n         * @returns Number\r\n         */\r\n        X: function(u, v) {\r\n            return this.F(u, v)[0];\r\n        },\r\n\r\n        /**\r\n         * Get y-coordinate of a point on the plane for parameters (u, v).\r\n         *\r\n         * @name Plane3D#Y\r\n         * @function\r\n         * @param {Number} u\r\n         * @param {Number} v\r\n         * @returns Number\r\n         */\r\n        Y: function(u, v) {\r\n            return this.F(u, v)[1];\r\n        },\r\n\r\n        /**\r\n         * Get z-coordinate of a point on the plane for parameters (u, v).\r\n         *\r\n         * @name Plane3D#Z\r\n         * @function\r\n         * @param {Number} u\r\n         * @param {Number} v\r\n         * @returns Number\r\n         */\r\n        Z: function(u, v) {\r\n            return this.F(u, v)[2];\r\n        },\r\n\r\n        /**\r\n         * Update the arrays {@link JXG.Plane3D#vec1} and {@link JXG.Plane3D#vec1} containing the homogeneous coords of the spanning vectors.\r\n         *\r\n         * @name Plane3D#updateCoords\r\n         * @function\r\n         * @returns {Object} Reference to Plane3D object\r\n         * @private\r\n         */\r\n        updateCoords: function() {\r\n            var i, s;\r\n\r\n            if (Type.exists(this.direction1.view) && this.direction1.type === Const.OBJECT_TYPE_LINE3D) {\r\n                this.vec1 = this.direction1.vec.slice();\r\n            } else if (Type.isFunction(this.direction1)) {\r\n                this.vec1 = Type.evaluate(this.direction1);\r\n                if (this.vec1.length === 3) {\r\n                    this.vec1.unshift(0);\r\n                }\r\n            } else {\r\n                s = 0;\r\n                if (this.direction1.length === 3) {\r\n                    this.vec1[0] = 0;\r\n                    s = 1;\r\n                }\r\n                for (i = 0; i < this.direction1.length; i++) {\r\n                    this.vec1[s + i] = Type.evaluate(this.direction1[i]);\r\n                }\r\n            }\r\n\r\n            if (Type.exists(this.direction2.view) && this.direction2.type === Const.OBJECT_TYPE_LINE3D) {\r\n                this.vec2 = this.direction2.vec.slice();\r\n            } else if (Type.isFunction(this.direction2)) {\r\n                this.vec2 = Type.evaluate(this.direction2);\r\n                if (this.vec2.length === 3) {\r\n                    this.vec2.unshift(0);\r\n                }\r\n            } else {\r\n                s = 0;\r\n                if (this.direction2.length === 3) {\r\n                    this.vec2[0] = 0;\r\n                    s = 1;\r\n                }\r\n                for (i = 0; i < this.direction2.length; i++) {\r\n                    this.vec2[s + i] = Type.evaluate(this.direction2[i]);\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Update the Hesse normal form of the plane, i.e. update normal vector and right hand side.\r\n         * Updates also {@link vec1} and {@link vec2}.\r\n         *\r\n         * @name Plane3D#updateNormal\r\n         * @function\r\n         * @returns {Object} Reference to the Plane3D object\r\n         * @private\r\n         * @example\r\n         *    plane.updateNormal();\r\n         *\r\n         */\r\n        updateNormal: function () {\r\n            var i, len;\r\n\r\n            if (!this.needsUpdate) {\r\n                // Extraordinary update, conflicts with rotating of box and plane transformations\r\n                // this.updateCoords();\r\n            }\r\n\r\n            this.normal = Mat.crossProduct(this.vec1.slice(1), this.vec2.slice(1));\r\n\r\n            len = Mat.norm(this.normal);\r\n            if (Math.abs(len) > Mat.eps * Mat.eps) {\r\n                for (i = 0; i < 3; i++) {\r\n                    this.normal[i] /= len;\r\n                }\r\n            }\r\n            this.normal.unshift(0);\r\n            this.d = Mat.innerProduct(this.point.coords, this.normal, 4);\r\n\r\n            return this;\r\n        },\r\n\r\n        // Already documented in element3d.js\r\n        updateDataArray: function () {\r\n            var s1, e1, s2, e2, c2d, l1, l2,\r\n                planes = ['xPlaneRear', 'yPlaneRear', 'zPlaneRear'], // Must be ordered x, y, z\r\n                points = [],\r\n                v1 = [0, 0, 0],\r\n                v2 = [0, 0, 0],\r\n                q = [0, 0, 0],\r\n                p = [0, 0, 0],\r\n                eps = 1.e-12,\r\n                d, i, j, a, b, first, pos, pos_akt,\r\n                view = this.view;\r\n\r\n            this.dataX = [];\r\n            this.dataY = [];\r\n\r\n            this.updateNormal();\r\n\r\n            // Infinite plane\r\n            if (\r\n                this.elType !== 'axisplane3d' &&\r\n                view.defaultAxes &&\r\n                Type.evaluate(this.range_u[0]) === -Infinity &&\r\n                Type.evaluate(this.range_u[1]) === Infinity &&\r\n                Type.evaluate(this.range_v[0]) === -Infinity &&\r\n                Type.evaluate(this.range_v[1]) === Infinity\r\n            ) {\r\n                // Determine the intersections of the new plane with\r\n                // the view bbox3d.\r\n                //\r\n                // Start with the rear plane.\r\n                // For each face of the bbox3d we determine two points\r\n                // which are the end points of the intersecting line\r\n                // between the plane and a face of bbox3d.\r\n                // We start with the three rear planes (set in planes[] above)\r\n                for (j = 0; j < planes.length; j++) {\r\n                    p = view.intersectionPlanePlane(this, view.defaultAxes[planes[j]]);\r\n                    if (p[0] !== false && p[1] !== false) {\r\n                        // This test is necessary to filter out intersection lines which are\r\n                        // identical to intersections of axis planes (they would occur twice),\r\n                        // i.e. edges of bbox3d.\r\n                        for (i = 0; i < points.length; i++) {\r\n                            if (\r\n                                (Geometry.distance(p[0], points[i][0], 4) < eps &&\r\n                                    Geometry.distance(p[1], points[i][1], 4) < eps) ||\r\n                                (Geometry.distance(p[0], points[i][1], 4) < eps &&\r\n                                    Geometry.distance(p[1], points[i][0], 4) < eps)\r\n                            ) {\r\n                                break;\r\n                            }\r\n                        }\r\n                        if (i === points.length) {\r\n                            points.push(p.slice());\r\n                        }\r\n                    }\r\n\r\n                    // Take a point on the corresponding front plane of bbox3d.\r\n                    p = [1, 0, 0, 0];\r\n                    p[j + 1] = view.bbox3D[j][1];\r\n\r\n                    // Use the Hesse normal form of front plane to intersect it with the plane\r\n                    // d is the rhs of the Hesse normal form of the front plane.\r\n                    d = Mat.innerProduct(p, view.defaultAxes[planes[j]].normal, 4);\r\n                    p = view.intersectionPlanePlane(this, view.defaultAxes[planes[j]], d);\r\n\r\n                    if (p[0] !== false && p[1] !== false) {\r\n                        // Do the same test as above\r\n                        for (i = 0; i < points.length; i++) {\r\n                            // Same test for edges of bbox3d as above\r\n                            if (\r\n                                (Geometry.distance(p[0], points[i][0], 4) < eps &&\r\n                                    Geometry.distance(p[1], points[i][1], 4) < eps) ||\r\n                                (Geometry.distance(p[0], points[i][1], 4) < eps &&\r\n                                    Geometry.distance(p[1], points[i][0], 4) < eps)\r\n                            ) {\r\n                                break;\r\n                            }\r\n                        }\r\n                        if (i === points.length) {\r\n                            points.push(p.slice());\r\n                        }\r\n                    }\r\n                }\r\n\r\n                // Handle the case that the plane does not intersect bbox3d at all.\r\n                if (points.length === 0) {\r\n                    return { X: this.dataX, Y: this.dataY };\r\n                }\r\n\r\n                // Concatenate the intersection points to a polygon.\r\n                // If all went well, each intersection should appear\r\n                // twice in the list.\r\n                first = 0;\r\n                pos = first;\r\n                i = 0;\r\n                do {\r\n                    p = points[pos][i];\r\n                    if (p.length === 4) {\r\n                        c2d = view.project3DTo2D(p);\r\n                        this.dataX.push(c2d[1]);\r\n                        this.dataY.push(c2d[2]);\r\n                    }\r\n                    i = (i + 1) % 2;\r\n                    p = points[pos][i];\r\n\r\n                    pos_akt = pos;\r\n                    for (j = 0; j < points.length; j++) {\r\n                        if (j !== pos && Geometry.distance(p, points[j][0]) < eps) {\r\n                            pos = j;\r\n                            i = 0;\r\n                            break;\r\n                        }\r\n                        if (j !== pos && Geometry.distance(p, points[j][1]) < eps) {\r\n                            pos = j;\r\n                            i = 1;\r\n                            break;\r\n                        }\r\n                    }\r\n                    if (pos === pos_akt) {\r\n                        console.log('Error plane3d update: did not find next', pos);\r\n                        break;\r\n                    }\r\n                } while (pos !== first);\r\n\r\n                c2d = view.project3DTo2D(points[first][0]);\r\n                this.dataX.push(c2d[1]);\r\n                this.dataY.push(c2d[2]);\r\n            } else {\r\n                // 3D bounded flat\r\n                s1 = Type.evaluate(this.range_u[0]);\r\n                e1 = Type.evaluate(this.range_u[1]);\r\n                s2 = Type.evaluate(this.range_v[0]);\r\n                e2 = Type.evaluate(this.range_v[1]);\r\n\r\n                q = this.point.coords;\r\n                v1 = this.vec1.slice();\r\n                v2 = this.vec2.slice();\r\n                l1 = Mat.norm(v1, 4);\r\n                l2 = Mat.norm(v2, 4);\r\n                for (i = 1; i < 4; i++) {\r\n                    v1[i] /= l1;\r\n                    v2[i] /= l2;\r\n                }\r\n\r\n                for (j = 0; j < 4; j++) {\r\n                    switch (j) {\r\n                        case 0:\r\n                            a = s1;\r\n                            b = s2;\r\n                            break;\r\n                        case 1:\r\n                            a = e1;\r\n                            b = s2;\r\n                            break;\r\n                        case 2:\r\n                            a = e1;\r\n                            b = e2;\r\n                            break;\r\n                        case 3:\r\n                            a = s1;\r\n                            b = e2;\r\n                    }\r\n                    for (i = 0; i < 4; i++) {\r\n                        p[i] = q[i] + a * v1[i] + b * v2[i];\r\n                    }\r\n                    c2d = view.project3DTo2D(p);\r\n                    this.dataX.push(c2d[1]);\r\n                    this.dataY.push(c2d[2]);\r\n                }\r\n                // Close the curve\r\n                this.dataX.push(this.dataX[0]);\r\n                this.dataY.push(this.dataY[0]);\r\n            }\r\n            return { X: this.dataX, Y: this.dataY };\r\n        },\r\n\r\n        // Already documented in element3d.js\r\n        addTransform: function (el, transform) {\r\n            this.addTransformGeneric(el, transform);\r\n            this.point.addTransform(el.point, transform);\r\n            return this;\r\n        },\r\n\r\n        // Already documented in element3d.js\r\n        updateTransform: function () {\r\n            var c1, c2, i;\r\n\r\n            if (this.transformations.length === 0 || this.baseElement === null) {\r\n                return this;\r\n            }\r\n\r\n            if (this === this.baseElement) {\r\n                c1 = this.vec1;\r\n                c2 = this.vec2;\r\n            } else {\r\n                c1 = this.baseElement.vec1;\r\n                c2 = this.baseElement.vec2;\r\n            }\r\n\r\n            for (i = 0; i < this.transformations.length; i++) {\r\n                this.transformations[i].update();\r\n                c1 = Mat.matVecMult(this.transformations[i].matrix, c1);\r\n                c2 = Mat.matVecMult(this.transformations[i].matrix, c2);\r\n            }\r\n            this.vec1 = c1;\r\n            this.vec2 = c2;\r\n\r\n            return this;\r\n        },\r\n\r\n        // Already documented in element3d.js\r\n        update: function () {\r\n            if (this.needsUpdate) {\r\n                this.updateCoords()\r\n                    .updateTransform();\r\n            }\r\n            return this;\r\n        },\r\n\r\n        // Already documented in element3d.js\r\n        updateRenderer: function () {\r\n            this.needsUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        // Already documented in element3d.js\r\n        projectCoords: function (p, params) {\r\n            return Geometry.projectCoordsToParametric(p, this, 2, params);\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * @class A 3D plane is defined either by a point and two linearly independent vectors, or by three points.\r\n *\r\n * @description\r\n * A 3D plane is defined either by a point and two linearly independent vectors, or by three points.\r\n * In the first case, the parameters are a 3D point (or a coordinate array) and two vectors (arrays).\r\n * In the second case, the parameters consist of three 3D points (given as points or coordinate arrays).\r\n * In order to distinguish the two cases, in the latter case (three points), the additional attribute {@link Plane3D#threePoints}\r\n * has to be supplied if both, the second point and the third point, are given as arrays or functions. Otherwise, it would not be\r\n * clear if the input arrays have to be interpreted as points or directions.\r\n * <p>\r\n * All coordinate arrays can be supplied as functions returning a coordinate array.\r\n *\r\n * @pseudo\r\n * @name  Plane3D\r\n * @augments JXG.GeometryElement3D\r\n * @constructor\r\n * @throws {Exception} If the element cannot be constructed with the given parent\r\n * objects an exception is thrown.\r\n *\r\n * @param {JXG.Point3D,array,function_JXG.Line3D,array,function_JXG.Line3D,array,function_array,function_array,function} point,direction1,direction2,[range1],[range2] The plane is defined by point, direction1, direction2, range1, and range2.\r\n * <ul>\r\n * <li> point: Point3D or array of length 3\r\n * <li> direction1: line3d element or array of length 3 or function returning an array of numbers or function returning an array\r\n * <li> direction2: line3d element or array of length 3 or function returning an array of numbers or function returning an array\r\n * <li> range1: array of length 2, elements can also be functions. Use [-Infinity, Infinity] for infinite lines.\r\n * <li> range2: array of length 2, elements can also be functions. Use [-Infinity, Infinity] for infinite lines.\r\n * </ul>\r\n * @param {JXG.Point3D,array,function_JXG.Point3D,array,function_JXG.Point3D,array,function} point1,point2,point3 The plane is defined by three points.\r\n * @type JXG.Plane3D\r\n *\r\n * @example\r\n *     var view = board.create(\r\n *         'view3d',\r\n *         [[-6, -3], [8, 8],\r\n *         [[-3, 3], [-3, 3], [-3, 3]]],\r\n *         {\r\n *             depthOrder: {\r\n *                 enabled: true\r\n *             },\r\n *             projection: 'central',\r\n *             xPlaneRear: {fillOpacity: 0.2},\r\n *             yPlaneRear: {fillOpacity: 0.2},\r\n *             zPlaneRear: {fillOpacity: 0.2}\r\n *         }\r\n *     );\r\n *\r\n *     var A = view.create('point3d', [-2, 0, 1], {size: 2});\r\n *\r\n *     // Infinite Plane by point and two directions\r\n *     var plane = view.create('plane3d', [A, [1, 0, 0], [0, 1, 0], [-Infinity, Infinity], [-Infinity, Infinity]]);\r\n *\r\n * </pre><div id=\"JXG69f491ef-d7c7-4105-a962-86a588fbd23b\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG69f491ef-d7c7-4105-a962-86a588fbd23b',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *         var view = board.create(\r\n *             'view3d',\r\n *             [[-6, -3], [8, 8],\r\n *             [[-3, 3], [-3, 3], [-3, 3]]],\r\n *             {\r\n *                 depthOrder: {\r\n *                     enabled: true\r\n *                 },\r\n *                 projection: 'central',\r\n *                 xPlaneRear: {fillOpacity: 0.2},\r\n *                 yPlaneRear: {fillOpacity: 0.2},\r\n *                 zPlaneRear: {fillOpacity: 0.2}\r\n *             }\r\n *         );\r\n *\r\n *         var A = view.create('point3d', [-2, 0, 1], {size: 2});\r\n *\r\n *         // Infinite Plane by point and two directions\r\n *         var plane = view.create('plane3d', [A, [1, 0, 0], [0, 1, 0], [-Infinity, Infinity], [-Infinity, Infinity]]);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *     var view = board.create(\r\n *         'view3d',\r\n *         [[-6, -3], [8, 8],\r\n *         [[-3, 3], [-3, 3], [-3, 3]]],\r\n *         {\r\n *             depthOrder: {\r\n *                 enabled: true\r\n *             },\r\n *             projection: 'central',\r\n *             xPlaneRear: {fillOpacity: 0.2},\r\n *             yPlaneRear: {fillOpacity: 0.2},\r\n *             zPlaneRear: {fillOpacity: 0.2}\r\n *         }\r\n *     );\r\n *\r\n *     var A = view.create('point3d', [-2, 0, 1], {size: 2});\r\n *\r\n *     // Finite Plane by point and two directions\r\n *     var plane1 = view.create('plane3d', [A, [1, 0, 0], [0, 1, 0], [-2, 2], [-2, 2]]);\r\n *     var plane2 = view.create('plane3d', [[0, 0, -1], [1, 0, 0], [0, 1, 0], [-2, 2], [-2, 2]], {\r\n *         mesh3d: { visible: true },\r\n *         point: {visible: true, name: \"B\", fixed: false}\r\n *     });\r\n *\r\n * </pre><div id=\"JXGea9dda1b-748b-4ed3-b4b3-57e310bd8141\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGea9dda1b-748b-4ed3-b4b3-57e310bd8141',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *         var view = board.create(\r\n *             'view3d',\r\n *             [[-6, -3], [8, 8],\r\n *             [[-3, 3], [-3, 3], [-3, 3]]],\r\n *             {\r\n *                 depthOrder: {\r\n *                     enabled: true\r\n *                 },\r\n *                 projection: 'central',\r\n *                 xPlaneRear: {fillOpacity: 0.2},\r\n *                 yPlaneRear: {fillOpacity: 0.2},\r\n *                 zPlaneRear: {fillOpacity: 0.2}\r\n *             }\r\n *         );\r\n *\r\n *         var A = view.create('point3d', [-2, 0, 1], {size: 2});\r\n *\r\n *         // Finite Plane by point and two directions\r\n *         var plane1 = view.create('plane3d', [A, [1, 0, 0], [0, 1, 0], [-2, 2], [-2, 2]]);\r\n *         var plane2 = view.create('plane3d', [[0, 0, -1], [1, 0, 0], [0, 1, 0], [-2, 2], [-2, 2]], {\r\n *             mesh3d: { visible: true },\r\n *             point: {visible: true, name: \"B\", fixed: false}\r\n *         });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n * @example\r\n *             var view = board.create(\r\n *                 'view3d',\r\n *                 [[-6, -3], [8, 8],\r\n *                 [[-3, 3], [-3, 3], [-3, 3]]],\r\n *                 {\r\n *                     depthOrder: {\r\n *                         enabled: true\r\n *                     },\r\n *                     projection: 'central',\r\n *                     xPlaneRear: { visible: false, fillOpacity: 0.2 },\r\n *                     yPlaneRear: { visible: false, fillOpacity: 0.2 },\r\n *                     zPlaneRear: { fillOpacity: 0.2 }\r\n *                 }\r\n *             );\r\n *\r\n *             var A = view.create('point3d', [-2, 0, 1], { size: 2 });\r\n *\r\n *             var line1 = view.create('line3d', [A, [0, 0, 1], [-Infinity, Infinity]], { strokeColor: 'blue' });\r\n *             var line2 = view.create('line3d', [A, [1, 1, 0], [-Infinity, Infinity]], { strokeColor: 'blue' });\r\n *\r\n *             // Plane by point and two lines\r\n *             var plane2 = view.create('plane3d', [A, line1, line2], {\r\n *                 fillColor: 'blue'\r\n *             });\r\n *\r\n * </pre><div id=\"JXG8bc6e266-e27c-4ffa-86a2-8076f4069573\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG8bc6e266-e27c-4ffa-86a2-8076f4069573',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *                 var view = board.create(\r\n *                     'view3d',\r\n *                     [[-6, -3], [8, 8],\r\n *                     [[-3, 3], [-3, 3], [-3, 3]]],\r\n *                     {\r\n *                         depthOrder: {\r\n *                             enabled: true\r\n *                         },\r\n *                         projection: 'central',\r\n *                         xPlaneRear: { visible: false, fillOpacity: 0.2 },\r\n *                         yPlaneRear: { visible: false, fillOpacity: 0.2 },\r\n *                         zPlaneRear: { fillOpacity: 0.2 }\r\n *                     }\r\n *                 );\r\n *\r\n *                 var A = view.create('point3d', [-2, 0, 1], { size: 2 });\r\n *\r\n *                 var line1 = view.create('line3d', [A, [0, 0, 1], [-Infinity, Infinity]], { strokeColor: 'blue' });\r\n *                 var line2 = view.create('line3d', [A, [1, 1, 0], [-Infinity, Infinity]], { strokeColor: 'blue' });\r\n *\r\n *                 // Plane by point and two lines\r\n *                 var plane2 = view.create('plane3d', [A, line1, line2], {\r\n *                     fillColor: 'blue'\r\n *                 });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *     var view = board.create(\r\n *         'view3d',\r\n *         [[-6, -3], [8, 8],\r\n *         [[-3, 3], [-3, 3], [-3, 3]]],\r\n *         {\r\n *             depthOrder: {\r\n *                 enabled: true\r\n *             },\r\n *             projection: 'central',\r\n *             xPlaneRear: {fillOpacity: 0.2},\r\n *             yPlaneRear: {fillOpacity: 0.2},\r\n *             zPlaneRear: {fillOpacity: 0.2}\r\n *         }\r\n *     );\r\n *\r\n *     var A = view.create('point3d', [0, 0, 1], {size: 2});\r\n *     var B = view.create('point3d', [2, 2, 1], {size: 2});\r\n *     var C = view.create('point3d', [-2, 0, 1], {size: 2});\r\n *\r\n *     // Plane by three points\r\n *     var plane = view.create('plane3d', [A, B, C], {\r\n *         fillColor: 'blue'\r\n *     });\r\n *\r\n * </pre><div id=\"JXG139100df-3ece-4cd1-b34f-28b5b3105106\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG139100df-3ece-4cd1-b34f-28b5b3105106',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *         var view = board.create(\r\n *             'view3d',\r\n *             [[-6, -3], [8, 8],\r\n *             [[-3, 3], [-3, 3], [-3, 3]]],\r\n *             {\r\n *                 depthOrder: {\r\n *                     enabled: true\r\n *                 },\r\n *                 projection: 'central',\r\n *                 xPlaneRear: {fillOpacity: 0.2},\r\n *                 yPlaneRear: {fillOpacity: 0.2},\r\n *                 zPlaneRear: {fillOpacity: 0.2}\r\n *             }\r\n *         );\r\n *\r\n *         var A = view.create('point3d', [0, 0, 1], {size: 2});\r\n *         var B = view.create('point3d', [2, 2, 1], {size: 2});\r\n *         var C = view.create('point3d', [-2, 0, 1], {size: 2});\r\n *\r\n *         // Plane by three points\r\n *         var plane = view.create('plane3d', [A, B, C], {\r\n *             fillColor: 'blue'\r\n *         });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *     var view = board.create(\r\n *         'view3d',\r\n *         [[-6, -3], [8, 8],\r\n *         [[-3, 3], [-3, 3], [-3, 3]]],\r\n *         {\r\n *             depthOrder: {\r\n *                 enabled: true\r\n *             },\r\n *             projection: 'central',\r\n *             xPlaneRear: {fillOpacity: 0.2},\r\n *             yPlaneRear: {fillOpacity: 0.2},\r\n *             zPlaneRear: {fillOpacity: 0.2}\r\n *         }\r\n *     );\r\n *\r\n *     var A = view.create('point3d', [-2, 0, 1], {size: 2});\r\n *\r\n *     // Infinite Plane by two directions,\r\n *     // range1 = range2 = [-Infinity, Infinity]\r\n *     var plane1 = view.create('plane3d', [A, [1, 0, 0], [0, 1, 0]], {\r\n *         fillColor: 'blue',\r\n *     });\r\n *\r\n *     // Infinite Plane by three points,\r\n *     var plane2 = view.create('plane3d', [A, [1, 0, 0], [0, 1, 0]], {\r\n *         threePoints: true,\r\n *         fillColor: 'red',\r\n *         point2: {visible: true},\r\n *         point3: {visible: true}\r\n *     });\r\n *\r\n * </pre><div id=\"JXGf31b9666-0c2e-45e7-a186-ae2c07b6bdb8\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGf31b9666-0c2e-45e7-a186-ae2c07b6bdb8',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *         var view = board.create(\r\n *             'view3d',\r\n *             [[-6, -3], [8, 8],\r\n *             [[-3, 3], [-3, 3], [-3, 3]]],\r\n *             {\r\n *                 depthOrder: {\r\n *                     enabled: true\r\n *                 },\r\n *                 projection: 'central',\r\n *                 xPlaneRear: {fillOpacity: 0.2},\r\n *                 yPlaneRear: {fillOpacity: 0.2},\r\n *                 zPlaneRear: {fillOpacity: 0.2}\r\n *             }\r\n *         );\r\n *\r\n *         var A = view.create('point3d', [-2, 0, 1], {size: 2});\r\n *\r\n *         // Infinite Plane by two directions,\r\n *         // range1 = range2 = [-Infinity, Infinity]\r\n *         var plane1 = view.create('plane3d', [A, [1, 0, 0], [0, 1, 0]], {\r\n *             fillColor: 'blue',\r\n *         });\r\n *\r\n *         // Infinite Plane by three points,\r\n *         var plane2 = view.create('plane3d', [A, [1, 0, 0], [0, 1, 0]], {\r\n *             threePoints: true,\r\n *             fillColor: 'red',\r\n *             point2: {visible: true},\r\n *             point3: {visible: true}\r\n *         });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createPlane3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        attr,\r\n        point, point2, point3,\r\n        dir1, dir2, range_u, range_v,\r\n        el, mesh3d,\r\n        base = null,\r\n        transform = null;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'plane3d');\r\n    if (//parents.length === 4 &&\r\n        // ()\r\n        attr.threepoints || Type.isPoint3D(parents[2]) || Type.isPoint3D(parents[3])\r\n    ) {\r\n        // Three points\r\n        point = Type.providePoints3D(view, [parents[1]], attributes, 'plane3d', ['point1'])[0];\r\n        point2 = Type.providePoints3D(view, [parents[2]], attributes, 'plane3d', ['point2'])[0];\r\n        point3 = Type.providePoints3D(view, [parents[3]], attributes, 'plane3d', ['point3'])[0];\r\n        dir1 = function() {\r\n            return [point2.X() - point.X(), point2.Y() - point.Y(), point2.Z() - point.Z()];\r\n        };\r\n        dir2 = function() {\r\n            return [point3.X() - point.X(), point3.Y() - point.Y(), point3.Z() - point.Z()];\r\n        };\r\n        range_u = parents[4] || [-Infinity, Infinity];\r\n        range_v = parents[5] || [-Infinity, Infinity];\r\n    } else {\r\n        if (parents[1].type === Const.OBJECT_TYPE_PLANE3D &&\r\n            Type.isTransformationOrArray(parents[2])\r\n        ) {\r\n            // Plane + transformation\r\n            base = parents[1];\r\n            transform = parents[2];\r\n\r\n            point = Type.providePoints3D(view, [[0, 0, 0, 0]],  attributes,  'plane3d', ['point'])[0];\r\n            dir1 = [0, 0.0001, 0, 0];\r\n            dir2 = [0, 0, 0.0001, 0];\r\n            range_u = parents[3] || [-Infinity, Infinity];\r\n            range_v = parents[4] || [-Infinity, Infinity];\r\n        } else {\r\n            // Point, direction and ranges\r\n            point = Type.providePoints3D(view, [parents[1]], attributes, 'plane3d', ['point'])[0];\r\n            dir1 = parents[2];\r\n            dir2 = parents[3];\r\n            range_u = parents[4] || [-Infinity, Infinity];\r\n            range_v = parents[5] || [-Infinity, Infinity];\r\n        }\r\n        if (point === false) {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create plane3d with first parent of type '\" + typeof parents[1] +\r\n                    \"'.\" +\r\n                    \"\\nPossible first parent types are: point3d, array of length 3, function returning an array of length 3.\"\r\n            );\r\n        }\r\n        if ((base !== null && parents < 3) || (base === null && parents.length < 4)) {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create plane3d with parents of type '\" +\r\n                    typeof parents[1] + \", \"  +\r\n                    typeof parents[2] + \", \"  +\r\n                    typeof parents[3] + \", \"  +\r\n                    typeof parents[4] + \", \"  +\r\n                    typeof parents[5] + \"'.\"\r\n            );\r\n        }\r\n    }\r\n\r\n    el = new JXG.Plane3D(view, point, dir1, range_u, dir2, range_v, attr);\r\n    point.addChild(el);\r\n\r\n    attr = el.setAttr2D(attr);\r\n    el.element2D = view.create('curve', [[], []], attr);\r\n    el.element2D.view = view;\r\n\r\n    if (base !== null && transform !== null) {\r\n        el.addTransform(base, transform);\r\n        el.addParents(base);\r\n    }\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    el.element2D.updateDataArray = function () {\r\n        var ret = el.updateDataArray();\r\n        this.dataX = ret.X;\r\n        this.dataY = ret.Y;\r\n    };\r\n    el.addChild(el.element2D);\r\n    el.inherits.push(el.element2D);\r\n    el.element2D.setParents(el);\r\n\r\n    if (\r\n        Math.abs(el.range_u[0]) !== Infinity &&\r\n        Math.abs(el.range_u[1]) !== Infinity &&\r\n        Math.abs(el.range_v[0]) !== Infinity &&\r\n        Math.abs(el.range_v[1]) !== Infinity\r\n    ) {\r\n        attr = Type.copyAttributes(attr.mesh3d, board.options, 'mesh3d');\r\n        mesh3d = view.create('mesh3d', [\r\n            function () {\r\n                return point.coords;\r\n            },\r\n            // dir1, dir2, range_u, range_v\r\n            function() { return el.vec1; },\r\n            function() { return el.vec2; },\r\n            el.range_u,\r\n            el.range_v\r\n        ], attr);\r\n        el.mesh3d = mesh3d;\r\n        el.addChild(mesh3d);\r\n        el.inherits.push(mesh3d);           // TODO Does not work\r\n        el.element2D.inherits.push(mesh3d); // Does work - instead\r\n        mesh3d.setParents(el);\r\n        el.mesh3d.view = view;\r\n    }\r\n\r\n    el.element2D.prepareUpdate().update();\r\n    if (!board.isSuspendedUpdate) {\r\n        el.element2D.updateVisibility().updateRenderer();\r\n    }\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement('plane3d', JXG.createPlane3D);\r\n\r\n/**\r\n * @class The line that is the intersection of two (infinite) plane elements in 3D.\r\n *\r\n * @pseudo\r\n * @name IntersectionLine3D\r\n * @augments JXG.Line3D\r\n * @constructor\r\n * @type JXG.Line3D\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Plane3D_JXG.Plane3D} el1,el2 The result will be the intersection of el1 and el2.\r\n * @example\r\n * // Create the intersection line of two planes\r\n * var view = board.create(\r\n *     'view3d',\r\n *     [[-6, -3], [8, 8],\r\n *     [[-1, 3], [-1, 3], [-1, 3]]],\r\n *     {\r\n *         xPlaneRear: {visible:false},\r\n *         yPlaneRear: {visible:false},\r\n *         zPlaneRear: {fillOpacity: 0.2, gradient: null}\r\n *     }\r\n * );\r\n * var a = view.create('point3d', [2, 2, 0]);\r\n *\r\n * var p1 = view.create(\r\n *    'plane3d',\r\n *     [a, [1, 0, 0], [0, 1, 0]],\r\n *     {fillColor: '#00ff80'}\r\n * );\r\n * var p2 = view.create(\r\n *    'plane3d',\r\n *     [a, [-2, 1, 1], [1, -2, 1]],\r\n *     {fillColor: '#ff0000'}\r\n * );\r\n *\r\n * var i = view.create('intersectionline3d', [p1, p2]);\r\n *\r\n * </pre><div id=\"JXGdb931076-b29a-4eff-b97e-4251aaf24943\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGdb931076-b29a-4eff-b97e-4251aaf24943',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});\r\n *         var view = board.create(\r\n *             'view3d',\r\n *             [[-6, -3], [8, 8],\r\n *             [[-1, 3], [-1, 3], [-1, 3]]],\r\n *             {\r\n *                 xPlaneRear: {visible:false},\r\n *                 yPlaneRear: {visible:false},\r\n *                 zPlaneRear: {fillOpacity: 0.2, gradient: null}\r\n *             }\r\n *         );\r\n *     var a = view.create('point3d', [2, 2, 0]);\r\n *\r\n *     var p1 = view.create(\r\n *        'plane3d',\r\n *         [a, [1, 0, 0], [0, 1, 0]],\r\n *         {fillColor: '#00ff80'}\r\n *     );\r\n *     var p2 = view.create(\r\n *        'plane3d',\r\n *         [a, [-2, 1, 1], [1, -2, 1]],\r\n *         {fillColor: '#ff0000'}\r\n *     );\r\n *\r\n *     var i = view.create('intersectionline3d', [p1, p2]);\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createIntersectionLine3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        el1 = parents[1],\r\n        el2 = parents[2],\r\n        ixnLine, i, func,\r\n        attr = Type.copyAttributes(attributes, board.options, 'intersectionline3d'),\r\n        pts = [];\r\n\r\n    func = Geometry.intersectionFunction3D(view, el1, el2);\r\n    for (i = 0; i < 2; i++) {\r\n        pts[i] = view.create('point3d', func[i], attr['point' + (i + 1)]);\r\n    }\r\n    ixnLine = view.create('line3d', pts, attr);\r\n\r\n    try {\r\n        el1.addChild(ixnLine);\r\n        el2.addChild(ixnLine);\r\n    } catch (_e) {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create 'intersection' with parent types '\" +\r\n            typeof parents[1] +\r\n            \"' and '\" +\r\n            typeof parents[2] +\r\n            \"'.\"\r\n        );\r\n    }\r\n\r\n    ixnLine.type = Const.OBJECT_TYPE_INTERSECTION_LINE3D;\r\n    ixnLine.elType = 'intersectionline3d';\r\n    ixnLine.setParents([el1.id, el2.id]);\r\n\r\n    return ixnLine;\r\n};\r\n\r\nJXG.registerElement('intersectionline3d', JXG.createIntersectionLine3D);\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*global JXG:true, define: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Type from \"../utils/type.js\";\r\n//, GeometryElement3D) {\r\n\r\n/**\r\n * A 3D text is a basic geometric element.\r\n * @class Creates a new 3D point object. Do not use this constructor to create a 3D point. Use {@link JXG.View3D#create} with\r\n * type {@link Point3D} instead.\r\n * @augments JXG.GeometryElement3D\r\n * @augments JXG.GeometryElement\r\n * @param {JXG.View3D} view The 3D view the point is drawn on.\r\n * @param {Function|Array} F Array of numbers, array of functions or function returning an array with defines the user coordinates of the point.\r\n * @param {JXG.GeometryElement3D} slide Object the 3D point should be bound to. If null, the point is a free point.\r\n * @param {Object} attributes An object containing visual properties like in {@link JXG.Options#point3d} and\r\n * {@link JXG.Options#elements}, and optional a name and an id.\r\n * @see JXG.Board#generateName\r\n */\r\nJXG.Text3D = function (view, F, text, slide, attributes) {\r\n    this.constructor(view.board, attributes, Const.OBJECT_TYPE_TEXT3D, Const.OBJECT_CLASS_3D);\r\n    this.constructor3D(view, 'text3d');\r\n\r\n    this.board.finalizeAdding(this);\r\n\r\n    /**\r\n     * Homogeneous coordinates of a Point3D, i.e. array of length 4: [w, x, y, z]. Usually, w=1 for finite points and w=0 for points\r\n     * which are infinitely far.\r\n     *\r\n     * @example\r\n     *   p.coords;\r\n     *\r\n     * @name Point3D#coords\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.coords = [0, 0, 0, 0];\r\n\r\n    /**\r\n     * Function or array of functions or array of numbers defining the coordinates of the point, used in {@link updateCoords}.\r\n     *\r\n     * @name Point3D#F\r\n     * @function\r\n     * @private\r\n     *\r\n     * @see updateCoords\r\n     */\r\n    this.F = F;\r\n\r\n    /**\r\n     * Optional slide element, i.e. element the Point3D lives on.\r\n     *\r\n     * @example\r\n     *   p.slide;\r\n     *\r\n     * @name Point3D#slide\r\n     * @type JXG.GeometryElement3D\r\n     * @default null\r\n     * @private\r\n     *\r\n     */\r\n    this.slide = slide;\r\n\r\n    /**\r\n     * Get x-coordinate of a 3D point.\r\n     *\r\n     * @name X\r\n     * @memberOf Point3D\r\n     * @function\r\n     * @returns {Number}\r\n     *\r\n     * @example\r\n     *   p.X();\r\n     */\r\n    this.X = function () {\r\n        return this.coords[1];\r\n    };\r\n\r\n    /**\r\n     * Get y-coordinate of a 3D point.\r\n     *\r\n     * @name Y\r\n     * @memberOf Point3D\r\n     * @function\r\n     * @returns Number\r\n     *\r\n     * @example\r\n     *   p.Y();\r\n     */\r\n    this.Y = function () {\r\n        return this.coords[2];\r\n    };\r\n\r\n    /**\r\n     * Get z-coordinate of a 3D point.\r\n     *\r\n     * @name Z\r\n     * @memberOf Point3D\r\n     * @function\r\n     * @returns Number\r\n     *\r\n     * @example\r\n     *   p.Z();\r\n     */\r\n    this.Z = function () {\r\n        return this.coords[3];\r\n    };\r\n\r\n    /**\r\n     * Store the last position of the 2D point for the optimizer.\r\n     *\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.position = [];\r\n\r\n    this._c2d = null;\r\n\r\n    this.methodMap = Type.deepCopy(this.methodMap, {\r\n        // TODO\r\n    });\r\n};\r\nJXG.Text3D.prototype = new JXG.GeometryElement();\r\nType.copyPrototypeMethods(JXG.Text3D, JXG.GeometryElement3D, 'constructor3D');\r\n\r\nJXG.extend(\r\n    JXG.Text3D.prototype,\r\n    /** @lends JXG.Text3D.prototype */ {\r\n        /**\r\n         * Update the homogeneous coords array.\r\n         *\r\n         * @name updateCoords\r\n         * @memberOf Text3D\r\n         * @function\r\n         * @returns {Object} Reference to the Text3D object\r\n         * @private\r\n         * @example\r\n         *    p.updateCoords();\r\n         */\r\n        updateCoords: function () {\r\n            var i;\r\n\r\n            if (Type.isFunction(this.F)) {\r\n                // this.coords = [1].concat(Type.evaluate(this.F));\r\n                this.coords = Type.evaluate(this.F);\r\n                this.coords.unshift(1);\r\n            } else {\r\n                this.coords[0] = 1;\r\n                for (i = 0; i < 3; i++) {\r\n                    // Attention: if F is array of numbers, coords are not updated.\r\n                    // Otherwise, dragging will not work anymore.\r\n                    if (Type.isFunction(this.F[i])) {\r\n                        this.coords[i + 1] = Type.evaluate(this.F[i]);\r\n                    }\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Initialize the coords array.\r\n         *\r\n         * @private\r\n         * @returns {Object} Reference to the Text3D object\r\n         */\r\n        initCoords: function () {\r\n            var i;\r\n\r\n            if (Type.isFunction(this.F)) {\r\n                // this.coords = [1].concat(Type.evaluate(this.F));\r\n                this.coords = Type.evaluate(this.F);\r\n                this.coords.unshift(1);\r\n            } else {\r\n                this.coords[0] = 1;\r\n                for (i = 0; i < 3; i++) {\r\n                    this.coords[i + 1] = Type.evaluate(this.F[i]);\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Normalize homogeneous coordinates such the the first coordinate (the w-coordinate is equal to 1 or 0)-\r\n         *\r\n         * @name normalizeCoords\r\n         * @memberOf Text3D\r\n         * @function\r\n         * @returns {Object} Reference to the Text3D object\r\n         * @private\r\n         * @example\r\n         *    p.normalizeCoords();\r\n         */\r\n        normalizeCoords: function () {\r\n            if (Math.abs(this.coords[0]) > Mat.eps) {\r\n                this.coords[1] /= this.coords[0];\r\n                this.coords[2] /= this.coords[0];\r\n                this.coords[3] /= this.coords[0];\r\n                this.coords[0] = 1.0;\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set the position of a 3D point.\r\n         *\r\n         * @name setPosition\r\n         * @memberOf Text3D\r\n         * @function\r\n         * @param {Array} coords 3D coordinates. Either of the form [x,y,z] (Euclidean) or [w,x,y,z] (homogeneous).\r\n         * @param {Boolean} [noevent] If true, no events are triggered.\r\n         * @returns {Object} Reference to the Text3D object\r\n         *\r\n         * @example\r\n         *    p.setPosition([1, 3, 4]);\r\n         */\r\n        setPosition: function (coords, noevent) {\r\n            var c = this.coords;\r\n                // oc = this.coords.slice(); // Copy of original values\r\n\r\n            if (coords.length === 3) {\r\n                // Euclidean coordinates\r\n                c[0] = 1.0;\r\n                c[1] = coords[0];\r\n                c[2] = coords[1];\r\n                c[3] = coords[2];\r\n            } else {\r\n                // Homogeneous coordinates (normalized)\r\n                c[0] = coords[0];\r\n                c[1] = coords[1];\r\n                c[2] = coords[2];\r\n                c[3] = coords[2];\r\n                this.normalizeCoords();\r\n            }\r\n\r\n            // console.log(el.emitter, !noevent, oc[0] !== c[0] || oc[1] !== c[1] || oc[2] !== c[2] || oc[3] !== c[3]);\r\n            // Not yet working TODO\r\n            // if (el.emitter && !noevent &&\r\n            //     (oc[0] !== c[0] || oc[1] !== c[1] || oc[2] !== c[2] || oc[3] !== c[3])) {\r\n            //     this.triggerEventHandlers(['update3D'], [oc]);\r\n            // }\r\n            return this;\r\n        },\r\n\r\n        update: function (drag) {\r\n            var c3d, foot, res;\r\n\r\n            // Update is called from board.updateElements.\r\n            // See Point3D.update() for the logic.\r\n            if (\r\n                this.element2D.draggable() &&\r\n                Geometry.distance(this._c2d, this.element2D.coords.usrCoords) !== 0\r\n            ) {\r\n                if (this.view.isVerticalDrag()) {\r\n                    // Drag the text in its vertical to the xy plane\r\n                    // If the text is outside of bbox3d,\r\n                    // c3d is already corrected.\r\n                    c3d = this.view.project2DTo3DVertical(this.element2D, this.coords);\r\n                } else {\r\n                    // Drag the text in its xy plane\r\n                    foot = [1, 0, 0, this.coords[3]];\r\n                    c3d = this.view.project2DTo3DPlane(this.element2D, [1, 0, 0, 1], foot);\r\n                }\r\n\r\n                if (c3d[0] !== 0) {\r\n                    // Check if c3d is inside of view.bbox3d\r\n                    // Otherwise, the coords are now corrected.\r\n                    res = this.view.project3DToCube(c3d);\r\n                    this.coords = res[0];\r\n\r\n                    if (res[1]) {\r\n                        // The 3D coordinates have been corrected, now\r\n                        // also correct the 2D element.\r\n                        this.element2D.coords.setCoordinates(\r\n                            Const.COORDS_BY_USER,\r\n                            this.view.project3DTo2D(this.coords)\r\n                        );\r\n                    }\r\n\r\n                    if (this.slide) {\r\n                        this.coords = this.slide.projectCoords([this.X(), this.Y(), this.Z()], this.position);\r\n                        this.element2D.coords.setCoordinates(\r\n                            Const.COORDS_BY_USER,\r\n                            this.view.project3DTo2D(this.coords)\r\n                        );\r\n                    }\r\n                }\r\n            } else {\r\n                this.updateCoords();\r\n                if (this.slide) {\r\n                    this.coords = this.slide.projectCoords([this.X(), this.Y(), this.Z()], this.position);\r\n                }\r\n                // Update 2D text from its 3D view\r\n                c3d = this.coords;\r\n                this.element2D.coords.setCoordinates(\r\n                    Const.COORDS_BY_USER,\r\n                    this.view.project3DTo2D(c3d)\r\n                );\r\n                // this.zIndex = Mat.matVecMult(this.view.matrix3DRotShift, c3d)[3];\r\n                this.zIndex = Mat.innerProduct(this.view.matrix3DRotShift[3], c3d);\r\n                this.element2D.prepareUpdate().update();\r\n            }\r\n            this._c2d = this.element2D.coords.usrCoords.slice();\r\n\r\n            return this;\r\n        },\r\n\r\n        updateRenderer: function () {\r\n            this.needsUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Check whether a text's position is finite, i.e. the first entry is not zero.\r\n         * @returns {Boolean} True if the first entry of the coordinate vector is not zero; false otherwise.\r\n         */\r\n        testIfFinite: function () {\r\n            return Math.abs(this.coords[0]) > Mat.eps ? true : false;\r\n            // return Type.cmpArrays(this.coords, [0, 0, 0, 0]);\r\n        },\r\n\r\n        // Not yet working\r\n        __evt__update3D: function (oc) {}\r\n    }\r\n);\r\n\r\n/**\r\n * @class Construct a text element in a 3D view.\r\n * @pseudo\r\n * @description A Text3D object is defined by 3 coordinates [x, y, z, text] or an array / function for the position of the text\r\n * and a string or function defining the text.\r\n * <p>\r\n * That is, all numbers can also be provided as functions returning a number.\r\n * <p>\r\n * At the time being, text display is independent from the camera view.\r\n *\r\n * @name Text3D\r\n * @augments JXG.Text3D\r\n * @augments Text\r\n * @constructor\r\n * @throws {Exception} If the element cannot be constructed with the given parent\r\n * objects an exception is thrown.\r\n * @param {number,function_number,function_number,function_String,function_JXG.GeometryElement3D} x,y,z,txt,[slide=undefined]\r\n * The coordinates are given as x, y, z consisting of numbers of functions and the text.\r\n * If an optional 3D element \"slide\" is supplied, the point is a glider on that element.\r\n * @param {array,function_string_JXG.GeometryElement3D}} F,txt,[slide=undefined] Alternatively, the coordinates can be supplied as array or function returning an array.\r\n * If an optional 3D element \"slide\" is supplied, the point is a glider on that element.\r\n *\r\n * @example\r\n *     var bound = [-4, 6];\r\n *     var view = board.create('view3d',\r\n *         [[-4, -3], [8, 8],\r\n *         [bound, bound, bound]],\r\n *         {\r\n *             projection: 'central'\r\n *         });\r\n *\r\n *     var txt1 = view.create('text3d', [[1, 2, 1], 'hello'], {\r\n *         fontSize: 20,\r\n *     });\r\n *\r\n * </pre><div id=\"JXGb61d7c50-617a-4bed-9a45-13c949f90e94\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGb61d7c50-617a-4bed-9a45-13c949f90e94',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});\r\n *         var bound = [-4, 6];\r\n *         var view = board.create('view3d',\r\n *             [[-4, -3], [8, 8],\r\n *             [bound, bound, bound]],\r\n *             {\r\n *                 projection: 'central'\r\n *             });\r\n *\r\n *         var txt1 = view.create('text3d', [[1, 2, 1], 'hello'], {\r\n *             fontSize: 20,\r\n *         });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createText3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        attr, F, slide,\r\n        text,\r\n        c2d, el;\r\n\r\n    // If the last element of parents is a 3D object,\r\n    // the point is a glider on that element.\r\n    if (parents.length > 2 && Type.exists(parents[parents.length - 1].is3D)) {\r\n        slide = parents.pop();\r\n    } else {\r\n        slide = null;\r\n    }\r\n\r\n    if (parents.length === 3) {\r\n        // [view, array|fun, text] (Array [x, y, z] | function) returning [x, y, z] and string | function\r\n        F = parents[1];\r\n        text = parents[2];\r\n    } else if (parents.length === 5) {\r\n        // [view, x, y, z, text], (3 numbers | functions) sand string | function\r\n        F = parents.slice(1, 4);\r\n        text = parents[4];\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create text3d with parent types '\" +\r\n                typeof parents[1] +\r\n                \"' and '\" +\r\n                typeof parents[2] +\r\n                \"'.\" +\r\n                \"\\nPossible parent types: [[x,y,z], text], [x,y,z, text]\"\r\n        );\r\n        //  \"\\nPossible parent types: [[x,y,z]], [x,y,z], [element,transformation]\"); // TODO\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'text3d');\r\n    el = new JXG.Text3D(view, F, text, slide, attr);\r\n    el.initCoords();\r\n\r\n    c2d = view.project3DTo2D(el.coords);\r\n\r\n    attr = el.setAttr2D(attr);\r\n    el.element2D = view.create('text', [c2d[1], c2d[2], text], attr);\r\n\r\n    el.element2D.view = view;\r\n    el.addChild(el.element2D);\r\n    el.inherits.push(el.element2D);\r\n    el.element2D.setParents(el);\r\n\r\n    // If this point is a glider, record that in the update tree\r\n    if (el.slide) {\r\n        el.slide.addChild(el);\r\n        el.setParents(el.slide);\r\n    }\r\n\r\n    el._c2d = el.element2D.coords.usrCoords.slice(); // Store a copy of the coordinates to detect dragging\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"text3d\", JXG.createText3D);\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*global JXG:true, define: true*/\r\n\r\n/**\r\n * Create axes and rear and front walls of the\r\n * view3d bounding box bbox3D.\r\n */\r\nimport JXG from \"../jxg.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Mat from \"../math/math.js\";\r\n\r\n/**\r\n * @class Ticks are used as distance markers on a line in a 3D view.\r\n * @pseudo\r\n * @description Create 3D ticks.\r\n * <p>\r\n * At the time being, the ticks are not connected to the line or axis. The connecting element is simply the\r\n * parameter point.\r\n *\r\n * @name Ticks3D\r\n * @augments Curve\r\n * @constructor\r\n * @type Object\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Array_Array_Number_Array} point,direction1,length,direction2 point is an array of length 3\r\n * determining the starting point of the grid. direction1 and direction2 are arrays of length 3. Here, direction1 is the direction\r\n * of the 3D line, direction2 is the direction of the ticks.\r\n * \"length\" is the length of the line.\r\n * All parameters can be supplied as functions returning an appropriate data type.\r\n * <p>\r\n * The step width of the ticks is determined by the attribute \"ticksDistance\".\r\n *\r\n */\r\nJXG.createTicks3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        point = parents[1],\r\n        dir1 = parents[2],\r\n        length = parents[3],\r\n        dir2 = parents[4],\r\n        el, attr;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'ticks3d');\r\n    el = view.create(\"curve\", [[], []], attr);\r\n\r\n    el.point = point;\r\n    el.direction1 = dir1;\r\n    el.len = length;\r\n    el.direction2 = dir2;\r\n\r\n    el.drawLabels = function(attr) {\r\n        var s1 = 0,\r\n            e1 = this.len,\r\n            step = this.evalVisProp('ticksdistance'),\r\n            range2 = this.evalVisProp('tickendings'),\r\n            mh =  this.evalVisProp('majorheight'),\r\n            e2,\r\n            l1, l2,\r\n            i,\r\n            u, val, p,\r\n            v1 = [0, 0, 0],\r\n            v2 = [0, 0, 0],\r\n            q = [0, 0, 0],\r\n            labels = [];\r\n\r\n        mh /= Math.sqrt(board.unitX * board.unitY); // Very crude estimation of tick length\r\n        e2 = mh * range2[1] * 2;\r\n\r\n        this.dataX = [];\r\n        this.dataY = [];\r\n\r\n        if (Type.isFunction(this.point)) {\r\n            q = this.point().slice(1);\r\n        } else {\r\n            for (i = 0; i < 3; i++) {\r\n                q[i] = Type.evaluate(this.point[i]);\r\n            }\r\n        }\r\n        for (i = 0; i < 3; i++) {\r\n            v1[i] = Type.evaluate(this.direction1[i]);\r\n            v2[i] = Type.evaluate(this.direction2[i]);\r\n        }\r\n\r\n        l1 = JXG.Math.norm(v1, 3);\r\n        l2 = JXG.Math.norm(v2, 3);\r\n        for (i = 0; i < 3; i++) {\r\n            v1[i] /= l1;\r\n            v2[i] /= l2;\r\n        }\r\n\r\n        if (Math.abs(step) < Mat.eps) {\r\n            return;\r\n        }\r\n        for (u = s1; u <= e1; u += step) {\r\n            // Label\r\n            p = [\r\n                q[0] + u * v1[0] + e2 * v2[0],\r\n                q[1] + u * v1[1] + e2 * v2[1],\r\n                q[2] + u * v1[2] + e2 * v2[2]\r\n            ];\r\n            for (i = 0; i < 3; i++) {\r\n                if (v1[i] !== 0) {\r\n                    val = q[i] + u * v1[i];\r\n                }\r\n            }\r\n            labels.push(view.create('text3d', [p, val], attr));\r\n        }\r\n        return labels;\r\n    };\r\n\r\n    if (el.evalVisProp('drawlabels')) {\r\n        el.labels = el.drawLabels(attr.label);\r\n    }\r\n\r\n    /**\r\n     * @ignore\r\n     */\r\n    el.updateDataArray = function () {\r\n        var s1 = 0,\r\n            e1 = this.len,\r\n            step = this.evalVisProp('ticksdistance'),\r\n            range2 = this.evalVisProp('tickendings'),\r\n            mh =  this.evalVisProp('majorheight'),\r\n            s2, e2,\r\n            l1, l2,\r\n            i,\r\n            u, c2d, p,\r\n            v1 = [0, 0, 0],\r\n            v2 = [0, 0, 0],\r\n            q = [0, 0, 0];\r\n\r\n        mh /= Math.sqrt(board.unitX * board.unitY); // Very crude estimation of tick length\r\n        s2 = mh * (-range2[0]);\r\n        e2 = mh * range2[1];\r\n\r\n        this.dataX = [];\r\n        this.dataY = [];\r\n\r\n        if (Type.isFunction(this.point)) {\r\n            q = this.point().slice(1);\r\n        } else {\r\n            for (i = 0; i < 3; i++) {\r\n                q[i] = Type.evaluate(this.point[i]);\r\n            }\r\n        }\r\n        for (i = 0; i < 3; i++) {\r\n            v1[i] = Type.evaluate(this.direction1[i]);\r\n            v2[i] = Type.evaluate(this.direction2[i]);\r\n        }\r\n\r\n        l1 = JXG.Math.norm(v1, 3);\r\n        l2 = JXG.Math.norm(v2, 3);\r\n        for (i = 0; i < 3; i++) {\r\n            v1[i] /= l1;\r\n            v2[i] /= l2;\r\n        }\r\n\r\n        if (Math.abs(step) < Mat.eps) {\r\n            return;\r\n        }\r\n        for (u = s1; u <= e1; u += step) {\r\n            p = [\r\n                q[0] + u * v1[0] + s2 * v2[0],\r\n                q[1] + u * v1[1] + s2 * v2[1],\r\n                q[2] + u * v1[2] + s2 * v2[2]\r\n            ];\r\n            c2d = view.project3DTo2D(p);\r\n            this.dataX.push(c2d[1]);\r\n            this.dataY.push(c2d[2]);\r\n            p = [\r\n                q[0] + u * v1[0] + e2 * v2[0],\r\n                q[1] + u * v1[1] + e2 * v2[1],\r\n                q[2] + u * v1[2] + e2 * v2[2]\r\n            ];\r\n            c2d = view.project3DTo2D(p);\r\n            this.dataX.push(c2d[1]);\r\n            this.dataY.push(c2d[2]);\r\n            this.dataX.push(NaN);\r\n            this.dataY.push(NaN);\r\n        }\r\n    };\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"ticks3d\", JXG.createTicks3D);\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Aaron Fenyes,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*global JXG:true, define: true*/\r\n\r\nimport JXG from '../jxg.js';\r\nimport Const from '../base/constants.js';\r\nimport Type from '../utils/type.js';\r\nimport Mat from '../math/math.js';\r\n\r\n/**\r\n * Constructor for 3D polygons.\r\n * @class Creates a new 3D polygon object. Do not use this constructor to create a 3D polygon. Use {@link JXG.View3D#create} with type {@link Polygon3D} instead.\r\n *\r\n * @augments JXG.GeometryElement3D\r\n * @augments JXG.GeometryElement\r\n * @param {View3D} view\r\n * @param {Point3D|Array} point\r\n * @param {Array} direction\r\n * @param {Array} range\r\n * @param {Object} attributes\r\n * @see JXG.Board#generateName\r\n */\r\nJXG.Polygon3D = function (view, vertices, attributes) {\r\n    var i;\r\n\r\n    this.constructor(view.board, attributes, Const.OBJECT_TYPE_POLYGON3D, Const.OBJECT_CLASS_3D);\r\n    this.constructor3D(view, 'polygon3d');\r\n\r\n    this.board.finalizeAdding(this);\r\n\r\n    /**\r\n     * References to the points defining the polygon.\r\n     * Compared to the 2D {@link JXG.Polygon#vertices}, it contains one point less, i.e. for a quadrangle\r\n     * 'vertices' contains four points. In a 2D quadrangle, 'vertices' will contain five points, the last one being\r\n     * a copy of the first one.\r\n     * @type Array\r\n     */\r\n    this.vertices = [];\r\n    for (i = 0; i < vertices.length; i++) {\r\n        this.vertices[i] = this.board.select(vertices[i]);\r\n\r\n        // The _is_new flag is replaced by _is_new_pol.\r\n        // Otherwise, the polygon would disappear if the last border element\r\n        // is removed (and the point has been provided by coordinates)\r\n        if (this.vertices[i]._is_new) {\r\n            delete this.vertices[i]._is_new;\r\n            this.vertices[i]._is_new_pol = true;\r\n        }\r\n    }\r\n};\r\nJXG.Polygon3D.prototype = new JXG.GeometryElement();\r\nType.copyPrototypeMethods(JXG.Polygon3D, JXG.GeometryElement3D, 'constructor3D');\r\n\r\nJXG.extend(\r\n    JXG.Polygon3D.prototype,\r\n    /** @lends JXG.Polygon3D.prototype */ {\r\n        update: function () {\r\n            return this;\r\n        },\r\n\r\n        updateRenderer: function () {\r\n            this.needsUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        updateZIndex: function() {\r\n            var i,\r\n                le = this.vertices.length, // - 1,\r\n                c3d = [1, 0, 0, 0];\r\n\r\n            if (le <= 0) {\r\n                return [NaN, NaN, NaN, NaN];\r\n            }\r\n            for (i = 0; i < le; i++) {\r\n                c3d[1] += this.vertices[i].coords[1];\r\n                c3d[2] += this.vertices[i].coords[2];\r\n                c3d[3] += this.vertices[i].coords[3];\r\n            }\r\n            c3d[1] /= le;\r\n            c3d[2] /= le;\r\n            c3d[3] /= le;\r\n\r\n            // this.zIndex = Mat.matVecMult(this.view.matrix3DRotShift, c3d)[3];\r\n            this.zIndex = Mat.innerProduct(this.view.matrix3DRotShift[3], c3d);\r\n\r\n            return this;\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * @class A polygon is a sequence of points connected by lines, with the last point\r\n * connecting back to the first one. The points are given by:\r\n * <ul>\r\n *    <li> a list of Point3D objects,\r\n *    <li> a list of coordinate arrays, or\r\n *    <li> a function returning a list of coordinate arrays.\r\n * </ul>\r\n * Each two consecutive points of the list define a line.\r\n * <p>\r\n * JSXGraph does not require and does not check planarity of the polygon.\r\n *\r\n * @pseudo\r\n * @constructor\r\n * @name Polygon3D\r\n * @type JXG.Polygon3D\r\n * @augments JXG.Polygon3D\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Array} vertices The polygon's vertices.\r\n */\r\nJXG.createPolygon3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        el, i, le, obj,\r\n        points = [],\r\n        points2d = [],\r\n        attr,\r\n        attr_points,\r\n        is_transform = false;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'polygon3d');\r\n    obj = board.select(parents[1]);\r\n    if (obj === null) {\r\n        // This is necessary if the original polygon is defined in another board.\r\n        obj = parents[1];\r\n    }\r\n    // TODO: Number of points? Is the last point equal to the first point?\r\n    if (\r\n        Type.isObject(obj) &&\r\n        obj.type === Const.OBJECT_TYPE_POLYGON3D &&\r\n        Type.isTransformationOrArray(parents[2])\r\n    ) {\r\n        is_transform = true;\r\n        le = obj.vertices.length - 1;\r\n        attr_points = Type.copyAttributes(attributes, board.options, 'polygon3d', 'vertices');\r\n        for (i = 0; i < le; i++) {\r\n            if (attr_points.withlabel) {\r\n                attr_points.name =\r\n                    obj.vertices[i].name === '' ? '' : obj.vertices[i].name + \"'\";\r\n            }\r\n            points.push(board.create('point3d', [obj.vertices[i], parents[2]], attr_points));\r\n        }\r\n    } else if (Type.isArray(parents[1]) && parents[1].every((x) => Type.isPoint3D(x))) {\r\n        // array of points [A, B, C]\r\n        // TODO mixing points and coords arrays\r\n        points = parents[1];\r\n    } else {\r\n        points = Type.providePoints3D(view, parents.slice(1), attributes, 'polygon3d', ['vertices']);\r\n        if (points === false) {\r\n            throw new Error(\r\n                \"JSXGraph: Can't create polygon3d with parent types other than 'point' and 'coordinate arrays' or a function returning an array of coordinates. Alternatively, a polygon3d and a transformation can be supplied\"\r\n            );\r\n        }\r\n    }\r\n\r\n    el = new JXG.Polygon3D(view, points, attr);\r\n    el.isDraggable = true;\r\n\r\n    attr = el.setAttr2D(attr);\r\n    for (i = 0; i < points.length; i++) {\r\n        points2d.push(points[i].element2D);\r\n    }\r\n    el.element2D = board.create('polygon', points2d, attr);\r\n    el.element2D.view = view;\r\n    el.addChild(el.element2D);\r\n    el.inherits.push(el.element2D);\r\n    el.element2D.setParents(el);\r\n\r\n    // Put the points in their positions\r\n    if (is_transform) {\r\n        el.prepareUpdate().update().updateVisibility().updateRenderer();\r\n        le = obj.vertices.length - 1;\r\n        for (i = 0; i < le; i++) {\r\n            points[i].prepareUpdate().update().updateVisibility().updateRenderer();\r\n        }\r\n    }\r\n\r\n    return el;\r\n};\r\nJXG.registerElement('polygon3d', JXG.createPolygon3D);","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*global JXG:true, define: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Mat from \"../math/math.js\";\r\n\r\n/**\r\n * 3D faces\r\n * @class Creates a new 3D face object. Do not use this constructor to create a 3D curve. Use {@link JXG.View3D#create} with type {@link Face3D} instead.\r\n *\r\n * @augments JXG.GeometryElement3D\r\n * @augments JXG.GeometryElement\r\n * @param {View3D} view\r\n * @param {Function} F\r\n * @param {Function} X\r\n * @param {Function} Y\r\n * @param {Function} Z\r\n * @param {Array} range\r\n * @param {Object} attributes\r\n * @see JXG.Board#generateName\r\n */\r\nJXG.Face3D = function (view, polyhedron, faceNumber, attributes) {\r\n    this.constructor(view.board, attributes, Const.OBJECT_TYPE_FACE3D, Const.OBJECT_CLASS_3D);\r\n    this.constructor3D(view, 'face3d');\r\n\r\n    this.board.finalizeAdding(this);\r\n\r\n    /**\r\n     * Link to the defining data of the parent polyhedron3d.\r\n     * @name Face3D#polyhedron\r\n     * @type Object\r\n     * @see Polyhedron3D#def\r\n     */\r\n    this.polyhedron = polyhedron;\r\n\r\n    /**\r\n     * Index of the face in the list of faces of the polyhedron\r\n     * @name Face3D#faceNumber\r\n     * @type Number\r\n     */\r\n    this.faceNumber = faceNumber;\r\n\r\n    /**\r\n     * Normal vector for the face. Array of length 4.\r\n     * @name Face3D#normal\r\n     * @type array\r\n     */\r\n    this.normal = [0, 0, 0, 0];\r\n\r\n    /**\r\n     * Hesse right hand side of the plane that contains the face.\r\n     * @name Face3D#d\r\n     * @type Number\r\n     */\r\n    this.d = 0;\r\n\r\n    /**\r\n     * First basis vector of the face. Vector of length 4.\r\n     * @name Face3D#vec1\r\n     * @type Array\r\n     */\r\n    this.vec1 = [0, 0, 0, 0];\r\n\r\n    /**\r\n     * Second basis vector of the face. Vector of length 4.\r\n     * @name Face3D#vec2\r\n     * @type Array\r\n     */\r\n    this.vec2 = [0, 0, 0, 0];\r\n\r\n    if (this.faceNumber === 0) {\r\n        this.updateCoords();\r\n    }\r\n\r\n    this.methodMap = Type.deepCopy(this.methodMap, {\r\n        // TODO\r\n    });\r\n};\r\nJXG.Face3D.prototype = new JXG.GeometryElement();\r\nType.copyPrototypeMethods(JXG.Face3D, JXG.GeometryElement3D, 'constructor3D');\r\n\r\nJXG.extend(\r\n    JXG.Face3D.prototype,\r\n    /** @lends JXG.Face3D.prototype */ {\r\n\r\n        /**\r\n         * Update the coordinates of all vertices of the polyhedron\r\n         * @function\r\n         * @name Face3D#updateCoords\r\n         * @returns {Face3D} reference to itself\r\n         */\r\n        updateCoords: function() {\r\n            var i, j, le, p,\r\n                def = this.polyhedron;\r\n\r\n            for (i in def.vertices) {\r\n                p = def.vertices[i];\r\n                if (Type.isFunction(p)) {\r\n                    def.coords[i] = Type.evaluate(p);\r\n                } else if (Type.isArray(p)) {\r\n                    def.coords[i] = [];\r\n                    le = p.length;\r\n                    for (j = 0; j < le; j++) {\r\n                        def.coords[i][j] = Type.evaluate(p[j]);\r\n                    }\r\n                } else {\r\n                    p = def.view.select(p);\r\n                    if (Type.isPoint3D(p)) {\r\n                        def.coords[i] = p.coords;\r\n                    } else {\r\n                        throw new Error('Polyhedron3D.updateCoords: unknown vertices type!');\r\n                    }\r\n                }\r\n                if (def.coords[i].length === 3) {\r\n                    def.coords[i].unshift(1);\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Update the 2D coordinates of the face and determine it's z-index.\r\n         * @function\r\n         * @name Face3D#updateDataArray2D\r\n         * @returns {Object} {X:[], Y:[]}\r\n         */\r\n        updateDataArray2D: function () {\r\n            var j, le,\r\n                c3d, c2d,\r\n                x = [],\r\n                y = [],\r\n                p = this.polyhedron,\r\n                face = p.faces[this.faceNumber];\r\n\r\n            if (this.faceNumber === 0) {\r\n                // coords2D equal to [] means, projection is needed down below.\r\n                // Thus, every vertex is projected only once.\r\n                for (j in p.vertices) {\r\n                    p.coords2D[j] = [];\r\n                }\r\n            }\r\n\r\n            // Add the projected coordinates of the vertices of this face\r\n            // to the 2D curve.\r\n            // If not done yet, project the 3D vertices of this face to 2D.\r\n            le = face.length;\r\n            this.zIndex = 0.0;\r\n            for (j = 0; j < le; j++) {\r\n                c2d = p.coords2D[face[j]];\r\n                if (c2d.length === 0) {\r\n                    // if coords2D.length > 0, it has already be projected\r\n                    // in another face3d.\r\n                    c3d = p.coords[face[j]];\r\n                    c2d = this.view.project3DTo2D(c3d);\r\n                    p.coords2D[face[j]] = c2d;\r\n                    // p.zIndex[face[j]] = Mat.matVecMult(this.view.matrix3DRotShift, c3d)[3];\r\n                    p.zIndex[face[j]] = Mat.innerProduct(this.view.matrix3DRotShift[3], c3d);\r\n                }\r\n                x.push(c2d[1]);\r\n                y.push(c2d[2]);\r\n\r\n                this.zIndex += p.zIndex[face[j]];\r\n            }\r\n            if (le > 0) {\r\n                this.zIndex /= le;\r\n            }\r\n            if (le !== 2) {\r\n                // 2D faces and points are a closed loop\r\n                x.push(x[0]);\r\n                y.push(y[0]);\r\n            }\r\n\r\n            return { X: x, Y: y };\r\n        },\r\n\r\n        addTransform: function (el, transform) {\r\n            if (this.faceNumber === 0) {\r\n                this.addTransformGeneric(el, transform);\r\n            }\r\n            return this;\r\n        },\r\n\r\n        updateTransform: function () {\r\n            var t, c, i, j, b;\r\n\r\n            if (this.faceNumber !== 0) {\r\n                return this;\r\n            }\r\n\r\n            if (this.transformations.length === 0 || this.baseElement === null) {\r\n                return this;\r\n            }\r\n\r\n            t = this.transformations;\r\n            for (i = 0; i < t.length; i++) {\r\n                t[i].update();\r\n            }\r\n\r\n            if (this === this.baseElement) {\r\n                b = this.polyhedron;\r\n            } else {\r\n                b = this.baseElement.polyhedron;\r\n            }\r\n            for (i in b.coords) {\r\n                if (b.coords.hasOwnProperty(i)) {\r\n                    c = b.coords[i];\r\n                    for (j = 0; j < t.length; j++) {\r\n                        c = Mat.matVecMult(t[j].matrix, c);\r\n                    }\r\n                    this.polyhedron.coords[i] = c;\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        update: function () {\r\n            var i, le,\r\n                phdr, nrm,\r\n                p1, p2,\r\n                face;\r\n\r\n            if (this.needsUpdate && !this.view.board._change3DView) {\r\n                phdr = this.polyhedron;\r\n\r\n                if (this.faceNumber === 0) {\r\n                    // Update coordinates of all vertices\r\n                    this.updateCoords()\r\n                        .updateTransform();\r\n                }\r\n\r\n                face = phdr.faces[this.faceNumber];\r\n                le = face.length;\r\n                if (le < 3) {\r\n                    // Get out of here if face is point or segment\r\n                    return this;\r\n                }\r\n\r\n                // Update spanning vectors\r\n                p1 = phdr.coords[face[0]];\r\n                p2 = phdr.coords[face[1]];\r\n                this.vec1 = [p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2], p2[3] - p1[3]];\r\n\r\n                p2 = phdr.coords[face[2]];\r\n                this.vec2 = [p2[0] - p1[0], p2[1] - p1[1], p2[2] - p1[2], p2[3] - p1[3]];\r\n\r\n                // Update Hesse form, i.e. normal and d\r\n                this.normal = Mat.crossProduct(this.vec1.slice(1), this.vec2.slice(1));\r\n                nrm = Mat.norm(this.normal);\r\n                this.normal.unshift(0);\r\n\r\n                if (Math.abs(nrm) > 1.e-12) {\r\n                    for (i = 1; i < 4; i++) {\r\n                        this.normal[i] /= nrm;\r\n                    }\r\n                }\r\n                this.d = Mat.innerProduct(p1, this.normal, 4);\r\n            }\r\n            return this;\r\n        },\r\n\r\n        updateRenderer: function () {\r\n            if (this.needsUpdate) {\r\n                this.needsUpdate = false;\r\n                this.shader();\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Determines the lightness of the face (in the HSL color scheme).\r\n         * <p>\r\n         * Sets the fillColor of the adjoint 2D curve.\r\n         * @name shader\r\n         * @memberOf Face3D\r\n         * @function\r\n         * @returns {Number} zIndex of the face\r\n         */\r\n        shader: function() {\r\n            var hue, sat, light, angle, hsl,\r\n                // bb = this.view.bbox3D,\r\n                minFace, maxFace,\r\n                minLight, maxLight;\r\n\r\n\r\n            if (this.evalVisProp('shader.enabled')) {\r\n                hue = this.evalVisProp('shader.hue');\r\n                sat = this.evalVisProp('shader.saturation');\r\n                minLight = this.evalVisProp('shader.minlightness');\r\n                maxLight = this.evalVisProp('shader.maxlightness');\r\n\r\n                if (this.evalVisProp('shader.type').toLowerCase() === 'angle') {\r\n                    // Angle normal / eye\r\n                    angle = Mat.innerProduct(this.view.matrix3DRotShift[3], this.normal);\r\n                    angle = Math.abs(angle);\r\n                    light = minLight + (maxLight - minLight) * angle;\r\n                } else {\r\n                    // zIndex\r\n                    maxFace = this.view.zIndexMax;\r\n                    minFace = this.view.zIndexMin;\r\n                    light = minLight + (maxLight - minLight) * ((this.zIndex - minFace) / (maxFace - minFace));\r\n                }\r\n\r\n                // hsl = `hsl(${hue}, ${sat}%, ${light}%)`;\r\n                hsl = 'hsl(' + hue + ',' + sat +'%,' + light + '%)';\r\n\r\n                this.element2D.visProp.fillcolor = hsl;\r\n                return this.zIndex;\r\n            }\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * @class This element creates a 3D face.\r\n * @pseudo\r\n * @description A 3D faces is TODO\r\n *\r\n * @name Face3D\r\n * @augments Curve\r\n * @constructor\r\n * @type Object\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n  */\r\nJXG.createFace3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        polyhedron = parents[1],\r\n        faceNumber = parents[2],\r\n        attr, el;\r\n\r\n    // TODO Throw new Error\r\n    attr = Type.copyAttributes(attributes, board.options, 'face3d');\r\n    el = new JXG.Face3D(view, polyhedron, faceNumber, attr);\r\n\r\n    attr = el.setAttr2D(attr);\r\n    el.element2D = view.create(\"curve\", [[], []], attr);\r\n    el.element2D.view = view;\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    el.element2D.updateDataArray = function () {\r\n        var ret = el.updateDataArray2D();\r\n        this.dataX = ret.X;\r\n        this.dataY = ret.Y;\r\n    };\r\n    el.addChild(el.element2D);\r\n    el.inherits.push(el.element2D);\r\n    el.element2D.setParents(el);\r\n\r\n    el.element2D.prepareUpdate().update();\r\n    if (!board.isSuspendedUpdate) {\r\n        el.element2D.updateVisibility().updateRenderer();\r\n    }\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"face3d\", JXG.createFace3D);\r\n\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*global JXG:true, define: true*/\r\n\r\n/**\r\n * Create axes and rear and front walls of the\r\n * view3d bounding box bbox3D.\r\n */\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\nJXG.Polyhedron3D = function (view, polyhedron, faces, attributes) {\r\n    var e,\r\n        genericMethods,\r\n        generateMethod,\r\n        that = this;\r\n\r\n    this.constructor(view.board, attributes, Const.OBJECT_TYPE_POLYHEDRON3D, Const.OBJECT_CLASS_3D);\r\n    this.constructor3D(view, 'polyhedron3d');\r\n\r\n    this.board.finalizeAdding(this);\r\n\r\n    this.elType = 'polyhedron3d';\r\n\r\n    /**\r\n     * List of Face3D objects.\r\n     * @name Polyhedron3D#faces\r\n     * @type Array\r\n     */\r\n    this.faces = faces;\r\n\r\n    /**\r\n     * Number of faces\r\n     * @name Polyhedron3D#numberFaces\r\n     * @type Number\r\n     */\r\n    this.numberFaces = faces.length;\r\n\r\n    /**\r\n     * Contains the defining data of the polyhedron:\r\n     * Definitions of vertices and a list of vertices for each face. This is pretty much the input given\r\n     * in the construction of the polyhedron plus internal data.\r\n     * @name Polyhedron3D#def\r\n     * @type Object\r\n     * @example\r\n     *  polyhedron = {\r\n     *      view: view,\r\n     *      vertices: {},\r\n     *      coords: {},\r\n     *      coords2D: {},\r\n     *      zIndex: {},\r\n     *      faces: []\r\n     *  };\r\n     */\r\n    this.def = polyhedron;\r\n\r\n    // Simultaneous methods for all faces\r\n    genericMethods = [\r\n        \"setAttribute\",\r\n        \"setParents\",\r\n        \"prepareUpdate\",\r\n        \"updateRenderer\",\r\n        \"update\",\r\n        \"fullUpdate\",\r\n        \"highlight\",\r\n        \"noHighlight\"\r\n    ];\r\n\r\n    generateMethod = function (what) {\r\n        return function () {\r\n            var i;\r\n\r\n            for (i in that.faces) {\r\n                if (that.faces.hasOwnProperty(i)) {\r\n                    if (Type.exists(that.faces[i][what])) {\r\n                        that.faces[i][what].apply(that.faces[i], arguments);\r\n                    }\r\n                }\r\n            }\r\n            return that;\r\n        };\r\n    };\r\n\r\n    for (e = 0; e < genericMethods.length; e++) {\r\n        this[genericMethods[e]] = generateMethod(genericMethods[e]);\r\n    }\r\n\r\n    this.methodMap = Type.deepCopy(this.methodMap, {\r\n        setAttribute: \"setAttribute\",\r\n        setParents: \"setParents\",\r\n        addTransform: \"addTransform\"\r\n    });\r\n};\r\nJXG.Polyhedron3D.prototype = new JXG.GeometryElement();\r\nType.copyPrototypeMethods(JXG.Polyhedron3D, JXG.GeometryElement3D, 'constructor3D');\r\n\r\nJXG.extend(\r\n    JXG.Polyhedron3D.prototype,\r\n    /** @lends JXG.Polyhedron3D.prototype */ {\r\n\r\n        // Already documented in element3d.js\r\n        addTransform: function (el, transform) {\r\n            if (this.faces.length > 0 && el.faces.length > 0) {\r\n                this.faces[0].addTransform(el.faces[0], transform);\r\n            } else {\r\n                throw new Error(\"Adding transformation failed. At least one of the two polyhedra has no faces.\");\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Output polyhedron in ASCII STL format.\r\n         * Normals are ignored and output as 0 0 0.\r\n         *\r\n         * @param {String} name Set name of the model, overwrites property name\r\n         * @returns String\r\n         */\r\n        toSTL: function(name) {\r\n            var i, j, v, f, c, le,\r\n                txt = 'solid ';\r\n\r\n            if (name === undefined) {\r\n                name = this.name;\r\n            }\r\n\r\n            txt += name + '\\n';\r\n\r\n            for (i = 0; i < this.def.faces.length; i++) {\r\n                txt += ' facet normal 0 0 0\\n  outer loop\\n';\r\n                f = this.def.faces[i];\r\n                le = f.length;\r\n                v = this.def.coords;\r\n                for (j = 0; j < le; j++) {\r\n                    c = v[f[j]];\r\n                    txt += '   vertex ' + c[1] + ' ' + c[2] + ' ' + c[3] + '\\n';\r\n                }\r\n                txt += '  endloop\\n endfacet\\n';\r\n            }\r\n            txt += 'endsolid ' + name + '\\n';\r\n\r\n            return txt;\r\n        }\r\n    }\r\n);\r\n\r\n/**\r\n * @class A polyhedron in a 3D view consists of faces.\r\n * @pseudo\r\n * @description Create a polyhedron in a 3D view consisting of faces. Faces can\r\n * be 0-, 1- or 2-dimensional.\r\n *\r\n * @name Polyhedron3D\r\n * @augments JXG.GeometryElement3D\r\n * @constructor\r\n * @type Object\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {} TODO\r\n *\r\n * @example\r\n * var box = [-4, 4];\r\n * var view = board.create(\r\n *     'view3d',\r\n *     [[-5, -3], [8, 8],\r\n *     [box, box, box]],\r\n *     {\r\n *         projection: 'parallel',\r\n *         trackball: { enabled: false },\r\n *         depthOrder: {\r\n *             enabled: true\r\n *         },\r\n *         xPlaneRear: { visible: false },\r\n *         yPlaneRear: { visible: false },\r\n *         zPlaneRear: { fillOpacity: 0.2 }\r\n *     }\r\n * );\r\n * var cube = view.create('polyhedron3d', [\r\n * [\r\n *     [-3, -3, -3],\r\n *     [3, -3, -3],\r\n *     [3, 3, -3],\r\n *     [-3, 3, -3],\r\n *\r\n *     [-3, -3, 3],\r\n *     [3, -3, 3],\r\n *     [3, 3, 3],\r\n *     [-3, 3, 3]\r\n * ],\r\n * [\r\n *     [0, 1, 2, 3],\r\n *     [0, 1, 5, 4],\r\n *     [[1, 2, 6, 5], { fillColor: 'black', fillOpacity: 0.5, strokeWidth: 5 }],\r\n *     [2, 3, 7, 6],\r\n *     [3, 0, 4, 7],\r\n *     [4, 5, 6, 7]\r\n * ]\r\n * ], {\r\n * fillColorArray: ['blue', 'red', 'yellow']\r\n * });\r\n *\r\n * </pre><div id=\"JXG2ab3325b-4171-4a00-9896-a1b886969e18\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG2ab3325b-4171-4a00-9896-a1b886969e18',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *     var box = [-4, 4];\r\n *     var view = board.create(\r\n *         'view3d',\r\n *         [[-5, -3], [8, 8],\r\n *         [box, box, box]],\r\n *         {\r\n *             projection: 'parallel',\r\n *             trackball: { enabled: false },\r\n *             depthOrder: {\r\n *                 enabled: true\r\n *             },\r\n *             xPlaneRear: { visible: false },\r\n *             yPlaneRear: { visible: false },\r\n *             zPlaneRear: { fillOpacity: 0.2 }\r\n *         }\r\n *     );\r\n *     var cube = view.create('polyhedron3d', [\r\n *     [\r\n *         [-3, -3, -3],\r\n *         [3, -3, -3],\r\n *         [3, 3, -3],\r\n *         [-3, 3, -3],\r\n *\r\n *         [-3, -3, 3],\r\n *         [3, -3, 3],\r\n *         [3, 3, 3],\r\n *         [-3, 3, 3]\r\n *     ],\r\n *     [\r\n *         [0, 1, 2, 3],\r\n *         [0, 1, 5, 4],\r\n *         [[1, 2, 6, 5], { fillColor: 'black', fillOpacity: 0.5, strokeWidth: 5 }],\r\n *         [2, 3, 7, 6],\r\n *         [3, 0, 4, 7],\r\n *         [4, 5, 6, 7]\r\n *     ]\r\n *     ], {\r\n *     fillColorArray: ['blue', 'red', 'yellow']\r\n *     });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var box = [-4, 4];\r\n * var view = board.create(\r\n *     'view3d',\r\n *     [[-5, -3], [8, 8],\r\n *     [box, box, box]],\r\n *     {\r\n *         projection: 'parallel',\r\n *         trackball: { enabled: false },\r\n *         depthOrder: {\r\n *             enabled: true\r\n *         },\r\n *         xPlaneRear: { visible: false },\r\n *         yPlaneRear: { visible: false },\r\n *         zPlaneRear: { fillOpacity: 0.2 }\r\n *     }\r\n * );\r\n * var aa = view.create('point3d', [-3, -3, -3], { name: 'A', layer: 12});\r\n * var bb = view.create('point3d', [() => aa.X(), () => aa.Y(), 3], { name: 'B', fixed: true, layer: 12});\r\n * var cube = view.create('polyhedron3d', [\r\n *     {\r\n *         a: 'A',\r\n *         b: [3, -3, -3],\r\n *         c: [3, 3, -3],\r\n *         d: [-3, 3, -3],\r\n *\r\n *         e: bb,\r\n *         f: [3, -3, 3],\r\n *         g: [3, 3, 3],\r\n *         h: [-3, 3, 3]\r\n *     },\r\n *     [\r\n *         ['a', 'b', 'c', 'd'],\r\n *         ['a', 'b', 'f', 'e'],\r\n *         ['b', 'c', 'g', 'f'],\r\n *         ['c', 'd', 'h', 'g'],\r\n *         ['d', 'a', 'e', 'h'],\r\n *         ['e', 'f', 'g', 'h'],\r\n *\r\n *         ['a', 'g'], // Edge\r\n *         ['f']       // Vertex\r\n *     ]\r\n * ], {\r\n *     fillColorArray: ['blue', 'red', 'yellow'],\r\n *     fillOpacity: 0.4,\r\n *     layer: 12\r\n * });\r\n * cube.faces[6].setAttribute({ strokeWidth: 5 });\r\n * cube.faces[7].setAttribute({ strokeWidth: 10 });\r\n *\r\n * </pre><div id=\"JXG1e862f44-3e38-424b-98d5-f972338a8b7f\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG1e862f44-3e38-424b-98d5-f972338a8b7f',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *     var box = [-4, 4];\r\n *     var view = board.create(\r\n *         'view3d',\r\n *         [[-5, -3], [8, 8],\r\n *         [box, box, box]],\r\n *         {\r\n *             projection: 'parallel',\r\n *             trackball: { enabled: false },\r\n *             depthOrder: {\r\n *                 enabled: true\r\n *             },\r\n *             xPlaneRear: { visible: false },\r\n *             yPlaneRear: { visible: false },\r\n *             zPlaneRear: { fillOpacity: 0.2 }\r\n *         }\r\n *     );\r\n *     var aa = view.create('point3d', [-3, -3, -3], { name: 'A', layer: 12});\r\n *     var bb = view.create('point3d', [() => aa.X(), () => aa.Y(), 3], { name: 'B', fixed: true, layer: 12});\r\n *     var cube = view.create('polyhedron3d', [\r\n *         {\r\n *             a: 'A',\r\n *             b: [3, -3, -3],\r\n *             c: [3, 3, -3],\r\n *             d: [-3, 3, -3],\r\n *\r\n *             e: bb,\r\n *             f: [3, -3, 3],\r\n *             g: [3, 3, 3],\r\n *             h: [-3, 3, 3]\r\n *         },\r\n *         [\r\n *             ['a', 'b', 'c', 'd'],\r\n *             ['a', 'b', 'f', 'e'],\r\n *             ['b', 'c', 'g', 'f'],\r\n *             ['c', 'd', 'h', 'g'],\r\n *             ['d', 'a', 'e', 'h'],\r\n *             ['e', 'f', 'g', 'h'],\r\n *\r\n *             ['a', 'g'], // Edge\r\n *             ['f']       // Vertex\r\n *         ]\r\n *     ], {\r\n *         fillColorArray: ['blue', 'red', 'yellow'],\r\n *         fillOpacity: 0.4,\r\n *         layer: 12\r\n *     });\r\n *     cube.faces[6].setAttribute({ strokeWidth: 5 });\r\n *     cube.faces[7].setAttribute({ strokeWidth: 10 });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var box = [-4, 4];\r\n * var view = board.create(\r\n *     'view3d',\r\n *     [[-5, -3], [8, 8],\r\n *     [box, box, box]],\r\n *     {\r\n *         projection: 'parallel',\r\n *         trackball: { enabled: false },\r\n *         depthOrder: {\r\n *             enabled: true\r\n *         },\r\n *         xPlaneRear: { visible: false },\r\n *         yPlaneRear: { visible: false },\r\n *         zPlaneRear: { fillOpacity: 0.2 }\r\n *     }\r\n * );\r\n * var s = board.create('slider', [[-4, -6], [4, -6], [0, 2, 4]], { name: 's' });\r\n * var cube = view.create('polyhedron3d', [\r\n *     [\r\n *         () => { let f = s.Value(); return [-f, -f, -f]; },\r\n *         () => { let f = s.Value(); return [f, -f, -f]; },\r\n *         () => { let f = s.Value(); return [f, f, -f]; },\r\n *         () => { let f = s.Value(); return [-f, f, -f]; },\r\n *\r\n *         () => { let f = s.Value(); return [-f, -f, f]; },\r\n *         () => { let f = s.Value(); return [f, -f, f]; },\r\n *         () => { let f = s.Value(); return [f, f, f]; },\r\n *         // () => { let f = s.Value(); return [-f, f, f]; }\r\n *         [ () => -s.Value(),  () => s.Value(), () => s.Value() ]\r\n *     ],\r\n *     [\r\n *         [0, 1, 2, 3],\r\n *         [0, 1, 5, 4],\r\n *         [1, 2, 6, 5],\r\n *         [2, 3, 7, 6],\r\n *         [3, 0, 4, 7],\r\n *         [4, 5, 6, 7],\r\n *     ]\r\n * ], {\r\n *     strokeWidth: 3,\r\n *     fillOpacity: 0.6,\r\n *     fillColorArray: ['blue', 'red', 'yellow'],\r\n *     shader: {\r\n *         enabled:false\r\n *     }\r\n * });\r\n *\r\n * </pre><div id=\"JXG6f27584b-b648-4743-a864-a6c559ead00e\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG6f27584b-b648-4743-a864-a6c559ead00e',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *     var box = [-4, 4];\r\n *     var view = board.create(\r\n *         'view3d',\r\n *         [[-5, -3], [8, 8],\r\n *         [box, box, box]],\r\n *         {\r\n *             projection: 'parallel',\r\n *             trackball: { enabled: false },\r\n *             depthOrder: {\r\n *                 enabled: true\r\n *             },\r\n *             xPlaneRear: { visible: false },\r\n *             yPlaneRear: { visible: false },\r\n *             zPlaneRear: { fillOpacity: 0.2 }\r\n *         }\r\n *     );\r\n *     var s = board.create('slider', [[-4, -6], [4, -6], [0, 2, 4]], { name: 's' });\r\n *     var cube = view.create('polyhedron3d', [\r\n *         [\r\n *             () => { let f = s.Value(); return [-f, -f, -f]; },\r\n *             () => { let f = s.Value(); return [f, -f, -f]; },\r\n *             () => { let f = s.Value(); return [f, f, -f]; },\r\n *             () => { let f = s.Value(); return [-f, f, -f]; },\r\n *\r\n *             () => { let f = s.Value(); return [-f, -f, f]; },\r\n *             () => { let f = s.Value(); return [f, -f, f]; },\r\n *             () => { let f = s.Value(); return [f, f, f]; },\r\n *             // () => { let f = s.Value(); return [-f, f, f]; }\r\n *             [ () => -s.Value(),  () => s.Value(), () => s.Value() ]\r\n *         ],\r\n *         [\r\n *             [0, 1, 2, 3],\r\n *             [0, 1, 5, 4],\r\n *             [1, 2, 6, 5],\r\n *             [2, 3, 7, 6],\r\n *             [3, 0, 4, 7],\r\n *             [4, 5, 6, 7],\r\n *         ]\r\n *     ], {\r\n *         strokeWidth: 3,\r\n *         fillOpacity: 0.6,\r\n *         fillColorArray: ['blue', 'red', 'yellow'],\r\n *         shader: {\r\n *             enabled:false\r\n *         }\r\n *     });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n * var box = [-4, 4];\r\n * var view = board.create(\r\n *     'view3d',\r\n *     [[-5, -3], [8, 8],\r\n *     [box, box, box]],\r\n *     {\r\n *         projection: 'parallel',\r\n *         trackball: { enabled: false },\r\n *         depthOrder: {\r\n *             enabled: true\r\n *         },\r\n *         xPlaneRear: { visible: false },\r\n *         yPlaneRear: { visible: false },\r\n *         zPlaneRear: { fillOpacity: 0.2 }\r\n *     }\r\n * );\r\n * let rho = 1.6180339887;\r\n * let vertexList = [\r\n *     [0, -1, -rho], [0, +1, -rho], [0, -1, rho], [0, +1, rho],\r\n *     [1, rho, 0], [-1, rho, 0], [1, -rho, 0], [-1, -rho, 0],\r\n *     [-rho, 0, 1], [-rho, 0, -1], [rho, 0, 1], [rho, 0, -1]\r\n * ];\r\n * let faceArray = [\r\n *     [4, 1, 11],\r\n *     [11, 1, 0],\r\n *     [6, 11, 0],\r\n *     [0, 1, 9],\r\n *     [11, 10, 4],\r\n *     [9, 1, 5],\r\n *     [8, 9, 5],\r\n *     [5, 3, 8],\r\n *     [6, 10, 11],\r\n *     [2, 3, 10],\r\n *     [2, 10, 6],\r\n *     [8, 3, 2],\r\n *     [3, 4, 10],\r\n *     [7, 8, 2],\r\n *     [9, 8, 7],\r\n *     [0, 9, 7],\r\n *     [4, 3, 5],\r\n *     [5, 1, 4],\r\n *     [0, 7, 6],\r\n *     [7, 2, 6]\r\n * ];\r\n * var ico = view.create('polyhedron3d', [vertexList, faceArray], {\r\n * fillColorArray: [],\r\n * fillOpacity: 1,\r\n * strokeWidth: 0.1,\r\n * layer: 12,\r\n * shader: {\r\n *     enabled: true,\r\n *     type: 'angle',\r\n *     hue: 60,\r\n *     saturation: 90,\r\n *     minlightness: 60,\r\n *     maxLightness: 80\r\n * }\r\n * });\r\n *\r\n * </pre><div id=\"JXGfea93484-96e9-4eb5-9e45-bb53d612aead\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXGfea93484-96e9-4eb5-9e45-bb53d612aead',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *     var box = [-4, 4];\r\n *     var view = board.create(\r\n *         'view3d',\r\n *         [[-5, -3], [8, 8],\r\n *         [box, box, box]],\r\n *         {\r\n *             projection: 'parallel',\r\n *             trackball: { enabled: false },\r\n *             depthOrder: {\r\n *                 enabled: true\r\n *             },\r\n *             xPlaneRear: { visible: false },\r\n *             yPlaneRear: { visible: false },\r\n *             zPlaneRear: { fillOpacity: 0.2 }\r\n *         }\r\n *     );\r\n *     let rho = 1.6180339887;\r\n *     let vertexList = [\r\n *     [0, -1, -rho], [0, +1, -rho], [0, -1, rho], [0, +1, rho],\r\n *     [1, rho, 0], [-1, rho, 0], [1, -rho, 0], [-1, -rho, 0],\r\n *     [-rho, 0, 1], [-rho, 0, -1], [rho, 0, 1], [rho, 0, -1]\r\n *     ];\r\n *     let faceArray = [\r\n *     [4, 1, 11],\r\n *     [11, 1, 0],\r\n *     [6, 11, 0],\r\n *     [0, 1, 9],\r\n *     [11, 10, 4],\r\n *     [9, 1, 5],\r\n *     [8, 9, 5],\r\n *     [5, 3, 8],\r\n *     [6, 10, 11],\r\n *     [2, 3, 10],\r\n *     [2, 10, 6],\r\n *     [8, 3, 2],\r\n *     [3, 4, 10],\r\n *     [7, 8, 2],\r\n *     [9, 8, 7],\r\n *     [0, 9, 7],\r\n *     [4, 3, 5],\r\n *     [5, 1, 4],\r\n *     [0, 7, 6],\r\n *     [7, 2, 6]\r\n *     ];\r\n *     var ico = view.create('polyhedron3d', [vertexList, faceArray], {\r\n *     fillColorArray: [],\r\n *     fillOpacity: 1,\r\n *     strokeWidth: 0.1,\r\n *     layer: 12,\r\n *     shader: {\r\n *         enabled: true,\r\n *         type: 'angle',\r\n *         hue: 60,\r\n *         saturation: 90,\r\n *         minlightness: 60,\r\n *         maxLightness: 80\r\n *     }\r\n *     });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createPolyhedron3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        i, le,\r\n        face, f,\r\n        el,\r\n        attr, attr_polyhedron,\r\n        faceList = [],\r\n        base = null,\r\n        transform = null,\r\n\r\n        polyhedron = {\r\n            view: view,\r\n            vertices: {},\r\n            coords: {},\r\n            coords2D: {},\r\n            zIndex: {},\r\n            faces: []\r\n        };\r\n\r\n    if (Type.exists(parents[1].type) && parents[1].type === Const.OBJECT_TYPE_POLYHEDRON3D) {\r\n        // Polyhedron from baseElement and transformations\r\n        base = parents[1];\r\n        transform = parents[2];\r\n        polyhedron.vertices = base.def.vertices;\r\n        polyhedron.faces = base.def.faces;\r\n    } else {\r\n        // Copy vertices into a dict\r\n        if (Type.isArray(parents[1])) {\r\n            le = parents[1].length;\r\n            for (i = 0; i < le; i++) {\r\n                polyhedron.vertices[i] = parents[1][i];\r\n            }\r\n        } else if (Type.isObject(parents[1])) {\r\n            for (i in parents[1]) {\r\n                if (parents[1].hasOwnProperty(i)) {\r\n                    polyhedron.vertices[i] = parents[1][i];\r\n                }\r\n            }\r\n        }\r\n        polyhedron.faces = parents[2];\r\n    }\r\n\r\n    attr_polyhedron = Type.copyAttributes(attributes, board.options, 'polyhedron3d');\r\n\r\n    console.time('polyhedron');\r\n\r\n    view.board.suspendUpdate();\r\n    // Create face3d elements\r\n    le = polyhedron.faces.length;\r\n    for (i = 0; i < le; i++) {\r\n        attr = Type.copyAttributes(attributes, board.options, 'face3d');\r\n        if (attr_polyhedron.fillcolorarray.length > 0) {\r\n            attr.fillcolor = attr_polyhedron.fillcolorarray[i % attr_polyhedron.fillcolorarray.length];\r\n        }\r\n        f = polyhedron.faces[i];\r\n\r\n        if (Type.isArray(f) && f.length === 2 && Type.isObject(f[1]) && Type.isArray(f[0])) {\r\n            // Handle case that face is of type [[points], {attr}]\r\n            Type.mergeAttr(attr, f[1]);\r\n            // Normalize face array, i.e. don't store attributes of that face in polyhedron\r\n            polyhedron.faces[i] = f[0];\r\n        }\r\n\r\n        face = view.create('face3d', [polyhedron, i], attr);\r\n        faceList.push(face);\r\n    }\r\n    el = new JXG.Polyhedron3D(view, polyhedron, faceList, attr_polyhedron);\r\n    el.setParents(el); // Sets el as parent to all faces.\r\n    for (i = 0; i < le; i++) {\r\n        el.inherits.push(el.faces[i]);\r\n        el.addChild(el.faces[i]);\r\n    }\r\n    if (base !== null) {\r\n        el.addTransform(base, transform);\r\n        el.addParents(base);\r\n    }\r\n    view.board.unsuspendUpdate();\r\n\r\n    console.timeEnd('polyhedron');\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"polyhedron3d\", JXG.createPolyhedron3D);\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Aaron Fenyes,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*global JXG:true, define: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Type from \"../utils/type.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Stat from \"../math/statistics.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\n\r\n/**\r\n * A sphere consists of all points with a given distance from a given point.\r\n * The given point is called the center, and the given distance is called the radius.\r\n * A sphere can be constructed by providing a center and a point on the sphere or a center and a radius (given as a number or function).\r\n * @class Creates a new 3D sphere object. Do not use this constructor to create a 3D sphere. Use {@link JXG.View3D#create} with\r\n * type {@link Sphere3D} instead.\r\n * @augments JXG.GeometryElement3D\r\n * @augments JXG.GeometryElement\r\n * @param {JXG.View3D} view The 3D view the sphere is drawn on.\r\n * @param {String} method Can be:\r\n * <ul><li> <b><code>'twoPoints'</code></b> &ndash; The sphere is defined by its center and a point on the sphere.</li>\r\n * <li><b><code>'pointRadius'</code></b> &ndash; The sphere is defined by its center and its radius in user units.</li></ul>\r\n * The parameters <code>p1</code>, <code>p2</code> and <code>radius</code> must be set according to this method parameter.\r\n * @param {JXG.Point3D} par1 The center of the sphere.\r\n * @param {JXG.Point3D} par2 Can be:\r\n * <ul><li>A point on the sphere (if the construction method is <code>'twoPoints'</code>)</li>\r\n * <ul><li>A number or function (if the construction method is <code>'pointRadius'</code>)</li>\r\n * @param {Object} attributes An object containing visual properties like in {@link JXG.Options#point3d} and\r\n * {@link JXG.Options#elements}, and optional a name and an id.\r\n * @see JXG.Board#generateName\r\n */\r\nJXG.Sphere3D = function (view, method, par1, par2, attributes) {\r\n    this.constructor(view.board, attributes, Const.OBJECT_TYPE_SPHERE3D, Const.OBJECT_CLASS_3D);\r\n    this.constructor3D(view, 'sphere3d');\r\n\r\n    this.board.finalizeAdding(this);\r\n\r\n    /**\r\n     * The construction method.\r\n     * Can be:\r\n     * <ul><li><b><code>'twoPoints'</code></b> &ndash; The sphere is defined by its center and a point on the sphere.</li>\r\n     * <li><b><code>'pointRadius'</code></b> &ndash; The sphere is defined by its center and its radius in user units.</li></ul>\r\n     * @type String\r\n     * @see JXG.Sphere3D#center\r\n     * @see JXG.Sphere3D#point2\r\n     */\r\n    this.method = method;\r\n\r\n    /**\r\n     * The sphere's center. Do not set this parameter directly, as that will break JSXGraph's update system.\r\n     * @type JXG.Point3D\r\n     */\r\n    this.center = this.board.select(par1);\r\n\r\n    /**\r\n     * A point on the sphere; only set if the construction method is 'twoPoints'. Do not set this parameter directly, as that will break JSXGraph's update system.\r\n     * @type JXG.Point3D\r\n     * @see JXG.Sphere3D#method\r\n     */\r\n    this.point2 = null;\r\n\r\n    this.points = [];\r\n\r\n    /**\r\n     * The 2D representation of the element.\r\n     * @type GeometryElement\r\n     */\r\n    this.element2D = null;\r\n\r\n    /**\r\n     * Elements supporting the 2D representation.\r\n     * @type Array\r\n     * @private\r\n     */\r\n    this.aux2D = [];\r\n\r\n    /**\r\n     * The type of projection (<code>'parallel'</code> or <code>'central'</code>) that the sphere is currently drawn in.\r\n     * @type String\r\n     */\r\n    this.projectionType = view.projectionType;\r\n\r\n    if (method === 'twoPoints') {\r\n        this.point2 = this.board.select(par2);\r\n        this.radius = this.Radius();\r\n    } else if (method === 'pointRadius') {\r\n        // Converts JessieCode syntax into JavaScript syntax and generally ensures that the radius is a function\r\n        this.updateRadius = Type.createFunction(par2, this.board);\r\n        // First evaluation of the radius function\r\n        this.updateRadius();\r\n        this.addParentsFromJCFunctions([this.updateRadius]);\r\n    }\r\n\r\n    if (Type.exists(this.center._is_new)) {\r\n        this.addChild(this.center);\r\n        delete this.center._is_new;\r\n    } else {\r\n        this.center.addChild(this);\r\n    }\r\n\r\n    if (method === 'twoPoints') {\r\n        if (Type.exists(this.point2._is_new)) {\r\n            this.addChild(this.point2);\r\n            delete this.point2._is_new;\r\n        } else {\r\n            this.point2.addChild(this);\r\n        }\r\n    }\r\n\r\n    this.methodMap = Type.deepCopy(this.methodMap, {\r\n        center: \"center\",\r\n        point2: \"point2\",\r\n        Radius: \"Radius\"\r\n    });\r\n};\r\nJXG.Sphere3D.prototype = new JXG.GeometryElement();\r\nType.copyPrototypeMethods(JXG.Sphere3D, JXG.GeometryElement3D, 'constructor3D');\r\n\r\nJXG.extend(\r\n    JXG.Sphere3D.prototype,\r\n    /** @lends JXG.Sphere3D.prototype */ {\r\n\r\n        X: function(u, v) {\r\n            var r = this.Radius();\r\n            return r * Math.sin(u) * Math.cos(v);\r\n        },\r\n\r\n        Y: function(u, v) {\r\n            var r = this.Radius();\r\n            return r * Math.sin(u) * Math.sin(v);\r\n        },\r\n\r\n        Z: function(u, v) {\r\n            var r = this.Radius();\r\n            return r * Math.cos(u);\r\n        },\r\n\r\n        range_u: [0, 2 * Math.PI],\r\n        range_v: [0, Math.PI],\r\n\r\n        update: function () {\r\n            if (this.projectionType !== this.view.projectionType) {\r\n                this.rebuildProjection();\r\n            }\r\n            return this;\r\n        },\r\n\r\n        updateRenderer: function () {\r\n            this.needsUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Set a new radius, then update the board.\r\n         * @param {String|Number|function} r A string, function or number describing the new radius\r\n         * @returns {JXG.Sphere3D} Reference to this sphere\r\n         */\r\n        setRadius: function (r) {\r\n            this.updateRadius = Type.createFunction(r, this.board);\r\n            this.addParentsFromJCFunctions([this.updateRadius]);\r\n            this.board.update();\r\n\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Calculates the radius of the circle.\r\n         * @param {String|Number|function} [value] Set new radius\r\n         * @returns {Number} The radius of the circle\r\n         */\r\n        Radius: function (value) {\r\n            if (Type.exists(value)) {\r\n                this.setRadius(value);\r\n                return this.Radius();\r\n            }\r\n\r\n            if (this.method === 'twoPoints') {\r\n                if (!this.center.testIfFinite() || !this.point2.testIfFinite()) {\r\n                    return NaN;\r\n                }\r\n\r\n                return this.center.distance(this.point2);\r\n            }\r\n\r\n            if (this.method === 'pointRadius') {\r\n                return Math.abs(this.updateRadius());\r\n            }\r\n\r\n            return NaN;\r\n        },\r\n\r\n        // The central projection of a sphere is an ellipse. The front and back\r\n        // points of the sphere---that is, the points closest to and furthest\r\n        // from the screen---project to the foci of the ellipse.\r\n        //\r\n        // To see this, look at the cone tangent to the sphere whose tip is at\r\n        // the camera. The image of the sphere is the ellipse where this cone\r\n        // intersects the screen. By acting on the sphere with scalings centered\r\n        // on the camera, you can send it to either of the Dandelin spheres that\r\n        // touch the screen at the foci of the image ellipse.\r\n        //\r\n        // This factory method produces two functions, `focusFn(-1)` and\r\n        // `focusFn(1)`, that evaluate to the projections of the front and back\r\n        // points of the sphere, respectively.\r\n        focusFn: function (sgn) {\r\n            var that = this;\r\n\r\n            return function () {\r\n                var camDir = that.view.boxToCam[3],\r\n                    r = that.Radius();\r\n\r\n                return that.view.project3DTo2D([\r\n                    that.center.X() + sgn * r * camDir[1],\r\n                    that.center.Y() + sgn * r * camDir[2],\r\n                    that.center.Z() + sgn * r * camDir[3]\r\n                ]).slice(1, 3);\r\n            };\r\n        },\r\n\r\n        innerVertexFn: function () {\r\n            var that = this;\r\n\r\n            return function () {\r\n                var view = that.view,\r\n                    p = view.worldToFocal(that.center.coords, false),\r\n                    distOffAxis = Mat.hypot(p[0], p[1]),\r\n                    cam = view.boxToCam,\r\n                    r = that.Radius(),\r\n                    angleOffAxis = Math.atan(-distOffAxis / p[2]),\r\n                    steepness = Math.acos(r / Mat.norm(p)),\r\n                    lean = angleOffAxis + steepness,\r\n                    cos_lean = Math.cos(lean),\r\n                    sin_lean = Math.sin(lean),\r\n                    inward;\r\n\r\n                if (distOffAxis > 1e-8) {\r\n                    // if the center of the sphere isn't too close to the camera\r\n                    // axis, find the direction in plane of the screen that\r\n                    // points from the center of the sphere toward the camera\r\n                    // axis\r\n                    inward = [\r\n                        -(p[0] * cam[1][1] + p[1] * cam[2][1]) / distOffAxis,\r\n                        -(p[0] * cam[1][2] + p[1] * cam[2][2]) / distOffAxis,\r\n                        -(p[0] * cam[1][3] + p[1] * cam[2][3]) / distOffAxis\r\n                    ];\r\n                } else {\r\n                    // if the center of the sphere is very close to the camera\r\n                    // axis, choose an arbitrary unit vector in the plane of the\r\n                    // screen\r\n                    inward = [cam[1][1], cam[1][2], cam[1][3]];\r\n                }\r\n                return view.project3DTo2D([\r\n                    that.center.X() + r * (sin_lean * inward[0] + cos_lean * cam[3][1]),\r\n                    that.center.Y() + r * (sin_lean * inward[1] + cos_lean * cam[3][2]),\r\n                    that.center.Z() + r * (sin_lean * inward[2] + cos_lean * cam[3][3])\r\n                ]);\r\n            };\r\n        },\r\n\r\n        buildCentralProjection: function (attr) {\r\n            var view = this.view,\r\n                auxStyle = { visible: false, withLabel: false },\r\n                frontFocus = view.create('point', this.focusFn(-1), auxStyle),\r\n                backFocus = view.create('point', this.focusFn(1), auxStyle),\r\n                innerVertex = view.create('point', this.innerVertexFn(view), auxStyle);\r\n\r\n            this.aux2D = [frontFocus, backFocus, innerVertex];\r\n            this.element2D = view.create('ellipse', this.aux2D, attr === undefined ? this.visProp : attr);\r\n        },\r\n\r\n        buildParallelProjection: function (attr) {\r\n            // The parallel projection of a sphere is a circle\r\n            var that = this,\r\n                // center2d = function () {\r\n                //     var c3d = [1, that.center.X(), that.center.Y(), that.center.Z()];\r\n                //     return that.view.project3DTo2D(c3d);\r\n                // },\r\n                radius2d = function () {\r\n                    var boxSize = that.view.bbox3D[0][1] - that.view.bbox3D[0][0];\r\n                    return that.Radius() * that.view.size[0] / boxSize;\r\n                };\r\n\r\n            this.aux2D = [];\r\n            this.element2D = this.view.create(\r\n                'circle',\r\n                // [center2d, radius2d],\r\n                [that.center.element2D, radius2d],\r\n                attr === undefined ? this.visProp : attr\r\n            );\r\n        },\r\n\r\n        // replace our 2D representation with a new one that's consistent with\r\n        // the view's current projection type\r\n        rebuildProjection: function (attr) {\r\n            var i;\r\n\r\n            // remove the old 2D representation from the scene tree\r\n            if (this.element2D) {\r\n                this.view.board.removeObject(this.element2D);\r\n                for (i in this.aux2D) {\r\n                    if (this.aux2D.hasOwnProperty(i)) {\r\n                        this.view.board.removeObject(this.aux2D[i]);\r\n                    }\r\n                }\r\n            }\r\n\r\n            // build a new 2D representation. the representation is stored in\r\n            // `this.element2D`, and any auxiliary elements are stored in\r\n            // `this.aux2D`\r\n            this.projectionType = this.view.projectionType;\r\n            if (this.projectionType === 'central') {\r\n                this.buildCentralProjection(attr);\r\n            } else {\r\n                this.buildParallelProjection(attr);\r\n            }\r\n\r\n            // attach the new 2D representation to the scene tree\r\n            this.addChild(this.element2D);\r\n            this.inherits.push(this.element2D);\r\n            this.element2D.view = this.view;\r\n        },\r\n\r\n        // Already documented in element3d.js\r\n        projectCoords: function(p, params) {\r\n            var r = this.Radius(),\r\n                pp = [1].concat(p),\r\n                c = this.center.coords,\r\n                d = Geometry.distance(c, pp, 4),\r\n                v = Stat.subtract(pp, c);\r\n\r\n            if (d === 0) {\r\n                // p is at the center, take an arbitrary point on sphere\r\n                params[0] = 0;\r\n                params[1] = 0;\r\n                return [1, r, 0, 0];\r\n            }\r\n            if (r === 0) {\r\n                params[0] = 0;\r\n                params[1] = 0;\r\n                return this.center.coords;\r\n            }\r\n\r\n            d = r / d;\r\n            v[0] = 1;\r\n            v[1] *= d;\r\n            v[2] *= d;\r\n            v[3] *= d;\r\n\r\n            // Preimage of the new position\r\n            params[1] = Math.atan2(v[2], v[1]);\r\n            params[1] += (params[1] < 0) ? Math.PI : 0;\r\n            if (params[1] !== 0) {\r\n                params[0] = Math.atan2(v[2], v[3] * Math.sin(params[1]));\r\n            } else {\r\n                params[0] = Math.atan2(v[1], v[3] * Math.cos(params[1]));\r\n            }\r\n            params[0] += (params[0] < 0) ? 2 * Math.PI : 0;\r\n\r\n            return v;\r\n        }\r\n\r\n        // projectScreenCoords: function (pScr, params) {\r\n        //     if (params.length === 0) {\r\n        //         params.unshift(\r\n        //             0.5 * (this.range_u[0] + this.range_u[1]),\r\n        //             0.5 * (this.range_v[0] + this.range_v[1])\r\n        //         );\r\n        //     }\r\n        //     return Geometry.projectScreenCoordsToParametric(pScr, this, params);\r\n        // }\r\n    }\r\n);\r\n\r\n/**\r\n * @class A sphere in a 3D view.\r\n * A sphere consists of all points with a given distance from a given point.\r\n * The given point is called the center, and the given distance is called the radius.\r\n * A sphere can be constructed by providing a center and a point on the sphere or a center and a radius (given as a number or function).\r\n * If the radius is a negative value, its absolute value is taken.\r\n *\r\n * @pseudo\r\n * @name Sphere3D\r\n * @augments JXG.Sphere3D\r\n * @constructor\r\n * @type JXG.Sphere3D\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {JXG.Point3D_number,JXG.Point3D} center,radius The center must be given as a {@link JXG.Point3D} (see {@link JXG.providePoints3D}),\r\n * but the radius can be given as a number (which will create a sphere with a fixed radius) or another {@link JXG.Point3D}.\r\n * <p>\r\n * If the radius is supplied as number or the output of a function, its absolute value is taken.\r\n *\r\n * @example\r\n * var view = board.create(\r\n *     'view3d',\r\n *     [[-6, -3], [8, 8],\r\n *     [[0, 3], [0, 3], [0, 3]]],\r\n *     {\r\n *         xPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *         yPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *         zPlaneRear: {fillOpacity: 0.2, gradient: null}\r\n *     }\r\n * );\r\n *\r\n * // Two points\r\n * var center = view.create(\r\n *     'point3d',\r\n *     [1.5, 1.5, 1.5],\r\n *     {\r\n *         withLabel: false,\r\n *         size: 5,\r\n *    }\r\n * );\r\n * var point = view.create(\r\n *     'point3d',\r\n *     [2, 1.5, 1.5],\r\n *     {\r\n *         withLabel: false,\r\n *         size: 5\r\n *    }\r\n * );\r\n *\r\n * // Sphere\r\n * var sphere = view.create(\r\n *     'sphere3d',\r\n *     [center, point],\r\n *     {}\r\n * );\r\n *\r\n * </pre><div id=\"JXG5969b83c-db67-4e62-9702-d0440e5fe2c1\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG5969b83c-db67-4e62-9702-d0440e5fe2c1',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});\r\n *         var view = board.create(\r\n *             'view3d',\r\n *             [[-6, -3], [8, 8],\r\n *             [[0, 3], [0, 3], [0, 3]]],\r\n *             {\r\n *                 xPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *                 yPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *                 zPlaneRear: {fillOpacity: 0.2, gradient: null}\r\n *             }\r\n *         );\r\n *\r\n *         // Two points\r\n *         var center = view.create(\r\n *             'point3d',\r\n *             [1.5, 1.5, 1.5],\r\n *             {\r\n *                 withLabel: false,\r\n *                 size: 5,\r\n *            }\r\n *         );\r\n *         var point = view.create(\r\n *             'point3d',\r\n *             [2, 1.5, 1.5],\r\n *             {\r\n *                 withLabel: false,\r\n *                 size: 5\r\n *            }\r\n *         );\r\n *\r\n *         // Sphere\r\n *         var sphere = view.create(\r\n *             'sphere3d',\r\n *             [center, point],\r\n *             {}\r\n *         );\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n * @example\r\n *     // Glider on sphere\r\n *     var view = board.create(\r\n *         'view3d',\r\n *         [[-6, -3], [8, 8],\r\n *         [[-3, 3], [-3, 3], [-3, 3]]],\r\n *         {\r\n *             depthOrder: {\r\n *                 enabled: true\r\n *             },\r\n *             projection: 'central',\r\n *             xPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *             yPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *             zPlaneRear: {fillOpacity: 0.2, gradient: null}\r\n *         }\r\n *     );\r\n *\r\n *     // Two points\r\n *     var center = view.create('point3d', [0, 0, 0], {withLabel: false, size: 2});\r\n *     var point = view.create('point3d', [2, 0, 0], {withLabel: false, size: 2});\r\n *\r\n *     // Sphere\r\n *     var sphere = view.create('sphere3d', [center, point], {fillOpacity: 0.8});\r\n *\r\n *     // Glider on sphere\r\n *     var glide = view.create('point3d', [2, 2, 0, sphere], {withLabel: false, color: 'red', size: 4});\r\n *     var l1 = view.create('line3d', [glide, center], { strokeWidth: 2, dash: 2 });\r\n *\r\n * </pre><div id=\"JXG672fe3c7-e6fd-48e0-9a24-22f51f2dfa71\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG672fe3c7-e6fd-48e0-9a24-22f51f2dfa71',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});\r\n *         var view = board.create(\r\n *             'view3d',\r\n *             [[-6, -3], [8, 8],\r\n *             [[-3, 3], [-3, 3], [-3, 3]]],\r\n *             {\r\n *                 depthOrder: {\r\n *                     enabled: true\r\n *                 },\r\n *                 projection: 'central',\r\n *                 xPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *                 yPlaneRear: {fillOpacity: 0.2, gradient: null},\r\n *                 zPlaneRear: {fillOpacity: 0.2, gradient: null}\r\n *             }\r\n *         );\r\n *\r\n *         // Two points\r\n *         var center = view.create('point3d', [0, 0, 0], {withLabel: false, size: 2});\r\n *         var point = view.create('point3d', [2, 0, 0], {withLabel: false, size: 2});\r\n *\r\n *         // Sphere\r\n *         var sphere = view.create('sphere3d', [center, point], {fillOpacity: 0.8});\r\n *\r\n *         // Glider on sphere\r\n *         var glide = view.create('point3d', [2, 2, 0, sphere], {withLabel: false, color: 'red', size: 4});\r\n *         var l1 = view.create('line3d', [glide, center], { strokeWidth: 2, dash: 2 });\r\n *\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createSphere3D = function (board, parents, attributes) {\r\n    //   parents[0]: view\r\n    //   parents[1]: point,\r\n    //   parents[2]: point or radius\r\n\r\n    var view = parents[0],\r\n        attr, p, point_style, provided,\r\n        el, i;\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'sphere3d');\r\n    p = [];\r\n    for (i = 1; i < parents.length; i++) {\r\n        if (Type.isPointType3D(board, parents[i])) {\r\n            if (p.length === 0) {\r\n                point_style = 'center';\r\n            } else {\r\n                point_style = 'point';\r\n            }\r\n            provided = Type.providePoints3D(view, [parents[i]], attributes, 'sphere3d', [point_style])[0];\r\n            if (provided === false) {\r\n                throw new Error(\r\n                    \"JSXGraph: Can't create sphere3d from this type. Please provide a point type.\"\r\n                );\r\n            }\r\n            p.push(provided);\r\n        } else {\r\n            p.push(parents[i]);\r\n        }\r\n    }\r\n\r\n    if (Type.isPoint3D(p[0]) && Type.isPoint3D(p[1])) {\r\n        // Point/Point\r\n        el = new JXG.Sphere3D(view, \"twoPoints\", p[0], p[1], attr);\r\n\r\n        /////////////// nothing in docs suggest you can use [number, pointType]\r\n        // } else if (\r\n        //     (Type.isNumber(p[0]) || Type.isFunction(p[0]) || Type.isString(p[0])) &&\r\n        //     Type.isPoint3D(p[1])\r\n        // ) {\r\n        //     // Number/Point\r\n        //     el = new JXG.Sphere3D(view, \"pointRadius\", p[1], p[0], attr);\r\n\r\n    } else if (\r\n        Type.isPoint3D(p[0]) &&\r\n        (Type.isNumber(p[1]) || Type.isFunction(p[1]) || Type.isString(p[1]))\r\n    ) {\r\n        // Point/Number\r\n        el = new JXG.Sphere3D(view, \"pointRadius\", p[0], p[1], attr);\r\n    } else {\r\n        throw new Error(\r\n            \"JSXGraph: Can't create sphere3d with parent types '\" +\r\n            typeof parents[1] +\r\n            \"' and '\" +\r\n            typeof parents[2] +\r\n            \"'.\" +\r\n            \"\\nPossible parent types: [point,point], [point,number], [point,function]\"\r\n        );\r\n    }\r\n\r\n    // Build a 2D representation, and attach it to the scene tree, and update it\r\n    // to the correct initial state\r\n    // Here, element2D is created.\r\n    attr = el.setAttr2D(attr);\r\n    el.rebuildProjection(attr);\r\n\r\n    el.element2D.prepareUpdate().update();\r\n    if (!board.isSuspendedUpdate) {\r\n        el.element2D.updateVisibility().updateRenderer();\r\n    }\r\n\r\n    return el;\r\n};\r\n\r\nJXG.registerElement(\"sphere3d\", JXG.createSphere3D);\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n/*global JXG:true, define: true*/\r\n\r\nimport JXG from \"../jxg.js\";\r\nimport Const from \"../base/constants.js\";\r\nimport Mat from \"../math/math.js\";\r\nimport Geometry from \"../math/geometry.js\";\r\nimport Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Constructor for 3D surfaces.\r\n * @class Creates a new 3D surface object. Do not use this constructor to create a 3D surface. Use {@link JXG.View3D#create} with type {@link Surface3D} instead.\r\n *\r\n * @augments JXG.GeometryElement3D\r\n * @augments JXG.GeometryElement\r\n * @param {View3D} view\r\n * @param {Function} F\r\n * @param {Function} X\r\n * @param {Function} Y\r\n * @param {Function} Z\r\n * @param {Array} range_u\r\n * @param {Array} range_v\r\n * @param {Object} attributes\r\n * @see JXG.Board#generateName\r\n */\r\nJXG.Surface3D = function (view, F, X, Y, Z, range_u, range_v, attributes) {\r\n    this.constructor(\r\n        view.board,\r\n        attributes,\r\n        Const.OBJECT_TYPE_SURFACE3D,\r\n        Const.OBJECT_CLASS_3D\r\n    );\r\n    this.constructor3D(view, 'surface3d');\r\n\r\n    this.board.finalizeAdding(this);\r\n\r\n    /**\r\n     * Internal function defining the surface\r\n     * without applying any transformations.\r\n     *\r\n     * @function\r\n     * @param {Number} u\r\n     * @param {Number} v\r\n     * @returns Array [x, y, z] of length 3\r\n     * @private\r\n     */\r\n    this._F = F;\r\n\r\n    /**\r\n     * Internal function which maps (u, v) to x; i.e. it defines the x-coordinate of the surface\r\n     * without applying any transformations.\r\n     * @function\r\n     * @param {Number} u\r\n     * @param {Number} v\r\n     * @returns Number\r\n     * @private\r\n     */\r\n    this._X = X;\r\n\r\n    /**\r\n     * Internal function which maps (u, v) to y; i.e. it defines the y-coordinate of the surface\r\n     * without applying any transformations.\r\n     * @function\r\n     * @param {Number} u\r\n     * @param {Number} v\r\n     * @returns Number\r\n     * @private\r\n     */\r\n    this._Y = Y;\r\n\r\n    /**\r\n     * Internal function which maps (u, v) to z; i.e. it defines the z-coordinate of the surface\r\n     * without applying any transformations.\r\n     * @function\r\n     * @param {Number} u\r\n     * @param {Number} v\r\n     * @returns Number\r\n     * @private\r\n     */\r\n    this._Z = Z;\r\n\r\n    if (this._F !== null) {\r\n        this._X = function (u, v) {\r\n            return this._F(u, v)[0];\r\n        };\r\n        this._Y = function (u, v) {\r\n            return this._F(u, v)[1];\r\n        };\r\n        this._Z = function (u, v) {\r\n            return this._F(u, v)[2];\r\n        };\r\n    } else {\r\n        if (this._X !== null) {\r\n            this._F = function(u, v) {\r\n                return [this._X(u, v), this._Y(u, v), this._Z(u, v)];\r\n            };\r\n        }\r\n    }\r\n\r\n    this.range_u = range_u;\r\n    this.range_v = range_v;\r\n\r\n    this.dataX = null;\r\n    this.dataY = null;\r\n    this.dataZ = null;\r\n    this.points = [];\r\n\r\n    this.methodMap = Type.deepCopy(this.methodMap, {\r\n        // TODO\r\n    });\r\n};\r\nJXG.Surface3D.prototype = new JXG.GeometryElement();\r\nType.copyPrototypeMethods(JXG.Surface3D, JXG.GeometryElement3D, 'constructor3D');\r\n\r\nJXG.extend(\r\n    JXG.Surface3D.prototype,\r\n    /** @lends JXG.Surface3D.prototype */ {\r\n\r\n        updateWireframe: function () {\r\n            var steps_u, steps_v,\r\n                i_u, i_v,\r\n                r_u, r_v,\r\n                s_u, s_v,\r\n                e_u, e_v,\r\n                delta_u, delta_v,\r\n                u, v,\r\n                c3d = [1, 0, 0, 0];\r\n\r\n            this.points = [];\r\n\r\n            steps_u = this.evalVisProp('stepsu');\r\n            steps_v = this.evalVisProp('stepsv');\r\n            r_u = Type.evaluate(this.range_u);\r\n            r_v = Type.evaluate(this.range_v);\r\n            s_u = Type.evaluate(r_u[0]);\r\n            s_v = Type.evaluate(r_v[0]);\r\n            e_u = Type.evaluate(r_u[1]);\r\n            e_v = Type.evaluate(r_v[1]);\r\n            delta_u = (e_u - s_u) / (steps_u);\r\n            delta_v = (e_v - s_v) / (steps_v);\r\n\r\n            for (i_u = 0, u = s_u; i_u <= steps_u; i_u++, u += delta_u) {\r\n                this.points.push([]);\r\n                for (i_v = 0, v = s_v; i_v <= steps_v; i_v++, v += delta_v) {\r\n                    c3d = this.F(u, v);\r\n                    c3d.unshift(1);\r\n                    this.points[i_u].push(c3d);\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        updateCoords: function () {\r\n            if (this._F !== null) {\r\n                this.updateWireframe();\r\n            } else {\r\n                this.updateTransform();\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * Generic function which evaluates the function term of the surface\r\n         * and applies its transformations.\r\n         * @param {Number} u\r\n         * @param {Number} v\r\n         * @returns\r\n         */\r\n        evalF: function(u, v) {\r\n            var t, i,\r\n                c3d = [0, 0, 0, 0];\r\n\r\n            if (this.transformations.length === 0 || !Type.exists(this.baseElement)) {\r\n                c3d = this._F(u, v);\r\n                return c3d;\r\n            }\r\n\r\n            t = this.transformations;\r\n            for (i = 0; i < t.length; i++) {\r\n                t[i].update();\r\n            }\r\n\r\n            if (this === this.baseElement) {\r\n                c3d = this._F(u, v);\r\n            } else {\r\n                c3d = this.baseElement.evalF(u, v);\r\n            }\r\n            c3d.unshift(1);\r\n            c3d = Mat.matVecMult(t[0].matrix, c3d);\r\n            for (i = 1; i < t.length; i++) {\r\n                c3d = Mat.matVecMult(t[i].matrix, c3d);\r\n            }\r\n\r\n            return c3d.slice(1);\r\n        },\r\n\r\n        /**\r\n         * Function defining the surface plus applying transformations.\r\n         * @param {Number} u\r\n         * @param {Number} v\r\n        * @returns Array [x, y, z] of length 3\r\n         */\r\n        F: function(u, v) {\r\n            return this.evalF(u, v);\r\n        },\r\n\r\n        /**\r\n        * Function which maps (u, v) to z; i.e. it defines the x-coordinate of the surface\r\n        * plus applying transformations.\r\n        * @param {Number} u\r\n        * @param {Number} v\r\n        * @returns Number\r\n        */\r\n        X: function(u, v) {\r\n            return this.evalF(u, v)[0];\r\n        },\r\n\r\n        /**\r\n        * Function which maps (u, v) to y; i.e. it defines the y-coordinate of the surface\r\n        * plus applying transformations.\r\n        * @param {Number} u\r\n        * @param {Number} v\r\n        * @returns Number\r\n        */\r\n        Y: function(u, v) {\r\n            return this.evalF(u, v)[1];\r\n        },\r\n\r\n        /**\r\n        * Function which maps (u, v) to z; i.e. it defines the z-coordinate of the surface\r\n        * plus applying transformations.\r\n        * @param {Number} u\r\n        * @param {Number} v\r\n        * @returns Number\r\n        */\r\n        Z: function(u, v) {\r\n            return this.evalF(u, v)[2];\r\n        },\r\n\r\n        /**\r\n         * @class\r\n         * @ignore\r\n         */\r\n        updateDataArray2D: function () {\r\n            var i, j, len_u, len_v,\r\n                dataX = [],\r\n                dataY = [],\r\n                c2d;\r\n\r\n            len_u = this.points.length;\r\n            if (len_u !== 0) {\r\n                len_v = this.points[0].length;\r\n\r\n                for (i = 0; i < len_u; i++) {\r\n                    for (j = 0; j < len_v; j++) {\r\n                        c2d = this.view.project3DTo2D(this.points[i][j]);\r\n                        dataX.push(c2d[1]);\r\n                        dataY.push(c2d[2]);\r\n                    }\r\n                    dataX.push(NaN);\r\n                    dataY.push(NaN);\r\n                }\r\n\r\n                for (j = 0; j < len_v; j++) {\r\n                    for (i = 0; i < len_u; i++) {\r\n                        c2d = this.view.project3DTo2D(this.points[i][j]);\r\n                        dataX.push(c2d[1]);\r\n                        dataY.push(c2d[2]);\r\n                    }\r\n                    dataX.push(NaN);\r\n                    dataY.push(NaN);\r\n                }\r\n            }\r\n\r\n            return {X: dataX, Y: dataY};\r\n        },\r\n\r\n        addTransform: function (el, transform) {\r\n            this.addTransformGeneric(el, transform);\r\n            return this;\r\n        },\r\n\r\n        updateTransform: function () {\r\n            var t, c, i, j, k,\r\n                len_u, len_v;\r\n\r\n            if (this.transformations.length === 0 || this.baseElement === null ||\r\n                Type.exists(this._F) // Transformations have only to be applied here\r\n                                     // if the curve is defined by arrays\r\n            ) {\r\n                return this;\r\n            }\r\n\r\n            t = this.transformations;\r\n            for (i = 0; i < t.length; i++) {\r\n                t[i].update();\r\n            }\r\n            if (this !== this.baseElement) {\r\n                this.points = [];\r\n            }\r\n\r\n            len_u = this.baseElement.points.length;\r\n            if (len_u > 0) {\r\n                len_v = this.baseElement.points[0].length;\r\n                for (i = 0; i < len_u; i++) {\r\n                    if (this !== this.baseElement) {\r\n                        this.points.push([]);\r\n                    }\r\n                    for (j = 0; j < len_v; j++) {\r\n                        if (this === this.baseElement) {\r\n                            c = this.points[i][j];\r\n                        } else {\r\n                            c = this.baseElement.points[i][j];\r\n                        }\r\n                        for (k = 0; k < t.length; k++) {\r\n                            c = Mat.matVecMult(t[k].matrix, c);\r\n                        }\r\n\r\n                        if (this === this.baseElement) {\r\n                            this.points[i][j] = c;\r\n                        } else {\r\n                            this.points[i].push(c);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            return this;\r\n        },\r\n\r\n        updateDataArray: function() { /* stub */ },\r\n\r\n        update: function () {\r\n            if (this.needsUpdate) {\r\n                this.updateDataArray();\r\n                this.updateCoords();\r\n            }\r\n            return this;\r\n        },\r\n\r\n        updateRenderer: function () {\r\n            this.needsUpdate = false;\r\n            return this;\r\n        },\r\n\r\n        projectCoords: function (p, params) {\r\n            return Geometry.projectCoordsToParametric(p, this, 2, params);\r\n        }\r\n\r\n        // projectScreenCoords: function (pScr, params) {\r\n        //     this.initParamsIfNeeded(params);\r\n        //     return Geometry.projectScreenCoordsToParametric(pScr, this, params);\r\n        // }\r\n    }\r\n);\r\n\r\n/**\r\n * @class A 3D parametric surface visualizes a map (u, v) &rarr; [X(u, v), Y(u, v), Z(u, v)].\r\n * @pseudo\r\n * @description A 3D parametric surface is defined by a function\r\n *    <i>F: R<sup>2</sup> &rarr; R<sup>3</sup></i>.\r\n *\r\n * @name ParametricSurface3D\r\n * @augments Curve\r\n * @constructor\r\n * @type Object\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n *\r\n * @param {Function_Function_Function_Array,Function_Array,Function} F<sub>X</sub>,F<sub>Y</sub>,F<sub>Z</sub>,rangeU,rangeV F<sub>X</sub>(u,v), F<sub>Y</sub>(u,v), F<sub>Z</sub>(u,v)\r\n * are functions returning a number, rangeU is the array containing lower and upper bound for the range of parameter u, rangeV is the array containing lower and\r\n * upper bound for the range of parameter v. rangeU and rangeV may also be functions returning an array of length two.\r\n * @param {Function_Array,Function_Array,Function} F,rangeU,rangeV Alternatively: F<sub>[X,Y,Z]</sub>(u,v)\r\n * a function returning an array [x,y,z] of numbers, rangeU and rangeV as above.\r\n *\r\n * @example\r\n * var view = board.create('view3d',\r\n * \t\t        [[-6, -3], [8, 8],\r\n * \t\t        [[-5, 5], [-5, 5], [-5, 5]]]);\r\n *\r\n * // Sphere\r\n * var c = view.create('parametricsurface3d', [\r\n *     (u, v) => 2 * Math.sin(u) * Math.cos(v),\r\n *     (u, v) => 2 * Math.sin(u) * Math.sin(v),\r\n *     (u, v) => 2 * Math.cos(u),\r\n *     [0, 2 * Math.PI],\r\n *     [0, Math.PI]\r\n * ], {\r\n *     strokeColor: '#ff0000',\r\n *     stepsU: 30,\r\n *     stepsV: 30\r\n * });\r\n *\r\n * </pre><div id=\"JXG52da0ecc-1ba9-4d41-850c-36e5120025a5\" class=\"jxgbox\" style=\"width: 500px; height: 500px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG52da0ecc-1ba9-4d41-850c-36e5120025a5',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});\r\n *     var view = board.create('view3d',\r\n *            [[-6, -3], [8, 8],\r\n *            [[-5, 5], [-5, 5], [-5, 5]]]);\r\n *\r\n *     // Sphere\r\n *     var c = view.create('parametricsurface3d', [\r\n *         (u, v) => 2 * Math.sin(u) * Math.cos(v),\r\n *         (u, v) => 2 * Math.sin(u) * Math.sin(v),\r\n *         (u, v) => 2 * Math.cos(u),\r\n *         [0, 2 * Math.PI],\r\n *         [0, Math.PI]\r\n *     ], {\r\n *         strokeColor: '#ff0000',\r\n *         stepsU: 20,\r\n *         stepsV: 20\r\n *     });\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createParametricSurface3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        F, X, Y, Z,\r\n        range_u, range_v, attr,\r\n        base = null,\r\n        transform = null,\r\n        el;\r\n\r\n    if (parents.length === 3) {\r\n        base = parents[1];\r\n        transform = parents[2];\r\n        F = null;\r\n        X = null;\r\n        Y = null;\r\n        Z = null;\r\n\r\n    } else if (parents.length === 4) {\r\n        // [view, F, range_u, range_v]\r\n        F = parents[1];\r\n        range_u = parents[2];\r\n        range_v = parents[3];\r\n        X = null;\r\n        Y = null;\r\n        Z = null;\r\n    } else {\r\n        // [view, X, Y, Z, range_u, range_v]\r\n        X = parents[1];\r\n        Y = parents[2];\r\n        Z = parents[3];\r\n        range_u = parents[4];\r\n        range_v = parents[5];\r\n        F = null;\r\n    }\r\n\r\n    attr = Type.copyAttributes(attributes, board.options, 'surface3d');\r\n    el = new JXG.Surface3D(view, F, X, Y, Z, range_u, range_v, attr);\r\n\r\n    attr = el.setAttr2D(attr);\r\n    el.element2D = view.create(\"curve\", [[], []], attr);\r\n    el.element2D.view = view;\r\n    if (base !== null) {\r\n        el.addTransform(base, transform);\r\n        el.addParents(base);\r\n    }\r\n\r\n    /**\r\n     * @class\r\n     * @ignore\r\n     */\r\n    el.element2D.updateDataArray = function () {\r\n        var ret = el.updateDataArray2D();\r\n        this.dataX = ret.X;\r\n        this.dataY = ret.Y;\r\n    };\r\n    el.addChild(el.element2D);\r\n    el.inherits.push(el.element2D);\r\n    el.element2D.setParents(el);\r\n\r\n    el.element2D.prepareUpdate().update();\r\n    if (!board.isSuspendedUpdate) {\r\n        el.element2D.updateVisibility().updateRenderer();\r\n    }\r\n\r\n    return el;\r\n};\r\nJXG.registerElement(\"parametricsurface3d\", JXG.createParametricSurface3D);\r\n\r\n/**\r\n * @class A 3D functiongraph  visualizes a map (x, y) &rarr; f(x, y).\r\n * The graph is a {@link Curve3D} element.\r\n * @pseudo\r\n * @description A 3D function graph is defined by a function\r\n *    <i>F: R<sup>2</sup> &rarr; R</i>.\r\n *\r\n * @name Functiongraph3D\r\n * @augments ParametricSurface3D\r\n * @constructor\r\n * @type Object\r\n * @throws {Exception} If the element cannot be constructed with the given parent objects an exception is thrown.\r\n * @param {Function,String_Array_Array} F,rangeX,rangeY  F(x,y) is a function returning a number (or a JessieCode string), rangeX is the array containing\r\n * lower and upper bound for the range of x, rangeY is the array containing\r\n * lower and upper bound for the range of y.\r\n * @example\r\n * var box = [-5, 5];\r\n * var view = board.create('view3d',\r\n *     [\r\n *         [-6, -3], [8, 8],\r\n *         [box, box, box]\r\n *     ],\r\n *     {\r\n *         xPlaneRear: {visible: false},\r\n *         yPlaneRear: {visible: false},\r\n *     });\r\n *\r\n * // Function F to be plotted\r\n * var F = (x, y) => Math.sin(x * y / 4);\r\n *\r\n * // 3D surface\r\n * var c = view.create('functiongraph3d', [\r\n *     F,\r\n *     box, // () => [-s.Value()*5, s.Value() * 5],\r\n *     box, // () => [-s.Value()*5, s.Value() * 5],\r\n * ], {\r\n *     strokeWidth: 0.5,\r\n *     stepsU: 70,\r\n *     stepsV: 70\r\n * });\r\n *\r\n * </pre><div id=\"JXG87646dd4-9fe5-4c21-8734-089abc612515\" class=\"jxgbox\" style=\"width: 500px; height: 500px;\"></div>\r\n * <script type=\"text/javascript\">\r\n *     (function() {\r\n *         var board = JXG.JSXGraph.initBoard('JXG87646dd4-9fe5-4c21-8734-089abc612515',\r\n *             {boundingbox: [-8, 8, 8,-8], axis: false, pan: {enabled: false}, showcopyright: false, shownavigation: false});\r\n *     var box = [-5, 5];\r\n *     var view = board.create('view3d',\r\n *         [\r\n *             [-6, -3], [8, 8],\r\n *             [box, box, box]\r\n *         ],\r\n *         {\r\n *             xPlaneRear: {visible: false},\r\n *             yPlaneRear: {visible: false},\r\n *         });\r\n *\r\n *     // Function F to be plotted\r\n *     var F = (x, y) => Math.sin(x * y / 4);\r\n *\r\n *     // 3D surface\r\n *     var c = view.create('functiongraph3d', [\r\n *         F,\r\n *         box, // () => [-s.Value()*5, s.Value() * 5],\r\n *         box, // () => [-s.Value()*5, s.Value() * 5],\r\n *     ], {\r\n *         strokeWidth: 0.5,\r\n *         stepsU: 70,\r\n *         stepsV: 70\r\n *     });\r\n *     })();\r\n *\r\n * </script><pre>\r\n *\r\n */\r\nJXG.createFunctiongraph3D = function (board, parents, attributes) {\r\n    var view = parents[0],\r\n        X = function (u, v) {\r\n            return u;\r\n        },\r\n        Y = function (u, v) {\r\n            return v;\r\n        },\r\n        Z = Type.createFunction(parents[1], board, 'x, y'),\r\n        range_u = parents[2],\r\n        range_v = parents[3],\r\n        el;\r\n\r\n    el = view.create(\"parametricsurface3d\", [X, Y, Z, range_u, range_v], attributes);\r\n    el.elType = 'functiongraph3d';\r\n    return el;\r\n};\r\nJXG.registerElement(\"functiongraph3d\", JXG.createFunctiongraph3D);\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Andreas Walter,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\n\r\n/*global JXG: true, define: true, Float32Array: true */\r\n/*jslint nomen: true, plusplus: true, bitwise: true*/\r\n\r\n/**\r\n * @fileoverview In this file the namespace JXG.Parse3D is defined.\r\n */\r\nimport JXG from \"../jxg.js\";\r\n// import Type from \"../utils/type.js\";\r\n\r\n/**\r\n * Namespace Parse3D. Contains parsers for 3D models like STL.\r\n * @namespace\r\n */\r\nJXG.Parse3D = {\r\n\r\n    /**\r\n     * Parser for the ASCII STL format, see https://en.wikipedia.org/wiki/STL_(file_format).\r\n     * STL stands for stereo-lithography.\r\n     *\r\n     * @param {String} str String containing STL file format\r\n     * @returns {Array} [[vertices, faces], ...] as list of polyhedra. Each entry is the input for a polyhedron3d.\r\n     * @example\r\n     *         const board = JXG.JSXGraph.initBoard(\r\n     *             'jxgbox',\r\n     *             {\r\n     *                 boundingbox: [-8, 8, 8, -8],\r\n     *                 minimizeReflow: 'svg',\r\n     *                 axis: false,\r\n     *                 showNavigation: false,\r\n     *                 zoom: {\r\n     *                     enabled: false\r\n     *                 },\r\n     *                 pan: {\r\n     *                     enabled: false\r\n     *                 }\r\n     *             }\r\n     *         );\r\n     *\r\n     *         var bound = [-1, 2];\r\n     *         var view = board.create(\r\n     *             'view3d',\r\n     *             [[-5, -3], [8, 8],\r\n     *             [bound, bound, bound]],\r\n     *             {\r\n     * \t            axesPosition: 'none',\r\n     *                 projection: 'central',\r\n     *                 trackball: { enabled: true },\r\n     *                 depthOrder: { enabled: true },\r\n     *                 xPlaneRear: { visible: false },\r\n     *                 yPlaneRear: { visible: false },\r\n     *                 zPlaneRear: { fillOpacity: 0.2, visible: true },\r\n     *                 az: {\r\n     *                     slider: {\r\n     *                         visible: true,\r\n     *                         start: 1.54\r\n     *                     }\r\n     *                 }\r\n     *\r\n     *             }\r\n     *         );\r\n     *\r\n     *  // Tetrahedron\r\n     *  var model = `solid m\r\n     *  facet normal 0 0 0\r\n     *    outer loop\r\n     *      vertex 0 0 0\r\n     *      vertex 1 0 0\r\n     *      vertex 1 1 0\r\n     *    endloop\r\n     *   endfacet\r\n     *  facet normal 0 0 0\r\n     *    outer loop\r\n     *      vertex 0 0 0\r\n     *      vertex 1 0 0\r\n     *      vertex 0.5 0.5 1\r\n     *    endloop\r\n     *   endfacet\r\n     *  facet normal 0 0 0\r\n     *    outer loop\r\n     *      vertex 0 0 0\r\n     *      vertex 1 1 0\r\n     *      vertex 0.5 0.5 1\r\n     *    endloop\r\n     *   endfacet\r\n     *  facet normal 0 0 0\r\n     *    outer loop\r\n     *      vertex 1 0 0\r\n     *      vertex 1 1 0\r\n     *      vertex 0.5 0.5 1\r\n     *    endloop\r\n     *   endfacet\r\n     * endsolid m`;\r\n     *\r\n     * var m = JXG.Parse3D.STL(model);\r\n     *\r\n     *  for (let i = 0; i < m.length; i++) {\r\n     *      view.create('polyhedron3d', m[i], {\r\n     *           fillColorArray: [], // ['yellow', 'red', 'green', 'blue'],\r\n     *           layer: 12,\r\n     *           strokeWidth: 0,\r\n     *           shader: {\r\n     *               enabled: true,\r\n     *               type: 'angle',\r\n     *               hue: 0 + 60 * i,\r\n     *               saturation: 90,\r\n     *               minlightness: 60,\r\n     *               maxLightness: 80\r\n     *           },\r\n     *           fillOpacity: 0.8\r\n     *       });\r\n     *   }\r\n     *\r\n     * </pre><div id=\"JXG8fa8ce22-3613-452f-9775-69588a1c1e34\" class=\"jxgbox\" style=\"width: 300px; height: 300px;\"></div>\r\n     * <script type=\"text/javascript\">\r\n     *     (function() {\r\n     *         var board = JXG.JSXGraph.initBoard('JXG8fa8ce22-3613-452f-9775-69588a1c1e34', {\r\n     *                     showcopyright: false, shownavigation: false,\r\n     *                     boundingbox: [-8, 8, 8, -8],\r\n     *                     minimizeReflow: 'svg',\r\n     *                     axis: false,\r\n     *                     showNavigation: false,\r\n     *                     zoom: {\r\n     *                         enabled: false\r\n     *                     },\r\n     *                     pan: {\r\n     *                         enabled: false\r\n     *                     }\r\n     *                 }\r\n     *             );\r\n     *\r\n     *             var bound = [-1, 2]; // Tetrahedron\r\n     *             var view = board.create(\r\n     *                 'view3d',\r\n     *                 [[-5, -3], [8, 8],\r\n     *                 [bound, bound, bound]],\r\n     *                 {\r\n     *     \t               axesPosition: 'none',\r\n     *                     projection: 'central',\r\n     *                     trackball: { enabled: true },\r\n     *                     depthOrder: { enabled: true },\r\n     *                     xPlaneRear: { visible: false },\r\n     *                     yPlaneRear: { visible: false },\r\n     *                     zPlaneRear: { fillOpacity: 0.2, visible: true },\r\n     *                     az: {\r\n     *                         slider: {\r\n     *                             visible: true,\r\n     *                             start: 1.54\r\n     *                         }\r\n     *                     }\r\n     *\r\n     *                 }\r\n     *             );\r\n     *\r\n     *   // Tetrahedron\r\n     *   var model = `solid m\r\n     *      facet normal 0 0 0\r\n     *        outer loop\r\n     *          vertex 0 0 0\r\n     *          vertex 1 0 0\r\n     *          vertex 1 1 0\r\n     *        endloop\r\n     *       endfacet\r\n     *      facet normal 0 0 0\r\n     *        outer loop\r\n     *          vertex 0 0 0\r\n     *          vertex 1 0 0\r\n     *          vertex 0.5 0.5 1\r\n     *        endloop\r\n     *       endfacet\r\n     *      facet normal 0 0 0\r\n     *        outer loop\r\n     *          vertex 0 0 0\r\n     *          vertex 1 1 0\r\n     *          vertex 0.5 0.5 1\r\n     *        endloop\r\n     *       endfacet\r\n     *      facet normal 0 0 0\r\n     *        outer loop\r\n     *          vertex 1 0 0\r\n     *          vertex 1 1 0\r\n     *          vertex 0.5 0.5 1\r\n     *        endloop\r\n     *       endfacet\r\n     *     endsolid m`;\r\n     *\r\n     *             var m = JXG.Parse3D.STL(model);\r\n     *\r\n     *  for (let i = 0; i < m.length; i++) {\r\n     *      view.create('polyhedron3d', m[i], {\r\n     *           fillColorArray: [], // ['yellow', 'red', 'green', 'blue'],\r\n     *           layer: 12,\r\n     *           strokeWidth: 0,\r\n     *           shader: {\r\n     *               enabled: true,\r\n     *               type: 'angle',\r\n     *               hue: 0 + 60 * i,\r\n     *               saturation: 90,\r\n     *               minlightness: 60,\r\n     *               maxLightness: 80\r\n     *           },\r\n     *           fillOpacity: 0.8\r\n     *       });\r\n     *   }\r\n     *     })();\r\n     *\r\n     * </script><pre>\r\n     *\r\n     */\r\n    STL: function (str) {\r\n        var i, j, pos, le,\r\n            li,\r\n            lines,\r\n            coords,\r\n            face_num, found,\r\n            polyhedra = [],\r\n            vertices = [],\r\n            faces = [];\r\n\r\n        lines = str.split('\\n');\r\n\r\n        le = lines.length;\r\n        for (i = 0; i < le; i++) {\r\n            li = lines[i].trim();\r\n\r\n            if (li.indexOf('solid') === 0) {\r\n                // New model\r\n                face_num = -1;\r\n                vertices = [];\r\n                faces = [];\r\n            } else if (li.indexOf('endsolid') === 0) {\r\n                polyhedra.push([vertices.slice(), faces.slice()]);\r\n                // break;\r\n            } else if (li.indexOf('facet') === 0) {\r\n                face_num++;\r\n                faces.push([]);\r\n            } else if (li.indexOf('outer loop') === 0 || li.indexOf('endloop') === 0) {\r\n                continue;\r\n            } else if (li.indexOf('vertex') === 0) {\r\n                coords = li.split(' ').slice(1).map((x) => parseFloat(x));\r\n                found = false;\r\n                for (j = 0; j < vertices.length; j++) {\r\n                    if (JXG.Math.Geometry.distance(vertices[j], coords, 3) < JXG.Math.eps) {\r\n                        // Debug:\r\n                        // console.log(\"Point already defined\")\r\n                        found = true;\r\n                        pos = j;\r\n                        break;\r\n                    }\r\n                }\r\n                if (found === false) {\r\n                    pos = vertices.length;\r\n                    vertices.push(coords);\r\n                }\r\n                faces[face_num].push(pos);\r\n            }\r\n        }\r\n        // console.log('v:', vertices.length, 'f:', faces.length)\r\n\r\n        // return [vertices, faces];\r\n        return polyhedra;\r\n    }\r\n\r\n};\r\n\r\n\r\nexport default JXG.Parse3D;\r\n","/*\r\n    Copyright 2008-2025\r\n        Matthias Ehmann,\r\n        Carsten Miller,\r\n        Alfred Wassermann\r\n\r\n    This file is part of JSXGraph.\r\n\r\n    JSXGraph is free software dual licensed under the GNU LGPL or MIT License.\r\n\r\n    You can redistribute it and/or modify it under the terms of the\r\n\r\n      * GNU Lesser General Public License as published by\r\n        the Free Software Foundation, either version 3 of the License, or\r\n        (at your option) any later version\r\n      OR\r\n      * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT\r\n\r\n    JSXGraph is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r\n    GNU Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public License and\r\n    the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>\r\n    and <https://opensource.org/licenses/MIT/>.\r\n */\r\nimport JXG from \"../jxg.js\";\r\n\r\n// Constants for this theme:\r\nlet size = 0.75,\r\n    color = '#000';\r\n\r\nJXG.themes['mono_thin'] = {\r\n\r\n        board: {\r\n            showInfobox: false,\r\n            showCopyright: true,\r\n            defaultAxes: {\r\n                x: {\r\n                    ticks: {\r\n                        minorTicks: 0,\r\n                        majorHeight: 10,\r\n                        majorTickEndings: [1, 0]\r\n                    }\r\n                },\r\n                y: {\r\n                    ticks: {\r\n                        minorTicks: 0,\r\n                        majorHeight: 10,\r\n                        majorTickEndings: [0, 1]\r\n                    }\r\n                }\r\n            }\r\n        },\r\n\r\n        navbar: {\r\n            strokeColor: '#bbb',\r\n            fillColor: 'none'\r\n        },\r\n\r\n        elements: {\r\n            strokeColor: color,\r\n            highlightStrokeColor: color,\r\n            fillColor: 'none',\r\n            highlightFillColor: 'none',\r\n            strokeOpacity: 0.6,\r\n            highlightStrokeOpacity: 1\r\n        },\r\n\r\n        angle: {\r\n            strokeColor: color,\r\n            fillColor: '#aaaaaa55',\r\n            fillOpacity: 0.3,\r\n            highlightFillColor: '#aaaaaa33',\r\n            highlightFillOpacity: 0.3,\r\n            label: {\r\n                strokeColor: color\r\n            }\r\n        },\r\n\r\n        arc: {\r\n            strokeColor: color,\r\n            strokeWidth: size,\r\n            highlightStrokeColor: color,\r\n            highlightStrokeWidth: size\r\n        },\r\n\r\n        axis: {\r\n            // ticks: {\r\n            //     strokeColor: '#bbb'\r\n            // }\r\n        },\r\n\r\n        boxplot: {\r\n            strokeWidth: size,\r\n            strokeColor: color,\r\n            fillColor: color,\r\n            fillOpacity: 0.2,\r\n            highlightStrokeWidth: size,\r\n            highlightStrokeColor: color,\r\n            highlightFillColor: color,\r\n            highlightFillOpacity: 0.1\r\n        },\r\n\r\n        circle: {\r\n            strokeWidth: size,\r\n            highlightStrokeWidth: 1.5 * size,\r\n            strokeColor: color,\r\n            highlightFillColor: 'none',\r\n            highlightStrokeColor: color,\r\n            center: {\r\n                size: size,\r\n                fillColor: color,\r\n                strokeColor: color,\r\n                highlightStrokeWidth: 4 * size,\r\n                highlightFillColor: color,\r\n                highlightStrokeColor: color\r\n            },\r\n            point2: {\r\n                size: size,\r\n                fillColor: color,\r\n                strokeColor: color,\r\n                highlightStrokeWidth: 4 * size,\r\n                highlightFillColor: color,\r\n                highlightStrokeColor: color\r\n            }\r\n        },\r\n\r\n        circumcircle: {\r\n            strokeWidth: size,\r\n            highlightStrokeWidth: 1.5 * size,\r\n            strokeColor: color,\r\n            highlightFillColor: 'none',\r\n            highlightStrokeColor: color,\r\n            center: {\r\n                size: size,\r\n                fillColor: color,\r\n                strokeColor: color,\r\n                highlightStrokeWidth: 4 * size,\r\n                highlightFillColor: color,\r\n                highlightStrokeColor: color\r\n            }\r\n        },\r\n\r\n        circumcirclearc: {\r\n            strokeColor: color,\r\n            strokeWidth: size,\r\n            highlightStrokeColor: color,\r\n            highlightStrokeWidth: size\r\n        },\r\n\r\n        circumcirclesector: {\r\n            strokeColor: color,\r\n            fillColor: '#aaaaaa55',\r\n            fillOpacity: 0.3,\r\n            highlightFillColor: '#aaaaaa33',\r\n            highlightFillOpacity: 0.3\r\n        },\r\n\r\n        comb: {\r\n            strokeColor: color,\r\n            strokeWidth: size\r\n        },\r\n\r\n        conic: {\r\n            strokeWidth: size,\r\n            highlightStrokeWidth: 1.5 * size,\r\n            strokeColor: color,\r\n            highlightStrokeColor: color,\r\n            fillColor: 'none',\r\n            highlightFillColor: 'none'\r\n        },\r\n\r\n        curve: {\r\n            strokeColor: color,\r\n            strokeWidth: size,\r\n            highlightStrokeColor: color,\r\n            highlightStrokeWidth: size\r\n        },\r\n\r\n        grid: {\r\n            strokeWidth: size\r\n        },\r\n\r\n        hatch: {\r\n            strokeColor: color,\r\n            strokeWidth: size\r\n        },\r\n\r\n        incircle: {\r\n            strokeWidth: size,\r\n            highlightStrokeWidth: 1.5 * size,\r\n            strokeColor: color,\r\n            highlightFillColor: 'none',\r\n            highlightStrokeColor: color,\r\n            center: {\r\n                size: size,\r\n                fillColor: color,\r\n                strokeColor: color,\r\n                highlightStrokeWidth: 4 * size,\r\n                highlightFillColor: color,\r\n                highlightStrokeColor: color\r\n            }\r\n        },\r\n\r\n        inequality: {\r\n            fillColor: '#aaaaaa55',\r\n            fillOpacity: 0.2\r\n        },\r\n\r\n        integral: {\r\n            fillColor: '#aaaaaa55',\r\n            highlightFillColor: '#aaaaa33',\r\n            fillOpacity: 0.3,\r\n            highlightFillOpacity: 0.3,\r\n            curveLeft: {\r\n                color: color\r\n            },\r\n            baseLeft: {\r\n                color: color\r\n            },\r\n            curveRight: {\r\n                color: color\r\n            },\r\n            baseRight: {\r\n                color: color\r\n            }\r\n        },\r\n\r\n        label: {\r\n            strokeColor: color\r\n        },\r\n\r\n        line: {\r\n            strokeColor: color,\r\n            strokeWidth: size,\r\n            highlightStrokeColor: color,\r\n            highlightStrokeWidth: size,\r\n            point1: {\r\n                size: size,\r\n                fillColor: color,\r\n                strokeColor: color,\r\n                highlightStrokeWidth: 4 * size,\r\n                highlightFillColor: color,\r\n                highlightStrokeColor: color\r\n            },\r\n            point2: {\r\n                size: size,\r\n                fillColor: color,\r\n                strokeColor: color,\r\n                highlightStrokeWidth: 4 * size,\r\n                highlightFillColor: color,\r\n                highlightStrokeColor: color\r\n            }\r\n        },\r\n\r\n        normal: {\r\n            strokeColor: color\r\n        },\r\n\r\n        parallel: {\r\n            strokeColor: color\r\n        },\r\n\r\n        perpendicular: {\r\n            strokeColor: color\r\n        },\r\n\r\n        perpendicularsegment: {\r\n            strokeColor: color\r\n        },\r\n\r\n        point: {\r\n            size: size,\r\n            fillColor: color,\r\n            strokeColor: color,\r\n            highlightStrokeWidth: 4 * size,\r\n            highlightFillColor: color,\r\n            highlightStrokeColor: color\r\n        },\r\n\r\n        polygon: {\r\n            fillColor: '#aaaaaa55',\r\n            highlightFillColor: '#aaaaaa33',\r\n            fillOpacity: 0.3,\r\n            highlightFillOpacity: 0.3,\r\n            vertices: {\r\n                size: size,\r\n                fillColor: color,\r\n                strokeColor: color,\r\n                highlightStrokeWidth: 4 * size,\r\n                highlightFillColor: color,\r\n                highlightStrokeColor: color\r\n            },\r\n            borders: {\r\n                strokeColor: color,\r\n                strokeWidth: size,\r\n                highlightStrokeColor: color,\r\n                highlightStrokeWidth: size\r\n            }\r\n        },\r\n\r\n        sector: {\r\n            strokeColor: color,\r\n            fillColor: '#aaaaaa55',\r\n            fillOpacity: 0.3,\r\n            highlightFillColor: '#aaaaaa33',\r\n            highlightFillOpacity: 0.3\r\n        },\r\n\r\n        semicircle: {\r\n            center: {\r\n                size: size,\r\n                fillColor: color,\r\n                strokeColor: color,\r\n                highlightStrokeWidth: 4 * size,\r\n                highlightFillColor: color,\r\n                highlightStrokeColor: color\r\n            }\r\n        },\r\n\r\n        slider: {\r\n            size: size,\r\n            fillColor: color,\r\n            strokeColor: color,\r\n            highlightStrokeWidth: 4 * size,\r\n            highlightFillColor: color,\r\n            highlightStrokeColor: color,\r\n            baseline: {\r\n                strokeWidth: size,\r\n                strokeColor: color,\r\n                highlightStrokeColor: color\r\n            },\r\n            label: {\r\n                strokeColor: color\r\n            },\r\n            highline: {\r\n                strokeWidth: 3 * size,\r\n                name: '',\r\n                strokeColor: color,\r\n                highlightStrokeColor: color\r\n            },\r\n            ticks: {\r\n                strokeColor: color\r\n            }\r\n        },\r\n\r\n        slopefield: {\r\n            strokeWidth: 0.75 * size,\r\n            highlightStrokeWidth: size,\r\n            highlightStrokeColor: color,\r\n            highlightStrokeOpacity: 0.8\r\n        },\r\n\r\n        tapemeasure: {\r\n            strokeColor: color,\r\n            strokeWidth: size,\r\n            highlightStrokeColor: color,\r\n            highlightStrokeWidth: size,\r\n            point1: {\r\n                size: size,\r\n                fillColor: color,\r\n                strokeColor: color,\r\n                highlightStrokeWidth: 4 * size,\r\n                highlightFillColor: color,\r\n                highlightStrokeColor: color\r\n            },\r\n            point2: {\r\n                size: size,\r\n                fillColor: color,\r\n                strokeColor: color,\r\n                highlightStrokeWidth: 4 * size,\r\n                highlightFillColor: color,\r\n                highlightStrokeColor: color\r\n            },\r\n            ticks: {\r\n                strokeWidth: size\r\n            }\r\n        },\r\n\r\n        text: {\r\n            strokeColor: color\r\n        },\r\n\r\n        tracecurve: {\r\n            strokeColor: color\r\n        },\r\n\r\n        turtle: {\r\n            strokeWidth: size,\r\n            strokeColor: color,\r\n            arrow: {\r\n                strokeWidth: 2 * size,\r\n                strokeColor: '#aaaaaa55'\r\n            }\r\n        },\r\n\r\n        vectorfield: {\r\n            strokeWidth: 0.75 * size,\r\n            highlightStrokeWidth: size,\r\n            highlightStrokeColor: color,\r\n            highlightStrokeOpacity: 0.8\r\n        }\r\n    // });\r\n};\r\n\r\nexport default JXG;","/* eslint-disable one-var */\r\nimport JXG from './jxg.js';\r\nimport Env from './utils/env.js'; // Needed below\r\nimport './base/constants.js';\r\nimport './utils/type.js';\r\nimport './utils/xml.js';\r\nimport './utils/event.js';\r\nimport './utils/expect.js';\r\nimport './math/math.js';\r\nimport './math/probfuncs.js';\r\nimport './math/ia.js';\r\nimport './math/extrapolate.js';\r\nimport './math/qdt.js';\r\nimport './math/bqdt.js';\r\nimport './math/numerics.js';\r\nimport './math/nlp.js';\r\nimport './math/plot.js';\r\nimport './math/implicitplot.js';\r\nimport './math/metapost.js';\r\nimport './math/statistics.js';\r\nimport './math/geometry.js';\r\nimport './math/clip.js';\r\nimport './math/poly.js';\r\nimport './math/complex.js';\r\nimport './renderer/abstract.js';\r\nimport './reader/file.js';\r\nimport './parser/geonext.js';\r\nimport './base/board.js';\r\nimport './options.js';\r\nimport './jsxgraph.js';\r\nimport './base/element.js';\r\nimport './base/coords.js';\r\nimport './base/coordselement.js';\r\nimport './base/point.js';\r\nimport './base/line.js';\r\nimport './base/group.js';\r\nimport './base/circle.js';\r\nimport './element/conic.js';\r\nimport './base/polygon.js';\r\nimport './base/curve.js';\r\nimport './element/arc.js';\r\nimport './element/sector.js';\r\nimport './base/composition.js';\r\nimport './element/composition.js';\r\nimport './element/grid.js';\r\nimport './base/text.js';\r\nimport './base/image.js';\r\nimport './element/slider.js';\r\nimport './element/measure.js';\r\nimport './base/chart.js';\r\nimport './base/transformation.js';\r\nimport './base/turtle.js';\r\nimport './utils/color.js';\r\nimport './base/ticks.js';\r\nimport './utils/zip.js';\r\nimport './utils/base64.js';\r\nimport './utils/uuid.js';\r\nimport './utils/encoding.js';\r\nimport './parser/datasource.js';\r\nimport './parser/jessiecode.js';\r\nimport './parser/prefix.js';\r\nimport './parser/ca.js';\r\nimport './utils/dump.js';\r\nimport './renderer/svg.js';\r\nimport './renderer/vml.js';\r\nimport './renderer/canvas.js';\r\nimport './renderer/no.js';\r\nimport './element/comb.js';\r\nimport './element/slopetriangle.js';\r\nimport './element/checkbox.js';\r\nimport './element/input.js';\r\nimport './element/button.js';\r\nimport './element/vectorfield.js';\r\nimport './element/smartlabel.js';\r\nimport './base/foreignobject.js';\r\nimport './options3d.js';\r\nimport './3d/view3d.js';\r\nimport './3d/element3d.js';\r\nimport './3d/box3d.js';\r\nimport './3d/circle3d.js';\r\nimport './3d/point3d.js';\r\nimport './3d/curve3d.js';\r\nimport './3d/linspace3d.js';\r\nimport './3d/text3d.js';\r\nimport './3d/ticks3d.js';\r\nimport './3d/polygon3d.js';\r\nimport './3d/face3d.js';\r\nimport './3d/polyhedron3d.js';\r\nimport './3d/sphere3d.js';\r\nimport './3d/surface3d.js';\r\nimport './parser/3dmodels.js';\r\nimport './themes/mono_thin.js';\r\n\r\n// The following exports are used to restore granular objects.\r\n// This is consistent with 1.4.x when a UMD bundle is used with a SystemJS loader.\r\n// Over time, the granular object can be made first-class objects and the JXG object\r\n// will only exist in a UMD bundle. This should improve tree-shaking.\r\n\r\n// Values\r\nexport const COORDS_BY_SCREEN = JXG.COORDS_BY_SCREEN;\r\nexport const COORDS_BY_USER = JXG.COORDS_BY_USER;\r\nexport const Dump = JXG.Dump;\r\nexport const Expect = JXG.Expect;\r\nexport const JSXGraph = JXG.JSXGraph;\r\nexport const Mat = JXG.Math;\r\nexport const Options = JXG.Options;\r\nexport const boards = JXG.boards;\r\nexport const elements = JXG.elements;\r\nexport const palette = JXG.palette;\r\nexport const paletteWong = JXG.paletteWong;\r\n\r\n// Classes\r\nexport const Board = JXG.Board;\r\nexport const Chart = JXG.Chart;\r\nexport const Circle = JXG.Circle;\r\nexport const Complex = JXG.Complex;\r\nexport const Composition = JXG.Composition;\r\nexport const Coords = JXG.Coords;\r\nexport const CoordsElement = JXG.CoordsElement;\r\nexport const Curve = JXG.Curve;\r\nexport const GeometryElement = JXG.GeometryElement;\r\nexport const Group = JXG.Group;\r\nexport const Image = JXG.Image;\r\nexport const JessieCode = JXG.JessieCode;\r\nexport const Prefix = JXG.PrefixParser;\r\nexport const Line = JXG.Line;\r\nexport const Point = JXG.Point;\r\nexport const Polygon = JXG.Polygon;\r\nexport const Text = JXG.Text;\r\nexport const Ticks = JXG.Ticks;\r\nexport const Transformation = JXG.Transformation;\r\nexport const Turtle = JXG.Turtle;\r\nexport const View3D = JXG.View3D;\r\n\r\n// Functions\r\nexport const LMS2rgb = JXG.LMS2rgb;\r\nexport const addEvent = JXG.addEvent;\r\nexport const autoDigits = JXG.autoDigits;\r\nexport const autoHighlight = JXG.autoHighlight;\r\nexport const bind = JXG.bind;\r\nexport const capitalize = JXG.capitalize;\r\nexport const clearVisPropOld = JXG.clearVisPropOld;\r\nexport const clone = JXG.clone;\r\nexport const cloneAndCopy = JXG.cloneAndCopy;\r\nexport const cmpArrays = JXG.cmpArrays;\r\nexport const coordsArrayToMatrix = JXG.coordsArrayToMatrix;\r\nexport const copyAttributes = JXG.copyAttributes;\r\nexport const createEvalFunction = JXG.createEvalFunction;\r\nexport const createFunction = JXG.createFunction;\r\nexport const createHTMLSlider = JXG.createHTMLSlider;\r\nexport const darkenColor = JXG.darkenColor;\r\nexport const debug = JXG.debug;\r\nexport const debugInt = JXG.debugInt;\r\nexport const debugLine = JXG.debugLine;\r\nexport const debugWST = JXG.debugWST;\r\nexport const deepCopy = JXG.deepCopy\r\nexport const def = JXG.def;\r\nexport const deprecated = JXG.deprecated;\r\nexport const eliminateDuplicates = JXG.eliminateDuplicates;\r\nexport const escapeHTML = JXG.escapeHTML;\r\nexport const evalSlider = JXG.evalSlider;\r\nexport const evaluate = JXG.evaluate;\r\nexport const filterElements = JXG.filterElements;\r\nexport const getBoardByContainerId = JXG.getBoardByContainerId;\r\nexport const getCSSTransformMatrix = JXG.getCSSTransformMatrix;\r\nexport const getCSSTransform = JXG.getCSSTransform;\r\nexport const getDimensions = JXG.getDimensions;\r\nexport const getOffset = JXG.getOffset;\r\nexport const getPosition = JXG.getPosition;\r\nexport const getProp = JXG.getProp;\r\nexport const hex2rgb = JXG.hex2rgb;\r\nexport const hsv2rgb = JXG.hsv2rgb;\r\nexport const isAndroid = JXG.isAndroid;\r\nexport const isApple = JXG.isApple;\r\nexport const isArray = JXG.isArray;\r\nexport const isDesktop = JXG.isDesktop;\r\nexport const isInArray = JXG.isInArray;\r\nexport const isInObject = JXG.isInObject;\r\nexport const isMetroApp = JXG.isMetroApp;\r\nexport const isMobile = JXG.isMobile;\r\nexport const isMozilla = JXG.isMozilla;\r\nexport const isBoard = JXG.isBoard;\r\nexport const isName = JXG.isName;\r\nexport const isNode = JXG.isNode;\r\nexport const isNumber = JXG.isNumber;\r\nexport const isObject = JXG.isObject;\r\nexport const isPoint = JXG.isPoint;\r\nexport const isPoint3D = JXG.isPoint3D;\r\nexport const isPointType = JXG.isPointType;\r\nexport const isPointType3D = JXG.isPointType3D;\r\nexport const isString = JXG.isString;\r\nexport const isTouchDevice = JXG.isTouchDevice;\r\nexport const isTransformationOrArray = JXG.isTransformationOrArray;\r\nexport const isWebWorker = JXG.isWebWorker;\r\nexport const isWebkitAndroid = JXG.isWebkitAndroid;\r\nexport const isWebkitApple = JXG.isWebkitApple;\r\nexport const keys = JXG.keys;\r\nexport const lightenColor = JXG.lightenColor;\r\nexport const merge = JXG.merge;\r\nexport const normalizePointFace = JXG.normalizePointFace;\r\nexport const providePoints = JXG.providePoints;\r\nexport const registerElement = JXG.registerElement;\r\nexport const registerReader = JXG.registerReader;\r\nexport const removeAllEvents = JXG.removeAllEvents;\r\nexport const removeElementFromArray = JXG.removeElementFromArray;\r\nexport const removeEvent = JXG.removeEvent;\r\nexport const rgb2LMS = JXG.rgb2LMS;\r\nexport const rgb2bw = JXG.rgb2bw;\r\nexport const rgb2cb = JXG.rgb2cb;\r\nexport const rgb2css = JXG.rgb2css;\r\nexport const rgb2hex = JXG.rgb2hex;\r\nexport const rgb2hsv = JXG.rgb2hsv;\r\nexport const rgbParser = JXG.rgbParser;\r\nexport const rgb2rgbo = JXG.rgba2rgbo;\r\nexport const rgb2rgba = JXG.rgbo2rgba;\r\nexport const sanitizeHTML = JXG.sanitizeHTML;\r\nexport const shortcut = JXG.shortcut;\r\nexport const strBool = JXG.str2Bool;\r\nexport const supportsCanvas = JXG.supportsCanvas\r\nexport const supportsPointerEvents = JXG.supportsPointerEvents;\r\nexport const supportsSVG = JXG.supportsSVG;\r\nexport const supportsVML = JXG.supportsVML;\r\nexport const swap = JXG.swap;\r\nexport const timeChunk = JXG.timedChunk;\r\nexport const toFixed = JXG.toFixed;\r\nexport const toFullscreen = JXG.toFullscreen;\r\nexport const toJSON = JXG.toJSON;\r\nexport const trim = JXG.trim;\r\nexport const trimNumber = JXG.trimNumber;\r\nexport const truncate = JXG.truncate;\r\nexport const unescapeHTML = JXG.unescapeHTML;\r\nexport const uniqueArray = JXG.uniqueArray;\r\nexport const useBlackWhiteOptions = JXG.useBlackWhiteOptions;\r\nexport const useStandardOptions = JXG.useStandardOptions;\r\nexport const warn = JXG.warn;\r\n\r\n// We're in the browser, export JXG to the global JXG symbol for backwards compatibility\r\nif (Env.isBrowser) {\r\n    window.JXG = JXG;\r\n\r\n    // In node there are two cases:\r\n    // 1) jsxgraph is used without requirejs (e.g. as jsxgraphcore.js)\r\n    // 2) jsxgraph is loaded using requirejs (e.g. the dev version)\r\n    //\r\n    // Nodejs compatibility is handled by webpack\r\n    // OLD: in case 2) module is undefined, the export is set in src/jsxgraphnode.js using\r\n    // the return value of this factory function\r\n    // } else if (Env.isNode() && typeof module === 'object') {\r\n    //     module.exports = JXG;\r\n} else if (Env.isWebWorker()) {\r\n    self.JXG = JXG;\r\n}\r\n\r\nexport default JXG;\r\n"],"names":[],"ignoreList":[],"sourceRoot":""}