/******/ (() => { // webpackBootstrap
/******/ 	// runtime can't be in strict mode because a global variable is assign and maybe created.
/******/ 	var __webpack_modules__ = ({

/***/ 823:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   ARRAY_TYPE: () => (/* binding */ ARRAY_TYPE),
/* harmony export */   EPSILON: () => (/* binding */ EPSILON),
/* harmony export */   RANDOM: () => (/* binding */ RANDOM),
/* harmony export */   equals: () => (/* binding */ equals),
/* harmony export */   setMatrixArrayType: () => (/* binding */ setMatrixArrayType),
/* harmony export */   toRadian: () => (/* binding */ toRadian)
/* harmony export */ });
/**
 * Common utilities
 * @module glMatrix
 */
// Configuration Constants
var EPSILON = 0.000001;
var ARRAY_TYPE = typeof Float32Array !== 'undefined' ? Float32Array : Array;
var RANDOM = Math.random;
/**
 * Sets the type of array used when creating new vectors and matrices
 *
 * @param {Type} type Array type, such as Float32Array or Array
 */

function setMatrixArrayType(type) {
  ARRAY_TYPE = type;
}
var degree = Math.PI / 180;
/**
 * Convert Degree To Radian
 *
 * @param {Number} a Angle in Degrees
 */

function toRadian(a) {
  return a * degree;
}
/**
 * Tests whether or not the arguments have approximately the same value, within an absolute
 * or relative tolerance of glMatrix.EPSILON (an absolute tolerance is used for values less
 * than or equal to 1.0, and a relative tolerance is used for larger values)
 *
 * @param {Number} a The first number to test.
 * @param {Number} b The second number to test.
 * @returns {Boolean} True if the numbers are approximately equal, false otherwise.
 */

function equals(a, b) {
  return Math.abs(a - b) <= EPSILON * Math.max(1.0, Math.abs(a), Math.abs(b));
}
if (!Math.hypot) Math.hypot = function () {
  var y = 0,
      i = arguments.length;

  while (i--) {
    y += arguments[i] * arguments[i];
  }

  return Math.sqrt(y);
};

/***/ }),

/***/ 522:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   LDU: () => (/* binding */ LDU),
/* harmony export */   add: () => (/* binding */ add),
/* harmony export */   adjoint: () => (/* binding */ adjoint),
/* harmony export */   clone: () => (/* binding */ clone),
/* harmony export */   copy: () => (/* binding */ copy),
/* harmony export */   create: () => (/* binding */ create),
/* harmony export */   determinant: () => (/* binding */ determinant),
/* harmony export */   equals: () => (/* binding */ equals),
/* harmony export */   exactEquals: () => (/* binding */ exactEquals),
/* harmony export */   frob: () => (/* binding */ frob),
/* harmony export */   fromRotation: () => (/* binding */ fromRotation),
/* harmony export */   fromScaling: () => (/* binding */ fromScaling),
/* harmony export */   fromValues: () => (/* binding */ fromValues),
/* harmony export */   identity: () => (/* binding */ identity),
/* harmony export */   invert: () => (/* binding */ invert),
/* harmony export */   mul: () => (/* binding */ mul),
/* harmony export */   multiply: () => (/* binding */ multiply),
/* harmony export */   multiplyScalar: () => (/* binding */ multiplyScalar),
/* harmony export */   multiplyScalarAndAdd: () => (/* binding */ multiplyScalarAndAdd),
/* harmony export */   rotate: () => (/* binding */ rotate),
/* harmony export */   scale: () => (/* binding */ scale),
/* harmony export */   set: () => (/* binding */ set),
/* harmony export */   str: () => (/* binding */ str),
/* harmony export */   sub: () => (/* binding */ sub),
/* harmony export */   subtract: () => (/* binding */ subtract),
/* harmony export */   transpose: () => (/* binding */ transpose)
/* harmony export */ });
/* harmony import */ var _common_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(823);

/**
 * 2x2 Matrix
 * @module mat2
 */

/**
 * Creates a new identity mat2
 *
 * @returns {mat2} a new 2x2 matrix
 */

function create() {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(4);

  if (_common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE != Float32Array) {
    out[1] = 0;
    out[2] = 0;
  }

  out[0] = 1;
  out[3] = 1;
  return out;
}
/**
 * Creates a new mat2 initialized with values from an existing matrix
 *
 * @param {mat2} a matrix to clone
 * @returns {mat2} a new 2x2 matrix
 */

function clone(a) {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(4);
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  return out;
}
/**
 * Copy the values from one mat2 to another
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the source matrix
 * @returns {mat2} out
 */

function copy(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  return out;
}
/**
 * Set a mat2 to the identity matrix
 *
 * @param {mat2} out the receiving matrix
 * @returns {mat2} out
 */

function identity(out) {
  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 1;
  return out;
}
/**
 * Create a new mat2 with the given values
 *
 * @param {Number} m00 Component in column 0, row 0 position (index 0)
 * @param {Number} m01 Component in column 0, row 1 position (index 1)
 * @param {Number} m10 Component in column 1, row 0 position (index 2)
 * @param {Number} m11 Component in column 1, row 1 position (index 3)
 * @returns {mat2} out A new 2x2 matrix
 */

function fromValues(m00, m01, m10, m11) {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(4);
  out[0] = m00;
  out[1] = m01;
  out[2] = m10;
  out[3] = m11;
  return out;
}
/**
 * Set the components of a mat2 to the given values
 *
 * @param {mat2} out the receiving matrix
 * @param {Number} m00 Component in column 0, row 0 position (index 0)
 * @param {Number} m01 Component in column 0, row 1 position (index 1)
 * @param {Number} m10 Component in column 1, row 0 position (index 2)
 * @param {Number} m11 Component in column 1, row 1 position (index 3)
 * @returns {mat2} out
 */

function set(out, m00, m01, m10, m11) {
  out[0] = m00;
  out[1] = m01;
  out[2] = m10;
  out[3] = m11;
  return out;
}
/**
 * Transpose the values of a mat2
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the source matrix
 * @returns {mat2} out
 */

function transpose(out, a) {
  // If we are transposing ourselves we can skip a few steps but have to cache
  // some values
  if (out === a) {
    var a1 = a[1];
    out[1] = a[2];
    out[2] = a1;
  } else {
    out[0] = a[0];
    out[1] = a[2];
    out[2] = a[1];
    out[3] = a[3];
  }

  return out;
}
/**
 * Inverts a mat2
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the source matrix
 * @returns {mat2} out
 */

function invert(out, a) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3]; // Calculate the determinant

  var det = a0 * a3 - a2 * a1;

  if (!det) {
    return null;
  }

  det = 1.0 / det;
  out[0] = a3 * det;
  out[1] = -a1 * det;
  out[2] = -a2 * det;
  out[3] = a0 * det;
  return out;
}
/**
 * Calculates the adjugate of a mat2
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the source matrix
 * @returns {mat2} out
 */

function adjoint(out, a) {
  // Caching this value is nessecary if out == a
  var a0 = a[0];
  out[0] = a[3];
  out[1] = -a[1];
  out[2] = -a[2];
  out[3] = a0;
  return out;
}
/**
 * Calculates the determinant of a mat2
 *
 * @param {mat2} a the source matrix
 * @returns {Number} determinant of a
 */

function determinant(a) {
  return a[0] * a[3] - a[2] * a[1];
}
/**
 * Multiplies two mat2's
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the first operand
 * @param {mat2} b the second operand
 * @returns {mat2} out
 */

function multiply(out, a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3];
  out[0] = a0 * b0 + a2 * b1;
  out[1] = a1 * b0 + a3 * b1;
  out[2] = a0 * b2 + a2 * b3;
  out[3] = a1 * b2 + a3 * b3;
  return out;
}
/**
 * Rotates a mat2 by the given angle
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat2} out
 */

function rotate(out, a, rad) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3];
  var s = Math.sin(rad);
  var c = Math.cos(rad);
  out[0] = a0 * c + a2 * s;
  out[1] = a1 * c + a3 * s;
  out[2] = a0 * -s + a2 * c;
  out[3] = a1 * -s + a3 * c;
  return out;
}
/**
 * Scales the mat2 by the dimensions in the given vec2
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the matrix to rotate
 * @param {vec2} v the vec2 to scale the matrix by
 * @returns {mat2} out
 **/

function scale(out, a, v) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3];
  var v0 = v[0],
      v1 = v[1];
  out[0] = a0 * v0;
  out[1] = a1 * v0;
  out[2] = a2 * v1;
  out[3] = a3 * v1;
  return out;
}
/**
 * Creates a matrix from a given angle
 * This is equivalent to (but much faster than):
 *
 *     mat2.identity(dest);
 *     mat2.rotate(dest, dest, rad);
 *
 * @param {mat2} out mat2 receiving operation result
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat2} out
 */

function fromRotation(out, rad) {
  var s = Math.sin(rad);
  var c = Math.cos(rad);
  out[0] = c;
  out[1] = s;
  out[2] = -s;
  out[3] = c;
  return out;
}
/**
 * Creates a matrix from a vector scaling
 * This is equivalent to (but much faster than):
 *
 *     mat2.identity(dest);
 *     mat2.scale(dest, dest, vec);
 *
 * @param {mat2} out mat2 receiving operation result
 * @param {vec2} v Scaling vector
 * @returns {mat2} out
 */

function fromScaling(out, v) {
  out[0] = v[0];
  out[1] = 0;
  out[2] = 0;
  out[3] = v[1];
  return out;
}
/**
 * Returns a string representation of a mat2
 *
 * @param {mat2} a matrix to represent as a string
 * @returns {String} string representation of the matrix
 */

function str(a) {
  return 'mat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
}
/**
 * Returns Frobenius norm of a mat2
 *
 * @param {mat2} a the matrix to calculate Frobenius norm of
 * @returns {Number} Frobenius norm
 */

function frob(a) {
  return Math.hypot(a[0], a[1], a[2], a[3]);
}
/**
 * Returns L, D and U matrices (Lower triangular, Diagonal and Upper triangular) by factorizing the input matrix
 * @param {mat2} L the lower triangular matrix
 * @param {mat2} D the diagonal matrix
 * @param {mat2} U the upper triangular matrix
 * @param {mat2} a the input matrix to factorize
 */

function LDU(L, D, U, a) {
  L[2] = a[2] / a[0];
  U[0] = a[0];
  U[1] = a[1];
  U[3] = a[3] - L[2] * U[1];
  return [L, D, U];
}
/**
 * Adds two mat2's
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the first operand
 * @param {mat2} b the second operand
 * @returns {mat2} out
 */

function add(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  out[2] = a[2] + b[2];
  out[3] = a[3] + b[3];
  return out;
}
/**
 * Subtracts matrix b from matrix a
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the first operand
 * @param {mat2} b the second operand
 * @returns {mat2} out
 */

function subtract(out, a, b) {
  out[0] = a[0] - b[0];
  out[1] = a[1] - b[1];
  out[2] = a[2] - b[2];
  out[3] = a[3] - b[3];
  return out;
}
/**
 * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
 *
 * @param {mat2} a The first matrix.
 * @param {mat2} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function exactEquals(a, b) {
  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3];
}
/**
 * Returns whether or not the matrices have approximately the same elements in the same position.
 *
 * @param {mat2} a The first matrix.
 * @param {mat2} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function equals(a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3];
  return Math.abs(a0 - b0) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3));
}
/**
 * Multiply each element of the matrix by a scalar.
 *
 * @param {mat2} out the receiving matrix
 * @param {mat2} a the matrix to scale
 * @param {Number} b amount to scale the matrix's elements by
 * @returns {mat2} out
 */

function multiplyScalar(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  out[2] = a[2] * b;
  out[3] = a[3] * b;
  return out;
}
/**
 * Adds two mat2's after multiplying each element of the second operand by a scalar value.
 *
 * @param {mat2} out the receiving vector
 * @param {mat2} a the first operand
 * @param {mat2} b the second operand
 * @param {Number} scale the amount to scale b's elements by before adding
 * @returns {mat2} out
 */

function multiplyScalarAndAdd(out, a, b, scale) {
  out[0] = a[0] + b[0] * scale;
  out[1] = a[1] + b[1] * scale;
  out[2] = a[2] + b[2] * scale;
  out[3] = a[3] + b[3] * scale;
  return out;
}
/**
 * Alias for {@link mat2.multiply}
 * @function
 */

var mul = multiply;
/**
 * Alias for {@link mat2.subtract}
 * @function
 */

var sub = subtract;

/***/ }),

/***/ 964:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   add: () => (/* binding */ add),
/* harmony export */   clone: () => (/* binding */ clone),
/* harmony export */   copy: () => (/* binding */ copy),
/* harmony export */   create: () => (/* binding */ create),
/* harmony export */   determinant: () => (/* binding */ determinant),
/* harmony export */   equals: () => (/* binding */ equals),
/* harmony export */   exactEquals: () => (/* binding */ exactEquals),
/* harmony export */   frob: () => (/* binding */ frob),
/* harmony export */   fromRotation: () => (/* binding */ fromRotation),
/* harmony export */   fromScaling: () => (/* binding */ fromScaling),
/* harmony export */   fromTranslation: () => (/* binding */ fromTranslation),
/* harmony export */   fromValues: () => (/* binding */ fromValues),
/* harmony export */   identity: () => (/* binding */ identity),
/* harmony export */   invert: () => (/* binding */ invert),
/* harmony export */   mul: () => (/* binding */ mul),
/* harmony export */   multiply: () => (/* binding */ multiply),
/* harmony export */   multiplyScalar: () => (/* binding */ multiplyScalar),
/* harmony export */   multiplyScalarAndAdd: () => (/* binding */ multiplyScalarAndAdd),
/* harmony export */   rotate: () => (/* binding */ rotate),
/* harmony export */   scale: () => (/* binding */ scale),
/* harmony export */   set: () => (/* binding */ set),
/* harmony export */   str: () => (/* binding */ str),
/* harmony export */   sub: () => (/* binding */ sub),
/* harmony export */   subtract: () => (/* binding */ subtract),
/* harmony export */   translate: () => (/* binding */ translate)
/* harmony export */ });
/* harmony import */ var _common_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(823);

/**
 * 2x3 Matrix
 * @module mat2d
 *
 * @description
 * A mat2d contains six elements defined as:
 * <pre>
 * [a, b, c,
 *  d, tx, ty]
 * </pre>
 * This is a short form for the 3x3 matrix:
 * <pre>
 * [a, b, 0,
 *  c, d, 0,
 *  tx, ty, 1]
 * </pre>
 * The last column is ignored so the array is shorter and operations are faster.
 */

/**
 * Creates a new identity mat2d
 *
 * @returns {mat2d} a new 2x3 matrix
 */

function create() {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(6);

  if (_common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE != Float32Array) {
    out[1] = 0;
    out[2] = 0;
    out[4] = 0;
    out[5] = 0;
  }

  out[0] = 1;
  out[3] = 1;
  return out;
}
/**
 * Creates a new mat2d initialized with values from an existing matrix
 *
 * @param {mat2d} a matrix to clone
 * @returns {mat2d} a new 2x3 matrix
 */

function clone(a) {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(6);
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  out[4] = a[4];
  out[5] = a[5];
  return out;
}
/**
 * Copy the values from one mat2d to another
 *
 * @param {mat2d} out the receiving matrix
 * @param {mat2d} a the source matrix
 * @returns {mat2d} out
 */

function copy(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  out[4] = a[4];
  out[5] = a[5];
  return out;
}
/**
 * Set a mat2d to the identity matrix
 *
 * @param {mat2d} out the receiving matrix
 * @returns {mat2d} out
 */

function identity(out) {
  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 1;
  out[4] = 0;
  out[5] = 0;
  return out;
}
/**
 * Create a new mat2d with the given values
 *
 * @param {Number} a Component A (index 0)
 * @param {Number} b Component B (index 1)
 * @param {Number} c Component C (index 2)
 * @param {Number} d Component D (index 3)
 * @param {Number} tx Component TX (index 4)
 * @param {Number} ty Component TY (index 5)
 * @returns {mat2d} A new mat2d
 */

function fromValues(a, b, c, d, tx, ty) {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(6);
  out[0] = a;
  out[1] = b;
  out[2] = c;
  out[3] = d;
  out[4] = tx;
  out[5] = ty;
  return out;
}
/**
 * Set the components of a mat2d to the given values
 *
 * @param {mat2d} out the receiving matrix
 * @param {Number} a Component A (index 0)
 * @param {Number} b Component B (index 1)
 * @param {Number} c Component C (index 2)
 * @param {Number} d Component D (index 3)
 * @param {Number} tx Component TX (index 4)
 * @param {Number} ty Component TY (index 5)
 * @returns {mat2d} out
 */

function set(out, a, b, c, d, tx, ty) {
  out[0] = a;
  out[1] = b;
  out[2] = c;
  out[3] = d;
  out[4] = tx;
  out[5] = ty;
  return out;
}
/**
 * Inverts a mat2d
 *
 * @param {mat2d} out the receiving matrix
 * @param {mat2d} a the source matrix
 * @returns {mat2d} out
 */

function invert(out, a) {
  var aa = a[0],
      ab = a[1],
      ac = a[2],
      ad = a[3];
  var atx = a[4],
      aty = a[5];
  var det = aa * ad - ab * ac;

  if (!det) {
    return null;
  }

  det = 1.0 / det;
  out[0] = ad * det;
  out[1] = -ab * det;
  out[2] = -ac * det;
  out[3] = aa * det;
  out[4] = (ac * aty - ad * atx) * det;
  out[5] = (ab * atx - aa * aty) * det;
  return out;
}
/**
 * Calculates the determinant of a mat2d
 *
 * @param {mat2d} a the source matrix
 * @returns {Number} determinant of a
 */

function determinant(a) {
  return a[0] * a[3] - a[1] * a[2];
}
/**
 * Multiplies two mat2d's
 *
 * @param {mat2d} out the receiving matrix
 * @param {mat2d} a the first operand
 * @param {mat2d} b the second operand
 * @returns {mat2d} out
 */

function multiply(out, a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3],
      a4 = a[4],
      a5 = a[5];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3],
      b4 = b[4],
      b5 = b[5];
  out[0] = a0 * b0 + a2 * b1;
  out[1] = a1 * b0 + a3 * b1;
  out[2] = a0 * b2 + a2 * b3;
  out[3] = a1 * b2 + a3 * b3;
  out[4] = a0 * b4 + a2 * b5 + a4;
  out[5] = a1 * b4 + a3 * b5 + a5;
  return out;
}
/**
 * Rotates a mat2d by the given angle
 *
 * @param {mat2d} out the receiving matrix
 * @param {mat2d} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat2d} out
 */

function rotate(out, a, rad) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3],
      a4 = a[4],
      a5 = a[5];
  var s = Math.sin(rad);
  var c = Math.cos(rad);
  out[0] = a0 * c + a2 * s;
  out[1] = a1 * c + a3 * s;
  out[2] = a0 * -s + a2 * c;
  out[3] = a1 * -s + a3 * c;
  out[4] = a4;
  out[5] = a5;
  return out;
}
/**
 * Scales the mat2d by the dimensions in the given vec2
 *
 * @param {mat2d} out the receiving matrix
 * @param {mat2d} a the matrix to translate
 * @param {vec2} v the vec2 to scale the matrix by
 * @returns {mat2d} out
 **/

function scale(out, a, v) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3],
      a4 = a[4],
      a5 = a[5];
  var v0 = v[0],
      v1 = v[1];
  out[0] = a0 * v0;
  out[1] = a1 * v0;
  out[2] = a2 * v1;
  out[3] = a3 * v1;
  out[4] = a4;
  out[5] = a5;
  return out;
}
/**
 * Translates the mat2d by the dimensions in the given vec2
 *
 * @param {mat2d} out the receiving matrix
 * @param {mat2d} a the matrix to translate
 * @param {vec2} v the vec2 to translate the matrix by
 * @returns {mat2d} out
 **/

function translate(out, a, v) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3],
      a4 = a[4],
      a5 = a[5];
  var v0 = v[0],
      v1 = v[1];
  out[0] = a0;
  out[1] = a1;
  out[2] = a2;
  out[3] = a3;
  out[4] = a0 * v0 + a2 * v1 + a4;
  out[5] = a1 * v0 + a3 * v1 + a5;
  return out;
}
/**
 * Creates a matrix from a given angle
 * This is equivalent to (but much faster than):
 *
 *     mat2d.identity(dest);
 *     mat2d.rotate(dest, dest, rad);
 *
 * @param {mat2d} out mat2d receiving operation result
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat2d} out
 */

function fromRotation(out, rad) {
  var s = Math.sin(rad),
      c = Math.cos(rad);
  out[0] = c;
  out[1] = s;
  out[2] = -s;
  out[3] = c;
  out[4] = 0;
  out[5] = 0;
  return out;
}
/**
 * Creates a matrix from a vector scaling
 * This is equivalent to (but much faster than):
 *
 *     mat2d.identity(dest);
 *     mat2d.scale(dest, dest, vec);
 *
 * @param {mat2d} out mat2d receiving operation result
 * @param {vec2} v Scaling vector
 * @returns {mat2d} out
 */

function fromScaling(out, v) {
  out[0] = v[0];
  out[1] = 0;
  out[2] = 0;
  out[3] = v[1];
  out[4] = 0;
  out[5] = 0;
  return out;
}
/**
 * Creates a matrix from a vector translation
 * This is equivalent to (but much faster than):
 *
 *     mat2d.identity(dest);
 *     mat2d.translate(dest, dest, vec);
 *
 * @param {mat2d} out mat2d receiving operation result
 * @param {vec2} v Translation vector
 * @returns {mat2d} out
 */

function fromTranslation(out, v) {
  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 1;
  out[4] = v[0];
  out[5] = v[1];
  return out;
}
/**
 * Returns a string representation of a mat2d
 *
 * @param {mat2d} a matrix to represent as a string
 * @returns {String} string representation of the matrix
 */

function str(a) {
  return 'mat2d(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ')';
}
/**
 * Returns Frobenius norm of a mat2d
 *
 * @param {mat2d} a the matrix to calculate Frobenius norm of
 * @returns {Number} Frobenius norm
 */

function frob(a) {
  return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], 1);
}
/**
 * Adds two mat2d's
 *
 * @param {mat2d} out the receiving matrix
 * @param {mat2d} a the first operand
 * @param {mat2d} b the second operand
 * @returns {mat2d} out
 */

function add(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  out[2] = a[2] + b[2];
  out[3] = a[3] + b[3];
  out[4] = a[4] + b[4];
  out[5] = a[5] + b[5];
  return out;
}
/**
 * Subtracts matrix b from matrix a
 *
 * @param {mat2d} out the receiving matrix
 * @param {mat2d} a the first operand
 * @param {mat2d} b the second operand
 * @returns {mat2d} out
 */

function subtract(out, a, b) {
  out[0] = a[0] - b[0];
  out[1] = a[1] - b[1];
  out[2] = a[2] - b[2];
  out[3] = a[3] - b[3];
  out[4] = a[4] - b[4];
  out[5] = a[5] - b[5];
  return out;
}
/**
 * Multiply each element of the matrix by a scalar.
 *
 * @param {mat2d} out the receiving matrix
 * @param {mat2d} a the matrix to scale
 * @param {Number} b amount to scale the matrix's elements by
 * @returns {mat2d} out
 */

function multiplyScalar(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  out[2] = a[2] * b;
  out[3] = a[3] * b;
  out[4] = a[4] * b;
  out[5] = a[5] * b;
  return out;
}
/**
 * Adds two mat2d's after multiplying each element of the second operand by a scalar value.
 *
 * @param {mat2d} out the receiving vector
 * @param {mat2d} a the first operand
 * @param {mat2d} b the second operand
 * @param {Number} scale the amount to scale b's elements by before adding
 * @returns {mat2d} out
 */

function multiplyScalarAndAdd(out, a, b, scale) {
  out[0] = a[0] + b[0] * scale;
  out[1] = a[1] + b[1] * scale;
  out[2] = a[2] + b[2] * scale;
  out[3] = a[3] + b[3] * scale;
  out[4] = a[4] + b[4] * scale;
  out[5] = a[5] + b[5] * scale;
  return out;
}
/**
 * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
 *
 * @param {mat2d} a The first matrix.
 * @param {mat2d} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function exactEquals(a, b) {
  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5];
}
/**
 * Returns whether or not the matrices have approximately the same elements in the same position.
 *
 * @param {mat2d} a The first matrix.
 * @param {mat2d} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function equals(a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3],
      a4 = a[4],
      a5 = a[5];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3],
      b4 = b[4],
      b5 = b[5];
  return Math.abs(a0 - b0) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5));
}
/**
 * Alias for {@link mat2d.multiply}
 * @function
 */

var mul = multiply;
/**
 * Alias for {@link mat2d.subtract}
 * @function
 */

var sub = subtract;

/***/ }),

/***/ 409:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   add: () => (/* binding */ add),
/* harmony export */   adjoint: () => (/* binding */ adjoint),
/* harmony export */   clone: () => (/* binding */ clone),
/* harmony export */   copy: () => (/* binding */ copy),
/* harmony export */   create: () => (/* binding */ create),
/* harmony export */   determinant: () => (/* binding */ determinant),
/* harmony export */   equals: () => (/* binding */ equals),
/* harmony export */   exactEquals: () => (/* binding */ exactEquals),
/* harmony export */   frob: () => (/* binding */ frob),
/* harmony export */   fromMat2d: () => (/* binding */ fromMat2d),
/* harmony export */   fromMat4: () => (/* binding */ fromMat4),
/* harmony export */   fromQuat: () => (/* binding */ fromQuat),
/* harmony export */   fromRotation: () => (/* binding */ fromRotation),
/* harmony export */   fromScaling: () => (/* binding */ fromScaling),
/* harmony export */   fromTranslation: () => (/* binding */ fromTranslation),
/* harmony export */   fromValues: () => (/* binding */ fromValues),
/* harmony export */   identity: () => (/* binding */ identity),
/* harmony export */   invert: () => (/* binding */ invert),
/* harmony export */   mul: () => (/* binding */ mul),
/* harmony export */   multiply: () => (/* binding */ multiply),
/* harmony export */   multiplyScalar: () => (/* binding */ multiplyScalar),
/* harmony export */   multiplyScalarAndAdd: () => (/* binding */ multiplyScalarAndAdd),
/* harmony export */   normalFromMat4: () => (/* binding */ normalFromMat4),
/* harmony export */   projection: () => (/* binding */ projection),
/* harmony export */   rotate: () => (/* binding */ rotate),
/* harmony export */   scale: () => (/* binding */ scale),
/* harmony export */   set: () => (/* binding */ set),
/* harmony export */   str: () => (/* binding */ str),
/* harmony export */   sub: () => (/* binding */ sub),
/* harmony export */   subtract: () => (/* binding */ subtract),
/* harmony export */   translate: () => (/* binding */ translate),
/* harmony export */   transpose: () => (/* binding */ transpose)
/* harmony export */ });
/* harmony import */ var _common_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(823);

/**
 * 3x3 Matrix
 * @module mat3
 */

/**
 * Creates a new identity mat3
 *
 * @returns {mat3} a new 3x3 matrix
 */

function create() {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(9);

  if (_common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE != Float32Array) {
    out[1] = 0;
    out[2] = 0;
    out[3] = 0;
    out[5] = 0;
    out[6] = 0;
    out[7] = 0;
  }

  out[0] = 1;
  out[4] = 1;
  out[8] = 1;
  return out;
}
/**
 * Copies the upper-left 3x3 values into the given mat3.
 *
 * @param {mat3} out the receiving 3x3 matrix
 * @param {mat4} a   the source 4x4 matrix
 * @returns {mat3} out
 */

function fromMat4(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[4];
  out[4] = a[5];
  out[5] = a[6];
  out[6] = a[8];
  out[7] = a[9];
  out[8] = a[10];
  return out;
}
/**
 * Creates a new mat3 initialized with values from an existing matrix
 *
 * @param {mat3} a matrix to clone
 * @returns {mat3} a new 3x3 matrix
 */

function clone(a) {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(9);
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  out[4] = a[4];
  out[5] = a[5];
  out[6] = a[6];
  out[7] = a[7];
  out[8] = a[8];
  return out;
}
/**
 * Copy the values from one mat3 to another
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the source matrix
 * @returns {mat3} out
 */

function copy(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  out[4] = a[4];
  out[5] = a[5];
  out[6] = a[6];
  out[7] = a[7];
  out[8] = a[8];
  return out;
}
/**
 * Create a new mat3 with the given values
 *
 * @param {Number} m00 Component in column 0, row 0 position (index 0)
 * @param {Number} m01 Component in column 0, row 1 position (index 1)
 * @param {Number} m02 Component in column 0, row 2 position (index 2)
 * @param {Number} m10 Component in column 1, row 0 position (index 3)
 * @param {Number} m11 Component in column 1, row 1 position (index 4)
 * @param {Number} m12 Component in column 1, row 2 position (index 5)
 * @param {Number} m20 Component in column 2, row 0 position (index 6)
 * @param {Number} m21 Component in column 2, row 1 position (index 7)
 * @param {Number} m22 Component in column 2, row 2 position (index 8)
 * @returns {mat3} A new mat3
 */

function fromValues(m00, m01, m02, m10, m11, m12, m20, m21, m22) {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(9);
  out[0] = m00;
  out[1] = m01;
  out[2] = m02;
  out[3] = m10;
  out[4] = m11;
  out[5] = m12;
  out[6] = m20;
  out[7] = m21;
  out[8] = m22;
  return out;
}
/**
 * Set the components of a mat3 to the given values
 *
 * @param {mat3} out the receiving matrix
 * @param {Number} m00 Component in column 0, row 0 position (index 0)
 * @param {Number} m01 Component in column 0, row 1 position (index 1)
 * @param {Number} m02 Component in column 0, row 2 position (index 2)
 * @param {Number} m10 Component in column 1, row 0 position (index 3)
 * @param {Number} m11 Component in column 1, row 1 position (index 4)
 * @param {Number} m12 Component in column 1, row 2 position (index 5)
 * @param {Number} m20 Component in column 2, row 0 position (index 6)
 * @param {Number} m21 Component in column 2, row 1 position (index 7)
 * @param {Number} m22 Component in column 2, row 2 position (index 8)
 * @returns {mat3} out
 */

function set(out, m00, m01, m02, m10, m11, m12, m20, m21, m22) {
  out[0] = m00;
  out[1] = m01;
  out[2] = m02;
  out[3] = m10;
  out[4] = m11;
  out[5] = m12;
  out[6] = m20;
  out[7] = m21;
  out[8] = m22;
  return out;
}
/**
 * Set a mat3 to the identity matrix
 *
 * @param {mat3} out the receiving matrix
 * @returns {mat3} out
 */

function identity(out) {
  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 1;
  out[5] = 0;
  out[6] = 0;
  out[7] = 0;
  out[8] = 1;
  return out;
}
/**
 * Transpose the values of a mat3
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the source matrix
 * @returns {mat3} out
 */

function transpose(out, a) {
  // If we are transposing ourselves we can skip a few steps but have to cache some values
  if (out === a) {
    var a01 = a[1],
        a02 = a[2],
        a12 = a[5];
    out[1] = a[3];
    out[2] = a[6];
    out[3] = a01;
    out[5] = a[7];
    out[6] = a02;
    out[7] = a12;
  } else {
    out[0] = a[0];
    out[1] = a[3];
    out[2] = a[6];
    out[3] = a[1];
    out[4] = a[4];
    out[5] = a[7];
    out[6] = a[2];
    out[7] = a[5];
    out[8] = a[8];
  }

  return out;
}
/**
 * Inverts a mat3
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the source matrix
 * @returns {mat3} out
 */

function invert(out, a) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2];
  var a10 = a[3],
      a11 = a[4],
      a12 = a[5];
  var a20 = a[6],
      a21 = a[7],
      a22 = a[8];
  var b01 = a22 * a11 - a12 * a21;
  var b11 = -a22 * a10 + a12 * a20;
  var b21 = a21 * a10 - a11 * a20; // Calculate the determinant

  var det = a00 * b01 + a01 * b11 + a02 * b21;

  if (!det) {
    return null;
  }

  det = 1.0 / det;
  out[0] = b01 * det;
  out[1] = (-a22 * a01 + a02 * a21) * det;
  out[2] = (a12 * a01 - a02 * a11) * det;
  out[3] = b11 * det;
  out[4] = (a22 * a00 - a02 * a20) * det;
  out[5] = (-a12 * a00 + a02 * a10) * det;
  out[6] = b21 * det;
  out[7] = (-a21 * a00 + a01 * a20) * det;
  out[8] = (a11 * a00 - a01 * a10) * det;
  return out;
}
/**
 * Calculates the adjugate of a mat3
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the source matrix
 * @returns {mat3} out
 */

function adjoint(out, a) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2];
  var a10 = a[3],
      a11 = a[4],
      a12 = a[5];
  var a20 = a[6],
      a21 = a[7],
      a22 = a[8];
  out[0] = a11 * a22 - a12 * a21;
  out[1] = a02 * a21 - a01 * a22;
  out[2] = a01 * a12 - a02 * a11;
  out[3] = a12 * a20 - a10 * a22;
  out[4] = a00 * a22 - a02 * a20;
  out[5] = a02 * a10 - a00 * a12;
  out[6] = a10 * a21 - a11 * a20;
  out[7] = a01 * a20 - a00 * a21;
  out[8] = a00 * a11 - a01 * a10;
  return out;
}
/**
 * Calculates the determinant of a mat3
 *
 * @param {mat3} a the source matrix
 * @returns {Number} determinant of a
 */

function determinant(a) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2];
  var a10 = a[3],
      a11 = a[4],
      a12 = a[5];
  var a20 = a[6],
      a21 = a[7],
      a22 = a[8];
  return a00 * (a22 * a11 - a12 * a21) + a01 * (-a22 * a10 + a12 * a20) + a02 * (a21 * a10 - a11 * a20);
}
/**
 * Multiplies two mat3's
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the first operand
 * @param {mat3} b the second operand
 * @returns {mat3} out
 */

function multiply(out, a, b) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2];
  var a10 = a[3],
      a11 = a[4],
      a12 = a[5];
  var a20 = a[6],
      a21 = a[7],
      a22 = a[8];
  var b00 = b[0],
      b01 = b[1],
      b02 = b[2];
  var b10 = b[3],
      b11 = b[4],
      b12 = b[5];
  var b20 = b[6],
      b21 = b[7],
      b22 = b[8];
  out[0] = b00 * a00 + b01 * a10 + b02 * a20;
  out[1] = b00 * a01 + b01 * a11 + b02 * a21;
  out[2] = b00 * a02 + b01 * a12 + b02 * a22;
  out[3] = b10 * a00 + b11 * a10 + b12 * a20;
  out[4] = b10 * a01 + b11 * a11 + b12 * a21;
  out[5] = b10 * a02 + b11 * a12 + b12 * a22;
  out[6] = b20 * a00 + b21 * a10 + b22 * a20;
  out[7] = b20 * a01 + b21 * a11 + b22 * a21;
  out[8] = b20 * a02 + b21 * a12 + b22 * a22;
  return out;
}
/**
 * Translate a mat3 by the given vector
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the matrix to translate
 * @param {vec2} v vector to translate by
 * @returns {mat3} out
 */

function translate(out, a, v) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2],
      a10 = a[3],
      a11 = a[4],
      a12 = a[5],
      a20 = a[6],
      a21 = a[7],
      a22 = a[8],
      x = v[0],
      y = v[1];
  out[0] = a00;
  out[1] = a01;
  out[2] = a02;
  out[3] = a10;
  out[4] = a11;
  out[5] = a12;
  out[6] = x * a00 + y * a10 + a20;
  out[7] = x * a01 + y * a11 + a21;
  out[8] = x * a02 + y * a12 + a22;
  return out;
}
/**
 * Rotates a mat3 by the given angle
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat3} out
 */

function rotate(out, a, rad) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2],
      a10 = a[3],
      a11 = a[4],
      a12 = a[5],
      a20 = a[6],
      a21 = a[7],
      a22 = a[8],
      s = Math.sin(rad),
      c = Math.cos(rad);
  out[0] = c * a00 + s * a10;
  out[1] = c * a01 + s * a11;
  out[2] = c * a02 + s * a12;
  out[3] = c * a10 - s * a00;
  out[4] = c * a11 - s * a01;
  out[5] = c * a12 - s * a02;
  out[6] = a20;
  out[7] = a21;
  out[8] = a22;
  return out;
}
;
/**
 * Scales the mat3 by the dimensions in the given vec2
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the matrix to rotate
 * @param {vec2} v the vec2 to scale the matrix by
 * @returns {mat3} out
 **/

function scale(out, a, v) {
  var x = v[0],
      y = v[1];
  out[0] = x * a[0];
  out[1] = x * a[1];
  out[2] = x * a[2];
  out[3] = y * a[3];
  out[4] = y * a[4];
  out[5] = y * a[5];
  out[6] = a[6];
  out[7] = a[7];
  out[8] = a[8];
  return out;
}
/**
 * Creates a matrix from a vector translation
 * This is equivalent to (but much faster than):
 *
 *     mat3.identity(dest);
 *     mat3.translate(dest, dest, vec);
 *
 * @param {mat3} out mat3 receiving operation result
 * @param {vec2} v Translation vector
 * @returns {mat3} out
 */

function fromTranslation(out, v) {
  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 1;
  out[5] = 0;
  out[6] = v[0];
  out[7] = v[1];
  out[8] = 1;
  return out;
}
/**
 * Creates a matrix from a given angle
 * This is equivalent to (but much faster than):
 *
 *     mat3.identity(dest);
 *     mat3.rotate(dest, dest, rad);
 *
 * @param {mat3} out mat3 receiving operation result
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat3} out
 */

function fromRotation(out, rad) {
  var s = Math.sin(rad),
      c = Math.cos(rad);
  out[0] = c;
  out[1] = s;
  out[2] = 0;
  out[3] = -s;
  out[4] = c;
  out[5] = 0;
  out[6] = 0;
  out[7] = 0;
  out[8] = 1;
  return out;
}
/**
 * Creates a matrix from a vector scaling
 * This is equivalent to (but much faster than):
 *
 *     mat3.identity(dest);
 *     mat3.scale(dest, dest, vec);
 *
 * @param {mat3} out mat3 receiving operation result
 * @param {vec2} v Scaling vector
 * @returns {mat3} out
 */

function fromScaling(out, v) {
  out[0] = v[0];
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = v[1];
  out[5] = 0;
  out[6] = 0;
  out[7] = 0;
  out[8] = 1;
  return out;
}
/**
 * Copies the values from a mat2d into a mat3
 *
 * @param {mat3} out the receiving matrix
 * @param {mat2d} a the matrix to copy
 * @returns {mat3} out
 **/

function fromMat2d(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = 0;
  out[3] = a[2];
  out[4] = a[3];
  out[5] = 0;
  out[6] = a[4];
  out[7] = a[5];
  out[8] = 1;
  return out;
}
/**
* Calculates a 3x3 matrix from the given quaternion
*
* @param {mat3} out mat3 receiving operation result
* @param {quat} q Quaternion to create matrix from
*
* @returns {mat3} out
*/

function fromQuat(out, q) {
  var x = q[0],
      y = q[1],
      z = q[2],
      w = q[3];
  var x2 = x + x;
  var y2 = y + y;
  var z2 = z + z;
  var xx = x * x2;
  var yx = y * x2;
  var yy = y * y2;
  var zx = z * x2;
  var zy = z * y2;
  var zz = z * z2;
  var wx = w * x2;
  var wy = w * y2;
  var wz = w * z2;
  out[0] = 1 - yy - zz;
  out[3] = yx - wz;
  out[6] = zx + wy;
  out[1] = yx + wz;
  out[4] = 1 - xx - zz;
  out[7] = zy - wx;
  out[2] = zx - wy;
  out[5] = zy + wx;
  out[8] = 1 - xx - yy;
  return out;
}
/**
* Calculates a 3x3 normal matrix (transpose inverse) from the 4x4 matrix
*
* @param {mat3} out mat3 receiving operation result
* @param {mat4} a Mat4 to derive the normal matrix from
*
* @returns {mat3} out
*/

function normalFromMat4(out, a) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2],
      a03 = a[3];
  var a10 = a[4],
      a11 = a[5],
      a12 = a[6],
      a13 = a[7];
  var a20 = a[8],
      a21 = a[9],
      a22 = a[10],
      a23 = a[11];
  var a30 = a[12],
      a31 = a[13],
      a32 = a[14],
      a33 = a[15];
  var b00 = a00 * a11 - a01 * a10;
  var b01 = a00 * a12 - a02 * a10;
  var b02 = a00 * a13 - a03 * a10;
  var b03 = a01 * a12 - a02 * a11;
  var b04 = a01 * a13 - a03 * a11;
  var b05 = a02 * a13 - a03 * a12;
  var b06 = a20 * a31 - a21 * a30;
  var b07 = a20 * a32 - a22 * a30;
  var b08 = a20 * a33 - a23 * a30;
  var b09 = a21 * a32 - a22 * a31;
  var b10 = a21 * a33 - a23 * a31;
  var b11 = a22 * a33 - a23 * a32; // Calculate the determinant

  var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;

  if (!det) {
    return null;
  }

  det = 1.0 / det;
  out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
  out[1] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
  out[2] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
  out[3] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
  out[4] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
  out[5] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
  out[6] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
  out[7] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
  out[8] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
  return out;
}
/**
 * Generates a 2D projection matrix with the given bounds
 *
 * @param {mat3} out mat3 frustum matrix will be written into
 * @param {number} width Width of your gl context
 * @param {number} height Height of gl context
 * @returns {mat3} out
 */

function projection(out, width, height) {
  out[0] = 2 / width;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = -2 / height;
  out[5] = 0;
  out[6] = -1;
  out[7] = 1;
  out[8] = 1;
  return out;
}
/**
 * Returns a string representation of a mat3
 *
 * @param {mat3} a matrix to represent as a string
 * @returns {String} string representation of the matrix
 */

function str(a) {
  return 'mat3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' + a[8] + ')';
}
/**
 * Returns Frobenius norm of a mat3
 *
 * @param {mat3} a the matrix to calculate Frobenius norm of
 * @returns {Number} Frobenius norm
 */

function frob(a) {
  return Math.hypot(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]);
}
/**
 * Adds two mat3's
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the first operand
 * @param {mat3} b the second operand
 * @returns {mat3} out
 */

function add(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  out[2] = a[2] + b[2];
  out[3] = a[3] + b[3];
  out[4] = a[4] + b[4];
  out[5] = a[5] + b[5];
  out[6] = a[6] + b[6];
  out[7] = a[7] + b[7];
  out[8] = a[8] + b[8];
  return out;
}
/**
 * Subtracts matrix b from matrix a
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the first operand
 * @param {mat3} b the second operand
 * @returns {mat3} out
 */

function subtract(out, a, b) {
  out[0] = a[0] - b[0];
  out[1] = a[1] - b[1];
  out[2] = a[2] - b[2];
  out[3] = a[3] - b[3];
  out[4] = a[4] - b[4];
  out[5] = a[5] - b[5];
  out[6] = a[6] - b[6];
  out[7] = a[7] - b[7];
  out[8] = a[8] - b[8];
  return out;
}
/**
 * Multiply each element of the matrix by a scalar.
 *
 * @param {mat3} out the receiving matrix
 * @param {mat3} a the matrix to scale
 * @param {Number} b amount to scale the matrix's elements by
 * @returns {mat3} out
 */

function multiplyScalar(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  out[2] = a[2] * b;
  out[3] = a[3] * b;
  out[4] = a[4] * b;
  out[5] = a[5] * b;
  out[6] = a[6] * b;
  out[7] = a[7] * b;
  out[8] = a[8] * b;
  return out;
}
/**
 * Adds two mat3's after multiplying each element of the second operand by a scalar value.
 *
 * @param {mat3} out the receiving vector
 * @param {mat3} a the first operand
 * @param {mat3} b the second operand
 * @param {Number} scale the amount to scale b's elements by before adding
 * @returns {mat3} out
 */

function multiplyScalarAndAdd(out, a, b, scale) {
  out[0] = a[0] + b[0] * scale;
  out[1] = a[1] + b[1] * scale;
  out[2] = a[2] + b[2] * scale;
  out[3] = a[3] + b[3] * scale;
  out[4] = a[4] + b[4] * scale;
  out[5] = a[5] + b[5] * scale;
  out[6] = a[6] + b[6] * scale;
  out[7] = a[7] + b[7] * scale;
  out[8] = a[8] + b[8] * scale;
  return out;
}
/**
 * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
 *
 * @param {mat3} a The first matrix.
 * @param {mat3} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function exactEquals(a, b) {
  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8];
}
/**
 * Returns whether or not the matrices have approximately the same elements in the same position.
 *
 * @param {mat3} a The first matrix.
 * @param {mat3} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function equals(a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3],
      a4 = a[4],
      a5 = a[5],
      a6 = a[6],
      a7 = a[7],
      a8 = a[8];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3],
      b4 = b[4],
      b5 = b[5],
      b6 = b[6],
      b7 = b[7],
      b8 = b[8];
  return Math.abs(a0 - b0) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8));
}
/**
 * Alias for {@link mat3.multiply}
 * @function
 */

var mul = multiply;
/**
 * Alias for {@link mat3.subtract}
 * @function
 */

var sub = subtract;

/***/ }),

/***/ 684:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   add: () => (/* binding */ add),
/* harmony export */   adjoint: () => (/* binding */ adjoint),
/* harmony export */   clone: () => (/* binding */ clone),
/* harmony export */   copy: () => (/* binding */ copy),
/* harmony export */   create: () => (/* binding */ create),
/* harmony export */   determinant: () => (/* binding */ determinant),
/* harmony export */   equals: () => (/* binding */ equals),
/* harmony export */   exactEquals: () => (/* binding */ exactEquals),
/* harmony export */   frob: () => (/* binding */ frob),
/* harmony export */   fromQuat: () => (/* binding */ fromQuat),
/* harmony export */   fromQuat2: () => (/* binding */ fromQuat2),
/* harmony export */   fromRotation: () => (/* binding */ fromRotation),
/* harmony export */   fromRotationTranslation: () => (/* binding */ fromRotationTranslation),
/* harmony export */   fromRotationTranslationScale: () => (/* binding */ fromRotationTranslationScale),
/* harmony export */   fromRotationTranslationScaleOrigin: () => (/* binding */ fromRotationTranslationScaleOrigin),
/* harmony export */   fromScaling: () => (/* binding */ fromScaling),
/* harmony export */   fromTranslation: () => (/* binding */ fromTranslation),
/* harmony export */   fromValues: () => (/* binding */ fromValues),
/* harmony export */   fromXRotation: () => (/* binding */ fromXRotation),
/* harmony export */   fromYRotation: () => (/* binding */ fromYRotation),
/* harmony export */   fromZRotation: () => (/* binding */ fromZRotation),
/* harmony export */   frustum: () => (/* binding */ frustum),
/* harmony export */   getRotation: () => (/* binding */ getRotation),
/* harmony export */   getScaling: () => (/* binding */ getScaling),
/* harmony export */   getTranslation: () => (/* binding */ getTranslation),
/* harmony export */   identity: () => (/* binding */ identity),
/* harmony export */   invert: () => (/* binding */ invert),
/* harmony export */   lookAt: () => (/* binding */ lookAt),
/* harmony export */   mul: () => (/* binding */ mul),
/* harmony export */   multiply: () => (/* binding */ multiply),
/* harmony export */   multiplyScalar: () => (/* binding */ multiplyScalar),
/* harmony export */   multiplyScalarAndAdd: () => (/* binding */ multiplyScalarAndAdd),
/* harmony export */   ortho: () => (/* binding */ ortho),
/* harmony export */   perspective: () => (/* binding */ perspective),
/* harmony export */   perspectiveFromFieldOfView: () => (/* binding */ perspectiveFromFieldOfView),
/* harmony export */   rotate: () => (/* binding */ rotate),
/* harmony export */   rotateX: () => (/* binding */ rotateX),
/* harmony export */   rotateY: () => (/* binding */ rotateY),
/* harmony export */   rotateZ: () => (/* binding */ rotateZ),
/* harmony export */   scale: () => (/* binding */ scale),
/* harmony export */   set: () => (/* binding */ set),
/* harmony export */   str: () => (/* binding */ str),
/* harmony export */   sub: () => (/* binding */ sub),
/* harmony export */   subtract: () => (/* binding */ subtract),
/* harmony export */   targetTo: () => (/* binding */ targetTo),
/* harmony export */   translate: () => (/* binding */ translate),
/* harmony export */   transpose: () => (/* binding */ transpose)
/* harmony export */ });
/* harmony import */ var _common_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(823);

/**
 * 4x4 Matrix<br>Format: column-major, when typed out it looks like row-major<br>The matrices are being post multiplied.
 * @module mat4
 */

/**
 * Creates a new identity mat4
 *
 * @returns {mat4} a new 4x4 matrix
 */

function create() {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(16);

  if (_common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE != Float32Array) {
    out[1] = 0;
    out[2] = 0;
    out[3] = 0;
    out[4] = 0;
    out[6] = 0;
    out[7] = 0;
    out[8] = 0;
    out[9] = 0;
    out[11] = 0;
    out[12] = 0;
    out[13] = 0;
    out[14] = 0;
  }

  out[0] = 1;
  out[5] = 1;
  out[10] = 1;
  out[15] = 1;
  return out;
}
/**
 * Creates a new mat4 initialized with values from an existing matrix
 *
 * @param {mat4} a matrix to clone
 * @returns {mat4} a new 4x4 matrix
 */

function clone(a) {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(16);
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  out[4] = a[4];
  out[5] = a[5];
  out[6] = a[6];
  out[7] = a[7];
  out[8] = a[8];
  out[9] = a[9];
  out[10] = a[10];
  out[11] = a[11];
  out[12] = a[12];
  out[13] = a[13];
  out[14] = a[14];
  out[15] = a[15];
  return out;
}
/**
 * Copy the values from one mat4 to another
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the source matrix
 * @returns {mat4} out
 */

function copy(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  out[4] = a[4];
  out[5] = a[5];
  out[6] = a[6];
  out[7] = a[7];
  out[8] = a[8];
  out[9] = a[9];
  out[10] = a[10];
  out[11] = a[11];
  out[12] = a[12];
  out[13] = a[13];
  out[14] = a[14];
  out[15] = a[15];
  return out;
}
/**
 * Create a new mat4 with the given values
 *
 * @param {Number} m00 Component in column 0, row 0 position (index 0)
 * @param {Number} m01 Component in column 0, row 1 position (index 1)
 * @param {Number} m02 Component in column 0, row 2 position (index 2)
 * @param {Number} m03 Component in column 0, row 3 position (index 3)
 * @param {Number} m10 Component in column 1, row 0 position (index 4)
 * @param {Number} m11 Component in column 1, row 1 position (index 5)
 * @param {Number} m12 Component in column 1, row 2 position (index 6)
 * @param {Number} m13 Component in column 1, row 3 position (index 7)
 * @param {Number} m20 Component in column 2, row 0 position (index 8)
 * @param {Number} m21 Component in column 2, row 1 position (index 9)
 * @param {Number} m22 Component in column 2, row 2 position (index 10)
 * @param {Number} m23 Component in column 2, row 3 position (index 11)
 * @param {Number} m30 Component in column 3, row 0 position (index 12)
 * @param {Number} m31 Component in column 3, row 1 position (index 13)
 * @param {Number} m32 Component in column 3, row 2 position (index 14)
 * @param {Number} m33 Component in column 3, row 3 position (index 15)
 * @returns {mat4} A new mat4
 */

function fromValues(m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(16);
  out[0] = m00;
  out[1] = m01;
  out[2] = m02;
  out[3] = m03;
  out[4] = m10;
  out[5] = m11;
  out[6] = m12;
  out[7] = m13;
  out[8] = m20;
  out[9] = m21;
  out[10] = m22;
  out[11] = m23;
  out[12] = m30;
  out[13] = m31;
  out[14] = m32;
  out[15] = m33;
  return out;
}
/**
 * Set the components of a mat4 to the given values
 *
 * @param {mat4} out the receiving matrix
 * @param {Number} m00 Component in column 0, row 0 position (index 0)
 * @param {Number} m01 Component in column 0, row 1 position (index 1)
 * @param {Number} m02 Component in column 0, row 2 position (index 2)
 * @param {Number} m03 Component in column 0, row 3 position (index 3)
 * @param {Number} m10 Component in column 1, row 0 position (index 4)
 * @param {Number} m11 Component in column 1, row 1 position (index 5)
 * @param {Number} m12 Component in column 1, row 2 position (index 6)
 * @param {Number} m13 Component in column 1, row 3 position (index 7)
 * @param {Number} m20 Component in column 2, row 0 position (index 8)
 * @param {Number} m21 Component in column 2, row 1 position (index 9)
 * @param {Number} m22 Component in column 2, row 2 position (index 10)
 * @param {Number} m23 Component in column 2, row 3 position (index 11)
 * @param {Number} m30 Component in column 3, row 0 position (index 12)
 * @param {Number} m31 Component in column 3, row 1 position (index 13)
 * @param {Number} m32 Component in column 3, row 2 position (index 14)
 * @param {Number} m33 Component in column 3, row 3 position (index 15)
 * @returns {mat4} out
 */

function set(out, m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33) {
  out[0] = m00;
  out[1] = m01;
  out[2] = m02;
  out[3] = m03;
  out[4] = m10;
  out[5] = m11;
  out[6] = m12;
  out[7] = m13;
  out[8] = m20;
  out[9] = m21;
  out[10] = m22;
  out[11] = m23;
  out[12] = m30;
  out[13] = m31;
  out[14] = m32;
  out[15] = m33;
  return out;
}
/**
 * Set a mat4 to the identity matrix
 *
 * @param {mat4} out the receiving matrix
 * @returns {mat4} out
 */

function identity(out) {
  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = 1;
  out[6] = 0;
  out[7] = 0;
  out[8] = 0;
  out[9] = 0;
  out[10] = 1;
  out[11] = 0;
  out[12] = 0;
  out[13] = 0;
  out[14] = 0;
  out[15] = 1;
  return out;
}
/**
 * Transpose the values of a mat4
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the source matrix
 * @returns {mat4} out
 */

function transpose(out, a) {
  // If we are transposing ourselves we can skip a few steps but have to cache some values
  if (out === a) {
    var a01 = a[1],
        a02 = a[2],
        a03 = a[3];
    var a12 = a[6],
        a13 = a[7];
    var a23 = a[11];
    out[1] = a[4];
    out[2] = a[8];
    out[3] = a[12];
    out[4] = a01;
    out[6] = a[9];
    out[7] = a[13];
    out[8] = a02;
    out[9] = a12;
    out[11] = a[14];
    out[12] = a03;
    out[13] = a13;
    out[14] = a23;
  } else {
    out[0] = a[0];
    out[1] = a[4];
    out[2] = a[8];
    out[3] = a[12];
    out[4] = a[1];
    out[5] = a[5];
    out[6] = a[9];
    out[7] = a[13];
    out[8] = a[2];
    out[9] = a[6];
    out[10] = a[10];
    out[11] = a[14];
    out[12] = a[3];
    out[13] = a[7];
    out[14] = a[11];
    out[15] = a[15];
  }

  return out;
}
/**
 * Inverts a mat4
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the source matrix
 * @returns {mat4} out
 */

function invert(out, a) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2],
      a03 = a[3];
  var a10 = a[4],
      a11 = a[5],
      a12 = a[6],
      a13 = a[7];
  var a20 = a[8],
      a21 = a[9],
      a22 = a[10],
      a23 = a[11];
  var a30 = a[12],
      a31 = a[13],
      a32 = a[14],
      a33 = a[15];
  var b00 = a00 * a11 - a01 * a10;
  var b01 = a00 * a12 - a02 * a10;
  var b02 = a00 * a13 - a03 * a10;
  var b03 = a01 * a12 - a02 * a11;
  var b04 = a01 * a13 - a03 * a11;
  var b05 = a02 * a13 - a03 * a12;
  var b06 = a20 * a31 - a21 * a30;
  var b07 = a20 * a32 - a22 * a30;
  var b08 = a20 * a33 - a23 * a30;
  var b09 = a21 * a32 - a22 * a31;
  var b10 = a21 * a33 - a23 * a31;
  var b11 = a22 * a33 - a23 * a32; // Calculate the determinant

  var det = b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;

  if (!det) {
    return null;
  }

  det = 1.0 / det;
  out[0] = (a11 * b11 - a12 * b10 + a13 * b09) * det;
  out[1] = (a02 * b10 - a01 * b11 - a03 * b09) * det;
  out[2] = (a31 * b05 - a32 * b04 + a33 * b03) * det;
  out[3] = (a22 * b04 - a21 * b05 - a23 * b03) * det;
  out[4] = (a12 * b08 - a10 * b11 - a13 * b07) * det;
  out[5] = (a00 * b11 - a02 * b08 + a03 * b07) * det;
  out[6] = (a32 * b02 - a30 * b05 - a33 * b01) * det;
  out[7] = (a20 * b05 - a22 * b02 + a23 * b01) * det;
  out[8] = (a10 * b10 - a11 * b08 + a13 * b06) * det;
  out[9] = (a01 * b08 - a00 * b10 - a03 * b06) * det;
  out[10] = (a30 * b04 - a31 * b02 + a33 * b00) * det;
  out[11] = (a21 * b02 - a20 * b04 - a23 * b00) * det;
  out[12] = (a11 * b07 - a10 * b09 - a12 * b06) * det;
  out[13] = (a00 * b09 - a01 * b07 + a02 * b06) * det;
  out[14] = (a31 * b01 - a30 * b03 - a32 * b00) * det;
  out[15] = (a20 * b03 - a21 * b01 + a22 * b00) * det;
  return out;
}
/**
 * Calculates the adjugate of a mat4
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the source matrix
 * @returns {mat4} out
 */

function adjoint(out, a) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2],
      a03 = a[3];
  var a10 = a[4],
      a11 = a[5],
      a12 = a[6],
      a13 = a[7];
  var a20 = a[8],
      a21 = a[9],
      a22 = a[10],
      a23 = a[11];
  var a30 = a[12],
      a31 = a[13],
      a32 = a[14],
      a33 = a[15];
  out[0] = a11 * (a22 * a33 - a23 * a32) - a21 * (a12 * a33 - a13 * a32) + a31 * (a12 * a23 - a13 * a22);
  out[1] = -(a01 * (a22 * a33 - a23 * a32) - a21 * (a02 * a33 - a03 * a32) + a31 * (a02 * a23 - a03 * a22));
  out[2] = a01 * (a12 * a33 - a13 * a32) - a11 * (a02 * a33 - a03 * a32) + a31 * (a02 * a13 - a03 * a12);
  out[3] = -(a01 * (a12 * a23 - a13 * a22) - a11 * (a02 * a23 - a03 * a22) + a21 * (a02 * a13 - a03 * a12));
  out[4] = -(a10 * (a22 * a33 - a23 * a32) - a20 * (a12 * a33 - a13 * a32) + a30 * (a12 * a23 - a13 * a22));
  out[5] = a00 * (a22 * a33 - a23 * a32) - a20 * (a02 * a33 - a03 * a32) + a30 * (a02 * a23 - a03 * a22);
  out[6] = -(a00 * (a12 * a33 - a13 * a32) - a10 * (a02 * a33 - a03 * a32) + a30 * (a02 * a13 - a03 * a12));
  out[7] = a00 * (a12 * a23 - a13 * a22) - a10 * (a02 * a23 - a03 * a22) + a20 * (a02 * a13 - a03 * a12);
  out[8] = a10 * (a21 * a33 - a23 * a31) - a20 * (a11 * a33 - a13 * a31) + a30 * (a11 * a23 - a13 * a21);
  out[9] = -(a00 * (a21 * a33 - a23 * a31) - a20 * (a01 * a33 - a03 * a31) + a30 * (a01 * a23 - a03 * a21));
  out[10] = a00 * (a11 * a33 - a13 * a31) - a10 * (a01 * a33 - a03 * a31) + a30 * (a01 * a13 - a03 * a11);
  out[11] = -(a00 * (a11 * a23 - a13 * a21) - a10 * (a01 * a23 - a03 * a21) + a20 * (a01 * a13 - a03 * a11));
  out[12] = -(a10 * (a21 * a32 - a22 * a31) - a20 * (a11 * a32 - a12 * a31) + a30 * (a11 * a22 - a12 * a21));
  out[13] = a00 * (a21 * a32 - a22 * a31) - a20 * (a01 * a32 - a02 * a31) + a30 * (a01 * a22 - a02 * a21);
  out[14] = -(a00 * (a11 * a32 - a12 * a31) - a10 * (a01 * a32 - a02 * a31) + a30 * (a01 * a12 - a02 * a11));
  out[15] = a00 * (a11 * a22 - a12 * a21) - a10 * (a01 * a22 - a02 * a21) + a20 * (a01 * a12 - a02 * a11);
  return out;
}
/**
 * Calculates the determinant of a mat4
 *
 * @param {mat4} a the source matrix
 * @returns {Number} determinant of a
 */

function determinant(a) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2],
      a03 = a[3];
  var a10 = a[4],
      a11 = a[5],
      a12 = a[6],
      a13 = a[7];
  var a20 = a[8],
      a21 = a[9],
      a22 = a[10],
      a23 = a[11];
  var a30 = a[12],
      a31 = a[13],
      a32 = a[14],
      a33 = a[15];
  var b00 = a00 * a11 - a01 * a10;
  var b01 = a00 * a12 - a02 * a10;
  var b02 = a00 * a13 - a03 * a10;
  var b03 = a01 * a12 - a02 * a11;
  var b04 = a01 * a13 - a03 * a11;
  var b05 = a02 * a13 - a03 * a12;
  var b06 = a20 * a31 - a21 * a30;
  var b07 = a20 * a32 - a22 * a30;
  var b08 = a20 * a33 - a23 * a30;
  var b09 = a21 * a32 - a22 * a31;
  var b10 = a21 * a33 - a23 * a31;
  var b11 = a22 * a33 - a23 * a32; // Calculate the determinant

  return b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06;
}
/**
 * Multiplies two mat4s
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the first operand
 * @param {mat4} b the second operand
 * @returns {mat4} out
 */

function multiply(out, a, b) {
  var a00 = a[0],
      a01 = a[1],
      a02 = a[2],
      a03 = a[3];
  var a10 = a[4],
      a11 = a[5],
      a12 = a[6],
      a13 = a[7];
  var a20 = a[8],
      a21 = a[9],
      a22 = a[10],
      a23 = a[11];
  var a30 = a[12],
      a31 = a[13],
      a32 = a[14],
      a33 = a[15]; // Cache only the current line of the second matrix

  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3];
  out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  b0 = b[4];
  b1 = b[5];
  b2 = b[6];
  b3 = b[7];
  out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  b0 = b[8];
  b1 = b[9];
  b2 = b[10];
  b3 = b[11];
  out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  b0 = b[12];
  b1 = b[13];
  b2 = b[14];
  b3 = b[15];
  out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
  out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
  out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
  out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
  return out;
}
/**
 * Translate a mat4 by the given vector
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the matrix to translate
 * @param {vec3} v vector to translate by
 * @returns {mat4} out
 */

function translate(out, a, v) {
  var x = v[0],
      y = v[1],
      z = v[2];
  var a00, a01, a02, a03;
  var a10, a11, a12, a13;
  var a20, a21, a22, a23;

  if (a === out) {
    out[12] = a[0] * x + a[4] * y + a[8] * z + a[12];
    out[13] = a[1] * x + a[5] * y + a[9] * z + a[13];
    out[14] = a[2] * x + a[6] * y + a[10] * z + a[14];
    out[15] = a[3] * x + a[7] * y + a[11] * z + a[15];
  } else {
    a00 = a[0];
    a01 = a[1];
    a02 = a[2];
    a03 = a[3];
    a10 = a[4];
    a11 = a[5];
    a12 = a[6];
    a13 = a[7];
    a20 = a[8];
    a21 = a[9];
    a22 = a[10];
    a23 = a[11];
    out[0] = a00;
    out[1] = a01;
    out[2] = a02;
    out[3] = a03;
    out[4] = a10;
    out[5] = a11;
    out[6] = a12;
    out[7] = a13;
    out[8] = a20;
    out[9] = a21;
    out[10] = a22;
    out[11] = a23;
    out[12] = a00 * x + a10 * y + a20 * z + a[12];
    out[13] = a01 * x + a11 * y + a21 * z + a[13];
    out[14] = a02 * x + a12 * y + a22 * z + a[14];
    out[15] = a03 * x + a13 * y + a23 * z + a[15];
  }

  return out;
}
/**
 * Scales the mat4 by the dimensions in the given vec3 not using vectorization
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the matrix to scale
 * @param {vec3} v the vec3 to scale the matrix by
 * @returns {mat4} out
 **/

function scale(out, a, v) {
  var x = v[0],
      y = v[1],
      z = v[2];
  out[0] = a[0] * x;
  out[1] = a[1] * x;
  out[2] = a[2] * x;
  out[3] = a[3] * x;
  out[4] = a[4] * y;
  out[5] = a[5] * y;
  out[6] = a[6] * y;
  out[7] = a[7] * y;
  out[8] = a[8] * z;
  out[9] = a[9] * z;
  out[10] = a[10] * z;
  out[11] = a[11] * z;
  out[12] = a[12];
  out[13] = a[13];
  out[14] = a[14];
  out[15] = a[15];
  return out;
}
/**
 * Rotates a mat4 by the given angle around the given axis
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @param {vec3} axis the axis to rotate around
 * @returns {mat4} out
 */

function rotate(out, a, rad, axis) {
  var x = axis[0],
      y = axis[1],
      z = axis[2];
  var len = Math.hypot(x, y, z);
  var s, c, t;
  var a00, a01, a02, a03;
  var a10, a11, a12, a13;
  var a20, a21, a22, a23;
  var b00, b01, b02;
  var b10, b11, b12;
  var b20, b21, b22;

  if (len < _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON) {
    return null;
  }

  len = 1 / len;
  x *= len;
  y *= len;
  z *= len;
  s = Math.sin(rad);
  c = Math.cos(rad);
  t = 1 - c;
  a00 = a[0];
  a01 = a[1];
  a02 = a[2];
  a03 = a[3];
  a10 = a[4];
  a11 = a[5];
  a12 = a[6];
  a13 = a[7];
  a20 = a[8];
  a21 = a[9];
  a22 = a[10];
  a23 = a[11]; // Construct the elements of the rotation matrix

  b00 = x * x * t + c;
  b01 = y * x * t + z * s;
  b02 = z * x * t - y * s;
  b10 = x * y * t - z * s;
  b11 = y * y * t + c;
  b12 = z * y * t + x * s;
  b20 = x * z * t + y * s;
  b21 = y * z * t - x * s;
  b22 = z * z * t + c; // Perform rotation-specific matrix multiplication

  out[0] = a00 * b00 + a10 * b01 + a20 * b02;
  out[1] = a01 * b00 + a11 * b01 + a21 * b02;
  out[2] = a02 * b00 + a12 * b01 + a22 * b02;
  out[3] = a03 * b00 + a13 * b01 + a23 * b02;
  out[4] = a00 * b10 + a10 * b11 + a20 * b12;
  out[5] = a01 * b10 + a11 * b11 + a21 * b12;
  out[6] = a02 * b10 + a12 * b11 + a22 * b12;
  out[7] = a03 * b10 + a13 * b11 + a23 * b12;
  out[8] = a00 * b20 + a10 * b21 + a20 * b22;
  out[9] = a01 * b20 + a11 * b21 + a21 * b22;
  out[10] = a02 * b20 + a12 * b21 + a22 * b22;
  out[11] = a03 * b20 + a13 * b21 + a23 * b22;

  if (a !== out) {
    // If the source and destination differ, copy the unchanged last row
    out[12] = a[12];
    out[13] = a[13];
    out[14] = a[14];
    out[15] = a[15];
  }

  return out;
}
/**
 * Rotates a matrix by the given angle around the X axis
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat4} out
 */

function rotateX(out, a, rad) {
  var s = Math.sin(rad);
  var c = Math.cos(rad);
  var a10 = a[4];
  var a11 = a[5];
  var a12 = a[6];
  var a13 = a[7];
  var a20 = a[8];
  var a21 = a[9];
  var a22 = a[10];
  var a23 = a[11];

  if (a !== out) {
    // If the source and destination differ, copy the unchanged rows
    out[0] = a[0];
    out[1] = a[1];
    out[2] = a[2];
    out[3] = a[3];
    out[12] = a[12];
    out[13] = a[13];
    out[14] = a[14];
    out[15] = a[15];
  } // Perform axis-specific matrix multiplication


  out[4] = a10 * c + a20 * s;
  out[5] = a11 * c + a21 * s;
  out[6] = a12 * c + a22 * s;
  out[7] = a13 * c + a23 * s;
  out[8] = a20 * c - a10 * s;
  out[9] = a21 * c - a11 * s;
  out[10] = a22 * c - a12 * s;
  out[11] = a23 * c - a13 * s;
  return out;
}
/**
 * Rotates a matrix by the given angle around the Y axis
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat4} out
 */

function rotateY(out, a, rad) {
  var s = Math.sin(rad);
  var c = Math.cos(rad);
  var a00 = a[0];
  var a01 = a[1];
  var a02 = a[2];
  var a03 = a[3];
  var a20 = a[8];
  var a21 = a[9];
  var a22 = a[10];
  var a23 = a[11];

  if (a !== out) {
    // If the source and destination differ, copy the unchanged rows
    out[4] = a[4];
    out[5] = a[5];
    out[6] = a[6];
    out[7] = a[7];
    out[12] = a[12];
    out[13] = a[13];
    out[14] = a[14];
    out[15] = a[15];
  } // Perform axis-specific matrix multiplication


  out[0] = a00 * c - a20 * s;
  out[1] = a01 * c - a21 * s;
  out[2] = a02 * c - a22 * s;
  out[3] = a03 * c - a23 * s;
  out[8] = a00 * s + a20 * c;
  out[9] = a01 * s + a21 * c;
  out[10] = a02 * s + a22 * c;
  out[11] = a03 * s + a23 * c;
  return out;
}
/**
 * Rotates a matrix by the given angle around the Z axis
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the matrix to rotate
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat4} out
 */

function rotateZ(out, a, rad) {
  var s = Math.sin(rad);
  var c = Math.cos(rad);
  var a00 = a[0];
  var a01 = a[1];
  var a02 = a[2];
  var a03 = a[3];
  var a10 = a[4];
  var a11 = a[5];
  var a12 = a[6];
  var a13 = a[7];

  if (a !== out) {
    // If the source and destination differ, copy the unchanged last row
    out[8] = a[8];
    out[9] = a[9];
    out[10] = a[10];
    out[11] = a[11];
    out[12] = a[12];
    out[13] = a[13];
    out[14] = a[14];
    out[15] = a[15];
  } // Perform axis-specific matrix multiplication


  out[0] = a00 * c + a10 * s;
  out[1] = a01 * c + a11 * s;
  out[2] = a02 * c + a12 * s;
  out[3] = a03 * c + a13 * s;
  out[4] = a10 * c - a00 * s;
  out[5] = a11 * c - a01 * s;
  out[6] = a12 * c - a02 * s;
  out[7] = a13 * c - a03 * s;
  return out;
}
/**
 * Creates a matrix from a vector translation
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.translate(dest, dest, vec);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {vec3} v Translation vector
 * @returns {mat4} out
 */

function fromTranslation(out, v) {
  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = 1;
  out[6] = 0;
  out[7] = 0;
  out[8] = 0;
  out[9] = 0;
  out[10] = 1;
  out[11] = 0;
  out[12] = v[0];
  out[13] = v[1];
  out[14] = v[2];
  out[15] = 1;
  return out;
}
/**
 * Creates a matrix from a vector scaling
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.scale(dest, dest, vec);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {vec3} v Scaling vector
 * @returns {mat4} out
 */

function fromScaling(out, v) {
  out[0] = v[0];
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = v[1];
  out[6] = 0;
  out[7] = 0;
  out[8] = 0;
  out[9] = 0;
  out[10] = v[2];
  out[11] = 0;
  out[12] = 0;
  out[13] = 0;
  out[14] = 0;
  out[15] = 1;
  return out;
}
/**
 * Creates a matrix from a given angle around a given axis
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.rotate(dest, dest, rad, axis);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {Number} rad the angle to rotate the matrix by
 * @param {vec3} axis the axis to rotate around
 * @returns {mat4} out
 */

function fromRotation(out, rad, axis) {
  var x = axis[0],
      y = axis[1],
      z = axis[2];
  var len = Math.hypot(x, y, z);
  var s, c, t;

  if (len < _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON) {
    return null;
  }

  len = 1 / len;
  x *= len;
  y *= len;
  z *= len;
  s = Math.sin(rad);
  c = Math.cos(rad);
  t = 1 - c; // Perform rotation-specific matrix multiplication

  out[0] = x * x * t + c;
  out[1] = y * x * t + z * s;
  out[2] = z * x * t - y * s;
  out[3] = 0;
  out[4] = x * y * t - z * s;
  out[5] = y * y * t + c;
  out[6] = z * y * t + x * s;
  out[7] = 0;
  out[8] = x * z * t + y * s;
  out[9] = y * z * t - x * s;
  out[10] = z * z * t + c;
  out[11] = 0;
  out[12] = 0;
  out[13] = 0;
  out[14] = 0;
  out[15] = 1;
  return out;
}
/**
 * Creates a matrix from the given angle around the X axis
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.rotateX(dest, dest, rad);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat4} out
 */

function fromXRotation(out, rad) {
  var s = Math.sin(rad);
  var c = Math.cos(rad); // Perform axis-specific matrix multiplication

  out[0] = 1;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = c;
  out[6] = s;
  out[7] = 0;
  out[8] = 0;
  out[9] = -s;
  out[10] = c;
  out[11] = 0;
  out[12] = 0;
  out[13] = 0;
  out[14] = 0;
  out[15] = 1;
  return out;
}
/**
 * Creates a matrix from the given angle around the Y axis
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.rotateY(dest, dest, rad);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat4} out
 */

function fromYRotation(out, rad) {
  var s = Math.sin(rad);
  var c = Math.cos(rad); // Perform axis-specific matrix multiplication

  out[0] = c;
  out[1] = 0;
  out[2] = -s;
  out[3] = 0;
  out[4] = 0;
  out[5] = 1;
  out[6] = 0;
  out[7] = 0;
  out[8] = s;
  out[9] = 0;
  out[10] = c;
  out[11] = 0;
  out[12] = 0;
  out[13] = 0;
  out[14] = 0;
  out[15] = 1;
  return out;
}
/**
 * Creates a matrix from the given angle around the Z axis
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.rotateZ(dest, dest, rad);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {Number} rad the angle to rotate the matrix by
 * @returns {mat4} out
 */

function fromZRotation(out, rad) {
  var s = Math.sin(rad);
  var c = Math.cos(rad); // Perform axis-specific matrix multiplication

  out[0] = c;
  out[1] = s;
  out[2] = 0;
  out[3] = 0;
  out[4] = -s;
  out[5] = c;
  out[6] = 0;
  out[7] = 0;
  out[8] = 0;
  out[9] = 0;
  out[10] = 1;
  out[11] = 0;
  out[12] = 0;
  out[13] = 0;
  out[14] = 0;
  out[15] = 1;
  return out;
}
/**
 * Creates a matrix from a quaternion rotation and vector translation
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.translate(dest, vec);
 *     let quatMat = mat4.create();
 *     quat4.toMat4(quat, quatMat);
 *     mat4.multiply(dest, quatMat);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {quat4} q Rotation quaternion
 * @param {vec3} v Translation vector
 * @returns {mat4} out
 */

function fromRotationTranslation(out, q, v) {
  // Quaternion math
  var x = q[0],
      y = q[1],
      z = q[2],
      w = q[3];
  var x2 = x + x;
  var y2 = y + y;
  var z2 = z + z;
  var xx = x * x2;
  var xy = x * y2;
  var xz = x * z2;
  var yy = y * y2;
  var yz = y * z2;
  var zz = z * z2;
  var wx = w * x2;
  var wy = w * y2;
  var wz = w * z2;
  out[0] = 1 - (yy + zz);
  out[1] = xy + wz;
  out[2] = xz - wy;
  out[3] = 0;
  out[4] = xy - wz;
  out[5] = 1 - (xx + zz);
  out[6] = yz + wx;
  out[7] = 0;
  out[8] = xz + wy;
  out[9] = yz - wx;
  out[10] = 1 - (xx + yy);
  out[11] = 0;
  out[12] = v[0];
  out[13] = v[1];
  out[14] = v[2];
  out[15] = 1;
  return out;
}
/**
 * Creates a new mat4 from a dual quat.
 *
 * @param {mat4} out Matrix
 * @param {quat2} a Dual Quaternion
 * @returns {mat4} mat4 receiving operation result
 */

function fromQuat2(out, a) {
  var translation = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(3);
  var bx = -a[0],
      by = -a[1],
      bz = -a[2],
      bw = a[3],
      ax = a[4],
      ay = a[5],
      az = a[6],
      aw = a[7];
  var magnitude = bx * bx + by * by + bz * bz + bw * bw; //Only scale if it makes sense

  if (magnitude > 0) {
    translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2 / magnitude;
    translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2 / magnitude;
    translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2 / magnitude;
  } else {
    translation[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2;
    translation[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2;
    translation[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2;
  }

  fromRotationTranslation(out, a, translation);
  return out;
}
/**
 * Returns the translation vector component of a transformation
 *  matrix. If a matrix is built with fromRotationTranslation,
 *  the returned vector will be the same as the translation vector
 *  originally supplied.
 * @param  {vec3} out Vector to receive translation component
 * @param  {mat4} mat Matrix to be decomposed (input)
 * @return {vec3} out
 */

function getTranslation(out, mat) {
  out[0] = mat[12];
  out[1] = mat[13];
  out[2] = mat[14];
  return out;
}
/**
 * Returns the scaling factor component of a transformation
 *  matrix. If a matrix is built with fromRotationTranslationScale
 *  with a normalized Quaternion paramter, the returned vector will be
 *  the same as the scaling vector
 *  originally supplied.
 * @param  {vec3} out Vector to receive scaling factor component
 * @param  {mat4} mat Matrix to be decomposed (input)
 * @return {vec3} out
 */

function getScaling(out, mat) {
  var m11 = mat[0];
  var m12 = mat[1];
  var m13 = mat[2];
  var m21 = mat[4];
  var m22 = mat[5];
  var m23 = mat[6];
  var m31 = mat[8];
  var m32 = mat[9];
  var m33 = mat[10];
  out[0] = Math.hypot(m11, m12, m13);
  out[1] = Math.hypot(m21, m22, m23);
  out[2] = Math.hypot(m31, m32, m33);
  return out;
}
/**
 * Returns a quaternion representing the rotational component
 *  of a transformation matrix. If a matrix is built with
 *  fromRotationTranslation, the returned quaternion will be the
 *  same as the quaternion originally supplied.
 * @param {quat} out Quaternion to receive the rotation component
 * @param {mat4} mat Matrix to be decomposed (input)
 * @return {quat} out
 */

function getRotation(out, mat) {
  var scaling = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(3);
  getScaling(scaling, mat);
  var is1 = 1 / scaling[0];
  var is2 = 1 / scaling[1];
  var is3 = 1 / scaling[2];
  var sm11 = mat[0] * is1;
  var sm12 = mat[1] * is2;
  var sm13 = mat[2] * is3;
  var sm21 = mat[4] * is1;
  var sm22 = mat[5] * is2;
  var sm23 = mat[6] * is3;
  var sm31 = mat[8] * is1;
  var sm32 = mat[9] * is2;
  var sm33 = mat[10] * is3;
  var trace = sm11 + sm22 + sm33;
  var S = 0;

  if (trace > 0) {
    S = Math.sqrt(trace + 1.0) * 2;
    out[3] = 0.25 * S;
    out[0] = (sm23 - sm32) / S;
    out[1] = (sm31 - sm13) / S;
    out[2] = (sm12 - sm21) / S;
  } else if (sm11 > sm22 && sm11 > sm33) {
    S = Math.sqrt(1.0 + sm11 - sm22 - sm33) * 2;
    out[3] = (sm23 - sm32) / S;
    out[0] = 0.25 * S;
    out[1] = (sm12 + sm21) / S;
    out[2] = (sm31 + sm13) / S;
  } else if (sm22 > sm33) {
    S = Math.sqrt(1.0 + sm22 - sm11 - sm33) * 2;
    out[3] = (sm31 - sm13) / S;
    out[0] = (sm12 + sm21) / S;
    out[1] = 0.25 * S;
    out[2] = (sm23 + sm32) / S;
  } else {
    S = Math.sqrt(1.0 + sm33 - sm11 - sm22) * 2;
    out[3] = (sm12 - sm21) / S;
    out[0] = (sm31 + sm13) / S;
    out[1] = (sm23 + sm32) / S;
    out[2] = 0.25 * S;
  }

  return out;
}
/**
 * Creates a matrix from a quaternion rotation, vector translation and vector scale
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.translate(dest, vec);
 *     let quatMat = mat4.create();
 *     quat4.toMat4(quat, quatMat);
 *     mat4.multiply(dest, quatMat);
 *     mat4.scale(dest, scale)
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {quat4} q Rotation quaternion
 * @param {vec3} v Translation vector
 * @param {vec3} s Scaling vector
 * @returns {mat4} out
 */

function fromRotationTranslationScale(out, q, v, s) {
  // Quaternion math
  var x = q[0],
      y = q[1],
      z = q[2],
      w = q[3];
  var x2 = x + x;
  var y2 = y + y;
  var z2 = z + z;
  var xx = x * x2;
  var xy = x * y2;
  var xz = x * z2;
  var yy = y * y2;
  var yz = y * z2;
  var zz = z * z2;
  var wx = w * x2;
  var wy = w * y2;
  var wz = w * z2;
  var sx = s[0];
  var sy = s[1];
  var sz = s[2];
  out[0] = (1 - (yy + zz)) * sx;
  out[1] = (xy + wz) * sx;
  out[2] = (xz - wy) * sx;
  out[3] = 0;
  out[4] = (xy - wz) * sy;
  out[5] = (1 - (xx + zz)) * sy;
  out[6] = (yz + wx) * sy;
  out[7] = 0;
  out[8] = (xz + wy) * sz;
  out[9] = (yz - wx) * sz;
  out[10] = (1 - (xx + yy)) * sz;
  out[11] = 0;
  out[12] = v[0];
  out[13] = v[1];
  out[14] = v[2];
  out[15] = 1;
  return out;
}
/**
 * Creates a matrix from a quaternion rotation, vector translation and vector scale, rotating and scaling around the given origin
 * This is equivalent to (but much faster than):
 *
 *     mat4.identity(dest);
 *     mat4.translate(dest, vec);
 *     mat4.translate(dest, origin);
 *     let quatMat = mat4.create();
 *     quat4.toMat4(quat, quatMat);
 *     mat4.multiply(dest, quatMat);
 *     mat4.scale(dest, scale)
 *     mat4.translate(dest, negativeOrigin);
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {quat4} q Rotation quaternion
 * @param {vec3} v Translation vector
 * @param {vec3} s Scaling vector
 * @param {vec3} o The origin vector around which to scale and rotate
 * @returns {mat4} out
 */

function fromRotationTranslationScaleOrigin(out, q, v, s, o) {
  // Quaternion math
  var x = q[0],
      y = q[1],
      z = q[2],
      w = q[3];
  var x2 = x + x;
  var y2 = y + y;
  var z2 = z + z;
  var xx = x * x2;
  var xy = x * y2;
  var xz = x * z2;
  var yy = y * y2;
  var yz = y * z2;
  var zz = z * z2;
  var wx = w * x2;
  var wy = w * y2;
  var wz = w * z2;
  var sx = s[0];
  var sy = s[1];
  var sz = s[2];
  var ox = o[0];
  var oy = o[1];
  var oz = o[2];
  var out0 = (1 - (yy + zz)) * sx;
  var out1 = (xy + wz) * sx;
  var out2 = (xz - wy) * sx;
  var out4 = (xy - wz) * sy;
  var out5 = (1 - (xx + zz)) * sy;
  var out6 = (yz + wx) * sy;
  var out8 = (xz + wy) * sz;
  var out9 = (yz - wx) * sz;
  var out10 = (1 - (xx + yy)) * sz;
  out[0] = out0;
  out[1] = out1;
  out[2] = out2;
  out[3] = 0;
  out[4] = out4;
  out[5] = out5;
  out[6] = out6;
  out[7] = 0;
  out[8] = out8;
  out[9] = out9;
  out[10] = out10;
  out[11] = 0;
  out[12] = v[0] + ox - (out0 * ox + out4 * oy + out8 * oz);
  out[13] = v[1] + oy - (out1 * ox + out5 * oy + out9 * oz);
  out[14] = v[2] + oz - (out2 * ox + out6 * oy + out10 * oz);
  out[15] = 1;
  return out;
}
/**
 * Calculates a 4x4 matrix from the given quaternion
 *
 * @param {mat4} out mat4 receiving operation result
 * @param {quat} q Quaternion to create matrix from
 *
 * @returns {mat4} out
 */

function fromQuat(out, q) {
  var x = q[0],
      y = q[1],
      z = q[2],
      w = q[3];
  var x2 = x + x;
  var y2 = y + y;
  var z2 = z + z;
  var xx = x * x2;
  var yx = y * x2;
  var yy = y * y2;
  var zx = z * x2;
  var zy = z * y2;
  var zz = z * z2;
  var wx = w * x2;
  var wy = w * y2;
  var wz = w * z2;
  out[0] = 1 - yy - zz;
  out[1] = yx + wz;
  out[2] = zx - wy;
  out[3] = 0;
  out[4] = yx - wz;
  out[5] = 1 - xx - zz;
  out[6] = zy + wx;
  out[7] = 0;
  out[8] = zx + wy;
  out[9] = zy - wx;
  out[10] = 1 - xx - yy;
  out[11] = 0;
  out[12] = 0;
  out[13] = 0;
  out[14] = 0;
  out[15] = 1;
  return out;
}
/**
 * Generates a frustum matrix with the given bounds
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {Number} left Left bound of the frustum
 * @param {Number} right Right bound of the frustum
 * @param {Number} bottom Bottom bound of the frustum
 * @param {Number} top Top bound of the frustum
 * @param {Number} near Near bound of the frustum
 * @param {Number} far Far bound of the frustum
 * @returns {mat4} out
 */

function frustum(out, left, right, bottom, top, near, far) {
  var rl = 1 / (right - left);
  var tb = 1 / (top - bottom);
  var nf = 1 / (near - far);
  out[0] = near * 2 * rl;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = near * 2 * tb;
  out[6] = 0;
  out[7] = 0;
  out[8] = (right + left) * rl;
  out[9] = (top + bottom) * tb;
  out[10] = (far + near) * nf;
  out[11] = -1;
  out[12] = 0;
  out[13] = 0;
  out[14] = far * near * 2 * nf;
  out[15] = 0;
  return out;
}
/**
 * Generates a perspective projection matrix with the given bounds.
 * Passing null/undefined/no value for far will generate infinite projection matrix.
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {number} fovy Vertical field of view in radians
 * @param {number} aspect Aspect ratio. typically viewport width/height
 * @param {number} near Near bound of the frustum
 * @param {number} far Far bound of the frustum, can be null or Infinity
 * @returns {mat4} out
 */

function perspective(out, fovy, aspect, near, far) {
  var f = 1.0 / Math.tan(fovy / 2),
      nf;
  out[0] = f / aspect;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = f;
  out[6] = 0;
  out[7] = 0;
  out[8] = 0;
  out[9] = 0;
  out[11] = -1;
  out[12] = 0;
  out[13] = 0;
  out[15] = 0;

  if (far != null && far !== Infinity) {
    nf = 1 / (near - far);
    out[10] = (far + near) * nf;
    out[14] = 2 * far * near * nf;
  } else {
    out[10] = -1;
    out[14] = -2 * near;
  }

  return out;
}
/**
 * Generates a perspective projection matrix with the given field of view.
 * This is primarily useful for generating projection matrices to be used
 * with the still experiemental WebVR API.
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {Object} fov Object containing the following values: upDegrees, downDegrees, leftDegrees, rightDegrees
 * @param {number} near Near bound of the frustum
 * @param {number} far Far bound of the frustum
 * @returns {mat4} out
 */

function perspectiveFromFieldOfView(out, fov, near, far) {
  var upTan = Math.tan(fov.upDegrees * Math.PI / 180.0);
  var downTan = Math.tan(fov.downDegrees * Math.PI / 180.0);
  var leftTan = Math.tan(fov.leftDegrees * Math.PI / 180.0);
  var rightTan = Math.tan(fov.rightDegrees * Math.PI / 180.0);
  var xScale = 2.0 / (leftTan + rightTan);
  var yScale = 2.0 / (upTan + downTan);
  out[0] = xScale;
  out[1] = 0.0;
  out[2] = 0.0;
  out[3] = 0.0;
  out[4] = 0.0;
  out[5] = yScale;
  out[6] = 0.0;
  out[7] = 0.0;
  out[8] = -((leftTan - rightTan) * xScale * 0.5);
  out[9] = (upTan - downTan) * yScale * 0.5;
  out[10] = far / (near - far);
  out[11] = -1.0;
  out[12] = 0.0;
  out[13] = 0.0;
  out[14] = far * near / (near - far);
  out[15] = 0.0;
  return out;
}
/**
 * Generates a orthogonal projection matrix with the given bounds
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {number} left Left bound of the frustum
 * @param {number} right Right bound of the frustum
 * @param {number} bottom Bottom bound of the frustum
 * @param {number} top Top bound of the frustum
 * @param {number} near Near bound of the frustum
 * @param {number} far Far bound of the frustum
 * @returns {mat4} out
 */

function ortho(out, left, right, bottom, top, near, far) {
  var lr = 1 / (left - right);
  var bt = 1 / (bottom - top);
  var nf = 1 / (near - far);
  out[0] = -2 * lr;
  out[1] = 0;
  out[2] = 0;
  out[3] = 0;
  out[4] = 0;
  out[5] = -2 * bt;
  out[6] = 0;
  out[7] = 0;
  out[8] = 0;
  out[9] = 0;
  out[10] = 2 * nf;
  out[11] = 0;
  out[12] = (left + right) * lr;
  out[13] = (top + bottom) * bt;
  out[14] = (far + near) * nf;
  out[15] = 1;
  return out;
}
/**
 * Generates a look-at matrix with the given eye position, focal point, and up axis.
 * If you want a matrix that actually makes an object look at another object, you should use targetTo instead.
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {vec3} eye Position of the viewer
 * @param {vec3} center Point the viewer is looking at
 * @param {vec3} up vec3 pointing up
 * @returns {mat4} out
 */

function lookAt(out, eye, center, up) {
  var x0, x1, x2, y0, y1, y2, z0, z1, z2, len;
  var eyex = eye[0];
  var eyey = eye[1];
  var eyez = eye[2];
  var upx = up[0];
  var upy = up[1];
  var upz = up[2];
  var centerx = center[0];
  var centery = center[1];
  var centerz = center[2];

  if (Math.abs(eyex - centerx) < _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON && Math.abs(eyey - centery) < _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON && Math.abs(eyez - centerz) < _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON) {
    return identity(out);
  }

  z0 = eyex - centerx;
  z1 = eyey - centery;
  z2 = eyez - centerz;
  len = 1 / Math.hypot(z0, z1, z2);
  z0 *= len;
  z1 *= len;
  z2 *= len;
  x0 = upy * z2 - upz * z1;
  x1 = upz * z0 - upx * z2;
  x2 = upx * z1 - upy * z0;
  len = Math.hypot(x0, x1, x2);

  if (!len) {
    x0 = 0;
    x1 = 0;
    x2 = 0;
  } else {
    len = 1 / len;
    x0 *= len;
    x1 *= len;
    x2 *= len;
  }

  y0 = z1 * x2 - z2 * x1;
  y1 = z2 * x0 - z0 * x2;
  y2 = z0 * x1 - z1 * x0;
  len = Math.hypot(y0, y1, y2);

  if (!len) {
    y0 = 0;
    y1 = 0;
    y2 = 0;
  } else {
    len = 1 / len;
    y0 *= len;
    y1 *= len;
    y2 *= len;
  }

  out[0] = x0;
  out[1] = y0;
  out[2] = z0;
  out[3] = 0;
  out[4] = x1;
  out[5] = y1;
  out[6] = z1;
  out[7] = 0;
  out[8] = x2;
  out[9] = y2;
  out[10] = z2;
  out[11] = 0;
  out[12] = -(x0 * eyex + x1 * eyey + x2 * eyez);
  out[13] = -(y0 * eyex + y1 * eyey + y2 * eyez);
  out[14] = -(z0 * eyex + z1 * eyey + z2 * eyez);
  out[15] = 1;
  return out;
}
/**
 * Generates a matrix that makes something look at something else.
 *
 * @param {mat4} out mat4 frustum matrix will be written into
 * @param {vec3} eye Position of the viewer
 * @param {vec3} center Point the viewer is looking at
 * @param {vec3} up vec3 pointing up
 * @returns {mat4} out
 */

function targetTo(out, eye, target, up) {
  var eyex = eye[0],
      eyey = eye[1],
      eyez = eye[2],
      upx = up[0],
      upy = up[1],
      upz = up[2];
  var z0 = eyex - target[0],
      z1 = eyey - target[1],
      z2 = eyez - target[2];
  var len = z0 * z0 + z1 * z1 + z2 * z2;

  if (len > 0) {
    len = 1 / Math.sqrt(len);
    z0 *= len;
    z1 *= len;
    z2 *= len;
  }

  var x0 = upy * z2 - upz * z1,
      x1 = upz * z0 - upx * z2,
      x2 = upx * z1 - upy * z0;
  len = x0 * x0 + x1 * x1 + x2 * x2;

  if (len > 0) {
    len = 1 / Math.sqrt(len);
    x0 *= len;
    x1 *= len;
    x2 *= len;
  }

  out[0] = x0;
  out[1] = x1;
  out[2] = x2;
  out[3] = 0;
  out[4] = z1 * x2 - z2 * x1;
  out[5] = z2 * x0 - z0 * x2;
  out[6] = z0 * x1 - z1 * x0;
  out[7] = 0;
  out[8] = z0;
  out[9] = z1;
  out[10] = z2;
  out[11] = 0;
  out[12] = eyex;
  out[13] = eyey;
  out[14] = eyez;
  out[15] = 1;
  return out;
}
;
/**
 * Returns a string representation of a mat4
 *
 * @param {mat4} a matrix to represent as a string
 * @returns {String} string representation of the matrix
 */

function str(a) {
  return 'mat4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ', ' + a[8] + ', ' + a[9] + ', ' + a[10] + ', ' + a[11] + ', ' + a[12] + ', ' + a[13] + ', ' + a[14] + ', ' + a[15] + ')';
}
/**
 * Returns Frobenius norm of a mat4
 *
 * @param {mat4} a the matrix to calculate Frobenius norm of
 * @returns {Number} Frobenius norm
 */

function frob(a) {
  return Math.hypot(a[0], a[1], a[3], a[4], a[5], a[6], a[7], a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15]);
}
/**
 * Adds two mat4's
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the first operand
 * @param {mat4} b the second operand
 * @returns {mat4} out
 */

function add(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  out[2] = a[2] + b[2];
  out[3] = a[3] + b[3];
  out[4] = a[4] + b[4];
  out[5] = a[5] + b[5];
  out[6] = a[6] + b[6];
  out[7] = a[7] + b[7];
  out[8] = a[8] + b[8];
  out[9] = a[9] + b[9];
  out[10] = a[10] + b[10];
  out[11] = a[11] + b[11];
  out[12] = a[12] + b[12];
  out[13] = a[13] + b[13];
  out[14] = a[14] + b[14];
  out[15] = a[15] + b[15];
  return out;
}
/**
 * Subtracts matrix b from matrix a
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the first operand
 * @param {mat4} b the second operand
 * @returns {mat4} out
 */

function subtract(out, a, b) {
  out[0] = a[0] - b[0];
  out[1] = a[1] - b[1];
  out[2] = a[2] - b[2];
  out[3] = a[3] - b[3];
  out[4] = a[4] - b[4];
  out[5] = a[5] - b[5];
  out[6] = a[6] - b[6];
  out[7] = a[7] - b[7];
  out[8] = a[8] - b[8];
  out[9] = a[9] - b[9];
  out[10] = a[10] - b[10];
  out[11] = a[11] - b[11];
  out[12] = a[12] - b[12];
  out[13] = a[13] - b[13];
  out[14] = a[14] - b[14];
  out[15] = a[15] - b[15];
  return out;
}
/**
 * Multiply each element of the matrix by a scalar.
 *
 * @param {mat4} out the receiving matrix
 * @param {mat4} a the matrix to scale
 * @param {Number} b amount to scale the matrix's elements by
 * @returns {mat4} out
 */

function multiplyScalar(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  out[2] = a[2] * b;
  out[3] = a[3] * b;
  out[4] = a[4] * b;
  out[5] = a[5] * b;
  out[6] = a[6] * b;
  out[7] = a[7] * b;
  out[8] = a[8] * b;
  out[9] = a[9] * b;
  out[10] = a[10] * b;
  out[11] = a[11] * b;
  out[12] = a[12] * b;
  out[13] = a[13] * b;
  out[14] = a[14] * b;
  out[15] = a[15] * b;
  return out;
}
/**
 * Adds two mat4's after multiplying each element of the second operand by a scalar value.
 *
 * @param {mat4} out the receiving vector
 * @param {mat4} a the first operand
 * @param {mat4} b the second operand
 * @param {Number} scale the amount to scale b's elements by before adding
 * @returns {mat4} out
 */

function multiplyScalarAndAdd(out, a, b, scale) {
  out[0] = a[0] + b[0] * scale;
  out[1] = a[1] + b[1] * scale;
  out[2] = a[2] + b[2] * scale;
  out[3] = a[3] + b[3] * scale;
  out[4] = a[4] + b[4] * scale;
  out[5] = a[5] + b[5] * scale;
  out[6] = a[6] + b[6] * scale;
  out[7] = a[7] + b[7] * scale;
  out[8] = a[8] + b[8] * scale;
  out[9] = a[9] + b[9] * scale;
  out[10] = a[10] + b[10] * scale;
  out[11] = a[11] + b[11] * scale;
  out[12] = a[12] + b[12] * scale;
  out[13] = a[13] + b[13] * scale;
  out[14] = a[14] + b[14] * scale;
  out[15] = a[15] + b[15] * scale;
  return out;
}
/**
 * Returns whether or not the matrices have exactly the same elements in the same position (when compared with ===)
 *
 * @param {mat4} a The first matrix.
 * @param {mat4} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function exactEquals(a, b) {
  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7] && a[8] === b[8] && a[9] === b[9] && a[10] === b[10] && a[11] === b[11] && a[12] === b[12] && a[13] === b[13] && a[14] === b[14] && a[15] === b[15];
}
/**
 * Returns whether or not the matrices have approximately the same elements in the same position.
 *
 * @param {mat4} a The first matrix.
 * @param {mat4} b The second matrix.
 * @returns {Boolean} True if the matrices are equal, false otherwise.
 */

function equals(a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3];
  var a4 = a[4],
      a5 = a[5],
      a6 = a[6],
      a7 = a[7];
  var a8 = a[8],
      a9 = a[9],
      a10 = a[10],
      a11 = a[11];
  var a12 = a[12],
      a13 = a[13],
      a14 = a[14],
      a15 = a[15];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3];
  var b4 = b[4],
      b5 = b[5],
      b6 = b[6],
      b7 = b[7];
  var b8 = b[8],
      b9 = b[9],
      b10 = b[10],
      b11 = b[11];
  var b12 = b[12],
      b13 = b[13],
      b14 = b[14],
      b15 = b[15];
  return Math.abs(a0 - b0) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7)) && Math.abs(a8 - b8) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a8), Math.abs(b8)) && Math.abs(a9 - b9) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a9), Math.abs(b9)) && Math.abs(a10 - b10) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a10), Math.abs(b10)) && Math.abs(a11 - b11) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a11), Math.abs(b11)) && Math.abs(a12 - b12) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a12), Math.abs(b12)) && Math.abs(a13 - b13) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a13), Math.abs(b13)) && Math.abs(a14 - b14) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a14), Math.abs(b14)) && Math.abs(a15 - b15) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a15), Math.abs(b15));
}
/**
 * Alias for {@link mat4.multiply}
 * @function
 */

var mul = multiply;
/**
 * Alias for {@link mat4.subtract}
 * @function
 */

var sub = subtract;

/***/ }),

/***/ 221:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   add: () => (/* binding */ add),
/* harmony export */   calculateW: () => (/* binding */ calculateW),
/* harmony export */   clone: () => (/* binding */ clone),
/* harmony export */   conjugate: () => (/* binding */ conjugate),
/* harmony export */   copy: () => (/* binding */ copy),
/* harmony export */   create: () => (/* binding */ create),
/* harmony export */   dot: () => (/* binding */ dot),
/* harmony export */   equals: () => (/* binding */ equals),
/* harmony export */   exactEquals: () => (/* binding */ exactEquals),
/* harmony export */   exp: () => (/* binding */ exp),
/* harmony export */   fromEuler: () => (/* binding */ fromEuler),
/* harmony export */   fromMat3: () => (/* binding */ fromMat3),
/* harmony export */   fromValues: () => (/* binding */ fromValues),
/* harmony export */   getAngle: () => (/* binding */ getAngle),
/* harmony export */   getAxisAngle: () => (/* binding */ getAxisAngle),
/* harmony export */   identity: () => (/* binding */ identity),
/* harmony export */   invert: () => (/* binding */ invert),
/* harmony export */   len: () => (/* binding */ len),
/* harmony export */   length: () => (/* binding */ length),
/* harmony export */   lerp: () => (/* binding */ lerp),
/* harmony export */   ln: () => (/* binding */ ln),
/* harmony export */   mul: () => (/* binding */ mul),
/* harmony export */   multiply: () => (/* binding */ multiply),
/* harmony export */   normalize: () => (/* binding */ normalize),
/* harmony export */   pow: () => (/* binding */ pow),
/* harmony export */   random: () => (/* binding */ random),
/* harmony export */   rotateX: () => (/* binding */ rotateX),
/* harmony export */   rotateY: () => (/* binding */ rotateY),
/* harmony export */   rotateZ: () => (/* binding */ rotateZ),
/* harmony export */   rotationTo: () => (/* binding */ rotationTo),
/* harmony export */   scale: () => (/* binding */ scale),
/* harmony export */   set: () => (/* binding */ set),
/* harmony export */   setAxes: () => (/* binding */ setAxes),
/* harmony export */   setAxisAngle: () => (/* binding */ setAxisAngle),
/* harmony export */   slerp: () => (/* binding */ slerp),
/* harmony export */   sqlerp: () => (/* binding */ sqlerp),
/* harmony export */   sqrLen: () => (/* binding */ sqrLen),
/* harmony export */   squaredLength: () => (/* binding */ squaredLength),
/* harmony export */   str: () => (/* binding */ str)
/* harmony export */ });
/* harmony import */ var _common_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(823);
/* harmony import */ var _mat3_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(409);
/* harmony import */ var _vec3_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(329);
/* harmony import */ var _vec4_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(796);




/**
 * Quaternion
 * @module quat
 */

/**
 * Creates a new identity quat
 *
 * @returns {quat} a new quaternion
 */

function create() {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(4);

  if (_common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE != Float32Array) {
    out[0] = 0;
    out[1] = 0;
    out[2] = 0;
  }

  out[3] = 1;
  return out;
}
/**
 * Set a quat to the identity quaternion
 *
 * @param {quat} out the receiving quaternion
 * @returns {quat} out
 */

function identity(out) {
  out[0] = 0;
  out[1] = 0;
  out[2] = 0;
  out[3] = 1;
  return out;
}
/**
 * Sets a quat from the given angle and rotation axis,
 * then returns it.
 *
 * @param {quat} out the receiving quaternion
 * @param {vec3} axis the axis around which to rotate
 * @param {Number} rad the angle in radians
 * @returns {quat} out
 **/

function setAxisAngle(out, axis, rad) {
  rad = rad * 0.5;
  var s = Math.sin(rad);
  out[0] = s * axis[0];
  out[1] = s * axis[1];
  out[2] = s * axis[2];
  out[3] = Math.cos(rad);
  return out;
}
/**
 * Gets the rotation axis and angle for a given
 *  quaternion. If a quaternion is created with
 *  setAxisAngle, this method will return the same
 *  values as providied in the original parameter list
 *  OR functionally equivalent values.
 * Example: The quaternion formed by axis [0, 0, 1] and
 *  angle -90 is the same as the quaternion formed by
 *  [0, 0, 1] and 270. This method favors the latter.
 * @param  {vec3} out_axis  Vector receiving the axis of rotation
 * @param  {quat} q     Quaternion to be decomposed
 * @return {Number}     Angle, in radians, of the rotation
 */

function getAxisAngle(out_axis, q) {
  var rad = Math.acos(q[3]) * 2.0;
  var s = Math.sin(rad / 2.0);

  if (s > _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON) {
    out_axis[0] = q[0] / s;
    out_axis[1] = q[1] / s;
    out_axis[2] = q[2] / s;
  } else {
    // If s is zero, return any axis (no rotation - axis does not matter)
    out_axis[0] = 1;
    out_axis[1] = 0;
    out_axis[2] = 0;
  }

  return rad;
}
/**
 * Gets the angular distance between two unit quaternions
 *
 * @param  {quat} a     Origin unit quaternion 
 * @param  {quat} b     Destination unit quaternion
 * @return {Number}     Angle, in radians, between the two quaternions
 */

function getAngle(a, b) {
  var dotproduct = dot(a, b);
  return Math.acos(2 * dotproduct * dotproduct - 1);
}
/**
 * Multiplies two quat's
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a the first operand
 * @param {quat} b the second operand
 * @returns {quat} out
 */

function multiply(out, a, b) {
  var ax = a[0],
      ay = a[1],
      az = a[2],
      aw = a[3];
  var bx = b[0],
      by = b[1],
      bz = b[2],
      bw = b[3];
  out[0] = ax * bw + aw * bx + ay * bz - az * by;
  out[1] = ay * bw + aw * by + az * bx - ax * bz;
  out[2] = az * bw + aw * bz + ax * by - ay * bx;
  out[3] = aw * bw - ax * bx - ay * by - az * bz;
  return out;
}
/**
 * Rotates a quaternion by the given angle about the X axis
 *
 * @param {quat} out quat receiving operation result
 * @param {quat} a quat to rotate
 * @param {number} rad angle (in radians) to rotate
 * @returns {quat} out
 */

function rotateX(out, a, rad) {
  rad *= 0.5;
  var ax = a[0],
      ay = a[1],
      az = a[2],
      aw = a[3];
  var bx = Math.sin(rad),
      bw = Math.cos(rad);
  out[0] = ax * bw + aw * bx;
  out[1] = ay * bw + az * bx;
  out[2] = az * bw - ay * bx;
  out[3] = aw * bw - ax * bx;
  return out;
}
/**
 * Rotates a quaternion by the given angle about the Y axis
 *
 * @param {quat} out quat receiving operation result
 * @param {quat} a quat to rotate
 * @param {number} rad angle (in radians) to rotate
 * @returns {quat} out
 */

function rotateY(out, a, rad) {
  rad *= 0.5;
  var ax = a[0],
      ay = a[1],
      az = a[2],
      aw = a[3];
  var by = Math.sin(rad),
      bw = Math.cos(rad);
  out[0] = ax * bw - az * by;
  out[1] = ay * bw + aw * by;
  out[2] = az * bw + ax * by;
  out[3] = aw * bw - ay * by;
  return out;
}
/**
 * Rotates a quaternion by the given angle about the Z axis
 *
 * @param {quat} out quat receiving operation result
 * @param {quat} a quat to rotate
 * @param {number} rad angle (in radians) to rotate
 * @returns {quat} out
 */

function rotateZ(out, a, rad) {
  rad *= 0.5;
  var ax = a[0],
      ay = a[1],
      az = a[2],
      aw = a[3];
  var bz = Math.sin(rad),
      bw = Math.cos(rad);
  out[0] = ax * bw + ay * bz;
  out[1] = ay * bw - ax * bz;
  out[2] = az * bw + aw * bz;
  out[3] = aw * bw - az * bz;
  return out;
}
/**
 * Calculates the W component of a quat from the X, Y, and Z components.
 * Assumes that quaternion is 1 unit in length.
 * Any existing W component will be ignored.
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a quat to calculate W component of
 * @returns {quat} out
 */

function calculateW(out, a) {
  var x = a[0],
      y = a[1],
      z = a[2];
  out[0] = x;
  out[1] = y;
  out[2] = z;
  out[3] = Math.sqrt(Math.abs(1.0 - x * x - y * y - z * z));
  return out;
}
/**
 * Calculate the exponential of a unit quaternion.
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a quat to calculate the exponential of
 * @returns {quat} out
 */

function exp(out, a) {
  var x = a[0],
      y = a[1],
      z = a[2],
      w = a[3];
  var r = Math.sqrt(x * x + y * y + z * z);
  var et = Math.exp(w);
  var s = r > 0 ? et * Math.sin(r) / r : 0;
  out[0] = x * s;
  out[1] = y * s;
  out[2] = z * s;
  out[3] = et * Math.cos(r);
  return out;
}
/**
 * Calculate the natural logarithm of a unit quaternion.
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a quat to calculate the exponential of
 * @returns {quat} out
 */

function ln(out, a) {
  var x = a[0],
      y = a[1],
      z = a[2],
      w = a[3];
  var r = Math.sqrt(x * x + y * y + z * z);
  var t = r > 0 ? Math.atan2(r, w) / r : 0;
  out[0] = x * t;
  out[1] = y * t;
  out[2] = z * t;
  out[3] = 0.5 * Math.log(x * x + y * y + z * z + w * w);
  return out;
}
/**
 * Calculate the scalar power of a unit quaternion.
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a quat to calculate the exponential of
 * @param {Number} b amount to scale the quaternion by
 * @returns {quat} out
 */

function pow(out, a, b) {
  ln(out, a);
  scale(out, out, b);
  exp(out, out);
  return out;
}
/**
 * Performs a spherical linear interpolation between two quat
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a the first operand
 * @param {quat} b the second operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {quat} out
 */

function slerp(out, a, b, t) {
  // benchmarks:
  //    http://jsperf.com/quaternion-slerp-implementations
  var ax = a[0],
      ay = a[1],
      az = a[2],
      aw = a[3];
  var bx = b[0],
      by = b[1],
      bz = b[2],
      bw = b[3];
  var omega, cosom, sinom, scale0, scale1; // calc cosine

  cosom = ax * bx + ay * by + az * bz + aw * bw; // adjust signs (if necessary)

  if (cosom < 0.0) {
    cosom = -cosom;
    bx = -bx;
    by = -by;
    bz = -bz;
    bw = -bw;
  } // calculate coefficients


  if (1.0 - cosom > _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON) {
    // standard case (slerp)
    omega = Math.acos(cosom);
    sinom = Math.sin(omega);
    scale0 = Math.sin((1.0 - t) * omega) / sinom;
    scale1 = Math.sin(t * omega) / sinom;
  } else {
    // "from" and "to" quaternions are very close
    //  ... so we can do a linear interpolation
    scale0 = 1.0 - t;
    scale1 = t;
  } // calculate final values


  out[0] = scale0 * ax + scale1 * bx;
  out[1] = scale0 * ay + scale1 * by;
  out[2] = scale0 * az + scale1 * bz;
  out[3] = scale0 * aw + scale1 * bw;
  return out;
}
/**
 * Generates a random unit quaternion
 * 
 * @param {quat} out the receiving quaternion
 * @returns {quat} out
 */

function random(out) {
  // Implementation of http://planning.cs.uiuc.edu/node198.html
  // TODO: Calling random 3 times is probably not the fastest solution
  var u1 = _common_js__WEBPACK_IMPORTED_MODULE_0__.RANDOM();
  var u2 = _common_js__WEBPACK_IMPORTED_MODULE_0__.RANDOM();
  var u3 = _common_js__WEBPACK_IMPORTED_MODULE_0__.RANDOM();
  var sqrt1MinusU1 = Math.sqrt(1 - u1);
  var sqrtU1 = Math.sqrt(u1);
  out[0] = sqrt1MinusU1 * Math.sin(2.0 * Math.PI * u2);
  out[1] = sqrt1MinusU1 * Math.cos(2.0 * Math.PI * u2);
  out[2] = sqrtU1 * Math.sin(2.0 * Math.PI * u3);
  out[3] = sqrtU1 * Math.cos(2.0 * Math.PI * u3);
  return out;
}
/**
 * Calculates the inverse of a quat
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a quat to calculate inverse of
 * @returns {quat} out
 */

function invert(out, a) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3];
  var dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;
  var invDot = dot ? 1.0 / dot : 0; // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0

  out[0] = -a0 * invDot;
  out[1] = -a1 * invDot;
  out[2] = -a2 * invDot;
  out[3] = a3 * invDot;
  return out;
}
/**
 * Calculates the conjugate of a quat
 * If the quaternion is normalized, this function is faster than quat.inverse and produces the same result.
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a quat to calculate conjugate of
 * @returns {quat} out
 */

function conjugate(out, a) {
  out[0] = -a[0];
  out[1] = -a[1];
  out[2] = -a[2];
  out[3] = a[3];
  return out;
}
/**
 * Creates a quaternion from the given 3x3 rotation matrix.
 *
 * NOTE: The resultant quaternion is not normalized, so you should be sure
 * to renormalize the quaternion yourself where necessary.
 *
 * @param {quat} out the receiving quaternion
 * @param {mat3} m rotation matrix
 * @returns {quat} out
 * @function
 */

function fromMat3(out, m) {
  // Algorithm in Ken Shoemake's article in 1987 SIGGRAPH course notes
  // article "Quaternion Calculus and Fast Animation".
  var fTrace = m[0] + m[4] + m[8];
  var fRoot;

  if (fTrace > 0.0) {
    // |w| > 1/2, may as well choose w > 1/2
    fRoot = Math.sqrt(fTrace + 1.0); // 2w

    out[3] = 0.5 * fRoot;
    fRoot = 0.5 / fRoot; // 1/(4w)

    out[0] = (m[5] - m[7]) * fRoot;
    out[1] = (m[6] - m[2]) * fRoot;
    out[2] = (m[1] - m[3]) * fRoot;
  } else {
    // |w| <= 1/2
    var i = 0;
    if (m[4] > m[0]) i = 1;
    if (m[8] > m[i * 3 + i]) i = 2;
    var j = (i + 1) % 3;
    var k = (i + 2) % 3;
    fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0);
    out[i] = 0.5 * fRoot;
    fRoot = 0.5 / fRoot;
    out[3] = (m[j * 3 + k] - m[k * 3 + j]) * fRoot;
    out[j] = (m[j * 3 + i] + m[i * 3 + j]) * fRoot;
    out[k] = (m[k * 3 + i] + m[i * 3 + k]) * fRoot;
  }

  return out;
}
/**
 * Creates a quaternion from the given euler angle x, y, z.
 *
 * @param {quat} out the receiving quaternion
 * @param {x} Angle to rotate around X axis in degrees.
 * @param {y} Angle to rotate around Y axis in degrees.
 * @param {z} Angle to rotate around Z axis in degrees.
 * @returns {quat} out
 * @function
 */

function fromEuler(out, x, y, z) {
  var halfToRad = 0.5 * Math.PI / 180.0;
  x *= halfToRad;
  y *= halfToRad;
  z *= halfToRad;
  var sx = Math.sin(x);
  var cx = Math.cos(x);
  var sy = Math.sin(y);
  var cy = Math.cos(y);
  var sz = Math.sin(z);
  var cz = Math.cos(z);
  out[0] = sx * cy * cz - cx * sy * sz;
  out[1] = cx * sy * cz + sx * cy * sz;
  out[2] = cx * cy * sz - sx * sy * cz;
  out[3] = cx * cy * cz + sx * sy * sz;
  return out;
}
/**
 * Returns a string representation of a quatenion
 *
 * @param {quat} a vector to represent as a string
 * @returns {String} string representation of the vector
 */

function str(a) {
  return 'quat(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
}
/**
 * Creates a new quat initialized with values from an existing quaternion
 *
 * @param {quat} a quaternion to clone
 * @returns {quat} a new quaternion
 * @function
 */

var clone = _vec4_js__WEBPACK_IMPORTED_MODULE_1__.clone;
/**
 * Creates a new quat initialized with the given values
 *
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @param {Number} w W component
 * @returns {quat} a new quaternion
 * @function
 */

var fromValues = _vec4_js__WEBPACK_IMPORTED_MODULE_1__.fromValues;
/**
 * Copy the values from one quat to another
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a the source quaternion
 * @returns {quat} out
 * @function
 */

var copy = _vec4_js__WEBPACK_IMPORTED_MODULE_1__.copy;
/**
 * Set the components of a quat to the given values
 *
 * @param {quat} out the receiving quaternion
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @param {Number} w W component
 * @returns {quat} out
 * @function
 */

var set = _vec4_js__WEBPACK_IMPORTED_MODULE_1__.set;
/**
 * Adds two quat's
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a the first operand
 * @param {quat} b the second operand
 * @returns {quat} out
 * @function
 */

var add = _vec4_js__WEBPACK_IMPORTED_MODULE_1__.add;
/**
 * Alias for {@link quat.multiply}
 * @function
 */

var mul = multiply;
/**
 * Scales a quat by a scalar number
 *
 * @param {quat} out the receiving vector
 * @param {quat} a the vector to scale
 * @param {Number} b amount to scale the vector by
 * @returns {quat} out
 * @function
 */

var scale = _vec4_js__WEBPACK_IMPORTED_MODULE_1__.scale;
/**
 * Calculates the dot product of two quat's
 *
 * @param {quat} a the first operand
 * @param {quat} b the second operand
 * @returns {Number} dot product of a and b
 * @function
 */

var dot = _vec4_js__WEBPACK_IMPORTED_MODULE_1__.dot;
/**
 * Performs a linear interpolation between two quat's
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a the first operand
 * @param {quat} b the second operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {quat} out
 * @function
 */

var lerp = _vec4_js__WEBPACK_IMPORTED_MODULE_1__.lerp;
/**
 * Calculates the length of a quat
 *
 * @param {quat} a vector to calculate length of
 * @returns {Number} length of a
 */

var length = _vec4_js__WEBPACK_IMPORTED_MODULE_1__.length;
/**
 * Alias for {@link quat.length}
 * @function
 */

var len = length;
/**
 * Calculates the squared length of a quat
 *
 * @param {quat} a vector to calculate squared length of
 * @returns {Number} squared length of a
 * @function
 */

var squaredLength = _vec4_js__WEBPACK_IMPORTED_MODULE_1__.squaredLength;
/**
 * Alias for {@link quat.squaredLength}
 * @function
 */

var sqrLen = squaredLength;
/**
 * Normalize a quat
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a quaternion to normalize
 * @returns {quat} out
 * @function
 */

var normalize = _vec4_js__WEBPACK_IMPORTED_MODULE_1__.normalize;
/**
 * Returns whether or not the quaternions have exactly the same elements in the same position (when compared with ===)
 *
 * @param {quat} a The first quaternion.
 * @param {quat} b The second quaternion.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

var exactEquals = _vec4_js__WEBPACK_IMPORTED_MODULE_1__.exactEquals;
/**
 * Returns whether or not the quaternions have approximately the same elements in the same position.
 *
 * @param {quat} a The first vector.
 * @param {quat} b The second vector.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

var equals = _vec4_js__WEBPACK_IMPORTED_MODULE_1__.equals;
/**
 * Sets a quaternion to represent the shortest rotation from one
 * vector to another.
 *
 * Both vectors are assumed to be unit length.
 *
 * @param {quat} out the receiving quaternion.
 * @param {vec3} a the initial vector
 * @param {vec3} b the destination vector
 * @returns {quat} out
 */

var rotationTo = function () {
  var tmpvec3 = _vec3_js__WEBPACK_IMPORTED_MODULE_2__.create();
  var xUnitVec3 = _vec3_js__WEBPACK_IMPORTED_MODULE_2__.fromValues(1, 0, 0);
  var yUnitVec3 = _vec3_js__WEBPACK_IMPORTED_MODULE_2__.fromValues(0, 1, 0);
  return function (out, a, b) {
    var dot = _vec3_js__WEBPACK_IMPORTED_MODULE_2__.dot(a, b);

    if (dot < -0.999999) {
      _vec3_js__WEBPACK_IMPORTED_MODULE_2__.cross(tmpvec3, xUnitVec3, a);
      if (_vec3_js__WEBPACK_IMPORTED_MODULE_2__.len(tmpvec3) < 0.000001) _vec3_js__WEBPACK_IMPORTED_MODULE_2__.cross(tmpvec3, yUnitVec3, a);
      _vec3_js__WEBPACK_IMPORTED_MODULE_2__.normalize(tmpvec3, tmpvec3);
      setAxisAngle(out, tmpvec3, Math.PI);
      return out;
    } else if (dot > 0.999999) {
      out[0] = 0;
      out[1] = 0;
      out[2] = 0;
      out[3] = 1;
      return out;
    } else {
      _vec3_js__WEBPACK_IMPORTED_MODULE_2__.cross(tmpvec3, a, b);
      out[0] = tmpvec3[0];
      out[1] = tmpvec3[1];
      out[2] = tmpvec3[2];
      out[3] = 1 + dot;
      return normalize(out, out);
    }
  };
}();
/**
 * Performs a spherical linear interpolation with two control points
 *
 * @param {quat} out the receiving quaternion
 * @param {quat} a the first operand
 * @param {quat} b the second operand
 * @param {quat} c the third operand
 * @param {quat} d the fourth operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {quat} out
 */

var sqlerp = function () {
  var temp1 = create();
  var temp2 = create();
  return function (out, a, b, c, d, t) {
    slerp(temp1, a, d, t);
    slerp(temp2, b, c, t);
    slerp(out, temp1, temp2, 2 * t * (1 - t));
    return out;
  };
}();
/**
 * Sets the specified quaternion with values corresponding to the given
 * axes. Each axis is a vec3 and is expected to be unit length and
 * perpendicular to all other specified axes.
 *
 * @param {vec3} view  the vector representing the viewing direction
 * @param {vec3} right the vector representing the local "right" direction
 * @param {vec3} up    the vector representing the local "up" direction
 * @returns {quat} out
 */

var setAxes = function () {
  var matr = _mat3_js__WEBPACK_IMPORTED_MODULE_3__.create();
  return function (out, view, right, up) {
    matr[0] = right[0];
    matr[3] = right[1];
    matr[6] = right[2];
    matr[1] = up[0];
    matr[4] = up[1];
    matr[7] = up[2];
    matr[2] = -view[0];
    matr[5] = -view[1];
    matr[8] = -view[2];
    return normalize(out, fromMat3(out, matr));
  };
}();

/***/ }),

/***/ 991:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   add: () => (/* binding */ add),
/* harmony export */   clone: () => (/* binding */ clone),
/* harmony export */   conjugate: () => (/* binding */ conjugate),
/* harmony export */   copy: () => (/* binding */ copy),
/* harmony export */   create: () => (/* binding */ create),
/* harmony export */   dot: () => (/* binding */ dot),
/* harmony export */   equals: () => (/* binding */ equals),
/* harmony export */   exactEquals: () => (/* binding */ exactEquals),
/* harmony export */   fromMat4: () => (/* binding */ fromMat4),
/* harmony export */   fromRotation: () => (/* binding */ fromRotation),
/* harmony export */   fromRotationTranslation: () => (/* binding */ fromRotationTranslation),
/* harmony export */   fromRotationTranslationValues: () => (/* binding */ fromRotationTranslationValues),
/* harmony export */   fromTranslation: () => (/* binding */ fromTranslation),
/* harmony export */   fromValues: () => (/* binding */ fromValues),
/* harmony export */   getDual: () => (/* binding */ getDual),
/* harmony export */   getReal: () => (/* binding */ getReal),
/* harmony export */   getTranslation: () => (/* binding */ getTranslation),
/* harmony export */   identity: () => (/* binding */ identity),
/* harmony export */   invert: () => (/* binding */ invert),
/* harmony export */   len: () => (/* binding */ len),
/* harmony export */   length: () => (/* binding */ length),
/* harmony export */   lerp: () => (/* binding */ lerp),
/* harmony export */   mul: () => (/* binding */ mul),
/* harmony export */   multiply: () => (/* binding */ multiply),
/* harmony export */   normalize: () => (/* binding */ normalize),
/* harmony export */   rotateAroundAxis: () => (/* binding */ rotateAroundAxis),
/* harmony export */   rotateByQuatAppend: () => (/* binding */ rotateByQuatAppend),
/* harmony export */   rotateByQuatPrepend: () => (/* binding */ rotateByQuatPrepend),
/* harmony export */   rotateX: () => (/* binding */ rotateX),
/* harmony export */   rotateY: () => (/* binding */ rotateY),
/* harmony export */   rotateZ: () => (/* binding */ rotateZ),
/* harmony export */   scale: () => (/* binding */ scale),
/* harmony export */   set: () => (/* binding */ set),
/* harmony export */   setDual: () => (/* binding */ setDual),
/* harmony export */   setReal: () => (/* binding */ setReal),
/* harmony export */   sqrLen: () => (/* binding */ sqrLen),
/* harmony export */   squaredLength: () => (/* binding */ squaredLength),
/* harmony export */   str: () => (/* binding */ str),
/* harmony export */   translate: () => (/* binding */ translate)
/* harmony export */ });
/* harmony import */ var _common_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(823);
/* harmony import */ var _quat_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(221);
/* harmony import */ var _mat4_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(684);



/**
 * Dual Quaternion<br>
 * Format: [real, dual]<br>
 * Quaternion format: XYZW<br>
 * Make sure to have normalized dual quaternions, otherwise the functions may not work as intended.<br>
 * @module quat2
 */

/**
 * Creates a new identity dual quat
 *
 * @returns {quat2} a new dual quaternion [real -> rotation, dual -> translation]
 */

function create() {
  var dq = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(8);

  if (_common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE != Float32Array) {
    dq[0] = 0;
    dq[1] = 0;
    dq[2] = 0;
    dq[4] = 0;
    dq[5] = 0;
    dq[6] = 0;
    dq[7] = 0;
  }

  dq[3] = 1;
  return dq;
}
/**
 * Creates a new quat initialized with values from an existing quaternion
 *
 * @param {quat2} a dual quaternion to clone
 * @returns {quat2} new dual quaternion
 * @function
 */

function clone(a) {
  var dq = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(8);
  dq[0] = a[0];
  dq[1] = a[1];
  dq[2] = a[2];
  dq[3] = a[3];
  dq[4] = a[4];
  dq[5] = a[5];
  dq[6] = a[6];
  dq[7] = a[7];
  return dq;
}
/**
 * Creates a new dual quat initialized with the given values
 *
 * @param {Number} x1 X component
 * @param {Number} y1 Y component
 * @param {Number} z1 Z component
 * @param {Number} w1 W component
 * @param {Number} x2 X component
 * @param {Number} y2 Y component
 * @param {Number} z2 Z component
 * @param {Number} w2 W component
 * @returns {quat2} new dual quaternion
 * @function
 */

function fromValues(x1, y1, z1, w1, x2, y2, z2, w2) {
  var dq = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(8);
  dq[0] = x1;
  dq[1] = y1;
  dq[2] = z1;
  dq[3] = w1;
  dq[4] = x2;
  dq[5] = y2;
  dq[6] = z2;
  dq[7] = w2;
  return dq;
}
/**
 * Creates a new dual quat from the given values (quat and translation)
 *
 * @param {Number} x1 X component
 * @param {Number} y1 Y component
 * @param {Number} z1 Z component
 * @param {Number} w1 W component
 * @param {Number} x2 X component (translation)
 * @param {Number} y2 Y component (translation)
 * @param {Number} z2 Z component (translation)
 * @returns {quat2} new dual quaternion
 * @function
 */

function fromRotationTranslationValues(x1, y1, z1, w1, x2, y2, z2) {
  var dq = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(8);
  dq[0] = x1;
  dq[1] = y1;
  dq[2] = z1;
  dq[3] = w1;
  var ax = x2 * 0.5,
      ay = y2 * 0.5,
      az = z2 * 0.5;
  dq[4] = ax * w1 + ay * z1 - az * y1;
  dq[5] = ay * w1 + az * x1 - ax * z1;
  dq[6] = az * w1 + ax * y1 - ay * x1;
  dq[7] = -ax * x1 - ay * y1 - az * z1;
  return dq;
}
/**
 * Creates a dual quat from a quaternion and a translation
 *
 * @param {quat2} dual quaternion receiving operation result
 * @param {quat} q a normalized quaternion
 * @param {vec3} t tranlation vector
 * @returns {quat2} dual quaternion receiving operation result
 * @function
 */

function fromRotationTranslation(out, q, t) {
  var ax = t[0] * 0.5,
      ay = t[1] * 0.5,
      az = t[2] * 0.5,
      bx = q[0],
      by = q[1],
      bz = q[2],
      bw = q[3];
  out[0] = bx;
  out[1] = by;
  out[2] = bz;
  out[3] = bw;
  out[4] = ax * bw + ay * bz - az * by;
  out[5] = ay * bw + az * bx - ax * bz;
  out[6] = az * bw + ax * by - ay * bx;
  out[7] = -ax * bx - ay * by - az * bz;
  return out;
}
/**
 * Creates a dual quat from a translation
 *
 * @param {quat2} dual quaternion receiving operation result
 * @param {vec3} t translation vector
 * @returns {quat2} dual quaternion receiving operation result
 * @function
 */

function fromTranslation(out, t) {
  out[0] = 0;
  out[1] = 0;
  out[2] = 0;
  out[3] = 1;
  out[4] = t[0] * 0.5;
  out[5] = t[1] * 0.5;
  out[6] = t[2] * 0.5;
  out[7] = 0;
  return out;
}
/**
 * Creates a dual quat from a quaternion
 *
 * @param {quat2} dual quaternion receiving operation result
 * @param {quat} q the quaternion
 * @returns {quat2} dual quaternion receiving operation result
 * @function
 */

function fromRotation(out, q) {
  out[0] = q[0];
  out[1] = q[1];
  out[2] = q[2];
  out[3] = q[3];
  out[4] = 0;
  out[5] = 0;
  out[6] = 0;
  out[7] = 0;
  return out;
}
/**
 * Creates a new dual quat from a matrix (4x4)
 *
 * @param {quat2} out the dual quaternion
 * @param {mat4} a the matrix
 * @returns {quat2} dual quat receiving operation result
 * @function
 */

function fromMat4(out, a) {
  //TODO Optimize this
  var outer = _quat_js__WEBPACK_IMPORTED_MODULE_1__.create();
  _mat4_js__WEBPACK_IMPORTED_MODULE_2__.getRotation(outer, a);
  var t = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(3);
  _mat4_js__WEBPACK_IMPORTED_MODULE_2__.getTranslation(t, a);
  fromRotationTranslation(out, outer, t);
  return out;
}
/**
 * Copy the values from one dual quat to another
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {quat2} a the source dual quaternion
 * @returns {quat2} out
 * @function
 */

function copy(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  out[4] = a[4];
  out[5] = a[5];
  out[6] = a[6];
  out[7] = a[7];
  return out;
}
/**
 * Set a dual quat to the identity dual quaternion
 *
 * @param {quat2} out the receiving quaternion
 * @returns {quat2} out
 */

function identity(out) {
  out[0] = 0;
  out[1] = 0;
  out[2] = 0;
  out[3] = 1;
  out[4] = 0;
  out[5] = 0;
  out[6] = 0;
  out[7] = 0;
  return out;
}
/**
 * Set the components of a dual quat to the given values
 *
 * @param {quat2} out the receiving quaternion
 * @param {Number} x1 X component
 * @param {Number} y1 Y component
 * @param {Number} z1 Z component
 * @param {Number} w1 W component
 * @param {Number} x2 X component
 * @param {Number} y2 Y component
 * @param {Number} z2 Z component
 * @param {Number} w2 W component
 * @returns {quat2} out
 * @function
 */

function set(out, x1, y1, z1, w1, x2, y2, z2, w2) {
  out[0] = x1;
  out[1] = y1;
  out[2] = z1;
  out[3] = w1;
  out[4] = x2;
  out[5] = y2;
  out[6] = z2;
  out[7] = w2;
  return out;
}
/**
 * Gets the real part of a dual quat
 * @param  {quat} out real part
 * @param  {quat2} a Dual Quaternion
 * @return {quat} real part
 */

var getReal = _quat_js__WEBPACK_IMPORTED_MODULE_1__.copy;
/**
 * Gets the dual part of a dual quat
 * @param  {quat} out dual part
 * @param  {quat2} a Dual Quaternion
 * @return {quat} dual part
 */

function getDual(out, a) {
  out[0] = a[4];
  out[1] = a[5];
  out[2] = a[6];
  out[3] = a[7];
  return out;
}
/**
 * Set the real component of a dual quat to the given quaternion
 *
 * @param {quat2} out the receiving quaternion
 * @param {quat} q a quaternion representing the real part
 * @returns {quat2} out
 * @function
 */

var setReal = _quat_js__WEBPACK_IMPORTED_MODULE_1__.copy;
/**
 * Set the dual component of a dual quat to the given quaternion
 *
 * @param {quat2} out the receiving quaternion
 * @param {quat} q a quaternion representing the dual part
 * @returns {quat2} out
 * @function
 */

function setDual(out, q) {
  out[4] = q[0];
  out[5] = q[1];
  out[6] = q[2];
  out[7] = q[3];
  return out;
}
/**
 * Gets the translation of a normalized dual quat
 * @param  {vec3} out translation
 * @param  {quat2} a Dual Quaternion to be decomposed
 * @return {vec3} translation
 */

function getTranslation(out, a) {
  var ax = a[4],
      ay = a[5],
      az = a[6],
      aw = a[7],
      bx = -a[0],
      by = -a[1],
      bz = -a[2],
      bw = a[3];
  out[0] = (ax * bw + aw * bx + ay * bz - az * by) * 2;
  out[1] = (ay * bw + aw * by + az * bx - ax * bz) * 2;
  out[2] = (az * bw + aw * bz + ax * by - ay * bx) * 2;
  return out;
}
/**
 * Translates a dual quat by the given vector
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {quat2} a the dual quaternion to translate
 * @param {vec3} v vector to translate by
 * @returns {quat2} out
 */

function translate(out, a, v) {
  var ax1 = a[0],
      ay1 = a[1],
      az1 = a[2],
      aw1 = a[3],
      bx1 = v[0] * 0.5,
      by1 = v[1] * 0.5,
      bz1 = v[2] * 0.5,
      ax2 = a[4],
      ay2 = a[5],
      az2 = a[6],
      aw2 = a[7];
  out[0] = ax1;
  out[1] = ay1;
  out[2] = az1;
  out[3] = aw1;
  out[4] = aw1 * bx1 + ay1 * bz1 - az1 * by1 + ax2;
  out[5] = aw1 * by1 + az1 * bx1 - ax1 * bz1 + ay2;
  out[6] = aw1 * bz1 + ax1 * by1 - ay1 * bx1 + az2;
  out[7] = -ax1 * bx1 - ay1 * by1 - az1 * bz1 + aw2;
  return out;
}
/**
 * Rotates a dual quat around the X axis
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {quat2} a the dual quaternion to rotate
 * @param {number} rad how far should the rotation be
 * @returns {quat2} out
 */

function rotateX(out, a, rad) {
  var bx = -a[0],
      by = -a[1],
      bz = -a[2],
      bw = a[3],
      ax = a[4],
      ay = a[5],
      az = a[6],
      aw = a[7],
      ax1 = ax * bw + aw * bx + ay * bz - az * by,
      ay1 = ay * bw + aw * by + az * bx - ax * bz,
      az1 = az * bw + aw * bz + ax * by - ay * bx,
      aw1 = aw * bw - ax * bx - ay * by - az * bz;
  _quat_js__WEBPACK_IMPORTED_MODULE_1__.rotateX(out, a, rad);
  bx = out[0];
  by = out[1];
  bz = out[2];
  bw = out[3];
  out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
  out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
  out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
  out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
  return out;
}
/**
 * Rotates a dual quat around the Y axis
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {quat2} a the dual quaternion to rotate
 * @param {number} rad how far should the rotation be
 * @returns {quat2} out
 */

function rotateY(out, a, rad) {
  var bx = -a[0],
      by = -a[1],
      bz = -a[2],
      bw = a[3],
      ax = a[4],
      ay = a[5],
      az = a[6],
      aw = a[7],
      ax1 = ax * bw + aw * bx + ay * bz - az * by,
      ay1 = ay * bw + aw * by + az * bx - ax * bz,
      az1 = az * bw + aw * bz + ax * by - ay * bx,
      aw1 = aw * bw - ax * bx - ay * by - az * bz;
  _quat_js__WEBPACK_IMPORTED_MODULE_1__.rotateY(out, a, rad);
  bx = out[0];
  by = out[1];
  bz = out[2];
  bw = out[3];
  out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
  out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
  out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
  out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
  return out;
}
/**
 * Rotates a dual quat around the Z axis
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {quat2} a the dual quaternion to rotate
 * @param {number} rad how far should the rotation be
 * @returns {quat2} out
 */

function rotateZ(out, a, rad) {
  var bx = -a[0],
      by = -a[1],
      bz = -a[2],
      bw = a[3],
      ax = a[4],
      ay = a[5],
      az = a[6],
      aw = a[7],
      ax1 = ax * bw + aw * bx + ay * bz - az * by,
      ay1 = ay * bw + aw * by + az * bx - ax * bz,
      az1 = az * bw + aw * bz + ax * by - ay * bx,
      aw1 = aw * bw - ax * bx - ay * by - az * bz;
  _quat_js__WEBPACK_IMPORTED_MODULE_1__.rotateZ(out, a, rad);
  bx = out[0];
  by = out[1];
  bz = out[2];
  bw = out[3];
  out[4] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
  out[5] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
  out[6] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
  out[7] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
  return out;
}
/**
 * Rotates a dual quat by a given quaternion (a * q)
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {quat2} a the dual quaternion to rotate
 * @param {quat} q quaternion to rotate by
 * @returns {quat2} out
 */

function rotateByQuatAppend(out, a, q) {
  var qx = q[0],
      qy = q[1],
      qz = q[2],
      qw = q[3],
      ax = a[0],
      ay = a[1],
      az = a[2],
      aw = a[3];
  out[0] = ax * qw + aw * qx + ay * qz - az * qy;
  out[1] = ay * qw + aw * qy + az * qx - ax * qz;
  out[2] = az * qw + aw * qz + ax * qy - ay * qx;
  out[3] = aw * qw - ax * qx - ay * qy - az * qz;
  ax = a[4];
  ay = a[5];
  az = a[6];
  aw = a[7];
  out[4] = ax * qw + aw * qx + ay * qz - az * qy;
  out[5] = ay * qw + aw * qy + az * qx - ax * qz;
  out[6] = az * qw + aw * qz + ax * qy - ay * qx;
  out[7] = aw * qw - ax * qx - ay * qy - az * qz;
  return out;
}
/**
 * Rotates a dual quat by a given quaternion (q * a)
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {quat} q quaternion to rotate by
 * @param {quat2} a the dual quaternion to rotate
 * @returns {quat2} out
 */

function rotateByQuatPrepend(out, q, a) {
  var qx = q[0],
      qy = q[1],
      qz = q[2],
      qw = q[3],
      bx = a[0],
      by = a[1],
      bz = a[2],
      bw = a[3];
  out[0] = qx * bw + qw * bx + qy * bz - qz * by;
  out[1] = qy * bw + qw * by + qz * bx - qx * bz;
  out[2] = qz * bw + qw * bz + qx * by - qy * bx;
  out[3] = qw * bw - qx * bx - qy * by - qz * bz;
  bx = a[4];
  by = a[5];
  bz = a[6];
  bw = a[7];
  out[4] = qx * bw + qw * bx + qy * bz - qz * by;
  out[5] = qy * bw + qw * by + qz * bx - qx * bz;
  out[6] = qz * bw + qw * bz + qx * by - qy * bx;
  out[7] = qw * bw - qx * bx - qy * by - qz * bz;
  return out;
}
/**
 * Rotates a dual quat around a given axis. Does the normalisation automatically
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {quat2} a the dual quaternion to rotate
 * @param {vec3} axis the axis to rotate around
 * @param {Number} rad how far the rotation should be
 * @returns {quat2} out
 */

function rotateAroundAxis(out, a, axis, rad) {
  //Special case for rad = 0
  if (Math.abs(rad) < _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON) {
    return copy(out, a);
  }

  var axisLength = Math.hypot(axis[0], axis[1], axis[2]);
  rad = rad * 0.5;
  var s = Math.sin(rad);
  var bx = s * axis[0] / axisLength;
  var by = s * axis[1] / axisLength;
  var bz = s * axis[2] / axisLength;
  var bw = Math.cos(rad);
  var ax1 = a[0],
      ay1 = a[1],
      az1 = a[2],
      aw1 = a[3];
  out[0] = ax1 * bw + aw1 * bx + ay1 * bz - az1 * by;
  out[1] = ay1 * bw + aw1 * by + az1 * bx - ax1 * bz;
  out[2] = az1 * bw + aw1 * bz + ax1 * by - ay1 * bx;
  out[3] = aw1 * bw - ax1 * bx - ay1 * by - az1 * bz;
  var ax = a[4],
      ay = a[5],
      az = a[6],
      aw = a[7];
  out[4] = ax * bw + aw * bx + ay * bz - az * by;
  out[5] = ay * bw + aw * by + az * bx - ax * bz;
  out[6] = az * bw + aw * bz + ax * by - ay * bx;
  out[7] = aw * bw - ax * bx - ay * by - az * bz;
  return out;
}
/**
 * Adds two dual quat's
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {quat2} a the first operand
 * @param {quat2} b the second operand
 * @returns {quat2} out
 * @function
 */

function add(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  out[2] = a[2] + b[2];
  out[3] = a[3] + b[3];
  out[4] = a[4] + b[4];
  out[5] = a[5] + b[5];
  out[6] = a[6] + b[6];
  out[7] = a[7] + b[7];
  return out;
}
/**
 * Multiplies two dual quat's
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {quat2} a the first operand
 * @param {quat2} b the second operand
 * @returns {quat2} out
 */

function multiply(out, a, b) {
  var ax0 = a[0],
      ay0 = a[1],
      az0 = a[2],
      aw0 = a[3],
      bx1 = b[4],
      by1 = b[5],
      bz1 = b[6],
      bw1 = b[7],
      ax1 = a[4],
      ay1 = a[5],
      az1 = a[6],
      aw1 = a[7],
      bx0 = b[0],
      by0 = b[1],
      bz0 = b[2],
      bw0 = b[3];
  out[0] = ax0 * bw0 + aw0 * bx0 + ay0 * bz0 - az0 * by0;
  out[1] = ay0 * bw0 + aw0 * by0 + az0 * bx0 - ax0 * bz0;
  out[2] = az0 * bw0 + aw0 * bz0 + ax0 * by0 - ay0 * bx0;
  out[3] = aw0 * bw0 - ax0 * bx0 - ay0 * by0 - az0 * bz0;
  out[4] = ax0 * bw1 + aw0 * bx1 + ay0 * bz1 - az0 * by1 + ax1 * bw0 + aw1 * bx0 + ay1 * bz0 - az1 * by0;
  out[5] = ay0 * bw1 + aw0 * by1 + az0 * bx1 - ax0 * bz1 + ay1 * bw0 + aw1 * by0 + az1 * bx0 - ax1 * bz0;
  out[6] = az0 * bw1 + aw0 * bz1 + ax0 * by1 - ay0 * bx1 + az1 * bw0 + aw1 * bz0 + ax1 * by0 - ay1 * bx0;
  out[7] = aw0 * bw1 - ax0 * bx1 - ay0 * by1 - az0 * bz1 + aw1 * bw0 - ax1 * bx0 - ay1 * by0 - az1 * bz0;
  return out;
}
/**
 * Alias for {@link quat2.multiply}
 * @function
 */

var mul = multiply;
/**
 * Scales a dual quat by a scalar number
 *
 * @param {quat2} out the receiving dual quat
 * @param {quat2} a the dual quat to scale
 * @param {Number} b amount to scale the dual quat by
 * @returns {quat2} out
 * @function
 */

function scale(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  out[2] = a[2] * b;
  out[3] = a[3] * b;
  out[4] = a[4] * b;
  out[5] = a[5] * b;
  out[6] = a[6] * b;
  out[7] = a[7] * b;
  return out;
}
/**
 * Calculates the dot product of two dual quat's (The dot product of the real parts)
 *
 * @param {quat2} a the first operand
 * @param {quat2} b the second operand
 * @returns {Number} dot product of a and b
 * @function
 */

var dot = _quat_js__WEBPACK_IMPORTED_MODULE_1__.dot;
/**
 * Performs a linear interpolation between two dual quats's
 * NOTE: The resulting dual quaternions won't always be normalized (The error is most noticeable when t = 0.5)
 *
 * @param {quat2} out the receiving dual quat
 * @param {quat2} a the first operand
 * @param {quat2} b the second operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {quat2} out
 */

function lerp(out, a, b, t) {
  var mt = 1 - t;
  if (dot(a, b) < 0) t = -t;
  out[0] = a[0] * mt + b[0] * t;
  out[1] = a[1] * mt + b[1] * t;
  out[2] = a[2] * mt + b[2] * t;
  out[3] = a[3] * mt + b[3] * t;
  out[4] = a[4] * mt + b[4] * t;
  out[5] = a[5] * mt + b[5] * t;
  out[6] = a[6] * mt + b[6] * t;
  out[7] = a[7] * mt + b[7] * t;
  return out;
}
/**
 * Calculates the inverse of a dual quat. If they are normalized, conjugate is cheaper
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {quat2} a dual quat to calculate inverse of
 * @returns {quat2} out
 */

function invert(out, a) {
  var sqlen = squaredLength(a);
  out[0] = -a[0] / sqlen;
  out[1] = -a[1] / sqlen;
  out[2] = -a[2] / sqlen;
  out[3] = a[3] / sqlen;
  out[4] = -a[4] / sqlen;
  out[5] = -a[5] / sqlen;
  out[6] = -a[6] / sqlen;
  out[7] = a[7] / sqlen;
  return out;
}
/**
 * Calculates the conjugate of a dual quat
 * If the dual quaternion is normalized, this function is faster than quat2.inverse and produces the same result.
 *
 * @param {quat2} out the receiving quaternion
 * @param {quat2} a quat to calculate conjugate of
 * @returns {quat2} out
 */

function conjugate(out, a) {
  out[0] = -a[0];
  out[1] = -a[1];
  out[2] = -a[2];
  out[3] = a[3];
  out[4] = -a[4];
  out[5] = -a[5];
  out[6] = -a[6];
  out[7] = a[7];
  return out;
}
/**
 * Calculates the length of a dual quat
 *
 * @param {quat2} a dual quat to calculate length of
 * @returns {Number} length of a
 * @function
 */

var length = _quat_js__WEBPACK_IMPORTED_MODULE_1__.length;
/**
 * Alias for {@link quat2.length}
 * @function
 */

var len = length;
/**
 * Calculates the squared length of a dual quat
 *
 * @param {quat2} a dual quat to calculate squared length of
 * @returns {Number} squared length of a
 * @function
 */

var squaredLength = _quat_js__WEBPACK_IMPORTED_MODULE_1__.squaredLength;
/**
 * Alias for {@link quat2.squaredLength}
 * @function
 */

var sqrLen = squaredLength;
/**
 * Normalize a dual quat
 *
 * @param {quat2} out the receiving dual quaternion
 * @param {quat2} a dual quaternion to normalize
 * @returns {quat2} out
 * @function
 */

function normalize(out, a) {
  var magnitude = squaredLength(a);

  if (magnitude > 0) {
    magnitude = Math.sqrt(magnitude);
    var a0 = a[0] / magnitude;
    var a1 = a[1] / magnitude;
    var a2 = a[2] / magnitude;
    var a3 = a[3] / magnitude;
    var b0 = a[4];
    var b1 = a[5];
    var b2 = a[6];
    var b3 = a[7];
    var a_dot_b = a0 * b0 + a1 * b1 + a2 * b2 + a3 * b3;
    out[0] = a0;
    out[1] = a1;
    out[2] = a2;
    out[3] = a3;
    out[4] = (b0 - a0 * a_dot_b) / magnitude;
    out[5] = (b1 - a1 * a_dot_b) / magnitude;
    out[6] = (b2 - a2 * a_dot_b) / magnitude;
    out[7] = (b3 - a3 * a_dot_b) / magnitude;
  }

  return out;
}
/**
 * Returns a string representation of a dual quatenion
 *
 * @param {quat2} a dual quaternion to represent as a string
 * @returns {String} string representation of the dual quat
 */

function str(a) {
  return 'quat2(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ', ' + a[4] + ', ' + a[5] + ', ' + a[6] + ', ' + a[7] + ')';
}
/**
 * Returns whether or not the dual quaternions have exactly the same elements in the same position (when compared with ===)
 *
 * @param {quat2} a the first dual quaternion.
 * @param {quat2} b the second dual quaternion.
 * @returns {Boolean} true if the dual quaternions are equal, false otherwise.
 */

function exactEquals(a, b) {
  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3] && a[4] === b[4] && a[5] === b[5] && a[6] === b[6] && a[7] === b[7];
}
/**
 * Returns whether or not the dual quaternions have approximately the same elements in the same position.
 *
 * @param {quat2} a the first dual quat.
 * @param {quat2} b the second dual quat.
 * @returns {Boolean} true if the dual quats are equal, false otherwise.
 */

function equals(a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3],
      a4 = a[4],
      a5 = a[5],
      a6 = a[6],
      a7 = a[7];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3],
      b4 = b[4],
      b5 = b[5],
      b6 = b[6],
      b7 = b[7];
  return Math.abs(a0 - b0) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3)) && Math.abs(a4 - b4) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a4), Math.abs(b4)) && Math.abs(a5 - b5) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a5), Math.abs(b5)) && Math.abs(a6 - b6) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a6), Math.abs(b6)) && Math.abs(a7 - b7) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a7), Math.abs(b7));
}

/***/ }),

/***/ 842:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   add: () => (/* binding */ add),
/* harmony export */   angle: () => (/* binding */ angle),
/* harmony export */   ceil: () => (/* binding */ ceil),
/* harmony export */   clone: () => (/* binding */ clone),
/* harmony export */   copy: () => (/* binding */ copy),
/* harmony export */   create: () => (/* binding */ create),
/* harmony export */   cross: () => (/* binding */ cross),
/* harmony export */   dist: () => (/* binding */ dist),
/* harmony export */   distance: () => (/* binding */ distance),
/* harmony export */   div: () => (/* binding */ div),
/* harmony export */   divide: () => (/* binding */ divide),
/* harmony export */   dot: () => (/* binding */ dot),
/* harmony export */   equals: () => (/* binding */ equals),
/* harmony export */   exactEquals: () => (/* binding */ exactEquals),
/* harmony export */   floor: () => (/* binding */ floor),
/* harmony export */   forEach: () => (/* binding */ forEach),
/* harmony export */   fromValues: () => (/* binding */ fromValues),
/* harmony export */   inverse: () => (/* binding */ inverse),
/* harmony export */   len: () => (/* binding */ len),
/* harmony export */   length: () => (/* binding */ length),
/* harmony export */   lerp: () => (/* binding */ lerp),
/* harmony export */   max: () => (/* binding */ max),
/* harmony export */   min: () => (/* binding */ min),
/* harmony export */   mul: () => (/* binding */ mul),
/* harmony export */   multiply: () => (/* binding */ multiply),
/* harmony export */   negate: () => (/* binding */ negate),
/* harmony export */   normalize: () => (/* binding */ normalize),
/* harmony export */   random: () => (/* binding */ random),
/* harmony export */   rotate: () => (/* binding */ rotate),
/* harmony export */   round: () => (/* binding */ round),
/* harmony export */   scale: () => (/* binding */ scale),
/* harmony export */   scaleAndAdd: () => (/* binding */ scaleAndAdd),
/* harmony export */   set: () => (/* binding */ set),
/* harmony export */   sqrDist: () => (/* binding */ sqrDist),
/* harmony export */   sqrLen: () => (/* binding */ sqrLen),
/* harmony export */   squaredDistance: () => (/* binding */ squaredDistance),
/* harmony export */   squaredLength: () => (/* binding */ squaredLength),
/* harmony export */   str: () => (/* binding */ str),
/* harmony export */   sub: () => (/* binding */ sub),
/* harmony export */   subtract: () => (/* binding */ subtract),
/* harmony export */   transformMat2: () => (/* binding */ transformMat2),
/* harmony export */   transformMat2d: () => (/* binding */ transformMat2d),
/* harmony export */   transformMat3: () => (/* binding */ transformMat3),
/* harmony export */   transformMat4: () => (/* binding */ transformMat4),
/* harmony export */   zero: () => (/* binding */ zero)
/* harmony export */ });
/* harmony import */ var _common_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(823);

/**
 * 2 Dimensional Vector
 * @module vec2
 */

/**
 * Creates a new, empty vec2
 *
 * @returns {vec2} a new 2D vector
 */

function create() {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(2);

  if (_common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE != Float32Array) {
    out[0] = 0;
    out[1] = 0;
  }

  return out;
}
/**
 * Creates a new vec2 initialized with values from an existing vector
 *
 * @param {vec2} a vector to clone
 * @returns {vec2} a new 2D vector
 */

function clone(a) {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(2);
  out[0] = a[0];
  out[1] = a[1];
  return out;
}
/**
 * Creates a new vec2 initialized with the given values
 *
 * @param {Number} x X component
 * @param {Number} y Y component
 * @returns {vec2} a new 2D vector
 */

function fromValues(x, y) {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(2);
  out[0] = x;
  out[1] = y;
  return out;
}
/**
 * Copy the values from one vec2 to another
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the source vector
 * @returns {vec2} out
 */

function copy(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  return out;
}
/**
 * Set the components of a vec2 to the given values
 *
 * @param {vec2} out the receiving vector
 * @param {Number} x X component
 * @param {Number} y Y component
 * @returns {vec2} out
 */

function set(out, x, y) {
  out[0] = x;
  out[1] = y;
  return out;
}
/**
 * Adds two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {vec2} out
 */

function add(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  return out;
}
/**
 * Subtracts vector b from vector a
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {vec2} out
 */

function subtract(out, a, b) {
  out[0] = a[0] - b[0];
  out[1] = a[1] - b[1];
  return out;
}
/**
 * Multiplies two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {vec2} out
 */

function multiply(out, a, b) {
  out[0] = a[0] * b[0];
  out[1] = a[1] * b[1];
  return out;
}
/**
 * Divides two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {vec2} out
 */

function divide(out, a, b) {
  out[0] = a[0] / b[0];
  out[1] = a[1] / b[1];
  return out;
}
/**
 * Math.ceil the components of a vec2
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a vector to ceil
 * @returns {vec2} out
 */

function ceil(out, a) {
  out[0] = Math.ceil(a[0]);
  out[1] = Math.ceil(a[1]);
  return out;
}
/**
 * Math.floor the components of a vec2
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a vector to floor
 * @returns {vec2} out
 */

function floor(out, a) {
  out[0] = Math.floor(a[0]);
  out[1] = Math.floor(a[1]);
  return out;
}
/**
 * Returns the minimum of two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {vec2} out
 */

function min(out, a, b) {
  out[0] = Math.min(a[0], b[0]);
  out[1] = Math.min(a[1], b[1]);
  return out;
}
/**
 * Returns the maximum of two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {vec2} out
 */

function max(out, a, b) {
  out[0] = Math.max(a[0], b[0]);
  out[1] = Math.max(a[1], b[1]);
  return out;
}
/**
 * Math.round the components of a vec2
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a vector to round
 * @returns {vec2} out
 */

function round(out, a) {
  out[0] = Math.round(a[0]);
  out[1] = Math.round(a[1]);
  return out;
}
/**
 * Scales a vec2 by a scalar number
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the vector to scale
 * @param {Number} b amount to scale the vector by
 * @returns {vec2} out
 */

function scale(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  return out;
}
/**
 * Adds two vec2's after scaling the second operand by a scalar value
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @param {Number} scale the amount to scale b by before adding
 * @returns {vec2} out
 */

function scaleAndAdd(out, a, b, scale) {
  out[0] = a[0] + b[0] * scale;
  out[1] = a[1] + b[1] * scale;
  return out;
}
/**
 * Calculates the euclidian distance between two vec2's
 *
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {Number} distance between a and b
 */

function distance(a, b) {
  var x = b[0] - a[0],
      y = b[1] - a[1];
  return Math.hypot(x, y);
}
/**
 * Calculates the squared euclidian distance between two vec2's
 *
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {Number} squared distance between a and b
 */

function squaredDistance(a, b) {
  var x = b[0] - a[0],
      y = b[1] - a[1];
  return x * x + y * y;
}
/**
 * Calculates the length of a vec2
 *
 * @param {vec2} a vector to calculate length of
 * @returns {Number} length of a
 */

function length(a) {
  var x = a[0],
      y = a[1];
  return Math.hypot(x, y);
}
/**
 * Calculates the squared length of a vec2
 *
 * @param {vec2} a vector to calculate squared length of
 * @returns {Number} squared length of a
 */

function squaredLength(a) {
  var x = a[0],
      y = a[1];
  return x * x + y * y;
}
/**
 * Negates the components of a vec2
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a vector to negate
 * @returns {vec2} out
 */

function negate(out, a) {
  out[0] = -a[0];
  out[1] = -a[1];
  return out;
}
/**
 * Returns the inverse of the components of a vec2
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a vector to invert
 * @returns {vec2} out
 */

function inverse(out, a) {
  out[0] = 1.0 / a[0];
  out[1] = 1.0 / a[1];
  return out;
}
/**
 * Normalize a vec2
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a vector to normalize
 * @returns {vec2} out
 */

function normalize(out, a) {
  var x = a[0],
      y = a[1];
  var len = x * x + y * y;

  if (len > 0) {
    //TODO: evaluate use of glm_invsqrt here?
    len = 1 / Math.sqrt(len);
  }

  out[0] = a[0] * len;
  out[1] = a[1] * len;
  return out;
}
/**
 * Calculates the dot product of two vec2's
 *
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {Number} dot product of a and b
 */

function dot(a, b) {
  return a[0] * b[0] + a[1] * b[1];
}
/**
 * Computes the cross product of two vec2's
 * Note that the cross product must by definition produce a 3D vector
 *
 * @param {vec3} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @returns {vec3} out
 */

function cross(out, a, b) {
  var z = a[0] * b[1] - a[1] * b[0];
  out[0] = out[1] = 0;
  out[2] = z;
  return out;
}
/**
 * Performs a linear interpolation between two vec2's
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the first operand
 * @param {vec2} b the second operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {vec2} out
 */

function lerp(out, a, b, t) {
  var ax = a[0],
      ay = a[1];
  out[0] = ax + t * (b[0] - ax);
  out[1] = ay + t * (b[1] - ay);
  return out;
}
/**
 * Generates a random vector with the given scale
 *
 * @param {vec2} out the receiving vector
 * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
 * @returns {vec2} out
 */

function random(out, scale) {
  scale = scale || 1.0;
  var r = _common_js__WEBPACK_IMPORTED_MODULE_0__.RANDOM() * 2.0 * Math.PI;
  out[0] = Math.cos(r) * scale;
  out[1] = Math.sin(r) * scale;
  return out;
}
/**
 * Transforms the vec2 with a mat2
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the vector to transform
 * @param {mat2} m matrix to transform with
 * @returns {vec2} out
 */

function transformMat2(out, a, m) {
  var x = a[0],
      y = a[1];
  out[0] = m[0] * x + m[2] * y;
  out[1] = m[1] * x + m[3] * y;
  return out;
}
/**
 * Transforms the vec2 with a mat2d
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the vector to transform
 * @param {mat2d} m matrix to transform with
 * @returns {vec2} out
 */

function transformMat2d(out, a, m) {
  var x = a[0],
      y = a[1];
  out[0] = m[0] * x + m[2] * y + m[4];
  out[1] = m[1] * x + m[3] * y + m[5];
  return out;
}
/**
 * Transforms the vec2 with a mat3
 * 3rd vector component is implicitly '1'
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the vector to transform
 * @param {mat3} m matrix to transform with
 * @returns {vec2} out
 */

function transformMat3(out, a, m) {
  var x = a[0],
      y = a[1];
  out[0] = m[0] * x + m[3] * y + m[6];
  out[1] = m[1] * x + m[4] * y + m[7];
  return out;
}
/**
 * Transforms the vec2 with a mat4
 * 3rd vector component is implicitly '0'
 * 4th vector component is implicitly '1'
 *
 * @param {vec2} out the receiving vector
 * @param {vec2} a the vector to transform
 * @param {mat4} m matrix to transform with
 * @returns {vec2} out
 */

function transformMat4(out, a, m) {
  var x = a[0];
  var y = a[1];
  out[0] = m[0] * x + m[4] * y + m[12];
  out[1] = m[1] * x + m[5] * y + m[13];
  return out;
}
/**
 * Rotate a 2D vector
 * @param {vec2} out The receiving vec2
 * @param {vec2} a The vec2 point to rotate
 * @param {vec2} b The origin of the rotation
 * @param {Number} c The angle of rotation
 * @returns {vec2} out
 */

function rotate(out, a, b, c) {
  //Translate point to the origin
  var p0 = a[0] - b[0],
      p1 = a[1] - b[1],
      sinC = Math.sin(c),
      cosC = Math.cos(c); //perform rotation and translate to correct position

  out[0] = p0 * cosC - p1 * sinC + b[0];
  out[1] = p0 * sinC + p1 * cosC + b[1];
  return out;
}
/**
 * Get the angle between two 2D vectors
 * @param {vec2} a The first operand
 * @param {vec2} b The second operand
 * @returns {Number} The angle in radians
 */

function angle(a, b) {
  var x1 = a[0],
      y1 = a[1],
      x2 = b[0],
      y2 = b[1];
  var len1 = x1 * x1 + y1 * y1;

  if (len1 > 0) {
    //TODO: evaluate use of glm_invsqrt here?
    len1 = 1 / Math.sqrt(len1);
  }

  var len2 = x2 * x2 + y2 * y2;

  if (len2 > 0) {
    //TODO: evaluate use of glm_invsqrt here?
    len2 = 1 / Math.sqrt(len2);
  }

  var cosine = (x1 * x2 + y1 * y2) * len1 * len2;

  if (cosine > 1.0) {
    return 0;
  } else if (cosine < -1.0) {
    return Math.PI;
  } else {
    return Math.acos(cosine);
  }
}
/**
 * Set the components of a vec2 to zero
 *
 * @param {vec2} out the receiving vector
 * @returns {vec2} out
 */

function zero(out) {
  out[0] = 0.0;
  out[1] = 0.0;
  return out;
}
/**
 * Returns a string representation of a vector
 *
 * @param {vec2} a vector to represent as a string
 * @returns {String} string representation of the vector
 */

function str(a) {
  return 'vec2(' + a[0] + ', ' + a[1] + ')';
}
/**
 * Returns whether or not the vectors exactly have the same elements in the same position (when compared with ===)
 *
 * @param {vec2} a The first vector.
 * @param {vec2} b The second vector.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

function exactEquals(a, b) {
  return a[0] === b[0] && a[1] === b[1];
}
/**
 * Returns whether or not the vectors have approximately the same elements in the same position.
 *
 * @param {vec2} a The first vector.
 * @param {vec2} b The second vector.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

function equals(a, b) {
  var a0 = a[0],
      a1 = a[1];
  var b0 = b[0],
      b1 = b[1];
  return Math.abs(a0 - b0) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1));
}
/**
 * Alias for {@link vec2.length}
 * @function
 */

var len = length;
/**
 * Alias for {@link vec2.subtract}
 * @function
 */

var sub = subtract;
/**
 * Alias for {@link vec2.multiply}
 * @function
 */

var mul = multiply;
/**
 * Alias for {@link vec2.divide}
 * @function
 */

var div = divide;
/**
 * Alias for {@link vec2.distance}
 * @function
 */

var dist = distance;
/**
 * Alias for {@link vec2.squaredDistance}
 * @function
 */

var sqrDist = squaredDistance;
/**
 * Alias for {@link vec2.squaredLength}
 * @function
 */

var sqrLen = squaredLength;
/**
 * Perform some operation over an array of vec2s.
 *
 * @param {Array} a the array of vectors to iterate over
 * @param {Number} stride Number of elements between the start of each vec2. If 0 assumes tightly packed
 * @param {Number} offset Number of elements to skip at the beginning of the array
 * @param {Number} count Number of vec2s to iterate over. If 0 iterates over entire array
 * @param {Function} fn Function to call for each vector in the array
 * @param {Object} [arg] additional argument to pass to fn
 * @returns {Array} a
 * @function
 */

var forEach = function () {
  var vec = create();
  return function (a, stride, offset, count, fn, arg) {
    var i, l;

    if (!stride) {
      stride = 2;
    }

    if (!offset) {
      offset = 0;
    }

    if (count) {
      l = Math.min(count * stride + offset, a.length);
    } else {
      l = a.length;
    }

    for (i = offset; i < l; i += stride) {
      vec[0] = a[i];
      vec[1] = a[i + 1];
      fn(vec, vec, arg);
      a[i] = vec[0];
      a[i + 1] = vec[1];
    }

    return a;
  };
}();

/***/ }),

/***/ 329:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   add: () => (/* binding */ add),
/* harmony export */   angle: () => (/* binding */ angle),
/* harmony export */   bezier: () => (/* binding */ bezier),
/* harmony export */   ceil: () => (/* binding */ ceil),
/* harmony export */   clone: () => (/* binding */ clone),
/* harmony export */   copy: () => (/* binding */ copy),
/* harmony export */   create: () => (/* binding */ create),
/* harmony export */   cross: () => (/* binding */ cross),
/* harmony export */   dist: () => (/* binding */ dist),
/* harmony export */   distance: () => (/* binding */ distance),
/* harmony export */   div: () => (/* binding */ div),
/* harmony export */   divide: () => (/* binding */ divide),
/* harmony export */   dot: () => (/* binding */ dot),
/* harmony export */   equals: () => (/* binding */ equals),
/* harmony export */   exactEquals: () => (/* binding */ exactEquals),
/* harmony export */   floor: () => (/* binding */ floor),
/* harmony export */   forEach: () => (/* binding */ forEach),
/* harmony export */   fromValues: () => (/* binding */ fromValues),
/* harmony export */   hermite: () => (/* binding */ hermite),
/* harmony export */   inverse: () => (/* binding */ inverse),
/* harmony export */   len: () => (/* binding */ len),
/* harmony export */   length: () => (/* binding */ length),
/* harmony export */   lerp: () => (/* binding */ lerp),
/* harmony export */   max: () => (/* binding */ max),
/* harmony export */   min: () => (/* binding */ min),
/* harmony export */   mul: () => (/* binding */ mul),
/* harmony export */   multiply: () => (/* binding */ multiply),
/* harmony export */   negate: () => (/* binding */ negate),
/* harmony export */   normalize: () => (/* binding */ normalize),
/* harmony export */   random: () => (/* binding */ random),
/* harmony export */   rotateX: () => (/* binding */ rotateX),
/* harmony export */   rotateY: () => (/* binding */ rotateY),
/* harmony export */   rotateZ: () => (/* binding */ rotateZ),
/* harmony export */   round: () => (/* binding */ round),
/* harmony export */   scale: () => (/* binding */ scale),
/* harmony export */   scaleAndAdd: () => (/* binding */ scaleAndAdd),
/* harmony export */   set: () => (/* binding */ set),
/* harmony export */   sqrDist: () => (/* binding */ sqrDist),
/* harmony export */   sqrLen: () => (/* binding */ sqrLen),
/* harmony export */   squaredDistance: () => (/* binding */ squaredDistance),
/* harmony export */   squaredLength: () => (/* binding */ squaredLength),
/* harmony export */   str: () => (/* binding */ str),
/* harmony export */   sub: () => (/* binding */ sub),
/* harmony export */   subtract: () => (/* binding */ subtract),
/* harmony export */   transformMat3: () => (/* binding */ transformMat3),
/* harmony export */   transformMat4: () => (/* binding */ transformMat4),
/* harmony export */   transformQuat: () => (/* binding */ transformQuat),
/* harmony export */   zero: () => (/* binding */ zero)
/* harmony export */ });
/* harmony import */ var _common_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(823);

/**
 * 3 Dimensional Vector
 * @module vec3
 */

/**
 * Creates a new, empty vec3
 *
 * @returns {vec3} a new 3D vector
 */

function create() {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(3);

  if (_common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE != Float32Array) {
    out[0] = 0;
    out[1] = 0;
    out[2] = 0;
  }

  return out;
}
/**
 * Creates a new vec3 initialized with values from an existing vector
 *
 * @param {vec3} a vector to clone
 * @returns {vec3} a new 3D vector
 */

function clone(a) {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(3);
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  return out;
}
/**
 * Calculates the length of a vec3
 *
 * @param {vec3} a vector to calculate length of
 * @returns {Number} length of a
 */

function length(a) {
  var x = a[0];
  var y = a[1];
  var z = a[2];
  return Math.hypot(x, y, z);
}
/**
 * Creates a new vec3 initialized with the given values
 *
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @returns {vec3} a new 3D vector
 */

function fromValues(x, y, z) {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(3);
  out[0] = x;
  out[1] = y;
  out[2] = z;
  return out;
}
/**
 * Copy the values from one vec3 to another
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the source vector
 * @returns {vec3} out
 */

function copy(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  return out;
}
/**
 * Set the components of a vec3 to the given values
 *
 * @param {vec3} out the receiving vector
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @returns {vec3} out
 */

function set(out, x, y, z) {
  out[0] = x;
  out[1] = y;
  out[2] = z;
  return out;
}
/**
 * Adds two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {vec3} out
 */

function add(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  out[2] = a[2] + b[2];
  return out;
}
/**
 * Subtracts vector b from vector a
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {vec3} out
 */

function subtract(out, a, b) {
  out[0] = a[0] - b[0];
  out[1] = a[1] - b[1];
  out[2] = a[2] - b[2];
  return out;
}
/**
 * Multiplies two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {vec3} out
 */

function multiply(out, a, b) {
  out[0] = a[0] * b[0];
  out[1] = a[1] * b[1];
  out[2] = a[2] * b[2];
  return out;
}
/**
 * Divides two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {vec3} out
 */

function divide(out, a, b) {
  out[0] = a[0] / b[0];
  out[1] = a[1] / b[1];
  out[2] = a[2] / b[2];
  return out;
}
/**
 * Math.ceil the components of a vec3
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a vector to ceil
 * @returns {vec3} out
 */

function ceil(out, a) {
  out[0] = Math.ceil(a[0]);
  out[1] = Math.ceil(a[1]);
  out[2] = Math.ceil(a[2]);
  return out;
}
/**
 * Math.floor the components of a vec3
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a vector to floor
 * @returns {vec3} out
 */

function floor(out, a) {
  out[0] = Math.floor(a[0]);
  out[1] = Math.floor(a[1]);
  out[2] = Math.floor(a[2]);
  return out;
}
/**
 * Returns the minimum of two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {vec3} out
 */

function min(out, a, b) {
  out[0] = Math.min(a[0], b[0]);
  out[1] = Math.min(a[1], b[1]);
  out[2] = Math.min(a[2], b[2]);
  return out;
}
/**
 * Returns the maximum of two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {vec3} out
 */

function max(out, a, b) {
  out[0] = Math.max(a[0], b[0]);
  out[1] = Math.max(a[1], b[1]);
  out[2] = Math.max(a[2], b[2]);
  return out;
}
/**
 * Math.round the components of a vec3
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a vector to round
 * @returns {vec3} out
 */

function round(out, a) {
  out[0] = Math.round(a[0]);
  out[1] = Math.round(a[1]);
  out[2] = Math.round(a[2]);
  return out;
}
/**
 * Scales a vec3 by a scalar number
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the vector to scale
 * @param {Number} b amount to scale the vector by
 * @returns {vec3} out
 */

function scale(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  out[2] = a[2] * b;
  return out;
}
/**
 * Adds two vec3's after scaling the second operand by a scalar value
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @param {Number} scale the amount to scale b by before adding
 * @returns {vec3} out
 */

function scaleAndAdd(out, a, b, scale) {
  out[0] = a[0] + b[0] * scale;
  out[1] = a[1] + b[1] * scale;
  out[2] = a[2] + b[2] * scale;
  return out;
}
/**
 * Calculates the euclidian distance between two vec3's
 *
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {Number} distance between a and b
 */

function distance(a, b) {
  var x = b[0] - a[0];
  var y = b[1] - a[1];
  var z = b[2] - a[2];
  return Math.hypot(x, y, z);
}
/**
 * Calculates the squared euclidian distance between two vec3's
 *
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {Number} squared distance between a and b
 */

function squaredDistance(a, b) {
  var x = b[0] - a[0];
  var y = b[1] - a[1];
  var z = b[2] - a[2];
  return x * x + y * y + z * z;
}
/**
 * Calculates the squared length of a vec3
 *
 * @param {vec3} a vector to calculate squared length of
 * @returns {Number} squared length of a
 */

function squaredLength(a) {
  var x = a[0];
  var y = a[1];
  var z = a[2];
  return x * x + y * y + z * z;
}
/**
 * Negates the components of a vec3
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a vector to negate
 * @returns {vec3} out
 */

function negate(out, a) {
  out[0] = -a[0];
  out[1] = -a[1];
  out[2] = -a[2];
  return out;
}
/**
 * Returns the inverse of the components of a vec3
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a vector to invert
 * @returns {vec3} out
 */

function inverse(out, a) {
  out[0] = 1.0 / a[0];
  out[1] = 1.0 / a[1];
  out[2] = 1.0 / a[2];
  return out;
}
/**
 * Normalize a vec3
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a vector to normalize
 * @returns {vec3} out
 */

function normalize(out, a) {
  var x = a[0];
  var y = a[1];
  var z = a[2];
  var len = x * x + y * y + z * z;

  if (len > 0) {
    //TODO: evaluate use of glm_invsqrt here?
    len = 1 / Math.sqrt(len);
  }

  out[0] = a[0] * len;
  out[1] = a[1] * len;
  out[2] = a[2] * len;
  return out;
}
/**
 * Calculates the dot product of two vec3's
 *
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {Number} dot product of a and b
 */

function dot(a, b) {
  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
/**
 * Computes the cross product of two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @returns {vec3} out
 */

function cross(out, a, b) {
  var ax = a[0],
      ay = a[1],
      az = a[2];
  var bx = b[0],
      by = b[1],
      bz = b[2];
  out[0] = ay * bz - az * by;
  out[1] = az * bx - ax * bz;
  out[2] = ax * by - ay * bx;
  return out;
}
/**
 * Performs a linear interpolation between two vec3's
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {vec3} out
 */

function lerp(out, a, b, t) {
  var ax = a[0];
  var ay = a[1];
  var az = a[2];
  out[0] = ax + t * (b[0] - ax);
  out[1] = ay + t * (b[1] - ay);
  out[2] = az + t * (b[2] - az);
  return out;
}
/**
 * Performs a hermite interpolation with two control points
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @param {vec3} c the third operand
 * @param {vec3} d the fourth operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {vec3} out
 */

function hermite(out, a, b, c, d, t) {
  var factorTimes2 = t * t;
  var factor1 = factorTimes2 * (2 * t - 3) + 1;
  var factor2 = factorTimes2 * (t - 2) + t;
  var factor3 = factorTimes2 * (t - 1);
  var factor4 = factorTimes2 * (3 - 2 * t);
  out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;
  out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;
  out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;
  return out;
}
/**
 * Performs a bezier interpolation with two control points
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the first operand
 * @param {vec3} b the second operand
 * @param {vec3} c the third operand
 * @param {vec3} d the fourth operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {vec3} out
 */

function bezier(out, a, b, c, d, t) {
  var inverseFactor = 1 - t;
  var inverseFactorTimesTwo = inverseFactor * inverseFactor;
  var factorTimes2 = t * t;
  var factor1 = inverseFactorTimesTwo * inverseFactor;
  var factor2 = 3 * t * inverseFactorTimesTwo;
  var factor3 = 3 * factorTimes2 * inverseFactor;
  var factor4 = factorTimes2 * t;
  out[0] = a[0] * factor1 + b[0] * factor2 + c[0] * factor3 + d[0] * factor4;
  out[1] = a[1] * factor1 + b[1] * factor2 + c[1] * factor3 + d[1] * factor4;
  out[2] = a[2] * factor1 + b[2] * factor2 + c[2] * factor3 + d[2] * factor4;
  return out;
}
/**
 * Generates a random vector with the given scale
 *
 * @param {vec3} out the receiving vector
 * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
 * @returns {vec3} out
 */

function random(out, scale) {
  scale = scale || 1.0;
  var r = _common_js__WEBPACK_IMPORTED_MODULE_0__.RANDOM() * 2.0 * Math.PI;
  var z = _common_js__WEBPACK_IMPORTED_MODULE_0__.RANDOM() * 2.0 - 1.0;
  var zScale = Math.sqrt(1.0 - z * z) * scale;
  out[0] = Math.cos(r) * zScale;
  out[1] = Math.sin(r) * zScale;
  out[2] = z * scale;
  return out;
}
/**
 * Transforms the vec3 with a mat4.
 * 4th vector component is implicitly '1'
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the vector to transform
 * @param {mat4} m matrix to transform with
 * @returns {vec3} out
 */

function transformMat4(out, a, m) {
  var x = a[0],
      y = a[1],
      z = a[2];
  var w = m[3] * x + m[7] * y + m[11] * z + m[15];
  w = w || 1.0;
  out[0] = (m[0] * x + m[4] * y + m[8] * z + m[12]) / w;
  out[1] = (m[1] * x + m[5] * y + m[9] * z + m[13]) / w;
  out[2] = (m[2] * x + m[6] * y + m[10] * z + m[14]) / w;
  return out;
}
/**
 * Transforms the vec3 with a mat3.
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the vector to transform
 * @param {mat3} m the 3x3 matrix to transform with
 * @returns {vec3} out
 */

function transformMat3(out, a, m) {
  var x = a[0],
      y = a[1],
      z = a[2];
  out[0] = x * m[0] + y * m[3] + z * m[6];
  out[1] = x * m[1] + y * m[4] + z * m[7];
  out[2] = x * m[2] + y * m[5] + z * m[8];
  return out;
}
/**
 * Transforms the vec3 with a quat
 * Can also be used for dual quaternions. (Multiply it with the real part)
 *
 * @param {vec3} out the receiving vector
 * @param {vec3} a the vector to transform
 * @param {quat} q quaternion to transform with
 * @returns {vec3} out
 */

function transformQuat(out, a, q) {
  // benchmarks: https://jsperf.com/quaternion-transform-vec3-implementations-fixed
  var qx = q[0],
      qy = q[1],
      qz = q[2],
      qw = q[3];
  var x = a[0],
      y = a[1],
      z = a[2]; // var qvec = [qx, qy, qz];
  // var uv = vec3.cross([], qvec, a);

  var uvx = qy * z - qz * y,
      uvy = qz * x - qx * z,
      uvz = qx * y - qy * x; // var uuv = vec3.cross([], qvec, uv);

  var uuvx = qy * uvz - qz * uvy,
      uuvy = qz * uvx - qx * uvz,
      uuvz = qx * uvy - qy * uvx; // vec3.scale(uv, uv, 2 * w);

  var w2 = qw * 2;
  uvx *= w2;
  uvy *= w2;
  uvz *= w2; // vec3.scale(uuv, uuv, 2);

  uuvx *= 2;
  uuvy *= 2;
  uuvz *= 2; // return vec3.add(out, a, vec3.add(out, uv, uuv));

  out[0] = x + uvx + uuvx;
  out[1] = y + uvy + uuvy;
  out[2] = z + uvz + uuvz;
  return out;
}
/**
 * Rotate a 3D vector around the x-axis
 * @param {vec3} out The receiving vec3
 * @param {vec3} a The vec3 point to rotate
 * @param {vec3} b The origin of the rotation
 * @param {Number} c The angle of rotation
 * @returns {vec3} out
 */

function rotateX(out, a, b, c) {
  var p = [],
      r = []; //Translate point to the origin

  p[0] = a[0] - b[0];
  p[1] = a[1] - b[1];
  p[2] = a[2] - b[2]; //perform rotation

  r[0] = p[0];
  r[1] = p[1] * Math.cos(c) - p[2] * Math.sin(c);
  r[2] = p[1] * Math.sin(c) + p[2] * Math.cos(c); //translate to correct position

  out[0] = r[0] + b[0];
  out[1] = r[1] + b[1];
  out[2] = r[2] + b[2];
  return out;
}
/**
 * Rotate a 3D vector around the y-axis
 * @param {vec3} out The receiving vec3
 * @param {vec3} a The vec3 point to rotate
 * @param {vec3} b The origin of the rotation
 * @param {Number} c The angle of rotation
 * @returns {vec3} out
 */

function rotateY(out, a, b, c) {
  var p = [],
      r = []; //Translate point to the origin

  p[0] = a[0] - b[0];
  p[1] = a[1] - b[1];
  p[2] = a[2] - b[2]; //perform rotation

  r[0] = p[2] * Math.sin(c) + p[0] * Math.cos(c);
  r[1] = p[1];
  r[2] = p[2] * Math.cos(c) - p[0] * Math.sin(c); //translate to correct position

  out[0] = r[0] + b[0];
  out[1] = r[1] + b[1];
  out[2] = r[2] + b[2];
  return out;
}
/**
 * Rotate a 3D vector around the z-axis
 * @param {vec3} out The receiving vec3
 * @param {vec3} a The vec3 point to rotate
 * @param {vec3} b The origin of the rotation
 * @param {Number} c The angle of rotation
 * @returns {vec3} out
 */

function rotateZ(out, a, b, c) {
  var p = [],
      r = []; //Translate point to the origin

  p[0] = a[0] - b[0];
  p[1] = a[1] - b[1];
  p[2] = a[2] - b[2]; //perform rotation

  r[0] = p[0] * Math.cos(c) - p[1] * Math.sin(c);
  r[1] = p[0] * Math.sin(c) + p[1] * Math.cos(c);
  r[2] = p[2]; //translate to correct position

  out[0] = r[0] + b[0];
  out[1] = r[1] + b[1];
  out[2] = r[2] + b[2];
  return out;
}
/**
 * Get the angle between two 3D vectors
 * @param {vec3} a The first operand
 * @param {vec3} b The second operand
 * @returns {Number} The angle in radians
 */

function angle(a, b) {
  var tempA = fromValues(a[0], a[1], a[2]);
  var tempB = fromValues(b[0], b[1], b[2]);
  normalize(tempA, tempA);
  normalize(tempB, tempB);
  var cosine = dot(tempA, tempB);

  if (cosine > 1.0) {
    return 0;
  } else if (cosine < -1.0) {
    return Math.PI;
  } else {
    return Math.acos(cosine);
  }
}
/**
 * Set the components of a vec3 to zero
 *
 * @param {vec3} out the receiving vector
 * @returns {vec3} out
 */

function zero(out) {
  out[0] = 0.0;
  out[1] = 0.0;
  out[2] = 0.0;
  return out;
}
/**
 * Returns a string representation of a vector
 *
 * @param {vec3} a vector to represent as a string
 * @returns {String} string representation of the vector
 */

function str(a) {
  return 'vec3(' + a[0] + ', ' + a[1] + ', ' + a[2] + ')';
}
/**
 * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===)
 *
 * @param {vec3} a The first vector.
 * @param {vec3} b The second vector.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

function exactEquals(a, b) {
  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2];
}
/**
 * Returns whether or not the vectors have approximately the same elements in the same position.
 *
 * @param {vec3} a The first vector.
 * @param {vec3} b The second vector.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

function equals(a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2];
  return Math.abs(a0 - b0) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2));
}
/**
 * Alias for {@link vec3.subtract}
 * @function
 */

var sub = subtract;
/**
 * Alias for {@link vec3.multiply}
 * @function
 */

var mul = multiply;
/**
 * Alias for {@link vec3.divide}
 * @function
 */

var div = divide;
/**
 * Alias for {@link vec3.distance}
 * @function
 */

var dist = distance;
/**
 * Alias for {@link vec3.squaredDistance}
 * @function
 */

var sqrDist = squaredDistance;
/**
 * Alias for {@link vec3.length}
 * @function
 */

var len = length;
/**
 * Alias for {@link vec3.squaredLength}
 * @function
 */

var sqrLen = squaredLength;
/**
 * Perform some operation over an array of vec3s.
 *
 * @param {Array} a the array of vectors to iterate over
 * @param {Number} stride Number of elements between the start of each vec3. If 0 assumes tightly packed
 * @param {Number} offset Number of elements to skip at the beginning of the array
 * @param {Number} count Number of vec3s to iterate over. If 0 iterates over entire array
 * @param {Function} fn Function to call for each vector in the array
 * @param {Object} [arg] additional argument to pass to fn
 * @returns {Array} a
 * @function
 */

var forEach = function () {
  var vec = create();
  return function (a, stride, offset, count, fn, arg) {
    var i, l;

    if (!stride) {
      stride = 3;
    }

    if (!offset) {
      offset = 0;
    }

    if (count) {
      l = Math.min(count * stride + offset, a.length);
    } else {
      l = a.length;
    }

    for (i = offset; i < l; i += stride) {
      vec[0] = a[i];
      vec[1] = a[i + 1];
      vec[2] = a[i + 2];
      fn(vec, vec, arg);
      a[i] = vec[0];
      a[i + 1] = vec[1];
      a[i + 2] = vec[2];
    }

    return a;
  };
}();

/***/ }),

/***/ 796:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   add: () => (/* binding */ add),
/* harmony export */   ceil: () => (/* binding */ ceil),
/* harmony export */   clone: () => (/* binding */ clone),
/* harmony export */   copy: () => (/* binding */ copy),
/* harmony export */   create: () => (/* binding */ create),
/* harmony export */   cross: () => (/* binding */ cross),
/* harmony export */   dist: () => (/* binding */ dist),
/* harmony export */   distance: () => (/* binding */ distance),
/* harmony export */   div: () => (/* binding */ div),
/* harmony export */   divide: () => (/* binding */ divide),
/* harmony export */   dot: () => (/* binding */ dot),
/* harmony export */   equals: () => (/* binding */ equals),
/* harmony export */   exactEquals: () => (/* binding */ exactEquals),
/* harmony export */   floor: () => (/* binding */ floor),
/* harmony export */   forEach: () => (/* binding */ forEach),
/* harmony export */   fromValues: () => (/* binding */ fromValues),
/* harmony export */   inverse: () => (/* binding */ inverse),
/* harmony export */   len: () => (/* binding */ len),
/* harmony export */   length: () => (/* binding */ length),
/* harmony export */   lerp: () => (/* binding */ lerp),
/* harmony export */   max: () => (/* binding */ max),
/* harmony export */   min: () => (/* binding */ min),
/* harmony export */   mul: () => (/* binding */ mul),
/* harmony export */   multiply: () => (/* binding */ multiply),
/* harmony export */   negate: () => (/* binding */ negate),
/* harmony export */   normalize: () => (/* binding */ normalize),
/* harmony export */   random: () => (/* binding */ random),
/* harmony export */   round: () => (/* binding */ round),
/* harmony export */   scale: () => (/* binding */ scale),
/* harmony export */   scaleAndAdd: () => (/* binding */ scaleAndAdd),
/* harmony export */   set: () => (/* binding */ set),
/* harmony export */   sqrDist: () => (/* binding */ sqrDist),
/* harmony export */   sqrLen: () => (/* binding */ sqrLen),
/* harmony export */   squaredDistance: () => (/* binding */ squaredDistance),
/* harmony export */   squaredLength: () => (/* binding */ squaredLength),
/* harmony export */   str: () => (/* binding */ str),
/* harmony export */   sub: () => (/* binding */ sub),
/* harmony export */   subtract: () => (/* binding */ subtract),
/* harmony export */   transformMat4: () => (/* binding */ transformMat4),
/* harmony export */   transformQuat: () => (/* binding */ transformQuat),
/* harmony export */   zero: () => (/* binding */ zero)
/* harmony export */ });
/* harmony import */ var _common_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(823);

/**
 * 4 Dimensional Vector
 * @module vec4
 */

/**
 * Creates a new, empty vec4
 *
 * @returns {vec4} a new 4D vector
 */

function create() {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(4);

  if (_common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE != Float32Array) {
    out[0] = 0;
    out[1] = 0;
    out[2] = 0;
    out[3] = 0;
  }

  return out;
}
/**
 * Creates a new vec4 initialized with values from an existing vector
 *
 * @param {vec4} a vector to clone
 * @returns {vec4} a new 4D vector
 */

function clone(a) {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(4);
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  return out;
}
/**
 * Creates a new vec4 initialized with the given values
 *
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @param {Number} w W component
 * @returns {vec4} a new 4D vector
 */

function fromValues(x, y, z, w) {
  var out = new _common_js__WEBPACK_IMPORTED_MODULE_0__.ARRAY_TYPE(4);
  out[0] = x;
  out[1] = y;
  out[2] = z;
  out[3] = w;
  return out;
}
/**
 * Copy the values from one vec4 to another
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the source vector
 * @returns {vec4} out
 */

function copy(out, a) {
  out[0] = a[0];
  out[1] = a[1];
  out[2] = a[2];
  out[3] = a[3];
  return out;
}
/**
 * Set the components of a vec4 to the given values
 *
 * @param {vec4} out the receiving vector
 * @param {Number} x X component
 * @param {Number} y Y component
 * @param {Number} z Z component
 * @param {Number} w W component
 * @returns {vec4} out
 */

function set(out, x, y, z, w) {
  out[0] = x;
  out[1] = y;
  out[2] = z;
  out[3] = w;
  return out;
}
/**
 * Adds two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */

function add(out, a, b) {
  out[0] = a[0] + b[0];
  out[1] = a[1] + b[1];
  out[2] = a[2] + b[2];
  out[3] = a[3] + b[3];
  return out;
}
/**
 * Subtracts vector b from vector a
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */

function subtract(out, a, b) {
  out[0] = a[0] - b[0];
  out[1] = a[1] - b[1];
  out[2] = a[2] - b[2];
  out[3] = a[3] - b[3];
  return out;
}
/**
 * Multiplies two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */

function multiply(out, a, b) {
  out[0] = a[0] * b[0];
  out[1] = a[1] * b[1];
  out[2] = a[2] * b[2];
  out[3] = a[3] * b[3];
  return out;
}
/**
 * Divides two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */

function divide(out, a, b) {
  out[0] = a[0] / b[0];
  out[1] = a[1] / b[1];
  out[2] = a[2] / b[2];
  out[3] = a[3] / b[3];
  return out;
}
/**
 * Math.ceil the components of a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a vector to ceil
 * @returns {vec4} out
 */

function ceil(out, a) {
  out[0] = Math.ceil(a[0]);
  out[1] = Math.ceil(a[1]);
  out[2] = Math.ceil(a[2]);
  out[3] = Math.ceil(a[3]);
  return out;
}
/**
 * Math.floor the components of a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a vector to floor
 * @returns {vec4} out
 */

function floor(out, a) {
  out[0] = Math.floor(a[0]);
  out[1] = Math.floor(a[1]);
  out[2] = Math.floor(a[2]);
  out[3] = Math.floor(a[3]);
  return out;
}
/**
 * Returns the minimum of two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */

function min(out, a, b) {
  out[0] = Math.min(a[0], b[0]);
  out[1] = Math.min(a[1], b[1]);
  out[2] = Math.min(a[2], b[2]);
  out[3] = Math.min(a[3], b[3]);
  return out;
}
/**
 * Returns the maximum of two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {vec4} out
 */

function max(out, a, b) {
  out[0] = Math.max(a[0], b[0]);
  out[1] = Math.max(a[1], b[1]);
  out[2] = Math.max(a[2], b[2]);
  out[3] = Math.max(a[3], b[3]);
  return out;
}
/**
 * Math.round the components of a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a vector to round
 * @returns {vec4} out
 */

function round(out, a) {
  out[0] = Math.round(a[0]);
  out[1] = Math.round(a[1]);
  out[2] = Math.round(a[2]);
  out[3] = Math.round(a[3]);
  return out;
}
/**
 * Scales a vec4 by a scalar number
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the vector to scale
 * @param {Number} b amount to scale the vector by
 * @returns {vec4} out
 */

function scale(out, a, b) {
  out[0] = a[0] * b;
  out[1] = a[1] * b;
  out[2] = a[2] * b;
  out[3] = a[3] * b;
  return out;
}
/**
 * Adds two vec4's after scaling the second operand by a scalar value
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @param {Number} scale the amount to scale b by before adding
 * @returns {vec4} out
 */

function scaleAndAdd(out, a, b, scale) {
  out[0] = a[0] + b[0] * scale;
  out[1] = a[1] + b[1] * scale;
  out[2] = a[2] + b[2] * scale;
  out[3] = a[3] + b[3] * scale;
  return out;
}
/**
 * Calculates the euclidian distance between two vec4's
 *
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {Number} distance between a and b
 */

function distance(a, b) {
  var x = b[0] - a[0];
  var y = b[1] - a[1];
  var z = b[2] - a[2];
  var w = b[3] - a[3];
  return Math.hypot(x, y, z, w);
}
/**
 * Calculates the squared euclidian distance between two vec4's
 *
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {Number} squared distance between a and b
 */

function squaredDistance(a, b) {
  var x = b[0] - a[0];
  var y = b[1] - a[1];
  var z = b[2] - a[2];
  var w = b[3] - a[3];
  return x * x + y * y + z * z + w * w;
}
/**
 * Calculates the length of a vec4
 *
 * @param {vec4} a vector to calculate length of
 * @returns {Number} length of a
 */

function length(a) {
  var x = a[0];
  var y = a[1];
  var z = a[2];
  var w = a[3];
  return Math.hypot(x, y, z, w);
}
/**
 * Calculates the squared length of a vec4
 *
 * @param {vec4} a vector to calculate squared length of
 * @returns {Number} squared length of a
 */

function squaredLength(a) {
  var x = a[0];
  var y = a[1];
  var z = a[2];
  var w = a[3];
  return x * x + y * y + z * z + w * w;
}
/**
 * Negates the components of a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a vector to negate
 * @returns {vec4} out
 */

function negate(out, a) {
  out[0] = -a[0];
  out[1] = -a[1];
  out[2] = -a[2];
  out[3] = -a[3];
  return out;
}
/**
 * Returns the inverse of the components of a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a vector to invert
 * @returns {vec4} out
 */

function inverse(out, a) {
  out[0] = 1.0 / a[0];
  out[1] = 1.0 / a[1];
  out[2] = 1.0 / a[2];
  out[3] = 1.0 / a[3];
  return out;
}
/**
 * Normalize a vec4
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a vector to normalize
 * @returns {vec4} out
 */

function normalize(out, a) {
  var x = a[0];
  var y = a[1];
  var z = a[2];
  var w = a[3];
  var len = x * x + y * y + z * z + w * w;

  if (len > 0) {
    len = 1 / Math.sqrt(len);
  }

  out[0] = x * len;
  out[1] = y * len;
  out[2] = z * len;
  out[3] = w * len;
  return out;
}
/**
 * Calculates the dot product of two vec4's
 *
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @returns {Number} dot product of a and b
 */

function dot(a, b) {
  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
}
/**
 * Returns the cross-product of three vectors in a 4-dimensional space
 *
 * @param {vec4} result the receiving vector
 * @param {vec4} U the first vector
 * @param {vec4} V the second vector
 * @param {vec4} W the third vector
 * @returns {vec4} result
 */

function cross(out, u, v, w) {
  var A = v[0] * w[1] - v[1] * w[0],
      B = v[0] * w[2] - v[2] * w[0],
      C = v[0] * w[3] - v[3] * w[0],
      D = v[1] * w[2] - v[2] * w[1],
      E = v[1] * w[3] - v[3] * w[1],
      F = v[2] * w[3] - v[3] * w[2];
  var G = u[0];
  var H = u[1];
  var I = u[2];
  var J = u[3];
  out[0] = H * F - I * E + J * D;
  out[1] = -(G * F) + I * C - J * B;
  out[2] = G * E - H * C + J * A;
  out[3] = -(G * D) + H * B - I * A;
  return out;
}
;
/**
 * Performs a linear interpolation between two vec4's
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the first operand
 * @param {vec4} b the second operand
 * @param {Number} t interpolation amount, in the range [0-1], between the two inputs
 * @returns {vec4} out
 */

function lerp(out, a, b, t) {
  var ax = a[0];
  var ay = a[1];
  var az = a[2];
  var aw = a[3];
  out[0] = ax + t * (b[0] - ax);
  out[1] = ay + t * (b[1] - ay);
  out[2] = az + t * (b[2] - az);
  out[3] = aw + t * (b[3] - aw);
  return out;
}
/**
 * Generates a random vector with the given scale
 *
 * @param {vec4} out the receiving vector
 * @param {Number} [scale] Length of the resulting vector. If ommitted, a unit vector will be returned
 * @returns {vec4} out
 */

function random(out, scale) {
  scale = scale || 1.0; // Marsaglia, George. Choosing a Point from the Surface of a
  // Sphere. Ann. Math. Statist. 43 (1972), no. 2, 645--646.
  // http://projecteuclid.org/euclid.aoms/1177692644;

  var v1, v2, v3, v4;
  var s1, s2;

  do {
    v1 = _common_js__WEBPACK_IMPORTED_MODULE_0__.RANDOM() * 2 - 1;
    v2 = _common_js__WEBPACK_IMPORTED_MODULE_0__.RANDOM() * 2 - 1;
    s1 = v1 * v1 + v2 * v2;
  } while (s1 >= 1);

  do {
    v3 = _common_js__WEBPACK_IMPORTED_MODULE_0__.RANDOM() * 2 - 1;
    v4 = _common_js__WEBPACK_IMPORTED_MODULE_0__.RANDOM() * 2 - 1;
    s2 = v3 * v3 + v4 * v4;
  } while (s2 >= 1);

  var d = Math.sqrt((1 - s1) / s2);
  out[0] = scale * v1;
  out[1] = scale * v2;
  out[2] = scale * v3 * d;
  out[3] = scale * v4 * d;
  return out;
}
/**
 * Transforms the vec4 with a mat4.
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the vector to transform
 * @param {mat4} m matrix to transform with
 * @returns {vec4} out
 */

function transformMat4(out, a, m) {
  var x = a[0],
      y = a[1],
      z = a[2],
      w = a[3];
  out[0] = m[0] * x + m[4] * y + m[8] * z + m[12] * w;
  out[1] = m[1] * x + m[5] * y + m[9] * z + m[13] * w;
  out[2] = m[2] * x + m[6] * y + m[10] * z + m[14] * w;
  out[3] = m[3] * x + m[7] * y + m[11] * z + m[15] * w;
  return out;
}
/**
 * Transforms the vec4 with a quat
 *
 * @param {vec4} out the receiving vector
 * @param {vec4} a the vector to transform
 * @param {quat} q quaternion to transform with
 * @returns {vec4} out
 */

function transformQuat(out, a, q) {
  var x = a[0],
      y = a[1],
      z = a[2];
  var qx = q[0],
      qy = q[1],
      qz = q[2],
      qw = q[3]; // calculate quat * vec

  var ix = qw * x + qy * z - qz * y;
  var iy = qw * y + qz * x - qx * z;
  var iz = qw * z + qx * y - qy * x;
  var iw = -qx * x - qy * y - qz * z; // calculate result * inverse quat

  out[0] = ix * qw + iw * -qx + iy * -qz - iz * -qy;
  out[1] = iy * qw + iw * -qy + iz * -qx - ix * -qz;
  out[2] = iz * qw + iw * -qz + ix * -qy - iy * -qx;
  out[3] = a[3];
  return out;
}
/**
 * Set the components of a vec4 to zero
 *
 * @param {vec4} out the receiving vector
 * @returns {vec4} out
 */

function zero(out) {
  out[0] = 0.0;
  out[1] = 0.0;
  out[2] = 0.0;
  out[3] = 0.0;
  return out;
}
/**
 * Returns a string representation of a vector
 *
 * @param {vec4} a vector to represent as a string
 * @returns {String} string representation of the vector
 */

function str(a) {
  return 'vec4(' + a[0] + ', ' + a[1] + ', ' + a[2] + ', ' + a[3] + ')';
}
/**
 * Returns whether or not the vectors have exactly the same elements in the same position (when compared with ===)
 *
 * @param {vec4} a The first vector.
 * @param {vec4} b The second vector.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

function exactEquals(a, b) {
  return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3];
}
/**
 * Returns whether or not the vectors have approximately the same elements in the same position.
 *
 * @param {vec4} a The first vector.
 * @param {vec4} b The second vector.
 * @returns {Boolean} True if the vectors are equal, false otherwise.
 */

function equals(a, b) {
  var a0 = a[0],
      a1 = a[1],
      a2 = a[2],
      a3 = a[3];
  var b0 = b[0],
      b1 = b[1],
      b2 = b[2],
      b3 = b[3];
  return Math.abs(a0 - b0) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a0), Math.abs(b0)) && Math.abs(a1 - b1) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a1), Math.abs(b1)) && Math.abs(a2 - b2) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a2), Math.abs(b2)) && Math.abs(a3 - b3) <= _common_js__WEBPACK_IMPORTED_MODULE_0__.EPSILON * Math.max(1.0, Math.abs(a3), Math.abs(b3));
}
/**
 * Alias for {@link vec4.subtract}
 * @function
 */

var sub = subtract;
/**
 * Alias for {@link vec4.multiply}
 * @function
 */

var mul = multiply;
/**
 * Alias for {@link vec4.divide}
 * @function
 */

var div = divide;
/**
 * Alias for {@link vec4.distance}
 * @function
 */

var dist = distance;
/**
 * Alias for {@link vec4.squaredDistance}
 * @function
 */

var sqrDist = squaredDistance;
/**
 * Alias for {@link vec4.length}
 * @function
 */

var len = length;
/**
 * Alias for {@link vec4.squaredLength}
 * @function
 */

var sqrLen = squaredLength;
/**
 * Perform some operation over an array of vec4s.
 *
 * @param {Array} a the array of vectors to iterate over
 * @param {Number} stride Number of elements between the start of each vec4. If 0 assumes tightly packed
 * @param {Number} offset Number of elements to skip at the beginning of the array
 * @param {Number} count Number of vec4s to iterate over. If 0 iterates over entire array
 * @param {Function} fn Function to call for each vector in the array
 * @param {Object} [arg] additional argument to pass to fn
 * @returns {Array} a
 * @function
 */

var forEach = function () {
  var vec = create();
  return function (a, stride, offset, count, fn, arg) {
    var i, l;

    if (!stride) {
      stride = 4;
    }

    if (!offset) {
      offset = 0;
    }

    if (count) {
      l = Math.min(count * stride + offset, a.length);
    } else {
      l = a.length;
    }

    for (i = offset; i < l; i += stride) {
      vec[0] = a[i];
      vec[1] = a[i + 1];
      vec[2] = a[i + 2];
      vec[3] = a[i + 3];
      fn(vec, vec, arg);
      a[i] = vec[0];
      a[i + 1] = vec[1];
      a[i + 2] = vec[2];
      a[i + 3] = vec[3];
    }

    return a;
  };
}();

/***/ }),

/***/ 344:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   k: () => (/* binding */ Anim)
/* harmony export */ });
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(125);
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(849);
/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(562);
/* harmony import */ var _anim_key_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(963);






/**
 * Keyframed interpolated animation.
 *
 * @class
 * @param cfg
 * @example
 * var anim=new CABLES.Anim();
 * anim.setValue(0,0);  // set value 0 at 0 seconds
 * anim.setValue(10,1); // set value 1 at 10 seconds
 * anim.getValue(5);    // get value at 5 seconds - this returns 0.5
 */

class Anim extends cables_shared_client__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A
{
    static EVENT_KEY_DELETE = "keyDelete";
    static EVENT_CHANGE = "onChange";
    static EVENT_UIATTRIB_CHANGE = "uiattrchange";

    static LOOP_OFF = 0;
    static LOOP_REPEAT = 1;
    static LOOP_MIRROR = 2;
    static LOOP_OFFSET = 3;

    static EASING_LINEAR = 0;
    static EASING_ABSOLUTE = 1;
    static EASING_SMOOTHSTEP = 2;
    static EASING_SMOOTHERSTEP = 3;
    static EASING_CUBICSPLINE = 4;

    static EASING_CUBIC_IN = 5;
    static EASING_CUBIC_OUT = 6;
    static EASING_CUBIC_INOUT = 7;

    static EASING_EXPO_IN = 8;
    static EASING_EXPO_OUT = 9;
    static EASING_EXPO_INOUT = 10;

    static EASING_SIN_IN = 11;
    static EASING_SIN_OUT = 12;
    static EASING_SIN_INOUT = 13;

    static EASING_BACK_IN = 14;
    static EASING_BACK_OUT = 15;
    static EASING_BACK_INOUT = 16;

    static EASING_ELASTIC_IN = 17;
    static EASING_ELASTIC_OUT = 18;

    static EASING_BOUNCE_IN = 19;
    static EASING_BOUNCE_OUT = 21;

    static EASING_QUART_IN = 22;
    static EASING_QUART_OUT = 23;
    static EASING_QUART_INOUT = 24;

    static EASING_QUINT_IN = 25;
    static EASING_QUINT_OUT = 26;
    static EASING_QUINT_INOUT = 27;

    static EASINGNAMES = ["linear", "absolute", "smoothstep", "smootherstep", "Cubic In", "Cubic Out", "Cubic In Out", "Expo In", "Expo Out", "Expo In Out", "Sin In", "Sin Out", "Sin In Out", "Quart In", "Quart Out", "Quart In Out", "Quint In", "Quint Out", "Quint In Out", "Back In", "Back Out", "Back In Out", "Elastic In", "Elastic Out", "Bounce In", "Bounce Out"];

    #tlActive = true;
    uiAttribs = {};

    /**
     * @param {AnimCfg} [cfg]
     */
    constructor(cfg = {})
    {
        super();
        cfg = cfg || {};
        this.id = (0,_utils_js__WEBPACK_IMPORTED_MODULE_1__.uuid)();

        /** @type {AnimKey[]} */
        this.keys = [];
        this.onChange = null;
        this.stayInTimeline = false;

        this.loop = 0;
        this._log = new cables_shared_client__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A("Anim");
        this._cachedIndex = 0;
        this.name = cfg.name || null;

        /** @type {Number} */
        this.defaultEasing = cfg.defaultEasing || Anim.EASING_LINEAR;
        this.onLooped = null;

        this._timesLooped = 0;
        this._needsSort = false;
    }

    forceChangeCallback()
    {
        if (this.onChange !== null) this.onChange();
        this.emitEvent(Anim.EVENT_CHANGE, this);
    }

    forceChangeCallbackSoon()
    {
        // clearTimeout(this.forcecbto);
        if (!this.forcecbto)
            this.forcecbto = setTimeout(() =>
            {
                this.forceChangeCallback();
                this.forcecbto = null;
            },
            50);
    }

    getLoop()
    {
        return this.loop;
    }

    /**
     * @param {number} loopType
     */
    setLoop(loopType)
    {
        if (loopType === false)loopType = 0;
        if (loopType === true)loopType = 1;

        this.loop = loopType;
        this.emitEvent(Anim.EVENT_CHANGE, this);
    }

    /**
     * returns true if animation has ended at @time
     * checks if last key time is < time
     * @param {Number} time
     * @returns {Boolean}
     * @memberof Anim
     * @instance
     * @function
     */
    hasEnded(time)
    {
        if (this._needsSort) this.sortKeys();
        if (this.keys.length === 0) return true;
        if (this.keys[this.keys.length - 1].time <= time) return true;
        return false;
    }

    /**
     * @param {number} time
     */
    isRising(time)
    {
        if (this._needsSort) this.sortKeys();
        if (this.hasEnded(time)) return false;
        const ki = this.getKeyIndex(time);
        if (this.keys[ki].value < this.keys[ki + 1].value) return true;
        return false;
    }

    /**
     * remove all keys from animation before time
     * @param {Number} time
     * @memberof Anim
     * @instance
     * @function
     */
    clearBefore(time)
    {
        if (this._needsSort) this.sortKeys();
        const v = this.getValue(time);
        const ki = this.getKeyIndex(time);

        this.setValue(time, v);

        if (ki > 1)
        {
            this.keys.splice(0, ki);
            this._needsSort = true;
        }
    }

    /**
     * remove all keys from animation
     * @param {Number} [time=0] set a new key at time with the old value at time
     * @memberof Anim
     * @instance
     * @function
     */
    clear(time)
    {
        if (this._needsSort) this.sortKeys();
        let v = 0;
        if (time) v = this.getValue(time);

        for (let i = 0; i < this.keys.length; i++)
            this.emitEvent(Anim.EVENT_KEY_DELETE, this.keys[i]);

        this.keys.length = 0;
        if (time) this.setValue(time, v);
        this._needsSort = true;
        if (this.onChange !== null) this.onChange();
        this.emitEvent(Anim.EVENT_CHANGE, this);
    }

    checkIsSorted()
    {
        let isSorted = true;
        for (let i = 0; i < this.keys.length - 1; i++)
            if (this.keys[i].time > this.keys[i + 1].time)
            {
                isSorted = false;
                break;
            }

        return isSorted;
    }

    sortKeys()
    {
        if (!this.checkIsSorted())
        {
            this.keys.sort((a, b) => { return a.time - b.time; });
            this._needsSort = false;
            if (this.keys.length > 999 && this.keys.length % 1000 == 0)console.log(this.name, this.keys.length);

            this.emitEvent(Anim.EVENT_CHANGE);
        }
    }

    hasDuplicates()
    {
        const test = {};
        let count = 0;
        for (let i = 0; i < this.keys.length; i++)
        {
            test[this.keys[i].time] = 1;
            count++;
        }

        const keys = Object.keys(test);
        if (keys.length != count)
        {
            return true;
        }
        return false;
    }

    removeDuplicates()
    {
        if (this.hasDuplicates())
        {
            if (this._needsSort) this.sortKeys();
            let count = 0;

            while (this.hasDuplicates())
            {
                for (let i = 0; i < this.keys.length - 1; i++)
                {
                    if (this.keys[i].time == this.keys[i + 1].time) this.keys.splice(i, 1);
                    count++;
                }
            }
            this._needsSort = true;
        }
    }

    getLengthLoop()
    {
        if (this._needsSort) this.sortKeys();
        if (this.keys.length < 2) return 0;
        return this.lastKey.time - this.firstKey.time;
    }

    getLength()
    {
        if (this._needsSort) this.sortKeys();
        if (this.keys.length === 0) return 0;
        return this.lastKey.time;
    }

    /**
     * @param {number} time
     */
    getKeyIndex(time)
    {
        if (this._needsSort) this.sortKeys();
        let index = 0;
        let start = 0;
        if (this._cachedIndex && this.keys.length > this._cachedIndex && time >= this.keys[this._cachedIndex].time) start = this._cachedIndex;
        for (let i = start; i < this.keys.length; i++)
        {
            if (time >= this.keys[i].time) index = i;
            if (this.keys[i].time > time)
            {
                if (time != 0) this._cachedIndex = index;
                return index;
            }
        }

        return index;
    }

    /**
     * set value at time
     * @param {Number} time
     * @param {Number} value
     * @param {Function} cb callback
     */
    setValue(time, value, cb = null)
    {
        if (this._needsSort) this.sortKeys();
        let found = null;

        if (this.keys.length == 0 || time <= this.lastKey.time)
            for (let i = 0; i < this.keys.length; i++)
                if (this.keys[i].time == time)
                {
                    found = this.keys[i];
                    this.keys[i].setValue(value);
                    this.keys[i].cb = cb;
                    break;
                }

        if (!found)
        {
            found = new _anim_key_js__WEBPACK_IMPORTED_MODULE_3__/* .AnimKey */ .rA(
                {
                    "time": time,
                    "value": value,
                    "e": this.defaultEasing,
                    "cb": cb,
                    "anim": this
                });
            this.keys.push(found);

            // if (this.keys.length % 1000 == 0)console.log(this.name, this.keys.length);
        }

        if (this.onChange) this.onChange();
        this.emitEvent(Anim.EVENT_CHANGE, this);
        this._needsSort = true;
        return found;
    }

    /**
     * @param {number} index
     * @param {number} easing
     */
    setKeyEasing(index, easing)
    {
        if (this.keys[index])
        {
            this.keys[index].setEasing(easing);
            this.emitEvent(Anim.EVENT_CHANGE, this);
        }
    }

    /**
     * @param {object} obj
     */
    deserialize(obj)
    {

        if (obj.loop) this.loop = obj.loop;
        if (obj.tlActive) this.#tlActive = obj.tlActive;
        for (const ani in obj.keys)
        {
            this.keys.push(new _anim_key_js__WEBPACK_IMPORTED_MODULE_3__/* .AnimKey */ .rA(obj.keys[ani], this));
        }
        this.sortKeys();
    }

    /**
     * @returns {SerializedAnim}
     */
    getSerialized()
    {

        /** @type {SerializedAnim} */
        const obj = {};
        obj.keys = [];
        obj.loop = this.loop;
        if (this.#tlActive)obj.tlActive = this.tlActive;

        for (let i = 0; i < this.keys.length; i++)
            obj.keys.push(this.keys[i].getSerialized());

        return obj;
    }

    /**
     * @param {number} time
     */
    getKey(time)
    {
        if (this._needsSort) this.sortKeys();
        const index = this.getKeyIndex(time);
        return this.keys[index];
    }

    /**
     * @param {number} time
     */
    getNextKey(time)
    {
        if (this._needsSort) this.sortKeys();
        let index = this.getKeyIndex(time) + 1;
        if (index >= this.keys.length) return null;

        return this.keys[index];
    }

    /**
     * @param {number} time
     */
    getPrevKey(time)
    {
        if (this._needsSort) this.sortKeys();
        let index = this.getKeyIndex(time) - 1;
        if (index < 0) return null;

        return this.keys[index];
    }

    /**
     * @param {number} time
     */
    isFinished(time)
    {
        if (this._needsSort) this.sortKeys();
        if (this.keys.length <= 0) return true;
        return time > this.lastKey.time;
    }

    /**
     * @param {number} time
     */
    isStarted(time)
    {
        if (this._needsSort) this.sortKeys();
        if (this.keys.length <= 0) return false;
        return time >= this.firstKey.time;
    }

    /**
     * @param {AnimKey} k
     */
    remove(k, events)
    {
        for (let i = 0; i < this.keys.length; i++)
        {
            if (this.keys[i] == k)
            {
                this.emitEvent(Anim.EVENT_KEY_DELETE, this.keys[i]);
                this.keys.splice(i, 1);
                this._needsSort = true;
                if (events === undefined)
                {
                    this.emitEvent(Anim.EVENT_CHANGE, this);
                }
                return;
            }
        }
    }

    get lastKey()
    {
        if (this._needsSort) this.sortKeys();
        return this.keys[this.keys.length - 1];
    }

    get firstKey()
    {
        if (this._needsSort) this.sortKeys();
        return this.keys[0];
    }

    /**
     * @param {number} time
     */
    getLoopIndex(time)
    {
        if (this._needsSort) this.sortKeys();
        if (this.keys.length < 2) return 0;
        return (time - this.firstKey.time) / this.getLengthLoop();
    }

    /**
     * get value at time
     * @function getValue
     * @memberof Anim
     * @instance
     * @param {Number} [time] time
     * @returns {Number} interpolated value at time
     */
    getValue(time)
    {
        let valAdd = 0;
        if (this.keys.length === 0) return 0;
        if (this._needsSort) this.sortKeys();

        if (!this.loop && time > this.keys[this.keys.length - 1].time)
        {
            if (this.lastKey.cb && !this.lastKey.cbTriggered) this.lastKey.trigger();

            return this.lastKey.value;
        }

        if (time < this.firstKey.time) return this.keys[0].value;

        if (this.loop && this.keys.length > 1 && time > this.lastKey.time)
        {
            const currentLoop = this.getLoopIndex(time);
            if (currentLoop > this._timesLooped)
            {
                this._timesLooped++;
                if (this.onLooped) this.onLooped();
            }

            time = (time - this.firstKey.time) % (this.getLengthLoop());

            if (this.loop == Anim.LOOP_REPEAT) { }
            else if (this.loop == Anim.LOOP_MIRROR)
            {
                if (Math.floor(currentLoop) % 2 == 1)time = this.getLengthLoop() - time;
            }
            else if (this.loop == Anim.LOOP_OFFSET)
            {
                valAdd = (this.lastKey.value - this.keys[0].value) * Math.floor(currentLoop);
            }

            time += this.firstKey.time;
        }

        const index = this.getKeyIndex(time);
        if (index >= this.keys.length - 1)
        {
            if (this.lastKey.cb && !this.lastKey.cbTriggered) this.lastKey.trigger();
            return this.lastKey.value;
        }

        const index2 = index + 1;
        const key1 = this.keys[index];
        const key2 = this.keys[index2];

        if (key1.cb && !key1.cbTriggered) key1.trigger();

        if (!key2) return -1;

        const perc = (time - key1.time) / (key2.time - key1.time);

        return key1.ease(perc, key2) + valAdd;
    }

    /**
     * @param {AnimKey} k
     */
    addKey(k)
    {
        if (k.time === undefined)
        {
            this._log.warn("key time undefined, ignoring!");
        }
        else
        {
            this.keys.push(k);
            if (this.onChange !== null) this.onChange();
            this.emitEvent(Anim.EVENT_CHANGE, this);
            this._needsSort = true;
        }
    }

    sortSoon()
    {
        this._needsSort = true;
    }

    /**
     * @param {string} str
     */
    easingFromString(str)
    {
        // todo smarter way to map ?
        if (str == "linear") return Anim.EASING_LINEAR;
        if (str == "absolute") return Anim.EASING_ABSOLUTE;
        if (str == "smoothstep") return Anim.EASING_SMOOTHSTEP;
        if (str == "smootherstep") return Anim.EASING_SMOOTHERSTEP;

        if (str == "Cubic In") return Anim.EASING_CUBIC_IN;
        if (str == "Cubic Out") return Anim.EASING_CUBIC_OUT;
        if (str == "Cubic In Out") return Anim.EASING_CUBIC_INOUT;

        if (str == "Expo In") return Anim.EASING_EXPO_IN;
        if (str == "Expo Out") return Anim.EASING_EXPO_OUT;
        if (str == "Expo In Out") return Anim.EASING_EXPO_INOUT;

        if (str == "Sin In") return Anim.EASING_SIN_IN;
        if (str == "Sin Out") return Anim.EASING_SIN_OUT;
        if (str == "Sin In Out") return Anim.EASING_SIN_INOUT;

        if (str == "Back In") return Anim.EASING_BACK_IN;
        if (str == "Back Out") return Anim.EASING_BACK_OUT;
        if (str == "Back In Out") return Anim.EASING_BACK_INOUT;

        if (str == "Elastic In") return Anim.EASING_ELASTIC_IN;
        if (str == "Elastic Out") return Anim.EASING_ELASTIC_OUT;

        if (str == "Bounce In") return Anim.EASING_BOUNCE_IN;
        if (str == "Bounce Out") return Anim.EASING_BOUNCE_OUT;

        if (str == "Quart Out") return Anim.EASING_QUART_OUT;
        if (str == "Quart In") return Anim.EASING_QUART_IN;
        if (str == "Quart In Out") return Anim.EASING_QUART_INOUT;

        if (str == "Quint Out") return Anim.EASING_QUINT_OUT;
        if (str == "Quint In") return Anim.EASING_QUINT_IN;
        if (str == "Quint In Out") return Anim.EASING_QUINT_INOUT;

        console.log("unknown anim easing?", str);
    }

    /**
     * @param {Op} op
     * @param {string} title
     * @param {function} cb
     * @returns {Port}
     */
    createPort(op, title, cb)
    {
        const port = op.inDropDown(title, Anim.EASINGNAMES, "linear");
        port.set("linear");
        port.defaultValue = "linear";

        port.onChange = () =>
        {
            this.defaultEasing = this.easingFromString(port.get());
            this.emitEvent("onChangeDefaultEasing", this);

            if (cb) cb();
        };

        return port;
    }

    get tlActive()
    {
        return this.#tlActive;
    }

    set tlActive(b)
    {
        if (CABLES.UI)
        {
            this.#tlActive = b;
            window.gui.emitEvent("tlActiveChanged", this);
            this.forceChangeCallbackSoon();
        }
    }

    /**
     * @param {Object} o
     */
    setUiAttribs(o)
    {
        for (const i in o)
        {
            this.uiAttribs[i] = o[i];
            if (o[i] === null) delete this.uiAttribs[i];
        }

        this.emitEvent(Anim.EVENT_UIATTRIB_CHANGE);
    }

    /**
     * @param {number} t
     * @param {number} t2
     */
    hasKeyframesBetween(t, t2)
    {
        return this.getKeyIndex(t) != this.getKeyIndex(t2);
    }
}

// ------------------------------


/***/ }),

/***/ 963:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   rA: () => (/* binding */ AnimKey)
/* harmony export */ });
/* unused harmony exports easeExpoIn, easeExpoOut, easeExpoInOut, easeCubicIn, easeCubicOut, easeCubicInOut */
/* harmony import */ var _anim_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(344);


class AnimKey
{

    /** @type {Anim} */
    anim = null;
    id = CABLES.shortId();
    time = 0.0;
    value = 0.0;
    selected = false;
    onChange = null;
    _easing = 0;
    bezCp1 = null;
    bezCp2 = null;
    bezAn = null;
    cb = null;
    cbTriggered = false;
    temp = {};
    uiAttribs = {};

    /**
     * @param {SerializedKey} obj
     * @param {Anim} [an]
     */
    constructor(obj, an)
    {
        this.anim = obj.anim || an || null;

        this.setEasing(_anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_LINEAR);
        this.set(obj);
    }

    emitChange()
    {
        if (!this.anim) return;
        this.bezAn = null;
        if (this.onChange !== null) this.onChange();
        this.anim.forceChangeCallbackSoon();
        for (let i = 0; i < this.anim.keys.length; i++)
            this.anim.keys[i].bezAn = null;

    }

    delete()
    {
        if (this.anim) this.anim.remove(this);
        else console.log("animkey without anim...");
    }

    /**
     * @param {Object} o
     */
    setUiAttribs(o)
    {
        for (const i in o)
        {
            this.uiAttribs[i] = o[i];
            if (o[i] === null) delete this.uiAttribs[i];
        }
        if (this.anim) this.anim.emitEvent(_anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EVENT_CHANGE);
    }

    /**
     * @param {Number} e
     */
    setEasing(e)
    {
        let changed = false;
        if (this._easing != e)changed = true;
        this._easing = e;

        if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_LINEAR) this.ease = this.easeLinear;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_ABSOLUTE) this.ease = this.easeAbsolute;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_SMOOTHSTEP) this.ease = AnimKey.easeSmoothStep;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_SMOOTHERSTEP) this.ease = AnimKey.easeSmootherStep;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_CUBIC_IN) this.ease = AnimKey.easeCubicIn;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_CUBIC_OUT) this.ease = AnimKey.easeCubicOut;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_CUBIC_INOUT) this.ease = AnimKey.easeCubicInOut;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_EXPO_IN) this.ease = AnimKey.easeExpoIn;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_EXPO_OUT) this.ease = AnimKey.easeExpoOut;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_EXPO_INOUT) this.ease = AnimKey.easeExpoInOut;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_SIN_IN) this.ease = AnimKey.easeSinIn;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_SIN_OUT) this.ease = AnimKey.easeSinOut;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_SIN_INOUT) this.ease = AnimKey.easeSinInOut;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_BACK_OUT) this.ease = AnimKey.easeOutBack;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_BACK_IN) this.ease = AnimKey.easeInBack;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_BACK_INOUT) this.ease = AnimKey.easeInOutBack;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_ELASTIC_IN) this.ease = AnimKey.easeInElastic;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_ELASTIC_OUT) this.ease = AnimKey.easeOutElastic;
        // else if (this._easing == Anim.EASING_ELASTIC_INOUT) this.ease = AnimKey.easeElasticInOut;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_BOUNCE_IN) this.ease = AnimKey.easeInBounce;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_BOUNCE_OUT) this.ease = AnimKey.easeOutBounce;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_QUART_OUT) this.ease = AnimKey.easeOutQuart;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_QUART_IN) this.ease = AnimKey.easeInQuart;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_QUART_INOUT) this.ease = AnimKey.easeInOutQuart;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_QUINT_OUT) this.ease = AnimKey.easeOutQuint;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_QUINT_IN) this.ease = AnimKey.easeInQuint;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_QUINT_INOUT) this.ease = AnimKey.easeInOutQuint;
        else if (this._easing == _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_CUBICSPLINE)
        {
            if (this.ease != this.easeCubicSpline)
            {
                this.ease = this.easeCubicSpline;
                this.bezReset();
            }

            this.bezAn = null;
        }
        else
        {
            this._easing = _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_LINEAR;
            this.ease = this.easeLinear;
        }
        if (changed) this.emitChange();
    }

    bezReset()
    {

        let xx = 0.5;
        const pk = this.anim.getPrevKey(this.time);
        if (pk)xx = (this.time - pk.time) / 2;

        let x2 = 0.5;
        const nk = this.anim.getNextKey(this.time);
        if (nk)x2 = (nk.time - this.time) / 2;

        this.bezCp1 = [-Math.min(xx, x2), 0];
        this.bezCp2 = [Math.min(xx, x2), 0];
        this.emitChange();
    }

    trigger()
    {
        this.cb();
        this.cbTriggered = true;
    }

    /**
     * @param {number} v
     */
    setValue(v)
    {
        this.value = v;
        this.emitChange();
    }

    /**
     * @param {number} t
     * @param {number} v
     */
    setBezCp1(t, v)
    {
        this.bezCp1 = [t, v];
        this.emitChange();
    }

    /**
     * @param {number} t
     * @param {number} v
     */
    setBezCp2(t, v)
    {
        this.bezCp2 = [t, v];
        this.emitChange();
    }

    /**
     * @param {SerializedKey} obj
     */
    set(obj)
    {
        if (obj)
        {
            if (obj.hasOwnProperty("e")) this.setEasing(obj.e);
            if (obj.cb)
            {
                this.cb = obj.cb;
                this.cbTriggered = false;
            }

            if (obj.hasOwnProperty("cp1"))
            {
                this.bezCp1 = obj.cp1;
                this.bezCp2 = obj.cp2;
            }

            if (obj.hasOwnProperty("t")) this.time = obj.t;
            if (obj.hasOwnProperty("time")) this.time = obj.time;
            if (obj.hasOwnProperty("v")) this.value = obj.v;
            else if (obj.hasOwnProperty("value")) this.value = obj.value;

            if (obj.hasOwnProperty("uiAttribs")) this.setUiAttribs(obj.uiAttribs);
        }
        this.emitChange();
    }

    /**
   * @returns {Object}
   */
    getSerialized()
    {
        const obj = {};
        obj.t = this.time;
        obj.v = this.value;
        obj.e = this._easing;
        obj.uiAttribs = this.uiAttribs;

        if (this._easing === _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASING_CUBICSPLINE)
        {
            obj.cp1 = this.bezCp1;
            obj.cp2 = this.bezCp2;
        }

        return obj;
    }

    getEasing()
    {
        return this._easing;
    }

    /**
     * @param {number} perc
     * @param {AnimKey} key2
     */
    easeCubicSpline(perc, key2)
    {
        if (!this.bezAn)
        {
            const samples = 30;

            // const prevKey = this.anim.getPrevKey(this.time);
            this.bezAn = new _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k();
            for (let i = 0; i <= samples + 1; i++)
            {
                const c = AnimKey.cubicSpline(i / samples, this, key2);
                this.bezAn.setValue(c[0], c[1]);
            }
        }

        return this.bezAn.getValue(this.time + perc * (key2.time - this.time));
        // return AnimKey.cubicSpline(perc, this, key2);
    }

    /**
     * @param {number} perc
     * @param {AnimKey} key2
     */
    easeLinear(perc, key2)
    {
        return AnimKey.linear(perc, this, key2);
    }

    easeAbsolute()
    {
        return this.value;
    }
}

AnimKey.cubicSpline = function (t, key1, key2)
{
    const tInv = 1 - t;
    const tInvSq = tInv * tInv;
    const tSq = t * t;

    const c0 = tInvSq * tInv;
    const c1 = 3 * tInvSq * t;
    const c2 = 3 * tInv * tSq;
    const c3 = tSq * t;

    key1.bezCp1 = key1.bezCp1 || [-0.5, 0];
    key1.bezCp2 = key1.bezCp2 || [0.5, 0];
    key2.bezCp1 = key2.bezCp1 || [-0.5, 0];
    key2.bezCp2 = key2.bezCp2 || [0.5, 0];

    const x1 = Math.min(key2.time, key1.bezCp2[0] + key1.time);
    const xp = Math.max(key1.time, key2.bezCp1[0] + key2.time);
    // const xp = key2.bezCp1[0] + key2.time;
    // console.log("textjjjj", key2.time, key0.time);

    // const x = c0 + c1 * (key1.bezCp2[0]) + c2 * (key2.bezCp1[0]) + c3;
    const x = c0 * key1.time + c1 * (x1) + c2 * (xp) + c3 * (key2.time);
    const y = c0 * key1.value + c1 * (key1.bezCp2[1] + key1.value) + c2 * (key2.bezCp1[1] + key2.value) + c3 * (key2.value);

    return [x, y];
};

AnimKey.linear = function (perc, key1, key2)
{
    return (key1.value) + (key2.value - key1.value) * perc;
};

const easeExpoIn = function (t)
{
    return (t = 2 ** (10 * (t - 1)));
};

AnimKey.easeExpoIn = function (t, key2)
{
    t = easeExpoIn(t);
    return AnimKey.linear(t, this, key2);
};

const easeExpoOut = function (t)
{
    t = -(2 ** (-10 * t)) + 1;
    return t;
};

AnimKey.easeExpoOut = function (t, key2)
{
    t = easeExpoOut(t);
    return AnimKey.linear(t, this, key2);
};

const easeExpoInOut = function (t)
{
    t *= 2;
    if (t < 1)
    {
        t = 0.5 * 2 ** (10 * (t - 1));
    }
    else
    {
        t--;
        t = 0.5 * (-(2 ** (-10 * t)) + 2);
    }
    return t;
};

AnimKey.easeExpoInOut = function (t, key2)
{
    t = easeExpoInOut(t);
    return AnimKey.linear(t, this, key2);
};

AnimKey.easeSinIn = function (t, key2)
{
    t = -1 * Math.cos((t * Math.PI) / 2) + 1;
    return AnimKey.linear(t, this, key2);
};

AnimKey.easeSinOut = function (t, key2)
{
    t = Math.sin((t * Math.PI) / 2);
    return AnimKey.linear(t, this, key2);
};

AnimKey.easeSinInOut = function (t, key2)
{
    t = -0.5 * (Math.cos(Math.PI * t) - 1.0);
    return AnimKey.linear(t, this, key2);
};

const easeCubicIn = function (t)
{
    t = t * t * t;
    return t;
};

AnimKey.easeCubicIn = function (t, key2)
{
    t = easeCubicIn(t);
    return AnimKey.linear(t, this, key2);
};

// b 0
// c 1/2 or 1
// d always 1
// easeOutCubic: function (x, t, b, c, d) {
//     return c*((t=t/d-1)*t*t + 1) + b;

AnimKey.easeInQuint = function (t, key2)
{
    t = t * t * t * t * t;
    return AnimKey.linear(t, this, key2);
};
AnimKey.easeOutQuint = function (t, key2)
{
    t = (t -= 1) * t * t * t * t + 1;
    return AnimKey.linear(t, this, key2);
};
AnimKey.easeInOutQuint = function (t, key2)
{
    if ((t /= 0.5) < 1) t = 0.5 * t * t * t * t * t;
    else t = 0.5 * ((t -= 2) * t * t * t * t + 2);
    return AnimKey.linear(t, this, key2);
};

AnimKey.easeInQuart = function (t, key2)
{
    t = t * t * t * t;
    return AnimKey.linear(t, this, key2);
};

AnimKey.easeOutQuart = function (t, key2)
{
    // return -c * ((t=t/d-1)*t*t*t - 1) + b;
    t = -1 * ((t -= 1) * t * t * t - 1);
    return AnimKey.linear(t, this, key2);
};

AnimKey.easeInOutQuart = function (t, key2)
{
    if ((t /= 0.5) < 1) t = 0.5 * t * t * t * t;
    else t = -0.5 * ((t -= 2) * t * t * t - 2);
    return AnimKey.linear(t, this, key2);
};

AnimKey.bounce = function (t)
{
    if ((t /= 1) < 1 / 2.75) t = 7.5625 * t * t;
    else if (t < 2 / 2.75) t = 7.5625 * (t -= 1.5 / 2.75) * t + 0.75;
    else if (t < 2.5 / 2.75) t = 7.5625 * (t -= 2.25 / 2.75) * t + 0.9375;
    else t = 7.5625 * (t -= 2.625 / 2.75) * t + 0.984375;
    return t;
};

AnimKey.easeInBounce = function (t, key2)
{
    return AnimKey.linear(AnimKey.bounce(t), this, key2);
    // return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d);
};

AnimKey.easeOutBounce = function (t, key2)
{
    return AnimKey.linear(AnimKey.bounce(t), this, key2);
};

AnimKey.easeInElastic = function (t, key2)
{
    let s = 1.70158;
    let p = 0;
    let a = 1;

    const b = 0;
    const d = 1;
    const c = 1;

    if (t === 0) t = b;
    else if ((t /= d) == 1) t = b + c;
    else
    {
        if (!p) p = d * 0.3;
        if (a < Math.abs(c))
        {
            a = c;
            s = p / 4;
        }
        else s = (p / (2 * Math.PI)) * Math.asin(c / a);
        t = -(a * 2 ** (10 * (t -= 1)) * Math.sin(((t * d - s) * (2 * Math.PI)) / p)) + b;
    }

    return AnimKey.linear(t, this, key2);
};

AnimKey.easeOutElastic = function (t, key2)
{
    let s = 1.70158;
    let p = 0;
    let a = 1;

    const b = 0;
    const d = 1;
    const c = 1;

    if (t === 0) t = b;
    else if ((t /= d) == 1) t = b + c;
    else
    {
        if (!p) p = d * 0.3;
        if (a < Math.abs(c))
        {
            a = c;
            s = p / 4;
        }
        else s = (p / (2 * Math.PI)) * Math.asin(c / a);
        t = a * 2 ** (-10 * t) * Math.sin(((t * d - s) * (2 * Math.PI)) / p) + c + b;
    }

    return AnimKey.linear(t, this, key2);
};

AnimKey.easeInBack = function (t, key2)
{
    const s = 1.70158;
    t = t * t * ((s + 1) * t - s);

    return AnimKey.linear(t, this, key2);
};

AnimKey.easeOutBack = function (t, key2)
{
    const s = 1.70158;
    t = (t = t / 1 - 1) * t * ((s + 1) * t + s) + 1;

    return AnimKey.linear(t, this, key2);
};

AnimKey.easeInOutBack = function (t, key2)
{
    let s = 1.70158;
    const c = 1 / 2;
    if ((t /= 1 / 2) < 1) t = c * (t * t * (((s *= 1.525) + 1) * t - s));
    else t = c * ((t -= 2) * t * (((s *= 1.525) + 1) * t + s) + 2);

    return AnimKey.linear(t, this, key2);
};

const easeCubicOut = function (t)
{
    t--;
    t = t * t * t + 1;
    return t;
};

AnimKey.easeCubicOut = function (t, key2)
{
    t = easeCubicOut(t);
    return AnimKey.linear(t, this, key2);
};

const easeCubicInOut = function (t)
{
    t *= 2;
    if (t < 1) t = 0.5 * t * t * t;
    else
    {
        t -= 2;
        t = 0.5 * (t * t * t + 2);
    }
    return t;
};

AnimKey.easeCubicInOut = function (t, key2)
{
    t = easeCubicInOut(t);
    return AnimKey.linear(t, this, key2);
};

AnimKey.easeSmoothStep = function (perc, key2)
{
    // var x = Math.max(0, Math.min(1, (perc-0)/(1-0)));
    const x = Math.max(0, Math.min(1, perc));
    perc = x * x * (3 - 2 * x); // smoothstep
    return AnimKey.linear(perc, this, key2);
};

AnimKey.easeSmootherStep = function (perc, key2)
{
    const x = Math.max(0, Math.min(1, (perc - 0) / (1 - 0)));
    perc = x * x * x * (x * (x * 6 - 15) + 10); // smootherstep
    return AnimKey.linear(perc, this, key2);
};


/***/ }),

/***/ 440:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   a: () => (/* binding */ CONSTANTS)
/* harmony export */ });
/* harmony import */ var _anim_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(344);


const CONSTANTS = {
    "ANIM": {
        "EASINGS": _anim_js__WEBPACK_IMPORTED_MODULE_0__/* .Anim */ .k.EASINGNAMES,
        "EASING_LINEAR": 0,
        "EASING_ABSOLUTE": 1,
        "EASING_SMOOTHSTEP": 2,
        "EASING_SMOOTHERSTEP": 3,
        "EASING_CUBICSPLINE": 4,

        "EASING_CUBIC_IN": 5,
        "EASING_CUBIC_OUT": 6,
        "EASING_CUBIC_INOUT": 7,

        "EASING_EXPO_IN": 8,
        "EASING_EXPO_OUT": 9,
        "EASING_EXPO_INOUT": 10,

        "EASING_SIN_IN": 11,
        "EASING_SIN_OUT": 12,
        "EASING_SIN_INOUT": 13,

        "EASING_BACK_IN": 14,
        "EASING_BACK_OUT": 15,
        "EASING_BACK_INOUT": 16,

        "EASING_ELASTIC_IN": 17,
        "EASING_ELASTIC_OUT": 18,

        "EASING_BOUNCE_IN": 19,
        "EASING_BOUNCE_OUT": 21,

        "EASING_QUART_IN": 22,
        "EASING_QUART_OUT": 23,
        "EASING_QUART_INOUT": 24,

        "EASING_QUINT_IN": 25,
        "EASING_QUINT_OUT": 26,
        "EASING_QUINT_INOUT": 27,
    },

    "OP": {
        "OP_PORT_TYPE_VALUE": 0,
        "OP_PORT_TYPE_NUMBER": 0,
        "OP_PORT_TYPE_FUNCTION": 1,
        "OP_PORT_TYPE_TRIGGER": 1,
        "OP_PORT_TYPE_OBJECT": 2,
        "OP_PORT_TYPE_TEXTURE": 2,
        "OP_PORT_TYPE_ARRAY": 3,
        "OP_PORT_TYPE_DYNAMIC": 4,
        "OP_PORT_TYPE_STRING": 5,

        "OP_VERSION_PREFIX": "_v",
    },

    "PORT": {
        "PORT_DIR_IN": 0,
        "PORT_DIR_OUT": 1,
    },

    "PACO": {
        "PACO_CLEAR": 0,
        "PACO_VALUECHANGE": 1,
        "PACO_OP_DELETE": 2,
        "PACO_UNLINK": 3,
        "PACO_LINK": 4,
        "PACO_LOAD": 5,
        "PACO_OP_CREATE": 6,
        "PACO_OP_ENABLE": 7,
        "PACO_OP_DISABLE": 8,
        "PACO_UIATTRIBS": 9,
        "PACO_VARIABLES": 10,
        "PACO_TRIGGERS": 11,
        "PACO_PORT_SETVARIABLE": 12,
        "PACO_PORT_SETANIMATED": 13,
        "PACO_PORT_ANIM_UPDATED": 14,
        "PACO_DESERIALIZE": 15,
        "PACO_OP_RELOAD": 16
    },
};


/***/ }),

/***/ 50:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   I: () => (/* binding */ Port)
/* harmony export */ });
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(125);
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(849);
/* harmony import */ var _constants_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(440);
/* harmony import */ var _utils_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(562);
/* harmony import */ var _anim_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(344);








/**
 * @typedef PortUiAttribs
 * @property  {String} [title] overwrite title of port (by default this is portname)
 * @property  {String} [display] how the port is displayed and interacted in the paramerer panel
 * @property  {Boolean} [greyout] port paramater will appear greyed out, can not be
 * @property  {Boolean} [hidePort] port will be hidden from op
 * @property  {Boolean} [hideParam] port params will be hidden from parameter panel
 * @property  {Boolean} [showIndex] only for dropdowns - show value index (e.g. `0 - normal` )
 * @property  {String} [editorSyntax] set syntax highlighting theme for editor port
 * @property  {Boolean} [ignoreObjTypeErrors] do not auto check object types
 * @property  {string} [group] do not set manually - group ports, usually set by op.setPortGroup...
 * @property  {Boolean} [isAnimated] internal: do not set manually
 * @property  {Boolean} [useVariable] internal: do not set manually
 * @property  {string} [variableName] internal: do not set manually
 * @property  {Number} [order] internal: do not set manually
 * @property  {Number} [stride] internal: do not set manually
 * @property  {Boolean} [expose] internal: do not set manually
 * @property  {Boolean} [multiPortManual] internal: do not set manually
 * @property  {String} [increment] internal: do not set manually
 * @property  {Number} [multiPortNum] internal: do not set manually
 * @property  {String} [display] internal: do not set manually
 * @property  {String} [axis] internal: do not set manually
 * @property  {String} [type] internal: do not set manually
 * @property  {String} [objType] internal: do not set manually
 * @property  {String} [filter] internal: do not set manually
 * @property  {boolean} [hideFormatButton] internal: do not set manually
 * @property  {boolean} [editShortcut] internal: do not set manually
 * @property  {String} [filter] internal: do not set manually
 * @property  {boolean} [preview] internal: do not set manually
 * @property  {boolean} [colorPick] internal: do not set manually
 * @property  {Array<String>} [values] internal: do not set manually
 * @property  {boolean} [boundToVar] internal: do not set manually
 * @property  {boolean} [addPort] internal: do not set manually
 * @property  {boolean} [notWorking] internal: do not set manually
 * @property  {number} [glPortIndex] internal: do not set manually
 * @property  {boolean} [readOnly] internal: do not set manually
 *
 */

/**
 * data is coming into and out of ops through input and output ports
 * @namespace external:CABLES#Port
 * @module Port
 * @class
 * @example
 * const myPort=op.inString("String Port");
 */
class Port extends cables_shared_client__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A
{
    static DIR_IN = 0;
    static DIR_OUT = 1;

    static TYPE_VALUE = 0;
    static TYPE_NUMBER = 0;
    static TYPE_FUNCTION = 1;
    static TYPE_TRIGGER = 1;
    static TYPE_OBJECT = 2;
    static TYPE_TEXTURE = 2;
    static TYPE_ARRAY = 3;
    static TYPE_DYNAMIC = 4;
    static TYPE_STRING = 5;

    static EVENT_UIATTRCHANGE = "onUiAttrChange";
    static EVENT_VALUE_CHANGE = "change";

    #oldAnimVal = -5711;

    animMuted = false;

    lastAnimTime = 0;
    #uiActiveState = true;
    #valueBeforeLink = null;
    // #lastAnimFrame = -1;
    #animated = false;
    // #tempLastUiValue = null;
    #useVariableName = null;

    /**
     * @param {Op} ___op
     * @param {string} name
     * @param {number} type
     * @param {PortUiAttribs} uiAttribs
     */
    constructor(___op, name, type, uiAttribs = {})
    {
        super();
        this.data = {}; // UNUSED, DEPRECATED, only left in for backwards compatibility with userops
        this._log = new cables_shared_client__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A("core_port");

        /**
         * @type {Number}
         * @name direction
         * @instance
         * @memberof Port
         * @description direction of port (input(0) or output(1))
         */
        this.direction = Port.DIR_IN;
        this.id = String(CABLES.simpleId());

        /** @type {Op|UiOp} */
        this._op = ___op;

        /** @type {Array<Link>} */
        this.links = [];

        /** @type {any} */
        this.value = 0.0;

        this.name = name;

        /** @type {number} */
        this.type = type || Port.TYPE_VALUE;

        /** @type {PortUiAttribs} */
        this.uiAttribs = uiAttribs || {};

        /** @type {Anim} */
        this.anim = null;

        this.defaultValue = null;

        this.ignoreValueSerialize = false;
        this.onLinkChanged = null;
        this.crashed = false;

        this.onValueChanged = null;
        this.onTriggered = null;
        this.changeAlways = false;
        this.forceRefChange = false;

        this.activityCounter = 0;
        this.apf = 0;
        this.activityCounterStartFrame = 0;

        this.canLink = null; // function can be overwritten
        this.preserveLinks = null;
        this.indexPort = null;
    }

    get parent()
    {
        this._log.stack("use port.op, not .parent");
        return this.op;
    }

    get title()
    {
        return this.uiAttribs.title || this.name;
    }

    get op()
    {
        return this._op;
    }

    get val()
    {
        return this.get();
    }

    set val(v)
    {
        this.setValue(v);
    }

    /**
     * copy over a uiattrib from an external connected port to another port
     * @function copyLinkedUiAttrib
     * @memberof Port
     * @param {string} which attrib name
     * @param {Port} port source port
     * @instance
     * @example
     *
     *  inArray.onLinkChanged=()=>
     *  {
     *      if(inArray) inArray.copyLinkedUiAttrib("stride", outArray);
     *  };
     *
     */
    copyLinkedUiAttrib(which, port)
    {
        if (!CABLES.UI) return;
        if (!this.isLinked()) return;

        const attr = {};
        attr[which] = this.links[0].getOtherPort(this).getUiAttrib(which);
        port.setUiAttribs(attr);
    }

    /*
     * TODO make extend class for ports, like for ops only for ui
     */
    getValueForDisplay()
    {
        let str = this.value;

        if (typeof this.value === "string" || this.value instanceof String)
        {
            if (str.length > 1000)
            {
                str = str.substring(0, 999);
                str += "...";
            }
            if (this.uiAttribs && (this.uiAttribs.display == "boolnum"))
            {
                str += " - ";

                if (!this.value) str += "false";
                else str += "true";
            }

            str = str.replace(/[\u00A0-\u9999<>\&]/g, function (/** @type {String} */ i)
            {
                return "&#" + i.charCodeAt(0) + ";";
            });

            if (str.length > 100) str = str.substring(0, 100);
        }
        else
        {
            str = String(this.value);
        }
        // if (this.type == Port.TYPE_NUMBER)
        // {
        //     if (isNaN(this.value)) return "NaN";

        // }
        return str;
    }

    /**
     * change listener for input value ports, overwrite to react to changes
     * @function onChange
     * @memberof Port
     * @instance
     * @example
     * const myPort=op.inString("MyPort");
     * myPort.onChange=function()
     * {
     *   console.log("was changed to: ",myPort.get());
     * }
     *
     */
    onAnimToggle() {}

    _onAnimToggle()
    {
        this.onAnimToggle();
    }

    /**
     * @function remove
     * @memberof Port
     * @instance
     * @description remove port
     */
    remove()
    {
        this.removeLinks();
        this._op.removePort(this);
    }

    /**
     * set ui attributes
     * @function setUiAttribs
     * @memberof Port
     * @instance
     * @param {PortUiAttribs} newAttribs

     * @example
     * myPort.setUiAttribs({greyout:true});
     */
    setUiAttribs(newAttribs)
    {
        let changed = false;
        if (!this.uiAttribs) this.uiAttribs = {};

        for (const p in newAttribs)
        {
            if (newAttribs[p] === undefined)
            {
                delete this.uiAttribs[p];
                continue;
            }
            if (this.uiAttribs[p] != newAttribs[p]) changed = true;
            this.uiAttribs[p] = newAttribs[p];

            if (p == "group" && this.indexPort) this.indexPort.setUiAttribs({ "group": newAttribs[p] });
        }

        if (newAttribs.hasOwnProperty("expose")) this._op.patch.emitEvent("subpatchExpose", this._op.uiAttribs.subPatch);

        if (changed) this.emitEvent(Port.EVENT_UIATTRCHANGE, newAttribs, this);
    }

    /**
     * get ui attributes
     * @function getUiAttribs
     * @memberof Port
     * @example
     * myPort.getUiAttribs();
     */
    getUiAttribs()
    {
        return this.uiAttribs;
    }

    /**
     * get ui attribute
     * @function getUiAttrib
     * @memberof Port
     * @instance
     * @param {String} attribName
     * <pre>
     * attribName - return value of the ui-attribute, or null on unknown attribute
     * </pre>
     * @example
     * myPort.setUiAttribs("values");
     */
    getUiAttrib(attribName)
    {
        if (!this.uiAttribs || !this.uiAttribs.hasOwnProperty(attribName)) return null;
        return this.uiAttribs[attribName];
    }

    /**
     * @function get
     * @memberof Port
     * @instance
     * @description get value of port
     */
    get()
    {
        if (CABLES.UI && this.#animated && this.lastAnimTime == this._op.patch.timer.getTime() && !CABLES.UI.keyframeAutoCreate)
        {
            return this.value;
        }
        if (!this.animMuted && this.#animated && this.lastAnimFrame != this._op.patch.getFrameNum())
        {
            this.lastAnimTime = this._op.patch.timer.getTime();
            this.lastAnimFrame = this._op.patch.getFrameNum();

            let animval = this.anim.getValue(this._op.patch.timer.getTime());

            if (this.value != animval)
            {
                this.value = animval;
                this.#oldAnimVal = this.value;
                this.forceChange();
            }
        }

        return this.value;
    }

    /**
     * @param {object|array} v
     */
    setRef(v)
    {
        this.forceRefChange = true;
        this.set(v);
    }

    /**
     * @function setValue
     * @memberof Port
     * @instance
     * @description set value of port / will send value to all linked ports (only for output ports)
     * @param {string | number | boolean | any[]} v
     */
    set(v)
    {

        this.setValue(v);
    }

    /**
     * @param {string|boolean|number} v
     */
    setValue(v)
    {
        if (v === undefined) v = null;

        if (CABLES.UI && CABLES.UI.showDevInfos)
            if (this.direction == _constants_js__WEBPACK_IMPORTED_MODULE_2__/* .CONSTANTS */ .a.PORT.PORT_DIR_OUT && this.type == Port.TYPE_OBJECT && v && !this.forceRefChange)
                this._log.warn("object port [" + this.name + "] uses .set [" + this.op.objName + "]");

        if (this._op.enabled && !this.crashed)
        {
            if (v !== this.value || this.changeAlways || this.type == Port.TYPE_TEXTURE || this.type == Port.TYPE_ARRAY)
            {
                if (CABLES.UI && this.#animated)
                {
                    CABLES.UI.PREVISKEYVAL = null;
                    if (!CABLES.UI.keyframeAutoCreate) CABLES.UI.PREVISKEYVAL = v;
                }

                if (CABLES.UI && this.#animated && CABLES.UI.keyframeAutoCreate)
                {
                    let t = this._op.patch.timer.getTime();
                    if (CABLES.UI && window.gui.glTimeline) window.gui.glTimeline.createKey(this.anim, t, v);
                    else this.anim.setValue(t, v);
                }
                else
                {
                    try
                    {
                        this.value = v;
                        this.forceChange();
                    }
                    catch (ex)
                    {
                        this.crashed = true;

                        this.setValue = function (_v) {};
                        this.onTriggered = function (a) {};

                        this._log.error("exception in ", this._op);
                        this._log.error(ex);

                        this._op.patch.emitEvent("exception", ex, this._op);
                    }

                    if (this._op && this._op.patch && this._op.patch.isEditorMode() && this.type == Port.TYPE_TEXTURE) gui.texturePreview().updateTexturePort(this);
                }

                if (this.direction == _constants_js__WEBPACK_IMPORTED_MODULE_2__/* .CONSTANTS */ .a.PORT.PORT_DIR_OUT) for (let i = 0; i < this.links.length; ++i) this.links[i].setValue();
            }
        }
    }

    updateAnim()
    {
        if (!this.#animated || this.animMuted) return;
        this.value = this.get();

        if (this.#oldAnimVal != this.value || this.changeAlways)
        {
            this.#oldAnimVal = this.value;
            this.forceChange();
        }
        this.#oldAnimVal = this.value;

    }

    forceChange()
    {
        if (this.onValueChanged || this.onChange)
        {

        /*
         * very temporary: deprecated warning!!!!!!!!!
         * if(params.length>0) this._log.warn('TOM: port has onchange params!',this._op.objName,this.name);
         */
        }
        this._activity();
        this.emitEvent(Port.EVENT_VALUE_CHANGE, this.value, this);

        if (this.onChange) this.onChange(this, this.value);
        else if (this.onValueChanged) this.onValueChanged(this, this.value); // deprecated
    }

    /**
     * @function getTypeString
     * @memberof Port
     * @instance
     * @description get port type as string, e.g. "Function","Value"...
     * @return {String} type
     */
    getTypeString()
    {
        if (this.type == Port.TYPE_VALUE) return "Number";
        if (this.type == Port.TYPE_FUNCTION) return "Trigger";
        if (this.type == Port.TYPE_OBJECT) return "Object";
        if (this.type == Port.TYPE_DYNAMIC) return "Dynamic";
        if (this.type == Port.TYPE_ARRAY) return "Array";
        if (this.type == Port.TYPE_STRING) return "String";
        return "Unknown";
    }

    /**
     * @param {Object} objPort
     */
    deSerializeSettings(objPort)
    {
        if (!objPort) return;
        if (objPort.animated) this.setAnimated(objPort.animated);
        if (objPort.useVariable) this.setVariableName(objPort.useVariable);
        if (objPort.title) this.setUiAttribs({ "title": objPort.title });
        if (objPort.expose) this.setUiAttribs({ "expose": true });
        if (objPort.order) this.setUiAttribs({ "order": objPort.order });

        if (objPort.multiPortManual) this.setUiAttribs({ "multiPortManual": objPort.multiPortManual });
        if (objPort.multiPortNum) this.setUiAttribs({ "multiPortNum": objPort.multiPortNum });

        if (objPort.anim)
        {
            if (!this.anim) this.anim = new _anim_js__WEBPACK_IMPORTED_MODULE_3__/* .Anim */ .k({ "name": "port " + this.name });
            this._op.hasAnimPort = true;
            this.anim.on(_anim_js__WEBPACK_IMPORTED_MODULE_3__/* .Anim */ .k.EVENT_CHANGE, () =>
            {
                this._op.patch.emitEvent("portAnimUpdated", this._op, this, this.anim);
            });
            this.anim.deserialize(objPort.anim);
            this._op.patch.emitEvent("portAnimUpdated", this._op, this, this.anim);

            this.anim.sortKeys();
        }
    }

    /**
     * @param {any} v
     */
    setInitialValue(v)
    {
        if (this.op.preservedPortLinks[this.name])
        {
            for (let i = 0; i < this.op.preservedPortLinks[this.name].length; i++)
            {
                const lobj = this.op.preservedPortLinks[this.name][i];
                this.op.patch._addLink(
                    lobj.objIn,
                    lobj.objOut,
                    lobj.portIn,
                    lobj.portOut);
            }
        }

        if (this.op.preservedPortValues && this.op.preservedPortValues.hasOwnProperty(this.name) && this.op.preservedPortValues[this.name] !== undefined)
        {
            this.set(this.op.preservedPortValues[this.name]);
        }
        else
        if (v !== undefined) this.set(v);
        if (v !== undefined) this.defaultValue = v;
    }

    getSerialized()
    {
        let obj = { "name": this.getName() };

        if (!this.ignoreValueSerialize && this.links.length === 0)
        {
            if (this.type == Port.TYPE_OBJECT && this.value && this.value.tex) {}
            else obj.value = this.value;
        }
        if (this.#useVariableName) obj.useVariable = this.#useVariableName;
        if (this.#animated) obj.animated = true;
        if (this.anim) obj.anim = this.anim.getSerialized();
        if (this.uiAttribs.multiPortNum) obj.multiPortNum = this.uiAttribs.multiPortNum;
        if (this.uiAttribs.multiPortManual) obj.multiPortManual = this.uiAttribs.multiPortManual;

        if (this.uiAttribs.display == "file") obj.display = this.uiAttribs.display;
        if (this.uiAttribs.expose)
        {
            obj.expose = true;
            if (this.uiAttribs.hasOwnProperty("order")) obj.order = this.uiAttribs.order;
        }
        if (this.uiAttribs.title) obj.title = this.uiAttribs.title;
        if ((this.preserveLinks || this.direction == _constants_js__WEBPACK_IMPORTED_MODULE_2__/* .CONSTANTS */ .a.PORT.PORT_DIR_OUT) && this.links.length > 0)
        {
            obj.links = [];
            for (const i in this.links)
            {
                if (!this.links[i].ignoreInSerialize && (this.links[i].portIn && this.links[i].portOut)) obj.links.push(this.links[i].getSerialized());
            }
        }

        if (this.direction == Port.DIR_IN && this.links.length > 0)
        {
            for (const i in this.links)
            {
                if (!this.links[i].portIn || !this.links[i].portOut) continue;

                const otherp = this.links[i].getOtherPort(this);
                // check if functions exist, are defined in core_extend_ops code in ui
                if (otherp.op.isInBlueprint2 && this.op.isInBlueprint2)
                {
                    if (otherp.op.isInBlueprint2() && !this.op.isInBlueprint2())
                    {
                        obj.links = obj.links || [];
                        obj.links.push(this.links[i].getSerialized());
                    }
                }
            }
        }

        if (obj.links && obj.links.length == 0) delete obj.links;
        if (this.type === Port.TYPE_FUNCTION) delete obj.value;
        if (this.type === Port.TYPE_FUNCTION && this.links.length == 0) obj = null;
        if (obj && Object.keys(obj).length == 1 && obj.name)obj = null; // obj is null if there is no real information other than name

        (0,_utils_js__WEBPACK_IMPORTED_MODULE_4__.cleanJson)(obj);

        return obj;
    }

    /**
     * will be overwritten in ui
     * @param {Port} port1
     * @param {Port} port2
     * @returns {boolean}
     */
    shouldLink(port1, port2)
    {
        return !!(port1 && port2);
    }

    /**
     * @function removeLinks
     * @memberof Port
     * @instance
     * @description remove all links from port
     */
    removeLinks()
    {
        let count = 0;
        while (this.links.length > 0)
        {
            count++;
            if (count > 5000)
            {
                this._log.warn("could not delete links... / infinite loop");
                this.links.length = 0;
                break;
            }
            this.links[0].remove();
        }
    }

    /**
     * @function removeLink
     * @memberof Port
     * @instance
     * @description remove all link from port
     * @param {Link} link
     */
    removeLink(link)
    {
        for (let i = 0; i < this.links.length; i++)
            if (this.links[i] == link)
                this.links.splice(i, 1);

        if (this.direction == Port.DIR_IN)
        {
            if (this.type == Port.TYPE_VALUE) this.setValue(this.#valueBeforeLink || 0);
            else this.setValue(this.#valueBeforeLink || null);
        }

        if (CABLES.UI && this._op.checkLinkTimeWarnings) this._op.checkLinkTimeWarnings();

        try
        {
            if (this.onLinkChanged) this.onLinkChanged();
            this.emitEvent("onLinkChanged");
            this.emitEvent("onLinkRemoved");
            this._op.emitEvent("onLinkChanged");
        }
        catch (e)
        {
            this._log.error(e);
        }
    }

    /**
     * @function getName
     * @memberof Port
     * @instance
     * @description return port name
     */
    getName()
    {
        return this.name;
    }

    /**
     * @function getTitle
     * @memberof Port
     * @instance
     * @description return port name or title
     */
    getTitle()
    {
        if (this.uiAttribs.title) return this.uiAttribs.title;
        return this.name;
    }

    /**
     * @param {Link} l
     */
    addLink(l)
    {
        this.#valueBeforeLink = this.value;
        this.links.push(l);
        if (CABLES.UI && this._op.checkLinkTimeWarnings) this._op.checkLinkTimeWarnings();

        try
        {
            if (this.onLinkChanged) this.onLinkChanged();
            this.emitEvent("onLinkChanged");
            this._op.emitEvent("onLinkChanged");
        }
        catch (e)
        {
            this._log.error(e);
        }
    }

    /**
     * @function getLinkTo
     * @memberof Port
     * @instance
     * @param {Port} p2 otherPort
     * @description return link, which is linked to otherPort
     */
    getLinkTo(p2)
    {
        for (const i in this.links) if (this.links[i].portIn == p2 || this.links[i].portOut == p2) return this.links[i];
    }

    /**
     * @function removeLinkTo
     * @memberof Port
     * @instance
     * @param {Port} p2 otherPort
     * @description removes link, which is linked to otherPort
     */
    removeLinkTo(p2)
    {
        for (const i in this.links)
        {
            if (this.links[i].portIn == p2 || this.links[i].portOut == p2)
            {
                this.links[i].remove();
                if (CABLES.UI && this._op.checkLinkTimeWarnings) this._op.checkLinkTimeWarnings();

                if (this.onLinkChanged) this.onLinkChanged();
                this.emitEvent("onLinkChanged");
                this.emitEvent("onLinkRemoved");
                return;
            }
        }
    }

    /**
     * @function isLinkedTo
     * @memberof Port
     * @instance
     * @param {Port} p2 otherPort
     * @description returns true if port is linked to otherPort
     */
    isLinkedTo(p2)
    {
        for (const i in this.links) if (this.links[i].portIn == p2 || this.links[i].portOut == p2) return true;

        return false;
    }

    _activity()
    {
        this.activityCounter++;
    }

    /**
     * @function trigger
     * @memberof Port
     * @instance
     * @description trigger the linked port (usually invoked on an output function port)
     */
    trigger()
    {
        const linksLength = this.links.length;

        this._activity();
        if (linksLength === 0) return;
        if (!this._op.enabled) return;

        let portTriggered = null;
        try
        {
            for (let i = 0; i < linksLength; ++i)
            {
                if (this.links[i].portIn)
                {
                    portTriggered = this.links[i].portIn;

                    portTriggered.op.patch.pushTriggerStack(portTriggered);
                    if (!portTriggered._onTriggered)
                    {
                        console.log(portTriggered, portTriggered._onTriggered);
                    }
                    portTriggered._onTriggered(null);

                    portTriggered.op.patch.popTriggerStack();
                }
                if (this.links[i]) this.links[i].activity();
            }
        }
        catch (ex)
        {
            portTriggered.op.enabled = false;

            if (this._op.patch.isEditorMode())
            {
                if (portTriggered.op.onError) portTriggered.op.onError(ex);
            }
            this._log.error("exception in port: ", portTriggered.name, portTriggered.op.name, portTriggered.op.id);
            this._log.error(ex);
        }
    }

    call()
    {
        this._log.warn("call deprecated - use trigger() ");
        this.trigger();
    }

    execute()
    {
    }

    /**
     * @param {string} n
     */
    setVariableName(n)
    {
        this.#useVariableName = n;

        this._op.patch.on("variableRename", (oldname, newname) =>
        {
            if (oldname != this.#useVariableName) return;
            this.#useVariableName = newname;
        });
    }

    getVariableName()
    {
        return this.#useVariableName;
    }

    /**
     * @param {String} v
     */
    setVariable(v)
    {
        this.setAnimated(false);
        const attr = { "useVariable": false };

        if (this._variableIn && this._varChangeListenerId)
        {
            this._variableIn.off(this._varChangeListenerId);
            this._variableIn = null;
        }

        if (v)
        {
            this._variableIn = this._op.patch.getVar(v);

            if (!this._variableIn)
            {
                // this._log.warn("PORT VAR NOT FOUND!!!", v);
            }
            else
            {
                if (this.type == Port.TYPE_OBJECT)
                {
                    this._varChangeListenerId = this._variableIn.on("change", () => { this.set(null); this.set(this._variableIn.getValue()); });
                }
                else
                {
                    this._varChangeListenerId = this._variableIn.on("change", this.set.bind(this));
                }

                this.set(this._variableIn.getValue());
            }
            this.#useVariableName = v;
            attr.useVariable = true;
            attr.variableName = this.#useVariableName;
        }
        else
        {
            attr.variableName = this.#useVariableName = null;
            attr.useVariable = false;
        }

        this.setUiAttribs(attr);
        this._op.patch.emitEvent("portSetVariable", this._op, this, v);
    }

    /**
     * @param {boolean} a
     */
    _handleNoTriggerOpAnimUpdates(a)
    {
        let hasTriggerPort = false;
        // for (let i = 0; i < this._op.portsIn.length; i++)
        // {
        //     if (this._op.portsIn[i].type == Port.TYPE_FUNCTION)
        //     {
        //         hasTriggerPort = true;
        //         break;
        //     }
        // }

        if (!hasTriggerPort)
        {
            if (a) this._notriggerAnimUpdate = this._op.patch.on("onRenderFrame", () =>
            {
                this.updateAnim();
            });
            else if (this._notriggerAnimUpdate) this._notriggerAnimUpdate = this._op.patch.off(this._notriggerAnimUpdate);
        }
    }

    /**
     * @param {boolean} a
     */
    setAnimated(a)
    {
        if (this.#animated != a)
        {
            this.#animated = a;
            this._op.hasAnimPort = true;

            if (this.#animated && !this.anim)
            {
                this.anim = new _anim_js__WEBPACK_IMPORTED_MODULE_3__/* .Anim */ .k({ "name": "port " + this.name });
                this.anim.on(_anim_js__WEBPACK_IMPORTED_MODULE_3__/* .Anim */ .k.EVENT_CHANGE, () =>
                {
                    this._op.patch.emitEvent("portAnimUpdated", this._op, this, this.anim);
                });
                // this.anim.setValue(this._op.patch.timer.getTime(), this.get());
            }
            this._onAnimToggle();
        }

        this._handleNoTriggerOpAnimUpdates(a);
        if (!a)
        {
            this.anim = null;
        }

        this._op.patch.emitEvent("portAnimToggle", this._op, this, this.anim);

        this.setUiAttribs({ "isAnimated": this.#animated });
    }

    toggleAnim()
    {
        this.#animated = !this.#animated;
        if (this.#animated && !this.anim)
        {
            this.anim = new _anim_js__WEBPACK_IMPORTED_MODULE_3__/* .Anim */ .k({ "name": "port " + this.name });
            this.anim.on(_anim_js__WEBPACK_IMPORTED_MODULE_3__/* .Anim */ .k.EVENT_CHANGE, () =>
            {
                this._op.patch.emitEvent("portAnimUpdated", this._op, this, this.anim);
            });
        }
        this.setAnimated(this.#animated);
        this._onAnimToggle();
        this.setUiAttribs({ "isAnimated": this.#animated });
        this._op.patch.emitEvent("portAnimUpdated", this._op, this, this.anim);
    }

    /**
     * <pre>
     * CABLES.Port.TYPE_VALUE = 0;
     * CABLES.Port.TYPE_FUNCTION = 1;
     * CABLES.Port.TYPE_OBJECT = 2;
     * CABLES.Port.TYPE_TEXTURE = 2;
     * CABLES.Port.TYPE_ARRAY = 3;
     * CABLES.Port.TYPE_DYNAMIC = 4;
     * CABLES.Port.TYPE_STRING = 5;
     * </pre>
     * @function getType
     * @memberof Port
     * @instance
     * @return {Number} type of port
     */
    getType()
    {
        return this.type;
    }

    /**
     * @function isLinked
     * @memberof Port
     * @instance
     * @return {Boolean} true if port is linked
     */
    isLinked()
    {
        return this.links.length > 0 || this.#animated || this.#useVariableName != null;
    }

    isBoundToVar()
    {
        const b = this.#useVariableName != null;
        this.uiAttribs.boundToVar = b;
        return b;
    }

    /**
     * @return {Boolean} true if port is animated
     */
    isAnimated()
    {
        return this.#animated;
    }

    /**
     * @function isHidden
     * @memberof Port
     * @instance
     * @return {Boolean} true if port is hidden
     */
    isHidden()
    {
        return this.uiAttribs.hidePort;
    }

    /**
     * @function onTriggered
     * @memberof Port
     * @instance
     * @param {function} a onTriggeredCallback
     * @description set callback, which will be executed when port was triggered (usually output port)
     */
    _onTriggered(a)
    {
        this._activity();
        this._op.updateAnims();
        if (this._op.enabled && this.onTriggered) this.onTriggered(a);

        if (this._op.enabled) this.emitEvent("trigger");
    }

    /**
     * @param {any} v
     */
    _onSetProfiling(v) // used in editor: profiler tab
    {
        this._op.patch.profiler.add("port", this);
        this.setValue(v);
        this._op.patch.profiler.add("port", null);
    }

    _onTriggeredProfiling() // used in editor: profiler tab
    {
        if (this._op.enabled && this.onTriggered)
        {
            this._op.patch.profiler.add("port", this);
            this.onTriggered();
            this._op.patch.profiler.add("port", null);
        }
    }

    /**
     * @deprecated
     * @param {function} cb
     */
    onValueChange(cb)
    {
        this.onChange = cb;
    }

    /**
     * @deprecated
     */
    hidePort() {}

    /**
     * Returns the port type string, e.g. "value" based on the port type number
     * @function portTypeNumberToString
     * @instance
     * @memberof Port
     * @param {Number} type - The port type number
     * @returns {String} - The port type as string
     */
    static portTypeNumberToString(type)
    {
        if (type == Port.TYPE_VALUE) return "value";
        if (type == Port.TYPE_FUNCTION) return "function";
        if (type == Port.TYPE_OBJECT) return "object";
        if (type == Port.TYPE_ARRAY) return "array";
        if (type == Port.TYPE_STRING) return "string";
        if (type == Port.TYPE_DYNAMIC) return "dynamic";
        return "unknown";
    }
}


/***/ }),

/***/ 606:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);

// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  Anim: () => (/* reexport */ anim/* Anim */.k),
  AnimKey: () => (/* reexport */ anim_key/* AnimKey */.rA),
  CONSTANTS: () => (/* reexport */ constants/* CONSTANTS */.a),
  EMBED: () => (/* reexport */ EMBED),
  Link: () => (/* reexport */ Link),
  LoadingStatus: () => (/* reexport */ LoadingStatus),
  Op: () => (/* reexport */ Op),
  Patch: () => (/* reexport */ Patch),
  PatchVariable: () => (/* reexport */ PatchVariable),
  Port: () => (/* reexport */ core_port/* Port */.I),
  Profiler: () => (/* reexport */ Profiler),
  Timer: () => (/* reexport */ timer/* Timer */.M4),
  "default": () => (/* binding */ core),
  now: () => (/* reexport */ timer/* now */.tB),
  utils: () => (/* reexport */ utils)
});

// NAMESPACE OBJECT: ./node_modules/gl-matrix/esm/index.js
var esm_namespaceObject = {};
__webpack_require__.r(esm_namespaceObject);
__webpack_require__.d(esm_namespaceObject, {
  glMatrix: () => (common),
  mat2: () => (mat2),
  mat2d: () => (mat2d),
  mat3: () => (mat3),
  mat4: () => (mat4),
  quat: () => (quat),
  quat2: () => (quat2),
  vec2: () => (vec2),
  vec3: () => (vec3),
  vec4: () => (vec4)
});

// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/common.js
var common = __webpack_require__(823);
// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/mat2.js
var mat2 = __webpack_require__(522);
// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/mat2d.js
var mat2d = __webpack_require__(964);
// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/mat3.js
var mat3 = __webpack_require__(409);
// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/mat4.js
var mat4 = __webpack_require__(684);
// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/quat.js
var quat = __webpack_require__(221);
// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/quat2.js
var quat2 = __webpack_require__(991);
// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/vec2.js
var vec2 = __webpack_require__(842);
// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/vec3.js
var vec3 = __webpack_require__(329);
// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/vec4.js
var vec4 = __webpack_require__(796);
;// CONCATENATED MODULE: ./node_modules/gl-matrix/esm/index.js











// EXTERNAL MODULE: ../shared/client/src/eventtarget.js + 2 modules
var eventtarget = __webpack_require__(125);
// EXTERNAL MODULE: ../shared/client/src/logger.js
var logger = __webpack_require__(849);
// EXTERNAL MODULE: ./src/core/utils.js + 1 modules
var utils = __webpack_require__(562);
// EXTERNAL MODULE: ./src/core/anim.js
var anim = __webpack_require__(344);
// EXTERNAL MODULE: ./src/core/core_port.js
var core_port = __webpack_require__(50);
;// CONCATENATED MODULE: ./src/core/core_link.js




/**
 * @namespace external:CABLES#Link
 * @description a link is a connection between two ops/ports -> one input and one output port
 * @hideconstructor
 * @class
 */
class Link extends eventtarget/* default */.A
{

    /**
     * @param {Patch} p
     */
    constructor(p)
    {
        super();

        this.id = CABLES.simpleId();

        /**
         * @type {Port}
         */
        this.portIn = null;

        /**
         * @type {Port}
         */
        this.portOut = null;

        /**
         * @type {Patch}
         */
        this._patch = p;
        this.activityCounter = 0;
        this.ignoreInSerialize = false;
    }

    /**
     * @param {any} v
     */
    setValue(v)
    {
        if (v === undefined) this._setValue();
        else this.portIn.set(v);
    }

    activity()
    {
        this.activityCounter++;
    }

    _setValue()
    {
        if (!this.portOut)
        {
            this.remove();
            return;
        }
        const v = this.portOut.get();

        if (v == v) // NaN is the only JavaScript value that is treated as unequal to itself
        {
            if (this.portIn.type != core_port/* Port */.I.TYPE_FUNCTION) this.activity();

            if (this.portIn.get() !== v)
            {
                this.portIn.set(v);
            }
            else
            {
                if (this.portIn.changeAlways) this.portIn.set(v);
                if (this.portOut.forceRefChange) this.portIn.forceChange();
            }
        }
    }

    /**
     * @function getOtherPort
     * @memberof Link
     * @instance
     * @param {Port} p port
     * @description returns the port of the link, which is not port
     */
    getOtherPort(p)
    {
        if (p == this.portIn) return this.portOut;
        return this.portIn;
    }

    /**
     * @function remove
     * @memberof Link
     * @instance
     * @description unlink/remove this link from all ports
     */
    remove()
    {
        if (this.portIn) this.portIn.removeLink(this);
        if (this.portOut) this.portOut.removeLink(this);
        if (this._patch)
        {
            this._patch.emitEvent("onUnLink", this.portIn, this.portOut, this);
        }

        if (this.portIn && (this.portIn.type == core_port/* Port */.I.TYPE_OBJECT || this.portIn.type == core_port/* Port */.I.TYPE_ARRAY))
        {
            this.portIn.set(null);
            if (this.portIn.links.length > 0) this.portIn.set(this.portIn.links[0].getOtherPort(this.portIn).get());
        }

        if (this.portIn) this.portIn.op._checkLinksNeededToWork();
        if (this.portOut) this.portOut.op._checkLinksNeededToWork();

        this.portIn = null;
        this.portOut = null;
        this._patch = null;
    }

    /**
     * @function link
     * @memberof Link
     * @instance
     * @description link those two ports
     * @param {Port} p1 port1
     * @param {Port} p2 port2
     */
    link(p1, p2)
    {
        if (!Link.canLink(p1, p2))
        {
            console.warn("[core_link] cannot link ports!", p1, p2);
            return false;
        }

        if (p1.direction == core_port/* Port */.I.DIR_IN)
        {
            this.portIn = p1;
            this.portOut = p2;
        }
        else
        {
            this.portIn = p2;
            this.portOut = p1;
        }

        p1.addLink(this);
        p2.addLink(this);

        this.setValue();

        p1.op._checkLinksNeededToWork();
        p2.op._checkLinksNeededToWork();
    }

    getSerialized()
    {
        const obj = {};

        obj.portIn = this.portIn.getName();
        obj.portOut = this.portOut.getName();
        obj.objIn = this.portIn.op.id;
        obj.objOut = this.portOut.op.id;

        return obj;
    }

    /**
     * return a text message with human readable reason if ports can not be linked, or can be
     *
     * @param {Port} p1 port1
     * @param {Port} p2 port2
     */
    static canLinkText(p1, p2)
    {
        if (p1.direction == p2.direction)
        {
            let txt = "(out)";
            if (p2.direction == core_port/* Port */.I.DIR_IN) txt = "(in)";
            return "can not link: same direction " + txt;
        }
        if (p1.op == p2.op) return "can not link: same op";
        if (p1.type != core_port/* Port */.I.TYPE_DYNAMIC && p2.type != core_port/* Port */.I.TYPE_DYNAMIC)
        {
            if (p1.type != p2.type) return "can not link: different type";
        }

        if (CABLES.UI && p1.type == core_port/* Port */.I.TYPE_OBJECT && p2.type == core_port/* Port */.I.TYPE_OBJECT)
        {
            if (p1.uiAttribs.objType && p2.uiAttribs.objType)
                if (p1.uiAttribs.objType != p2.uiAttribs.objType)
                    return "incompatible objects";
        }

        if (!p1) return "can not link: port 1 invalid";
        if (!p2) return "can not link: port 2 invalid";

        if (p1.direction == core_port/* Port */.I.DIR_IN && p1.isAnimated()) return "can not link: is animated";
        if (p2.direction == core_port/* Port */.I.DIR_IN && p2.isAnimated()) return "can not link: is animated";

        if (p1.isLinkedTo(p2)) return "ports already linked";

        if ((p1.canLink && !p1.canLink(p2)) || (p2.canLink && !p2.canLink(p1))) return "Incompatible";

        return "can link";
    }

    /**
     * return true if ports can be linked
     *
     * @param {Port} p1 port1
     * @param {Port} p2 port2
     * @returns {Boolean}
     */
    static canLink(p1, p2)
    {
        if (!p1) return false;
        if (!p2) return false;
        if (p1.direction == core_port/* Port */.I.DIR_IN && p1.isAnimated()) return false;
        if (p2.direction == core_port/* Port */.I.DIR_IN && p2.isAnimated()) return false;

        if (p1.isHidden() || p2.isHidden()) return false;

        if (p1.isLinkedTo(p2)) return false;

        if (p1.direction == p2.direction) return false;

        if (CABLES.UI && p1.type == core_port/* Port */.I.TYPE_OBJECT && p2.type == core_port/* Port */.I.TYPE_OBJECT)
        {
            if (p1.uiAttribs.objType && p2.uiAttribs.objType)
            {
                if (p1.uiAttribs.objType.indexOf("sg_") == 0 && p2.uiAttribs.objType.indexOf("sg_") == 0) return true;
                if (p1.uiAttribs.objType != p2.uiAttribs.objType)
                    return false;
            }
        }

        if (p1.type != p2.type && (p1.type != core_port/* Port */.I.TYPE_DYNAMIC && p2.type != core_port/* Port */.I.TYPE_DYNAMIC)) return false;
        if (p1.type == core_port/* Port */.I.TYPE_DYNAMIC || p2.type == core_port/* Port */.I.TYPE_DYNAMIC) return true;

        if (p1.op == p2.op) return false;

        if (p1.canLink && !p1.canLink(p2)) return false;
        if (p2.canLink && !p2.canLink(p1)) return false;

        return true;
    }
}

// --------------------------------------------

// EXTERNAL MODULE: ./src/corelibs/cgl/index.js + 4 modules
var cgl = __webpack_require__(772);
// EXTERNAL MODULE: ./src/corelibs/cgl/cgl_state.js
var cgl_state = __webpack_require__(308);
// EXTERNAL MODULE: ./src/core/constants.js
var constants = __webpack_require__(440);
;// CONCATENATED MODULE: ./src/core/core_port_switch.js


class SwitchPort extends core_port/* Port */.I
{
    constructor(__parent, name, type, uiAttribs, indexPort)
    {
        super(__parent, name, type, uiAttribs);

        this.get = () =>
        {
            let s = super.get();

            if (CABLES.UI)
            {
                if (
                    s === "" ||
                    s === null ||
                    s === undefined ||
                    (uiAttribs.values && uiAttribs.values.indexOf(String(s)) === -1)
                )
                {
                    this.op.setUiError("invalidswitch", "Invalid Value [" + this.name + "]: \"" + s + "\"", 1);
                }
                else this.op.setUiError("invalidswitch", null);
            }

            if (s === null || s === undefined)s = "";

            return s;
        };

        this.indexPort = indexPort;
        this.indexPort.set = (value) =>
        {
            const values = uiAttribs.values;

            if (!values)
            {
                // console.log("switch port has no values", this);
                return;
            }

            let intValue = Math.floor(value);

            intValue = Math.min(intValue, values.length - 1);
            intValue = Math.max(intValue, 0);

            this.indexPort.setValue(intValue);
            this.set(values[intValue]);

            if (this.op.patch.isEditorMode() && performance.now() - (this.lastTime || 0) > 100 && window.gui && gui.patchView.isCurrentOp(this.op))
            {
                gui.opParams.show(this.op);
                this.lastTime = performance.now();
            }
        };
    }

    setUiAttribs(attribs)
    {
        const hidePort = attribs.hidePort;
        attribs.hidePort = true;
        super.setUiAttribs(attribs);
        if (typeof hidePort !== "undefined")
        {
            this.indexPort.setUiAttribs({ hidePort });
        }
    }
}

;// CONCATENATED MODULE: ./src/core/core_port_select.js


class ValueSelectPort extends SwitchPort
{
    setUiAttribs(newAttribs)
    {
        // never unhide valuePort when indexPort is linked
        if (this.indexPort.isLinked())
        {
            for (const p in newAttribs)
            {
                if (p == "greyout" && !newAttribs[p]) newAttribs[p] = "true";
            }
        }
        super.setUiAttribs(newAttribs);
    }
}

;// CONCATENATED MODULE: ./src/core/core_port_multi.js



const MIN_NUM_PORTS = 2;

class MultiPort extends core_port/* Port */.I
{
    constructor(__parent, name, type, dir, uiAttribs, uiAttribsPorts)
    {
        super(__parent, name, core_port/* Port */.I.TYPE_ARRAY, uiAttribs);

        this.setUiAttribs({ "multiPort": true, "group": this.name, "order": -1 });
        this.ports = [];
        this.direction = dir;
        this._uiAttribsPorts = uiAttribsPorts;

        const updateArray = () =>
        {
            const arr = [];

            let ll = 1;
            if (this.uiAttribs.multiPortManual)ll = 0;

            for (let i = 0; i < this.ports.length - ll; i++)
                arr[i] = this.ports[i];

            this.setRef(arr);
        };

        const updateUi = () =>
        {
            let grey = !this.uiAttribs.multiPortManual || false;

            if (this.direction == constants/* CONSTANTS */.a.PORT.PORT_DIR_OUT)grey = false;

            for (let i = 0; i < this.ports.length; i++)
            {
                let lp; // undefined to remove/not set it
                // let opacity;// undefined to remove/not set it
                // let grey;// undefined to remove/not set it
                let addPort = false;
                let title;
                let o = {};

                // console.log("this.op.preservedPortTitles", this.op.preservedPortTitles, this.op.preservedPortTitles[po.name], po.name);
                if (this.op.preservedPortTitles && this.op.preservedPortTitles[this.ports[i].name]) title = this.op.preservedPortTitles[this.ports[i].name];

                // if (!this.uiAttribs.multiPortManual)grey = true;
                if (i == 0) lp = this.ports.length;

                if (!this.uiAttribs.multiPortManual)
                    if (i == this.ports.length - 1)
                    {
                        title = "add port";
                        addPort = true;
                        grey = true;
                    }

                for (const attin in this._uiAttribsPorts)
                {
                    o[attin] = this._uiAttribsPorts[attin];
                }

                o.addPort = addPort;
                o.longPort = lp;
                o.title = title;
                o.greyout = grey;
                o.group = this.name;

                this.ports[i].setUiAttribs(o);
            }
        };

        this.removeInvalidPorts = () =>
        {
            for (let i = 0; i < this.ports.length; i++)
            {
                if (!this.ports[i]) this.ports.splice(i, 1);
            }

            if (!this.uiAttribs.multiPortManual)
            {
                if (this.ports.length > MIN_NUM_PORTS)

                    for (let i = this.ports.length - 1; i > 1; i--)
                    {
                        if (!this.ports[i].isLinked()) this.uiAttribs.multiPortNum = i;
                        else break;
                    }
            }

            updateArray();
        };

        this.countPorts = () =>
        {
            if (CABLES.UI && !gui.isRemoteClient && gui.patchView && gui.patchView.patchRenderer && gui.patchView.patchRenderer.isDraggingPort())
            {
                clearTimeout(this.retryTo);
                this.retryTo = setTimeout(this.countPorts.bind(this));
                return;
            }
            this.retryTo = null;

            let redo = false;
            this.removeListeners();
            this.removeInvalidPorts();

            for (let i = 0; i < this.ports.length; i++)
            {
                if (this.ports[i] && this.ports[i].links.length > 1)
                {
                    const po = this.ports[i + 1];
                    const otherPort = this.ports[i].links[0].getOtherPort(this.ports[i]);

                    if (!po || !otherPort)
                    {
                        this._log.warn("no port found?");
                    }
                    else
                    {
                        this.ports[i].links[0].remove();
                        this.op.patch.link(this.op, po.name, otherPort.op, otherPort.name);
                        redo = true;
                    }
                    break;
                }
            }

            if (!this.uiAttribs.multiPortManual)
            {
                let foundHole = true;
                while (foundHole)
                {
                    // console.log("search holes...");
                    foundHole = false;

                    for (let i = this.ports.length - 1; i > 1; i--)
                    {
                        if (this.ports[i] && this.ports[i].links.length > 0 && this.ports[i - 1].links.length == 0)
                        {
                            // console.log("found hole!");

                            // found hole
                            const otherPort = this.ports[i].links[0].getOtherPort(this.ports[i]);
                            this.ports[i].links[0].remove();

                            const po = this.ports[i - 1];

                            if (po && this.ports[i])
                            {
                                // console.log("move ", this.ports[i].name, "to", po.name);
                                this.op.patch.link(this.op, po.name, otherPort.op, otherPort.name);
                                foundHole = true;
                                redo = true;
                                break;
                            }
                        }
                    }

                    // this.checkNum();
                }

                // this.removeInvalidPorts();
            }

            if (!this.uiAttribs.multiPortManual) // if auto
            {
                while (this.ports.length > MIN_NUM_PORTS && !this.ports[this.ports.length - 1].isLinked() && !this.ports[this.ports.length - 2].isLinked())
                {
                    let i = this.ports.length - 1;
                    if (!this.ports[i].isLinked() && this.ports[i - 1] && !this.ports[i - 1].isLinked())
                    {
                        this.ports[i].setUiAttribs({ "removed": true });
                        this.ports[i].remove();
                        // this.ports[i] = null;
                        this.ports.splice(i, 1);
                    }
                }
            }

            this.removeInvalidPorts();

            if (!this.uiAttribs.multiPortManual && this.ports.length > 0 && this.ports[this.ports.length - 1].isLinked()) this.newPort();

            updateArray();
            updateUi();

            if (redo) this.countPorts();
            else this.addListeners();
        };

        this.removeListeners = () =>
        {
            for (let i = 0; i < this.ports.length; i++)
            {
                const po = this.ports[i];
                if (po.multiPortChangeListener) po.multiPortChangeListener = po.off(po.multiPortChangeListener);
                if (po.multiLinkChangeListener) po.multiLinkChangeListener = po.off(po.multiLinkChangeListener);
            }
        };

        this.addListeners = () =>
        {
            for (let i = 0; i < this.ports.length; i++)
            {
                const po = this.ports[i];
                const idx = i;

                if (po.multiPortChangeListener)po.multiPortChangeListener = po.off(po.multiPortChangeListener);
                po.multiPortChangeListener = po.on("change", updateArray.bind(this));

                if (po.multiPortTriggerListener)po.multiPortTriggerListener = po.off(po.multiPortTriggerListener);
                po.multiPortTriggerListener = po.on("trigger", () => { this._onTriggered(idx); });

                if (po.multiLinkChangeListener)po.multiLinkChangeListener = po.off(po.multiLinkChangeListener);
                po.multiLinkChangeListener = po.on("onLinkChanged", () =>
                {
                    this.countPorts();
                    this.emitEvent("onLinkChanged");
                });

                if (po.multiLinkRemoveListener)po.multiLinkRemoveListener = po.off(po.multiLinkRemoveListener);
                po.multiLinkRemoveListener = po.on("onLinkRemoved", () =>
                {
                    // this.removeInvalidPorts();
                    // this.checkNum();
                    // this.countPorts();
                    updateUi();
                    this.emitEvent("onLinkChanged");
                    // this.countPorts.bind(this);
                });
            }
        };

        this.newPort = () =>
        {
            const attrs = {};
            // if (type == CABLES.OP_PORT_TYPE_STRING) attrs.type = "string";
            attrs.type = type;
            const po = new core_port/* Port */.I(this.op, name + "_" + this.ports.length, type, attrs);

            po.direction = dir;
            this.ports.push(po);
            // console.log("CONSTANTS.PORT_DIR_OUT", CONSTANTS.PORT.PORT_DIR_OUT, this.direction);
            if (this.direction == constants/* CONSTANTS */.a.PORT.PORT_DIR_OUT) this.op.addOutPort(po);
            else this.op.addInPort(po);

            if (type == core_port/* Port */.I.TYPE_NUMBER) po.setInitialValue(0);
            else if (type == core_port/* Port */.I.TYPE_STRING) po.setInitialValue("");

            this.addListeners();

            updateUi();
            updateArray();
            this.emitEvent("onLinkChanged");
            // console.log("this.op.preservedPortTitles", this.op.preservedPortTitles, this.op.preservedPortTitles[po.name], po.name);
            if (this.op.preservedPortTitles && this.op.preservedPortTitles[po.name]) po.setUiAttribs({ "title": this.op.preservedPortTitles[po.name] });

            return po;
        };

        this.initPorts = () =>
        {
            for (let i = 0; i < MIN_NUM_PORTS; i++) this.newPort();
            updateArray();
            updateUi();
        };

        this.checkNum = () =>
        {
            this.uiAttribs.multiPortNum = Math.max(MIN_NUM_PORTS, this.uiAttribs.multiPortNum);

            while (this.ports.length < this.uiAttribs.multiPortNum) this.newPort();
            while (this.ports.length > this.uiAttribs.multiPortNum) if (this.ports[this.ports.length - 1]) this.ports.pop().remove();

            this.removeInvalidPorts();
        };

        this.incDec = (incDir) =>
        {
            this.uiAttribs.multiPortNum = this.uiAttribs.multiPortNum || MIN_NUM_PORTS;
            // console.log("this.uiAttribs.multiPortNum", this.uiAttribs.multiPortNum, this.uiAttribs.multiPortNum + incDir);
            this.setUiAttribs({ "multiPortNum": this.uiAttribs.multiPortNum + incDir });
            this.checkNum();

            updateUi();
        };

        this.toggleManual = () =>
        {
            this.setUiAttribs({ "multiPortManual": !this.uiAttribs.multiPortManual });
            this.op.refreshParams();
        };

        this.on("onUiAttrChange", (attribs) =>
        {
            if (attribs.hasOwnProperty("multiPortManual"))
            {
                updateUi();
                this.removeInvalidPorts();
                this.checkNum();
                this.countPorts();
                updateUi();
            }
        });

        this.on("onUiAttrChange", this.checkNum.bind(this));
        this.checkNum();
        this.countPorts();
        this.removeInvalidPorts();
        updateUi();
    }
}

;// CONCATENATED MODULE: ./src/core/core_op.js











/**
 * @typedef Translation
 * @property {number} [x]
 * @property {number} [y]
 */

/**
 * configuration object for loading a patch
 * @typedef OpUiAttribs
 * @property {string} [title] overwrite op title
 * @property {string} [hidePort] hidePort
 * @property {string} [title] overwrite op title
 * @property {String} [title=''] overwrite title of port (by default this is portname)
 * @property {string} [extendTitle] extended op title, shown in grey next to op name
 * @property {object} [storage]
 * @property {boolean} [working]
 * @property {boolean} [bookmarked]
 * @property {boolean} [selected]
 * @property {boolean} [disabled]
 * @property {boolean} [loading]
 * @property {boolean} [resizable]
 * @property {boolean} [hidden]
 * @property {object} [uierrors]
 * @property {string} [color]
 * @property {object} [area]
 * @property {string} [comment]
 * @property {number} [height]
 * @property {number} [width]
 * @property {Translation} [translate]
 * @property {string|number} [subPatch]
 * @property {string} [comment_title]
 */

/**
 * @typedef CorePatch
 * @type Patch
 */

/**
 * @template {CorePatch} Patch
 */
class Op extends eventtarget/* default */.A
{
    static OP_VERSION_PREFIX = "_v";
    static EVENT_INIT = "init";
    static EVENT_UIATTR_CHANGE = "onUiAttribsChange";

    #objName = "";
    _log = new logger/* default */.A("core_op");
    //    #name = "";
    #shortOpName = "";

    opId = ""; // unique op id

    /** @type {Array<Port>} */
    portsOut = [];

    /** @type {Patch} */
    patch = null;

    data = {}; // UNUSED, DEPRECATED, only left in for backwards compatibility with userops
    storage = {}; // op-specific data to be included in export

    /** @type {Array<Port>} */
    portsIn = [];
    portsInData = []; // original loaded patch data

    /** @type {OpUiAttribs} */
    uiAttribs = {};
    enabled = true;

    onAnimFrame = null;

    preservedPortTitles = {};
    preservedPortValues = {};
    preservedPortLinks = {};

    linkTimeRules = {
        "needsLinkedToWork": [],
        "needsStringToWork": [],
        "needsParentOp": null
    };

    shouldWork = {};
    hasUiErrors = 0;

    /** @type {Object} */
    uiErrors = {};
    hasAnimPort = false;

    /** @type {Port} */
    patchId = null; // will be defined by subpatchops

    /**
     * @param {Patch} _patch
     * @param {String} _objName
     * @param {String} _id=null
    */
    constructor(_patch, _objName, _id = null)
    {
        super();

        // this.#name = _objName;
        this.opId = _id;
        this.#objName = _objName;
        this.patch = _patch;

        this.#shortOpName = CABLES.getShortOpName(_objName);
        this.getTitle();

        this.id = _id || (0,utils.shortId)(); // instance id
        this.onAddPort = null;
        this.onCreate = null;
        this.onResize = null;
        this.onLoaded = null;
        this.onDelete = null;
        this.onError = null;

        this._instances = null;

        /**
         * overwrite this to prerender shader and meshes / will be called by op `loadingStatus`
         */
        this.preRender = null;

        /**
         * overwrite this to initialize your op
         */
        this.init = null;

        /**
         * Implement to render 2d canvas based graphics from in an op - optionaly defined in op instance
         * @param {CanvasRenderingContext2D} context of canvas 2d
         * @param {Object} layer info
         * @param {number} layer.x x position on canvas
         * @param {number} layer.y y position on canvas
         * @param {number} layer.width width of canvas
         * @param {number} layer.height height of canvas
         * @param {number} layer.scale current scaling of patchfield view
         */
    }

    isInBlueprint2() // will be overwritten in ui
    {
        return false;
    }

    get name()
    {
        return this.getTitle();
    }

    set name(n)
    {
        this.setTitle(n);
    }

    /**
     * @param {string} on
     */
    set _objName(on)
    {
        this.#objName = on;
        this._log = new logger/* default */.A("op " + on);
    }

    get objName()
    {
        return this.#objName;
    }

    get shortName()
    {
        return this.#shortOpName;
    }

    /**
     * op.require
     *
     * @param {String} _name - module name
     * @returns {Object}
     */
    require(_name)
    {
        if (CABLES.platform && CABLES.StandaloneElectron && !CABLES.platform.frontendOptions.isElectron)
            this.setUiError("notstandalone", "This op will only work in cables standalone version", 3);

        return null;
    }

    checkMainloopExists()
    {
        if (!CABLES.UI) return;
        if (!this.patch.tempData.mainloopOp) this.setUiError("nomainloop", "patch should have a mainloop to use this op");
        else this.setUiError("nomainloop", null);
    }

    /** @returns {string} */
    getTitle()
    {
        if (!this.uiAttribs) return "nouiattribs" + this.shortName;

        /*
         * if ((this.uiAttribs.title === undefined || this.uiAttribs.title === "") && this.objName.indexOf("Ops.Ui.") == -1)
         *     this.uiAttribs.title = this._shortOpName;
         */

        return this.uiAttribs.title || this.#shortOpName;
    }

    /**
     * @param {string} title
     */
    setTitle(title)
    {

        /*
         * this._log.log("settitle", title);
         * this._log.log(
         *     (new Error()).stack
         * );
         */

        if (title != this.getTitle()) this._setUiAttrib({ "title": title });
    }

    /**
     * @param {Object} newAttribs
     */
    setStorage(newAttribs)
    {
        if (!newAttribs) return;
        this.storage = this.storage || {};

        let changed = false;
        for (const p in newAttribs)
        {
            if (this.storage[p] != newAttribs[p]) changed = true;
            this.storage[p] = newAttribs[p];
        }

        if (changed) this.emitEvent("onStorageChange", newAttribs);
    }

    isSubPatchOp()
    {
        if (this.patchId && this.storage) return (this.storage.subPatchVer || this.storage.blueprintVer || 0);
        return false;
    }

    /**
     * setUiAttrib
     * possible values:
     * <pre>
     * warning - warning message - showing up in op parameter panel
     * error - error message - showing up in op parameter panel
     * extendTitle - op title extension, e.g. [ + ]
     * </pre>
     // * @param {OpUiAttribs} newAttribs, e.g. {"attrib":value}
     * @example
     * op.setUiAttrib({"extendTitle":str});
     */
    setUiAttrib(newAttribs)
    {
        this._setUiAttrib(newAttribs);
    }

    /**
     * @param {OpUiAttribs} a
     */
    setUiAttribs(a)
    {
        this._setUiAttrib(a);
    }

    /**
     * @deprecated
     * @param {OpUiAttribs} a
     */
    uiAttr(a)
    {
        this._setUiAttrib(a);
    }

    /**
     * @param {OpUiAttribs} newAttribs
     */
    _setUiAttrib(newAttribs)
    {
        if (!newAttribs) return;

        if (typeof newAttribs != "object") this._log.error("op.uiAttrib attribs are not of type object");
        if (!this.uiAttribs) this.uiAttribs = {};

        let changed = false;
        let emitMove = false;
        if (
            CABLES.UI &&
            newAttribs.hasOwnProperty("translate") &&
            (
                !this.uiAttribs.translate ||
                this.uiAttribs.translate.x != newAttribs.translate.x ||
                this.uiAttribs.translate.y != newAttribs.translate.y
            )) emitMove = true;

        if (newAttribs.hasOwnProperty("title") && newAttribs.title != this.uiAttribs.title)
        {
            this.uiAttribs.title = newAttribs.title;
            changed = true;
        }

        if (newAttribs.hasOwnProperty("disabled"))
        {
            changed = true;
            this.setEnabled(!newAttribs.disabled);
        }

        for (const p in newAttribs)
        {
            if (this.uiAttribs[p] != newAttribs[p]) changed = true;
            this.uiAttribs[p] = newAttribs[p];
        }

        if (this.uiAttribs.hasOwnProperty("selected") && this.uiAttribs.selected == false) delete this.uiAttribs.selected;
        if (this.uiAttribs.hasOwnProperty("selected")) changed = true;

        if (changed)
        {
            this.emitEvent(Op.EVENT_UIATTR_CHANGE, newAttribs);
            this.patch.emitEvent("onUiAttribsChange", this, newAttribs);
        }

        if (emitMove) this.emitEvent("move");
    }

    getName()
    {
        return this.#shortOpName;
    }

    /**
     * @param {Port} p
     */
    addOutPort(p)
    {
        p.direction = constants/* CONSTANTS */.a.PORT.PORT_DIR_OUT;
        p._op = this;
        this.portsOut.push(p);
        this.emitEvent("onPortAdd", p);
        return p;
    }

    hasDynamicPort()
    {
        let i = 0;
        for (i = 0; i < this.portsIn.length; i++)
        {
            if (this.portsIn[i].type == core_port/* Port */.I.TYPE_DYNAMIC) return true;
            if (this.portsIn[i].getName() == "dyn") return true;
        }
        for (i = 0; i < this.portsOut.length; i++)
        {
            if (this.portsOut[i].type == core_port/* Port */.I.TYPE_DYNAMIC) return true;
            if (this.portsOut[i].getName() == "dyn") return true;
        }

        return false;
    }

    /**
     * @param {any|Port | MultiPort} p
     */
    addInPort(p)
    {
        p.direction = core_port/* Port */.I.DIR_IN;
        p._op = this;

        this.portsIn.push(p);
        this.emitEvent("onPortAdd", p);

        return p;
    }

    /**
     *
     * @param {string} name
     * @param {string} v
     */
    inFunction(name, v)
    {
        return this.inTrigger(name, v);
    }

    /**
     * create a trigger input port
     * @param {String} name
     * @param {String} v
     * @return {Port} created port
     *
     */
    inTrigger(name, v)
    {
        const p = this.addInPort(new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_FUNCTION));
        if (v !== undefined) p.set(v);
        return p;
    }

    /**
     * create multiple UI trigger buttons
     * @param {String} name
     * @param {Array} v
     * @return {Port} created port
     */
    inTriggerButton(name, v)
    {
        const p = this.addInPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_FUNCTION, {
                "display": "button"
            })
        );
        if (v !== undefined) p.set(v);
        return p;
    }

    /**
     * @param {string} name
     * @param {any} v
     */
    inUiTriggerButtons(name, v)
    {
        const p = this.addInPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_FUNCTION, {
                "display": "buttons"
            })
        );
        if (v !== undefined) p.set(v);
        return p;
    }

    /**
     * @deprecated
     */
    inValueFloat(name, v)
    {
        return this.inFloat(name, v);
    }

    /**
     * @deprecated
     */
    inValue(name, v)
    {
        return this.inFloat(name, v);
    }

    /**
     * create a number value input port
     * @param {String} name
     * @param {Number} v
     * @return {Port} created port
     */
    inFloat(name, v)
    {
        const p = this.addInPort(new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_VALUE));

        p.setInitialValue(v);

        return p;
    }

    /**
     * @deprecated
     */
    inValueBool(name, v)
    {
        return this.inBool(name, v);
    }

    /**
     * create a boolean input port, displayed as a checkbox
     * @param {String} name
     * @param {Boolean|number} v
     * @return {Port} created port
     */
    inBool(name, v)
    {
        const p = this.addInPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_NUMBER, {
                "display": "bool"
            })
        );

        if (v === true)v = 1;
        if (v === false)v = 0;
        p.setInitialValue(v);

        return p;
    }

    /**
     * @param {string} name
     * @param {number} type
     */
    inMultiPort(name, type)
    {
        const p = new MultiPort(
            this,
            name,
            type,
            core_port/* Port */.I.DIR_IN,
            {
                "addPort": true,
                "hidePort": true
            }
        );
        p.ignoreValueSerialize = true;

        this.addInPort(p);
        p.initPorts();

        return p;
    }

    /**
     * @param {string} name
     * @param {number} type
     */
    outMultiPort(name, type, uiAttribsPort = {})
    {
        const p = new MultiPort(
            this,
            name,
            type,
            constants/* CONSTANTS */.a.PORT.PORT_DIR_OUT,
            {
                "display": "multiport",
                "hidePort": true
            },
            uiAttribsPort
        );
        p.ignoreValueSerialize = true;

        this.addOutPort(p);
        p.initPorts();

        return p;
    }

    /**
     * @param {string} name
     * @param {string} v
     */
    inValueString(name, v)
    {
        const p = this.addInPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_VALUE, {
                "type": "string"
            })
        );
        p.value = "";

        p.setInitialValue(v);
        return p;
    }

    /**
     * create a String value input port
     * @param {String} name
     * @param {String} v default value
     * @return {Port} created port
     */
    inString(name, v)
    {
        const p = this.addInPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_STRING, {
                "type": "string"
            })
        );
        v = v || "";

        p.setInitialValue(v);
        return p;
    }

    // /**
    //  * create a String value input port displayed as TextArea
    //  * @memberof Op
    //  * @param {String} name
    //  * @param {String} v default value
    //  * @return {Port} created port
    //  */
    // inValueText(name, v)
    // {
    //     const p = this.addInPort(
    //         new Port(this, name, Port.TYPE_VALUE, {
    //             "type": "string",
    //             "display": "text"
    //         })
    //     );
    //     p.value = "";

    //     p.setInitialValue(v);

    //     /*
    //      * if (v !== undefined)
    //      * {
    //      *     p.set(v);
    //      *     p.defaultValue = v;
    //      * }
    //      */
    //     return p;
    // }

    /**
     * @param {string} name
     * @param {string} v
     */
    inTextarea(name, v)
    {
        const p = this.addInPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_STRING, {
                "type": "string",
                "display": "text"
            })
        );
        p.value = "";
        if (v !== undefined)
        {
            p.set(v);
            p.defaultValue = v;
        }
        return p;
    }

    /**
     * create a String value input port displayed as editor
     * @param {String} name
     * @param {String} v default value
     * @param {String} syntax language
     * @param {Boolean} hideFormatButton
     * @return {Port} created port
     */
    inStringEditor(name, v, syntax, hideFormatButton = true)
    {
        const p = this.addInPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_STRING, {
                "type": "string",
                "display": "editor",
                "editShortcut": true,
                "editorSyntax": syntax,
                "hideFormatButton": hideFormatButton
            }));

        p.value = "";
        if (v !== undefined)
        {
            p.set(v);
            p.defaultValue = v;
        }
        return p;
    }

    /**
     *
     * @param {string} name
     * @param {String} v
     * @param {String} syntax
     */
    inValueEditor(name, v, syntax, hideFormatButton = true)
    {
        const p = this.addInPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_NUMBER, {
                "type": "string",
                "display": "editor",
                "editorSyntax": syntax,
                "hideFormatButton": hideFormatButton
            })
        );
        p.value = "";
        if (v !== undefined)
        {
            p.set(v);
            p.defaultValue = v;
        }
        return p;
    }

    /**
     * @deprecated
     * @param {string} name
     * @param {any[]} values
     * @param {string} v
     * @param {boolean} noindex
     */
    inValueSelect(name, values, v, noindex)
    {
        return this.inDropDown(name, values, v, noindex);
    }

    /**
     * create a string select box
     * @param {String} name
     * @param {Array} values
     * @param {String} v default value
     * @return {Port} created port
     * @param {boolean} [noindex]
     */
    inDropDown(name, values, v, noindex)
    {
        let p = null;
        if (!noindex)
        {
            const indexPort = new core_port/* Port */.I(this, name + " index", core_port/* Port */.I.TYPE_NUMBER, {
                "increment": "integer",
                "hideParam": true
            });
            const n = this.addInPort(indexPort);

            if (values) for (let i = 0; i < values.length; i++) values[i] = String(values[i]);

            const valuePort = new ValueSelectPort(
                this,
                name,
                core_port/* Port */.I.TYPE_NUMBER,
                {
                    "display": "dropdown",
                    "hidePort": true,
                    "type": "string",
                    "values": values
                },
                n
            );

            valuePort.indexPort = indexPort;

            valuePort.on("change", (/** @type {any} */ val, /** @type {Port} */ thePort) =>
            {
                if (!thePort.indexPort.isLinked() && thePort.uiAttribs.values)
                {
                    const idx = thePort.uiAttribs.values.indexOf(val);
                    if (idx > -1) thePort.indexPort.set(idx);
                }
            });

            indexPort.onLinkChanged = () =>
            {
                valuePort.setUiAttribs({ "greyout": indexPort.isLinked() });
            };

            p = this.addInPort(valuePort);

            if (v !== undefined)
            {
                p.set(v);
                const index = values.findIndex((item) => { return item == v; });
                n.setValue(index);
                p.defaultValue = v;
                n.defaultValue = index;
            }
        }
        else
        {
            const valuePort = new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_VALUE, {
                "display": "dropdown",
                "hidePort": true,
                "type": "string",
                "values": values
            });

            p = this.addInPort(valuePort);
        }

        return p;
    }

    /**
     * create a string switch box
     * @param {String} name
     * @param {Array} values
     * @param {String} v default value
     * @param {boolean} noindex
     * @return {Port} created port
     */
    inSwitch(name, values, v, noindex)
    {
        let p = null;
        if (!noindex)
        {
            if (!v)v = values[0];
            const indexPort = new core_port/* Port */.I(this, name + " index", core_port/* Port */.I.TYPE_VALUE, {
                "increment": "integer",
                "values": values,
                "hideParam": true
            });
            const n = this.addInPort(indexPort);

            if (values) for (let i = 0; i < values.length; i++) values[i] = String(values[i]);

            const switchPort = new SwitchPort(
                this,
                name,
                core_port/* Port */.I.TYPE_STRING,
                {
                    "display": "switch",
                    "hidePort": true,
                    "type": "string",
                    "values": values
                },
                n
            );

            switchPort.indexPort = indexPort;

            switchPort.on("change", (val, thePort) =>
            {
                if (!thePort.indexPort.isLinked() && thePort.uiAttribs.values)
                {
                    const idx = thePort.uiAttribs.values.indexOf(val);
                    if (idx > -1) thePort.indexPort.set(idx);
                }
            });

            indexPort.onLinkChanged = function ()
            {
                switchPort.setUiAttribs({ "greyout": indexPort.isLinked() });
            };
            p = this.addInPort(switchPort);

            if (v !== undefined)
            {
                p.set(v);
                const index = values.findIndex((item) => { return item == v; });
                n.setValue(index);
                p.defaultValue = v;
                n.defaultValue = index;
            }
        }
        else
        {
            const switchPort = new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_STRING, {
                "display": "switch",
                "hidePort": true,
                "type": "string",
                "values": values
            });
            p = this.addInPort(switchPort);
        }

        return p;
    }

    /**
     * @deprecated
     */
    inValueInt(name, v)
    {
        return this.inInt(name, v);
    }

    /**
     * create a integer input port
     * @param {String} name
     * @param {number} v default value
     * @return {Port} created port
     */
    inInt(name, v)
    {
        // old
        const p = this.addInPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_VALUE, { "increment": "integer" })
        );
        if (v !== undefined)
        {
            p.set(v);
            p.defaultValue = v;
        }
        return p;
    }

    /**
     * create a file/URL input port
     * @param {String} name
     * @param {String} filter
     * @param {String} v
     * @return {Port} created port
     */
    inFile(name, filter, v)
    {
        const p = this.addInPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_VALUE, {
                "display": "file",
                "type": "string",
                "filter": filter
            })
        );
        if (v !== undefined)
        {
            p.set(v);
            p.defaultValue = v;
        }
        return p;
    }

    /**
     * create a file/URL input port
     * @param {String} name
     * @param {String} filter
     * @param {String} v
     * @return {Port} created port
     */
    inUrl(name, filter, v)
    {
        const p = this.addInPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_STRING, {
                "display": "file",
                "type": "string",
                "filter": filter
            })
        );
        if (v !== undefined)
        {
            p.set(v);
            p.defaultValue = v;
        }
        return p;
    }

    /**
     * create a texture input port
     * @param {String} name
     * @return {Port} created port
     */
    inTexture(name, v)
    {
        const p = this.addInPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_OBJECT, {
                "display": "texture",
                "objType": "texture",
                "preview": true
            })
        );
        p.ignoreValueSerialize = true;
        if (v !== undefined) p.set(v);
        return p;
    }

    /**
     * create a object input port
     * @param {String} name
     * @param {Object} v
     * @param {String} objType
     * @return {Port} created port
     */
    inObject(name, v, objType)
    {
        const p = this.addInPort(new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_OBJECT, { "objType": objType }));
        p.ignoreValueSerialize = true;

        if (v !== undefined) p.set(v);
        return p;
    }

    /**
     * @param {string} name
     * @param {string} v
     */
    inGradient(name, v)
    {
        const p = this.addInPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_VALUE, {
                "display": "gradient"
                // "hidePort": true
            })
        );
        if (v !== undefined) p.set(v);
        return p;
    }

    /**
     * @param {Port} p
     * returns {number}
     */
    getPortVisibleIndex(p)
    {
        let ports = this.portsIn;
        if (p.direction == constants/* CONSTANTS */.a.PORT_DIR_OUT)ports = this.portsOut;

        let index = 0;
        for (let i = 0; i < ports.length; i++)
        {
            if (ports[i].uiAttribs.hidePort) continue;
            index++;
            if (ports[i] == p) return index;
        }
    }

    /**
     * create a array input port
     * @param {String} name
     * @param {Array|Number} v
     * @param {Number} _stride
     * @return {Port} created port
     */
    inArray(name, v = undefined, _stride = undefined)
    {
        let stride = _stride;
        // @ts-ignore
        if (!_stride && CABLES.isNumeric(v))stride = v;

        const p = this.addInPort(new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_ARRAY, { "stride": stride }));

        if (v !== undefined && (Array.isArray(v) || v == null)) p.set(v);

        return p;
    }

    /**
     * @deprecated
     */
    inValueSlider(name, v, min, max)
    {
        return this.inFloatSlider(name, v, min, max);
    }

    /**
     * create a value slider input port
     * @param {String} name
     * @param {number} v
     * @param {number} min
     * @param {number} max
     * @return {Port} created port
     */
    inFloatSlider(name, v, min, max)
    {
        const uiattribs = { "display": "range" };

        if (min != undefined && max != undefined)
        {
            uiattribs.min = min;
            uiattribs.max = max;
        }

        const p = this.addInPort(new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_VALUE, uiattribs));
        if (v !== undefined)
        {
            p.set(v);
            p.defaultValue = v;
        }
        return p;
    }

    /**
     * @deprecated
     */
    outFunction(name, v)
    {
        return this.outTrigger(name, v);
    }

    /**
     * create output trigger port
     * @param {String} name
     * @param {String} v
     * @return {Port} created port
     */
    outTrigger(name, v)
    {
        // old
        const p = this.addOutPort(new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_FUNCTION));
        if (v !== undefined) p.set(v);
        return p;
    }

    /**
     * @deprecated
     */
    outValue(name, v)
    {
        return this.outNumber(name, v);
    }

    /**
     * create output value port
     * @param {String} name
     * @param {number} v default value
     * @return {Port} created port
     */
    outNumber(name, v)
    {
        const p = this.addOutPort(new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_VALUE));
        if (v !== undefined) p.set(v);
        return p;
    }

    /**
     * @deprecated
     */
    outValueBool(name, v)
    {
        return this.outBool(name, v);
    }

    /**
     * deprecated create output boolean port
     * @deprecated
     * @param {String} name
     * @param {boolean} v default value
     * @return {Port} created port
     */
    outBool(name, v)
    {
        // old: use outBoolNum
        const p = this.addOutPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_VALUE, {
                "display": "bool"
            })
        );
        if (v !== undefined) p.set(v);
        else p.set(0);
        return p;
    }

    /**
     * create output boolean port,value will be converted to 0 or 1
     * @param {String} name
     * @return {Port} created port
     */
    outBoolNum(name, v)
    {
        const p = this.addOutPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_VALUE, {
                "display": "boolnum"
            })
        );

        p.set = function (b)
        {
            this.setValue(b ? 1 : 0);
        }.bind(p);

        if (v !== undefined) p.set(v);
        else p.set(0);
        return p;
    }

    /**
     * @deprecated
     * @param {string} name
     * @param {string} v
     */
    outValueString(name, v)
    {
        const p = this.addOutPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_VALUE, {
                "type": "string"
            })
        );
        if (v !== undefined) p.set(v);
        return p;
    }

    /**
     * create output string port
     * @param {string} name
     * @param {String} v
     * @return {Port} created port
     */
    outString(name, v)
    {
        const p = this.addOutPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_STRING, {
                "type": "string"
            })
        );
        if (v !== undefined) p.set(v);
        else p.set("");
        return p;
    }

    /**
     * create output object port
     * @param {String} name
     * @return {Port} created port
     * @param {object} v
     * @param {string} objType
     */
    outObject(name, v, objType)
    {
        const p = this.addOutPort(new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_OBJECT, { "objType": objType || null }));
        p.set(v || null);
        p.ignoreValueSerialize = true;
        return p;
    }

    /**
     * create output array port
     * @param {String} name
     * @return {Port} created port
     * @param {array|number} v
     * @param {number} stride
     */
    outArray(name, v, stride)
    {
        if (!stride && CABLES.isNumeric(v))stride = v;
        const p = this.addOutPort(new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_ARRAY, { "stride": stride }));
        if (v !== undefined && (Array.isArray(v) || v == null)) p.set(v);

        p.ignoreValueSerialize = true;
        return p;
    }

    /**
     * create output texture port
     * @param {String} name
     * @return {Port} created port
     * @param {any} v
     */
    outTexture(name, v)
    {
        const p = this.addOutPort(
            new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_OBJECT, {
                "preview": true,
                "objType": "texture",
                "display": "texture"
            })
        );
        if (v !== undefined) p.setRef(v || cgl/* CGL */.Rq.Texture.getEmptyTexture(this.patch.cgl));

        p.ignoreValueSerialize = true;
        return p;
    }

    /**
     * @deprecated
     * @param {string} name
     * @param {any} filter
     * @param {any} options
     * @param {any} v
     */
    inDynamic(name, filter, options, v)
    {
        const p = new core_port/* Port */.I(this, name, core_port/* Port */.I.TYPE_DYNAMIC, options);

        p.shouldLink = (p1, p2) =>
        {
            if (filter && CABLES.isArray(filter))
            {
                // for (let i = 0; i < filter.length; i++)
                // {
                // if (p1 == this && p2.type === filter[i]) return true;
                // if (p2 == this && p1.type === filter[i]) return true;
                // }
                return false; // types do not match
            }
            return true; // no filter set
        };

        this.addInPort(p);
        if (v !== undefined)
        {
            p.set(v);
            p.defaultValue = v;
        }
        return p;
    }

    removeLinks()
    {
        for (let i = 0; i < this.portsIn.length; i++) this.portsIn[i].removeLinks();
        for (let i = 0; i < this.portsOut.length; i++) this.portsOut[i].removeLinks();
    }

    getSerialized()
    {
        const opObj = {};

        if (this.opId) opObj.opId = this.opId;
        if (this.patch.storeObjNames) opObj.objName = this.objName;

        opObj.id = this.id;
        opObj.uiAttribs = JSON.parse(JSON.stringify(this.uiAttribs)) || {};

        if (this.storage && Object.keys(this.storage).length > 0) opObj.storage = JSON.parse(JSON.stringify(this.storage));
        if (this.uiAttribs.hasOwnProperty("working") && this.uiAttribs.working == true) delete this.uiAttribs.working;
        if (opObj.uiAttribs.hasOwnProperty("uierrors")) delete opObj.uiAttribs.uierrors;

        if (opObj.uiAttribs.title === "") delete opObj.uiAttribs.title;
        if (opObj.uiAttribs.color === null) delete opObj.uiAttribs.color;
        if (opObj.uiAttribs.comment === null) delete opObj.uiAttribs.comment;

        if (opObj.uiAttribs.title == this.#shortOpName ||
            (this.uiAttribs.title || "").toLowerCase() == this.#shortOpName.toLowerCase()) delete opObj.uiAttribs.title;

        opObj.portsIn = [];
        opObj.portsOut = [];

        for (let i = 0; i < this.portsIn.length; i++)
        {
            const s = this.portsIn[i].getSerialized();
            if (s) opObj.portsIn.push(s);
        }

        for (let i = 0; i < this.portsOut.length; i++)
        {
            const s = this.portsOut[i].getSerialized();
            if (s) opObj.portsOut.push(s);
        }

        if (opObj.portsIn.length == 0) delete opObj.portsIn;
        if (opObj.portsOut.length == 0) delete opObj.portsOut;
        (0,utils.cleanJson)(opObj);

        return opObj;
    }

    /**
     * @param {number} type
     */
    getFirstOutPortByType(type)
    {
        for (let i = 0; i < this.portsOut.length; i++)
            if (this.portsOut[i].type == type) return this.portsOut[i];
    }

    /**
     * @param {number} type
     */
    getFirstInPortByType(type)
    {
        for (let i = 0; i < this.portsIn.length; i++)
            if (this.portsIn[i].type == type) return this.portsIn[i];
    }

    /**
     * return port by the name portName
     * @param {String} name
     * @param {boolean} [lowerCase]
     * @return {Port}
     */
    getPort(name, lowerCase = false)
    {
        return this.getPortByName(name, lowerCase);
    }

    /**
     * @param {string} name
     * @param {boolean} [lowerCase]
     * @returns {Port}
     */
    getPortByName(name, lowerCase = false)
    {
        if (lowerCase)
        {
            for (let ipi = 0; ipi < this.portsIn.length; ipi++)
                if (this.portsIn[ipi].getName().toLowerCase() == name || this.portsIn[ipi].id.toLowerCase() == name)
                    return this.portsIn[ipi];

            for (let ipo = 0; ipo < this.portsOut.length; ipo++)
                if (this.portsOut[ipo].getName().toLowerCase() == name || this.portsOut[ipo].id.toLowerCase() == name)
                    return this.portsOut[ipo];
        }
        else
        {
            for (let ipi = 0; ipi < this.portsIn.length; ipi++)
                if (this.portsIn[ipi].getName() == name || this.portsIn[ipi].id == name)
                    return this.portsIn[ipi];

            for (let ipo = 0; ipo < this.portsOut.length; ipo++)
                if (this.portsOut[ipo].getName() == name || this.portsOut[ipo].id == name)
                    return this.portsOut[ipo];
        }
    }

    /**
     * return port by the name id
     * @param {String} id
     * @return {Port}
     */
    getPortById(id)
    {
        for (let ipi = 0; ipi < this.portsIn.length; ipi++) if (this.portsIn[ipi].id == id) return this.portsIn[ipi];
        for (let ipo = 0; ipo < this.portsOut.length; ipo++) if (this.portsOut[ipo].id == id) return this.portsOut[ipo];
    }

    updateAnims()
    {
        if (this.hasAnimPort)
            for (let i = 0; i < this.portsIn.length; i++) this.portsIn[i].updateAnim();
    }

    log()
    {
        this._log.log(...arguments);
    }

    /**
     * @deprecated
     */
    error()
    {
        this._log.error(...arguments);
    }

    logError()
    {
        this._log.error(...arguments);
    }

    /**
     * @deprecated
     */
    warn()
    {
        this._log.warn(...arguments);
    }

    logWarn()
    {
        this._log.warn(...arguments);
    }

    /**
     * @deprecated
     */
    verbose()
    {
        this._log.verbose(...arguments);
    }

    logVerbose()
    {
        this._log.verbose(...arguments);
    }

    profile()
    {
        for (let ipi = 0; ipi < this.portsIn.length; ipi++)
        {
            this.portsIn[ipi]._onTriggered = this.portsIn[ipi]._onTriggeredProfiling;
            this.portsIn[ipi].set = this.portsIn[ipi]._onSetProfiling;
        }
    }

    // todo: check instancing stuff?
    cleanUp()
    {
        if (this._instances)
        {
            for (let i = 0; i < this._instances.length; i++)
                if (this._instances[i].onDelete) this._instances[i].onDelete();

            this._instances.length = 0;
        }

        for (let i = 0; i < this.portsIn.length; i++)
            this.portsIn[i].setAnimated(false);

        if (this.onAnimFrame) this.patch.removeOnAnimFrame(this);
    }

    // todo: check instancing stuff?
    instanced(triggerPort)
    {
        return false;

        /*
         * this._log.log("instanced", this.patch.instancing.numCycles());
         * if (this.patch.instancing.numCycles() === 0) return false;
         */

        /*
         * let i = 0;
         * let ipi = 0;
         * if (!this._instances || this._instances.length != this.patch.instancing.numCycles())
         * {
         *     if (!this._instances) this._instances = [];
         *     this._.log("creating instances of ", this.objName, this.patch.instancing.numCycles(), this._instances.length);
         *     this._instances.length = this.patch.instancing.numCycles();
         */

        /*
         *     for (i = 0; i < this._instances.length; i++)
         *     {
         *         this._instances[i] = this.patch.createOp(this.objName, true);
         *         this._instances[i].instanced ()
         *         {
         *             return false;
         *         };
         *         this._instances[i].uiAttr(this.uiAttribs);
         */

        /*
         *         for (let ipo = 0; ipo < this.portsOut.length; ipo++)
         *         {
         *             if (this.portsOut[ipo].type == Port.TYPE_FUNCTION)
         *             {
         *                 this._instances[i].getPortByName(this.portsOut[ipo].name).trigger = this.portsOut[ipo].trigger.bind(this.portsOut[ipo]);
         *             }
         *         }
         *     }
         */

        /*
         *     for (ipi = 0; ipi < this.portsIn.length; ipi++)
         *     {
         *         this.portsIn[ipi].onChange = null;
         *         this.portsIn[ipi].onValueChanged = null;
         *     }
         * }
         */

        /*
         * const theTriggerPort = null;
         * for (ipi = 0; ipi < this.portsIn.length; ipi++)
         * {
         *     if (
         *         this.portsIn[ipi].type == Port.TYPE_VALUE ||
         *         this.portsIn[ipi].type == Port.TYPE_ARRAY
         *     )
         *     {
         *         this._instances[this.patch.instancing.index()].portsIn[ipi].set(this.portsIn[ipi].get());
         *     }
         *     if (this.portsIn[ipi].type == Port.TYPE_FUNCTION)
         *     {
         *         // if(this._instances[ this.patch.instancing.index() ].portsIn[ipi].name==triggerPort.name)
         *         // theTriggerPort=this._instances[ this.patch.instancing.index() ].portsIn[ipi];
         *     }
         * }
         */

        // if (theTriggerPort) theTriggerPort.onTriggered();

        /*
         * for (ipi = 0; ipi < this.portsOut.length; ipi++)
         * {
         *     if (this.portsOut[ipi].type == Port.TYPE_VALUE)
         *     {
         *         this.portsOut[ipi].set(this._instances[this.patch.instancing.index()].portsOut[ipi].get());
         *     }
         * }
         */

        // return true;
    }

    // todo: check instancing stuff?
    initInstancable()
    {
        //         if(this.isInstanced)
        //         {
        //             this._log.log('cancel instancing');
        //             return;
        //         }
        //         this._instances=[];
        //         for(var ipi=0;ipi<this.portsIn.length;ipi++)
        //         {
        //             if(this.portsIn[ipi].type==Port.TYPE_VALUE)
        //             {
        //
        //             }
        //             if(this.portsIn[ipi].type==Port.TYPE_FUNCTION)
        //             {
        //                 // var piIndex=ipi;
        //                 this.portsIn[ipi].onTriggered=function(piIndex)
        //                 {
        //
        //                     var i=0;
        // // this._log.log('trigger',this._instances.length);
        //
        //                 }.bind(this,ipi );
        //
        //             }
        // };
        // this._instances=null;
    }

    // setValues(obj)
    // {
    //     for (const i in obj)
    //     {
    //         const port = this.getPortByName(i);
    //         if (port) port.set(obj[i]);
    //         else this._log.warn("op.setValues: port not found:", i);
    //     }
    // }

    /**
     * return true if op has this error message id
     * @param {String} id
     * @returns {Boolean} - has id
     */
    hasUiError(id)
    {
        return this.uiErrors.hasOwnProperty(id) && this.uiErrors[id];
    }

    /**
     * show op error message - set message to null to remove error message
     * @param {string} id error id
     * @param {string} txt text message
     * @param {number} level level
     */
    setUiError(id, txt, level = 2, options = {})
    {
        // overwritten in ui: core_extend_op
    }

    /**
     * enable/disable op
     * @function
     * @param {boolean} b
     */
    setEnabled(b)
    {
        this.enabled = b;
        this.emitEvent("onEnabledChange", b);
    }

    /**
     * organize ports into a group
     * @function
     * @param {String} name
     * @param {Array} ports
     */
    setPortGroup(name, ports)
    {
        for (let i = 0; i < ports.length; i++)
        {
            if (ports[i])
                if (ports[i].setUiAttribs) ports[i].setUiAttribs({ "group": name });
                else this._log.error("setPortGroup: invalid port!");
        }
    }

    /**
     * visually indicate ports that they are coordinate inputs
     * @function
     * @param {Port} px
     * @param {Port} py
     * @param {Port} pz
     */
    setUiAxisPorts(px, py, pz)
    {
        if (px) px.setUiAttribs({ "axis": "X" });
        if (py) py.setUiAttribs({ "axis": "Y" });
        if (pz) pz.setUiAttribs({ "axis": "Z" });
    }

    /**
     * remove port from op
     * @param {Port} port to remove
     */
    removePort(port)
    {
        for (let ipi = 0; ipi < this.portsIn.length; ipi++)
        {
            if (this.portsIn[ipi] == port)
            {
                this.portsIn.splice(ipi, 1);
                this.emitEvent(Op.EVENT_UIATTR_CHANGE, {});
                this.emitEvent("onPortRemoved", {});
                return;
            }
        }
        for (let ipi = 0; ipi < this.portsOut.length; ipi++)
        {
            if (this.portsOut[ipi] == port)
            {
                this.portsOut.splice(ipi, 1);
                this.emitEvent(Op.EVENT_UIATTR_CHANGE, {});
                this.emitEvent("onPortRemoved", {});
                return;
            }
        }
    }

    /**
     * show a warning of this op is not a child of parentOpName
     * @function
     * @param {String} parentOpName
     */
    toWorkNeedsParent(parentOpName)
    {
        this.linkTimeRules.needsParentOp = parentOpName;
    }

    /**
     * show a warning of this op is a child of parentOpName
     * @function
     * @instance
     * @memberof Op
     * @param {String} parentOpName
     * @param {number} type
     */
    toWorkShouldNotBeChild(parentOpName, type)
    {
        if (!this.patch.isEditorMode()) return;
        this.linkTimeRules.forbiddenParent = parentOpName;
        if (type != undefined) this.linkTimeRules.forbiddenParentType = type;
    }

    toWorkPortsNeedsString()
    {
        if (!this.patch.isEditorMode()) return;
        for (let i = 0; i < arguments.length; i++)
            if (this.linkTimeRules.needsStringToWork.indexOf(arguments[i]) == -1) this.linkTimeRules.needsStringToWork.push(arguments[i]);
    }

    /**
     * show a small X to indicate op is not working when given ports are not linked
     * @function
     * @instance
     * @memberof Op
     * @param {Array<Port>} port
     */
    toWorkPortsNeedToBeLinked()
    {
        if (!this.patch.isEditorMode()) return;
        for (let i = 0; i < arguments.length; i++)
            if (this.linkTimeRules.needsLinkedToWork.indexOf(arguments[i]) == -1) this.linkTimeRules.needsLinkedToWork.push(arguments[i]);
    }

    toWorkPortsNeedToBeLinkedReset()
    {
        if (!this.patch.isEditorMode()) return;
        this.linkTimeRules.needsLinkedToWork.length = 0;
        if (this.checkLinkTimeWarnings) this.checkLinkTimeWarnings();
    }

    initVarPorts()
    {
        for (let i = 0; i < this.portsIn.length; i++)
            if (this.portsIn[i].getVariableName()) this.portsIn[i].setVariable(this.portsIn[i].getVariableName());
    }

    checkLinkTimeWarnings() {}
    _checkLinksNeededToWork() { }

    /**
     * refresh op parameters, if current op is selected
     * @function
     * @instance
     * @memberof Op
     */
    refreshParams()
    {
        if (this.patch && this.patch.isEditorMode() && this.isCurrentUiOp()) gui.opParams.show(this);
    }

    /**
     * Returns true if op is selected and parameter are shown in the editor, can only return true if in editor/ui
     * @instance
     * @memberof Op
     * @returns {Boolean} - is current ui op
     */
    isCurrentUiOp()
    {
        if (this.patch.isEditorMode()) return gui.patchView.isCurrentOp(this);
    }

    checkGraphicsApi(api = cgl_state/* CglContext */.G.API_WEBGL)
    {
        if (this.patch.isEditorMode())
            if (this.patch.cg && this.patch.cg.gApi != api)
                this.setUiError("wronggapi", "Wrong graphics API", 2);
    }
}

;// CONCATENATED MODULE: ./src/core/loadingstatus.js





/**
 * LoadingStatus class, manages asynchronous loading jobs
 *
 * @namespace external:CABLES#LoadingStatus
 * @hideconstructor
 * @class
 * @param patch
 */

class LoadingStatus extends eventtarget/* default */.A
{

    /**
     * @param {Patch} patch
     */
    constructor(patch)
    {
        super();
        this._log = new logger/* default */.A("LoadingStatus");
        this._loadingAssets = {};
        this._cbFinished = [];
        this._assetTasks = [];
        this._percent = 0;
        this._count = 0;
        this._countFinished = 0;
        this._order = 0;
        this._startTime = 0;
        this._patch = patch;
        this._wasFinishedPrinted = false;
        this._loadingAssetTaskCb = false;
    }

    /**
     * @param {Function} cb
     */
    setOnFinishedLoading(cb)
    {
        this._cbFinished.push(cb);
    }

    getNumAssets()
    {
        return this._countFinished;
    }

    getProgress()
    {
        return this._percent;
    }

    checkStatus()
    {
        this._countFinished = 0;
        this._count = 0;

        for (const i in this._loadingAssets)
        {
            this._count++;
            if (!this._loadingAssets[i].finished)
            {
                this._countFinished++;
            }
        }

        this._percent = (this._count - this._countFinished) / this._count;

        if (this._countFinished === 0)
        {
            for (let j = 0; j < this._cbFinished.length; j++)
            {
                if (this._cbFinished[j])
                {
                    const cb = this._cbFinished[j];
                    setTimeout(() => { cb(this._patch); this.emitEvent("finishedAll"); }, 100);
                }
            }

            if (!this._wasFinishedPrinted)
            {
                this._wasFinishedPrinted = true;
                this.print();
            }
            this.emitEvent("finishedAll");
        }
    }

    getList()
    {
        let arr = [];
        for (const i in this._loadingAssets)
        {
            arr.push(this._loadingAssets[i]);
        }

        return arr;
    }

    getListJobs()
    {
        let arr = [];
        for (const i in this._loadingAssets)
        {
            if (!this._loadingAssets[i].finished)arr.push(this._loadingAssets[i].name);
        }

        return arr;
    }

    print()
    {
        if (this._patch.config.silent) return;

        const rows = [];

        for (const i in this._loadingAssets)
        {
            rows.push([
                this._loadingAssets[i].order,
                this._loadingAssets[i].type,
                this._loadingAssets[i].name,
                (this._loadingAssets[i].timeEnd - this._loadingAssets[i].timeStart) / 1000 + "s",
            ]);
        }

        this._log.groupCollapsed("finished loading " + this._order + " assets in " + (Date.now() - this._startTime) / 1000 + "s");
        this._log.table(rows);
        this._log.groupEnd();
    }

    /**
     * @param {string} id
     */
    finished(id)
    {
        const l = this._loadingAssets[id];
        if (l)
        {
            if (l.finished) this._log.warn("loading job was already finished", l);

            if (l.op) l.op.setUiAttribs({ "loading": false });
            l.finished = true;
            l.timeEnd = Date.now();
        }

        this.checkStatus();
        this.emitEvent("finishedTask");
        return null;
    }

    _startAssetTasks()
    {
        for (let i = 0; i < this._assetTasks.length; i++) this._assetTasks[i]();
        this._assetTasks.length = 0;
    }

    /**
     * delay an asset loading task, mainly to wait for ui to be finished loading and showing, and only then start loading assets
     * @function addAssetLoadingTask
     * @instance
     * @memberof LoadingStatus
     * @param {function} cb callback
     */
    addAssetLoadingTask(cb)
    {
        if (this._patch.isEditorMode() && !CABLES.UI.loaded)
        {
            this._assetTasks.push(cb);

            if (!this._loadingAssetTaskCb)window.gui.addEventListener("uiloaded", this._startAssetTasks.bind(this));
            this._loadingAssetTaskCb = true;
        }
        else
        {
            cb();
        }
        this.emitEvent("addAssetTask");
    }

    /**
     * @param {string} name
     */
    existByName(name)
    {
        for (let i in this._loadingAssets)
        {
            if (this._loadingAssets[i].name == name && !this._loadingAssets[i].finished)
                return true;
        }
    }

    /**
     * @param {string} type
     * @param {string} name
     * @param {Op} [op]
     */
    start(type, name, op)
    {
        if (this._startTime == 0) this._startTime = Date.now();
        const id = (0,utils.generateUUID)();

        name = name || "unknown";
        if (name.length > 100)name = name.substring(0, 100);

        if (op)op.setUiAttrib({ "loading": true });

        this._loadingAssets[id] = {
            "id": id,
            "op": op,
            "type": type,
            "name": name,
            "finished": false,
            "timeStart": Date.now(),
            "order": this._order,
        };
        this._order++;

        this.emitEvent("startTask");

        return id;
    }
}

// EXTERNAL MODULE: ./src/core/timer.js
var timer = __webpack_require__(920);
;// CONCATENATED MODULE: ./src/core/core_profiler.js



class Profiler
{

    /**
     * @param {Patch} patch
     */
    constructor(patch)
    {
        this.startFrame = patch.getFrameNum();
        this.items = {};
        this.currentId = null;
        this.currentStart = 0;
        this._patch = patch;
    }

    getItems()
    {
        return this.items;
    }

    clear()
    {
        if (this.paused) return;
        this.items = {};
    }

    togglePause()
    {
        this.paused = !this.paused;
        if (!this.paused)
        {
            this.items = {};
            this.currentStart = performance.now();
        }
    }

    add(type, object)
    {
        if (this.paused) return;

        if (this.currentId !== null)
        {
            if (!object || object.id != this.currentId)
            {
                if (this.items[this.currentId])
                {
                    this.items[this.currentId].timeUsed += performance.now() - this.currentStart;

                    if (!this.items[this.currentId].peakTime || (0,timer/* now */.tB)() - this.items[this.currentId].peakTime > 5000)
                    {
                        this.items[this.currentId].peak = 0;
                        this.items[this.currentId].peakTime = (0,timer/* now */.tB)();
                    }
                    this.items[this.currentId].peak = Math.max(this.items[this.currentId].peak, performance.now() - this.currentStart);
                }
            }
        }

        if (object !== null)
        {
            if (!this.items[object.id])
            {
                this.items[object.id] = {
                    "numTriggers": 0,
                    "timeUsed": 0,
                };
            }

            if (this.items[object.id].lastFrame != this._patch.getFrameNum()) this.items[object.id].numTriggers = 0;

            this.items[object.id].lastFrame = this._patch.getFrameNum();
            this.items[object.id].numTriggers++;
            this.items[object.id].opid = object.op.id;
            this.items[object.id].title = object.op.name + "." + object.name;
            this.items[object.id].subPatch = object.op.uiAttribs.subPatch;

            this.currentId = object.id;
            this.currentStart = performance.now();
        }
        else
        {
            this.currentId = null;
        }
    }

    print()
    {
        console.log("--------");
        for (const i in this.items)
        {
            console.log(this.items[i].title + ": " + this.items[i].numTriggers + " / " + this.items[i].timeUsed);
        }
    }
}

;// CONCATENATED MODULE: ./src/core/core_variable.js


class PatchVariable extends eventtarget/* default */.A
{

    /**
     * @param {String} name
     * @param {String|Number} val
     * @param {number} type
     */
    constructor(name, val, type)
    {
        super();
        this._name = name;
        this.type = type;
        this.setValue(val);
    }

    /**
     * keeping this for backwards compatibility in older
     * exports before using eventtarget
     *
     * @param cb
     */
    addListener(cb)
    {
        this.on("change", cb, "var");
    }

    /**
     * @function Variable.getValue
     * @memberof PatchVariable
     * @returns {String|Number|Boolean}
     */
    getValue()
    {
        return this._v;
    }

    /**
     * @function getName
     * @memberof PatchVariable
     * @instance
     * @returns {String|Number|Boolean}
     * @function
     */
    getName()
    {
        return this._name;
    }

    /**
     * @function setValue
     * @memberof PatchVariable
     * @instance
     * @param v
     * @returns {any}
     * @function
     */
    setValue(v)
    {
        this._v = v;
        this.emitEvent("change", v, this);
    }
}

;// CONCATENATED MODULE: ./src/core/core_patch.js











/** @global CABLES.OPS  */

/**
 * @typedef {import("./core_op.js").OpUiAttribs} OpUiAttribs
 */

/**
 * @typedef PatchConfig
 * @property {String} [prefixAssetPath=''] prefix for path to assets
 * @property {String} [assetPath=''] path to assets
 * @property {String} [jsPath=''] path to javascript files
 * @property {String} [glCanvasId='glcanvas'] dom element id of canvas element
 * @property {Function} [onError=null] called when an error occurs
 * @property {Function} [onFinishedLoading=null] called when patch finished loading all assets
 * @property {Function} [onFirstFrameRendered=null] called when patch rendered it's first frame
 * @property {Boolean} [glCanvasResizeToWindow=false] resize canvas automatically to window size
 * @property {Boolean} [glCanvasResizeToParent] resize canvas automatically to parent element
 * @property {Boolean} [doRequestAnimation=true] do requestAnimationFrame set to false if you want to trigger exec() from outside (only do if you know what you are doing)
 * @property {Boolean} [clearCanvasColor=true] clear canvas in transparent color every frame
 * @property {Boolean} [clearCanvasDepth=true] clear depth every frame
 * @property {Boolean} [glValidateShader=true] enable/disable validation of shaders *
 * @property {Boolean} [silent=false]
 * @property {Number} [fpsLimit=0] 0 for maximum possible frames per second
 * @property {String} [glslPrecision='mediump'] default precision for glsl shader
 * @property {String} [prefixJsPath]
 * @property {Function} [onPatchLoaded]
 * @property {Object} [canvas]
 * @property {Object} [patch]
 * @property {String} [patchFile]
 * @property {String} [subPatch] internal use
 * @property {Number} [masterVolume] 0 for maximum possible frames per second
 * @property {HTMLCanvasElement} [glCanvas]
*/

/**
 * @typedef CoreOp
 * @type Op
 */

/**
 * @template {CoreOp} Op
 *
 * Patch class, contains all operators,values,links etc. manages loading and running of the whole patch
 *
 * see {@link PatchConfig}
 *
 * @example
 * CABLES.patch=new CABLES.Patch(
 * {
 *     patch:pStr,
 *     glCanvasId:'glcanvas',
 *     glCanvasResizeToWindow:true,
 *     canvas:{powerPreference:"high-performance"},
 *     prefixAssetPath:'/assets/',
 *     prefixJsPath:'/js/',
 *     onError:function(e){console.log(e);}
 *     glslPrecision:'highp'
 * });
 */
class Patch extends eventtarget/* default */.A
{
    static EVENT_OP_DELETED = "onOpDelete";
    static EVENT_OP_ADDED = "onOpAdd";
    static EVENT_PAUSE = "pause";
    static EVENT_RESUME = "resume";
    static EVENT_PATCHLOADEND = "patchLoadEnd";
    static EVENT_VARIABLES_CHANGED = "variablesChanged";
    static EVENT_RENDER_FRAME = "onRenderFrame";
    static EVENT_RENDERED_ONE_FRAME = "renderedOneFrame";
    static EVENT_LINK = "onLink";
    static EVENT_VALUESSET = "loadedValueSet";

    #renderOneFrame = false;
    #initialDeserialize = true;

    /** @param {PatchConfig} cfg */
    constructor(cfg)
    {
        super();

        this._log = new logger/* default */.A("core_patch", { "onError": cfg.onError });

        /** @type {Array<Op>} */
        this.ops = [];
        this.settings = {};

        /** @type {PatchConfig} */
        this.config = cfg ||
        {
            "glCanvasResizeToWindow": false,
            "prefixAssetPath": "",
            "prefixJsPath": "",
            "silent": true,
            "onError": null,
            "onFinishedLoading": null,
            "onFirstFrameRendered": null,
            "onPatchLoaded": null,
            "fpsLimit": 0,

        };

        this.timer = new timer/* Timer */.M4();
        this.freeTimer = new timer/* Timer */.M4();
        this.animFrameOps = [];
        this.animFrameCallbacks = [];
        this.gui = false;
        CABLES.logSilent = this.silent = true;
        this.profiler = null;
        this.aborted = false;
        this._crashedOps = [];

        this._animReq = null;
        this._opIdCache = {};
        this._triggerStack = [];
        this.storeObjNames = false; // remove after may release

        /** @type {LoadingStatus} */
        this.loading = new LoadingStatus(this);

        this._volumeListeners = [];
        this._paused = false;
        this._frameNum = 0;
        this.onOneFrameRendered = null;
        this.namedTriggers = {};

        this._origData = null;
        this._frameNext = 0;
        this._frameInterval = 0;
        this._lastFrameTime = 0;
        this._frameWasdelayed = true;
        this.tempData = this.frameStore = {};
        this.reqAnimTimeStamp = 0;

        this.cgCanvas = null;

        if (!(function () { return !this; }())) console.log("not in strict mode: core patch");

        if (this.config.hasOwnProperty("silent")) this.silent = CABLES.logSilent = this.config.silent;
        if (!this.config.hasOwnProperty("doRequestAnimation")) this.config.doRequestAnimation = true;

        if (!this.config.prefixAssetPath) this.config.prefixAssetPath = "";
        if (!this.config.prefixJsPath) this.config.prefixJsPath = "";
        if (!this.config.masterVolume) this.config.masterVolume = 1.0;

        this._variables = {};

        this.vars = {};
        if (cfg && cfg.vars) this.vars = cfg.vars; // vars is old!

        this.cgl = new cgl/* CGL */.Rq.Context(this);
        this.cgp = null;

        this._subpatchOpCache = {};

        this.cgl.setCanvas(this.config.glCanvasId || this.config.glCanvas || "glcanvas");
        if (this.config.glCanvasResizeToWindow === true) this.cgl.setAutoResize("window");
        if (this.config.glCanvasResizeToParent === true) this.cgl.setAutoResize("parent");
        this.loading.setOnFinishedLoading(this.config.onFinishedLoading);

        if (this.cgl.aborted) this.aborted = true;
        if (this.cgl.silent) this.silent = true;

        if (!CABLES.OPS)
        {
            this.aborted = true;
            throw new Error("no CABLES.OPS found");
        }
        this.freeTimer.play();
        this.exec();

        if (!this.aborted)
        {
            if (this.config.patch)
            {
                this.deSerialize(this.config.patch);
            }
            else if (this.config.patchFile)
            {
                (0,utils.ajax)(
                    this.config.patchFile,
                    (err, _data) =>
                    {
                        try
                        {
                            const data = JSON.parse(_data);
                            if (err)
                            {
                                const txt = "";
                                this._log.error("err", err);
                                this._log.error("data", data);
                                this._log.error("data", data.msg);
                                return;
                            }
                            this.deSerialize(data);
                        }
                        catch (e)
                        {
                            this._log.error("could not load/parse patch ", e);
                        }
                    }
                );
            }
            this.timer.play();
        }

        console.log("made with https://cables.gl"); // eslint-disable-line
        this.cg = undefined;

    }

    isPlaying()
    {
        return !this._paused;
    }

    /** @deprecated */
    renderOneFrame()
    {
        this._paused = true;
        this._renderOneFrame = true;
        this.exec();
        this._renderOneFrame = false;
    }

    /**
     * returns true if patch is opened in editor/gui mode
     * @function isEditorMode
     * @memberof Patch
     * @instance
     * @return {Boolean} editor mode
     */
    isEditorMode()
    {
        return this.config.editorMode === true;
    }

    /**
     * pauses patch execution
     * @function pause
     * @memberof Patch
     * @instance
     */
    pause()
    {
        cancelAnimationFrame(this._animReq);
        this.emitEvent(Patch.EVENT_PAUSE);
        this._animReq = null;
        this._paused = true;
        this.freeTimer.pause();
    }

    /**
     * resumes patch execution
     * @function resume
     * @memberof Patch
     * @instance
     */
    resume()
    {
        if (this._paused)
        {
            cancelAnimationFrame(this._animReq);
            this._paused = false;
            this.freeTimer.play();
            this.emitEvent(Patch.EVENT_RESUME);
            this.exec();
        }
    }

    /**
     * set volume [0-1]
     * @function setVolume
     * @param {Number} v volume
     * @memberof Patch
     * @instance
     */
    setVolume(v)
    {
        this.config.masterVolume = v;
        for (let i = 0; i < this._volumeListeners.length; i++) this._volumeListeners[i].onMasterVolumeChanged(v);
    }

    /**
     * get asset path
     * @function getAssetPath
     * @memberof Patch
     * @param patchId
     * @instance
     */
    getAssetPath(patchId = null)
    {
        if (this.config.hasOwnProperty("assetPath"))
        {
            return this.config.assetPath;
        }
        else if (this.isEditorMode())
        {
            let id = patchId || gui.project()._id;
            return "/assets/" + id + "/";
        }
        else if (document.location.href.indexOf("cables.gl") > 0 || document.location.href.indexOf("cables.local") > 0)
        {
            const parts = document.location.pathname.split("/");
            let id = patchId || parts[parts.length - 1];
            return "/assets/" + id + "/";
        }
        else
        {
            return "assets/";
        }
    }

    /**
     * get js path
     * @function getJsPath
     * @memberof Patch
     * @instance
     */
    getJsPath()
    {
        if (this.config.hasOwnProperty("jsPath"))
        {
            return this.config.jsPath;
        }
        else
        {
            return "js/";
        }
    }

    /**
     * get url/filepath for a filename
     * this uses prefixAssetpath in exported patches
     * @function getFilePath
     * @memberof Patch
     * @instance
     * @param {String} filename
     * @return {String} url
     */
    getFilePath(filename)
    {
        if (!filename) return filename;
        filename = String(filename);
        if (filename.indexOf("https:") === 0 || filename.indexOf("http:") === 0) return filename;
        if (filename.indexOf("data:") === 0) return filename;
        if (filename.indexOf("file:") === 0) return filename;
        filename = filename.replace("//", "/");
        if (filename.startsWith(this.config.prefixAssetPath)) filename = filename.replace(this.config.prefixAssetPath, "");
        return this.config.prefixAssetPath + filename + (this.config.suffixAssetPath || ""); //
    }

    clear()
    {
        this.emitEvent("patchClearStart");
        this.cgl.TextureEffectMesh = null;
        this.animFrameOps.length = 0;
        this.timer = new timer/* Timer */.M4();
        while (this.ops.length > 0) this.deleteOp(this.ops[0].id);

        this._opIdCache = {};
        this.emitEvent("patchClearEnd");
    }

    /**
     * @param {string} identifier
     * @param {string} id
     * @param {string} [opName]
     * @returns {Op}
     */
    createOp(identifier, id, opName = null)
    {

        /**
         * @type {Op}
         */
        let op = null;
        let objName = "";

        try
        {
            if (!identifier)
            {
                console.error("createop identifier false", identifier);
                console.log((new Error()).stack);
                return;
            }
            if (identifier.indexOf("Ops.") === -1)
            {

                /*
                 * this should be a uuid, not a namespace
                 * creating ops by id should be the default way from now on!
                 */
                const opId = identifier;

                if (CABLES.OPS[opId])
                {
                    objName = CABLES.OPS[opId].objName;
                    op = new CABLES.OPS[opId].f(this, objName, id, opId);
                    op.opId = opId;
                }
                else
                {
                    if (opName)
                    {
                        identifier = opName;
                        this._log.warn("could not find op by id: " + opId);
                    }
                    else
                    {
                        throw new Error("could not find op by id: " + opId, { "cause": "opId:" + opId });
                    }
                }
            }

            if (!op)
            {
                // fallback: create by objname!
                objName = identifier;
                const parts = identifier.split(".");
                const opObj = Patch.getOpClass(objName);

                if (!opObj)
                {
                    this.emitEvent("criticalError", { "title": "Unknown op: " + objName, "text": "Unknown op: " + objName });

                    this._log.error("unknown op: " + objName);
                    throw new Error("unknown op: " + objName);
                }
                else
                {
                    if (parts.length == 2) op = new window[parts[0]][parts[1]](this, objName, id);
                    else if (parts.length == 3) op = new window[parts[0]][parts[1]][parts[2]](this, objName, id);
                    else if (parts.length == 4) op = new window[parts[0]][parts[1]][parts[2]][parts[3]](this, objName, id);
                    else if (parts.length == 5) op = new window[parts[0]][parts[1]][parts[2]][parts[3]][parts[4]](this, objName, id);
                    else if (parts.length == 6) op = new window[parts[0]][parts[1]][parts[2]][parts[3]][parts[4]][parts[5]](this, objName, id);
                    else if (parts.length == 7) op = new window[parts[0]][parts[1]][parts[2]][parts[3]][parts[4]][parts[5]][parts[6]](this, objName, id);
                    else if (parts.length == 8) op = new window[parts[0]][parts[1]][parts[2]][parts[3]][parts[4]][parts[5]][parts[6]][parts[7]](this, objName, id);
                    else if (parts.length == 9) op = new window[parts[0]][parts[1]][parts[2]][parts[3]][parts[4]][parts[5]][parts[6]][parts[7]][parts[8]](this, objName, id);
                    else if (parts.length == 10) op = new window[parts[0]][parts[1]][parts[2]][parts[3]][parts[4]][parts[5]][parts[6]][parts[7]][parts[8]][parts[9]](this, objName, id);
                    else console.log("parts.length", parts.length);
                }

                if (op)
                {
                    op.opId = null;
                    for (const i in CABLES.OPS)
                    {
                        if (CABLES.OPS[i].objName == objName) op.opId = i;
                    }
                }
            }
        }
        catch (e)
        {
            this._crashedOps.push(objName);

            this._log.error("[instancing error] " + objName, e);

            if (!this.isEditorMode())
            {
                this._log.error("INSTANCE_ERR", "Instancing Error: " + objName, e);
                // throw new Error("instancing error 1" + objName);
            }
        }

        if (op)
        {
            op._objName = objName;
            op.patch = this;
        }
        else
        {
            this._log.log("no op was created!?", identifier, id);
        }
        return op;
    }

    /**
     * create a new op in patch
     * @function addOp
     * @memberof Patch
     * @instance
     * @param {string} opIdentifier uuid or name, e.g. Ops.Math.Sum
     * @param {OpUiAttribs} uiAttribs Attributes
     * @param {string} [id]
     * @param {boolean} [fromDeserialize]
     * @param {string} [opName] e.g. Ops.Math.Sum
     * @example
     * // add invisible op
     * patch.addOp('Ops.Math.Sum', { showUiAttribs: false });
     */
    addOp(opIdentifier, uiAttribs, id, fromDeserialize = false, opName = null)
    {
        const op = this.createOp(opIdentifier, id, opName);

        if (op)
        {
            uiAttribs = uiAttribs || {};
            if (uiAttribs.hasOwnProperty("errors")) delete uiAttribs.errors;
            if (uiAttribs.hasOwnProperty("error")) delete uiAttribs.error;
            uiAttribs.subPatch = uiAttribs.subPatch || 0;
            op.setUiAttribs(uiAttribs);
            if (op.onCreate) op.onCreate();

            if (op.hasOwnProperty("onAnimFrame")) this.addOnAnimFrame(op);
            if (op.hasOwnProperty("onMasterVolumeChanged")) this._volumeListeners.push(op);

            if (this._opIdCache[op.id])
            {
                this._log.warn("opid with id " + op.id + " already exists in patch!");
                this.deleteOp(op.id); // strange with subpatch ops: why is this needed, somehow ops get added twice ???.....
                // return;
            }

            this.ops.push(op);
            this._opIdCache[op.id] = op;

            if (this._subPatchCacheAdd) this._subPatchCacheAdd(uiAttribs.subPatch, op);
            this.emitEvent(Patch.EVENT_OP_ADDED, op, fromDeserialize);

            if (op.init) op.init();

            op.emitEvent(Op.EVENT_INIT, fromDeserialize);
        }
        else
        {
            this._log.error("addop: op could not be created: ", opIdentifier);
        }

        return op;
    }

    addOnAnimFrame(op)
    {
        for (let i = 0; i < this.animFrameOps.length; i++) if (this.animFrameOps[i] == op) { return; }

        this.animFrameOps.push(op);
    }

    removeOnAnimFrame(op)
    {
        for (let i = 0; i < this.animFrameOps.length; i++)
        {
            if (this.animFrameOps[i] == op)
            {
                this.animFrameOps.splice(i, 1);
                return;
            }
        }
    }

    addOnAnimFrameCallback(cb)
    {
        this.animFrameCallbacks.push(cb);
    }

    removeOnAnimCallback(cb)
    {
        for (let i = 0; i < this.animFrameCallbacks.length; i++)
        {
            if (this.animFrameCallbacks[i] == cb)
            {
                this.animFrameCallbacks.splice(i, 1);
                return;
            }
        }
    }

    deleteOp(opid, tryRelink, reloadingOp)
    {
        let found = false;
        for (let i = 0; i < this.ops.length; i++)
        {
            if (this.ops[i].id == opid)
            {
                const op = this.ops[i];

                /** @type {Port} */
                let reLinkP1 = null;

                /** @type {Port} */
                let reLinkP2 = null;

                if (op)
                {
                    found = true;
                    if (tryRelink)
                    {
                        if (op.portsIn.length > 0 && op.portsIn[0].isLinked() && (op.portsOut.length > 0 && op.portsOut[0].isLinked()))
                        {
                            if (op.portsIn[0].getType() == op.portsOut[0].getType() && op.portsIn[0].links[0])
                            {
                                reLinkP1 = op.portsIn[0].links[0].getOtherPort(op.portsIn[0]);
                                reLinkP2 = op.portsOut[0].links[0].getOtherPort(op.portsOut[0]);
                            }
                        }
                    }

                    const opToDelete = this.ops[i];
                    opToDelete.removeLinks();

                    this.ops.splice(i, 1);
                    opToDelete.emitEvent("delete", opToDelete);
                    this.emitEvent(Patch.EVENT_OP_DELETED, opToDelete, reloadingOp);

                    if (this.clearSubPatchCache) this.clearSubPatchCache(opToDelete.uiAttribs.subPatch);

                    if (opToDelete.onDelete) opToDelete.onDelete(reloadingOp);
                    opToDelete.cleanUp();

                    if (reLinkP1 !== null && reLinkP2 !== null)
                    {
                        this.link(reLinkP1.op, reLinkP1.getName(), reLinkP2.op, reLinkP2.getName());
                    }

                    delete this._opIdCache[opid];
                    break;
                }
            }
        }

        if (!found) this._log.warn("core patch deleteop: not found...", opid);
    }

    getFrameNum()
    {
        return this._frameNum;
    }

    emitOnAnimFrameEvent(time, delta)
    {
        time = time || this.timer.getTime();

        for (let i = 0; i < this.animFrameCallbacks.length; ++i)
            if (this.animFrameCallbacks[i])
                this.animFrameCallbacks[i](time, this._frameNum, delta);

        for (let i = 0; i < this.animFrameOps.length; ++i)
            if (this.animFrameOps[i].onAnimFrame)
                this.animFrameOps[i].onAnimFrame(time, this._frameNum, delta);
    }

    renderFrame(timestamp)
    {
        this.timer.update(this.reqAnimTimeStamp);
        this.freeTimer.update(this.reqAnimTimeStamp);
        const time = this.timer.getTime();
        const startTime = performance.now();
        this.cgl.frameStartTime = this.timer.getTime();

        const delta = timestamp - this.reqAnimTimeStamp || timestamp;

        this.emitOnAnimFrameEvent(null, delta);

        this.cgl.profileData.profileFrameDelta = delta;
        this.reqAnimTimeStamp = timestamp;
        this.cgl.profileData.profileOnAnimFrameOps = performance.now() - startTime;

        this.emitEvent(Patch.EVENT_RENDER_FRAME, time);

        this._frameNum++;
        if (this._frameNum == 1)
        {
            if (this.config.onFirstFrameRendered) this.config.onFirstFrameRendered();
        }
    }

    /**
     * @param {number} [timestamp]
     */
    exec(timestamp)
    {
        if (!this.#renderOneFrame && (this._paused || this.aborted)) return;
        this.emitEvent("reqAnimFrame");
        cancelAnimationFrame(this._animReq);

        this.config.fpsLimit = this.config.fpsLimit || 0;
        if (this.config.fpsLimit)
        {
            this._frameInterval = 1000 / this.config.fpsLimit;
        }

        const now = CABLES.now();
        const frameDelta = now - this._frameNext;

        if (this.isEditorMode())
        {
            if (!this.#renderOneFrame)
            {
                if (now - this._lastFrameTime >= 500 && this._lastFrameTime !== 0 && !this._frameWasdelayed)
                {
                    this._lastFrameTime = 0;
                    setTimeout(this.exec.bind(this), 500);
                    this.emitEvent("renderDelayStart");
                    this._frameWasdelayed = true;
                    return;
                }
            }
        }

        if (this.#renderOneFrame || this.config.fpsLimit === 0 || frameDelta > this._frameInterval || this._frameWasdelayed)
        {
            this.renderFrame(timestamp);

            if (this._frameInterval) this._frameNext = now - (frameDelta % this._frameInterval);
        }

        if (this._frameWasdelayed)
        {
            this.emitEvent("renderDelayEnd");
            this._frameWasdelayed = false;
        }

        if (this.#renderOneFrame)
        {
            if (this.onOneFrameRendered) this.onOneFrameRendered(); // todo remove everywhere and use propper event...
            this.emitEvent(Patch.EVENT_RENDERED_ONE_FRAME);
            this._renderOneFrame = false;
        }

        if (this.config.doRequestAnimation) this._animReq = this.cgl.canvas.ownerDocument.defaultView.requestAnimationFrame(this.exec.bind(this));
    }

    /**
     * link two ops/ports
     * @function link
     * @memberof Patch
     * @instance
     * @param {Op} op1
     * @param {String} port1Name
     * @param {Op} op2
     * @param {String} port2Name
     * @param {boolean} lowerCase
     * @param {boolean} fromDeserialize
     */
    link(op1, port1Name, op2, port2Name, lowerCase = false, fromDeserialize = false)
    {
        if (!op1) return this._log.warn("link: op1 is null ");
        if (!op2) return this._log.warn("link: op2 is null");

        const port1 = op1.getPort(port1Name, lowerCase);
        const port2 = op2.getPort(port2Name, lowerCase);

        if (!port1) return this._log.warn("port1 not found! " + port1Name + " (" + op1.objName + ")");
        if (!port2) return this._log.warn("port2 not found! " + port2Name + " of " + op2.name + "(" + op2.objName + ")", op2);

        if (!port1.shouldLink(port1, port2) || !port2.shouldLink(port1, port2)) return false;

        if (Link.canLink(port1, port2))
        {
            const link = new Link(this);
            link.link(port1, port2);

            this.emitEvent(Patch.EVENT_LINK, port1, port2, link, fromDeserialize);
            return link;
        }
    }

    /**
     * @param {Object} options
     * @returns {Object|String}
     */
    serialize(options)
    {
        const obj = {};

        options = options || {};
        obj.ops = [];
        obj.settings = this.settings;
        for (let i = 0; i < this.ops.length; i++)
        {
            const op = this.ops[i];
            if (op && op.getSerialized)obj.ops.push(op.getSerialized());
        }

        (0,utils.cleanJson)(obj);

        if (options.asObject) return obj;
        return JSON.stringify(obj);
    }

    getOpsByRefId(refId) // needed for instancing ops ?
    {
        const perf = gui.uiProfiler.start("[corepatchetend] getOpsByRefId");
        const refOps = [];
        const ops = gui.corePatch().ops;
        for (let i = 0; i < ops.length; i++)
            if (ops[i].storage && ops[i].storage.ref == refId) refOps.push(ops[i]);
        perf.finish();
        return refOps;
    }

    /**
     * @param {String} opid
     * @returns {Op}
     */
    getOpById(opid)
    {
        return this._opIdCache[opid];
    }

    /**
     * @param {String} name
     */
    getOpsByObjName(name)
    {
        const arr = [];
        // for (const i in this.ops
        for (let i = 0; i < this.ops.length; i++)
            if (this.ops[i].objName == name) arr.push(this.ops[i]);
        return arr;
    }

    /**
     * @param {String} opid
     */
    getOpsByOpId(opid)
    {
        const arr = [];
        // for (const i in this.ops)
        for (let i = 0; i < this.ops.length; i++)
            if (this.ops[i].opId == opid) arr.push(this.ops[i]);
        return arr;
    }

    getSubPatchOpsByName(patchId, objName)
    {
        const arr = [];
        // for (const i in this.ops)
        for (let i = 0; i < this.ops.length; i++)
            if (this.ops[i].uiAttribs && this.ops[i].uiAttribs.subPatch == patchId && this.ops[i].objName == objName)
                arr.push(this.ops[i]);

        return arr;
    }

    getSubPatchOp(patchId, objName)
    {
        return this.getFirstSubPatchOpByName(patchId, objName);
    }

    /**
     * @param {string} patchId
     * @param {string} objName
     * @returns {Op}
     */
    getFirstSubPatchOpByName(patchId, objName)
    {
        for (let i = 0; i < this.ops.length; i++)
            if (this.ops[i].uiAttribs && this.ops[i].uiAttribs.subPatch == patchId && this.ops[i].objName == objName)
                return this.ops[i];

        return null;
    }

    _addLink(opinid, opoutid, inName, outName)
    {
        return this.link(this.getOpById(opinid), inName, this.getOpById(opoutid), outName, false, true);
    }

    /**
     * @param {String} s
     */
    logStartup(s)
    {
        if (window.logStartup)window.logStartup(s);
    }

    /**
     * @typedef DeserializeOptions
     * @property {boolean} [genIds]
     * @property {boolean} [createRef]
     */

    /**
     * Description
     * @param {Object} obj
     * @param {DeserializeOptions} options
     * @returns {any}
     */
    deSerialize(obj, options = { "genIds": false, "createRef": false })
    {
        if (this.aborted) return;
        const newOps = [];
        const loadingId = this.loading.start("core", "deserialize");

        if (typeof obj === "string") obj = JSON.parse(obj);

        if (this.#initialDeserialize)
        {
            this.#initialDeserialize = false;
            this.namespace = obj.namespace || "";
            this.name = obj.name || "";
            this.settings = obj.settings;
        }

        this.emitEvent("patchLoadStart");

        obj.ops = obj.ops || [];

        this.logStartup("add " + obj.ops.length + " ops... ");

        const addedOps = [];

        // add ops...
        for (let iop = 0; iop < obj.ops.length; iop++)
        {
            const start = CABLES.now();
            const opData = obj.ops[iop];
            let op = null;

            try
            {
                if (opData.opId) op = this.addOp(opData.opId, opData.uiAttribs, opData.id, true, opData.objName);
                else op = this.addOp(opData.objName, opData.uiAttribs, opData.id, true);
            }
            catch (e)
            {
                this._log.error("[instancing error] op data:", opData, e);
                // throw new Error("could not create op by id: <b>" + (opData.objName || opData.opId) + "</b> (" + opData.id + ")");
            }

            if (op)
            {
                addedOps.push(op);
                if (options.genIds) op.id = (0,utils.shortId)();
                op.portsInData = opData.portsIn;
                op._origData = JSON.parse(JSON.stringify(opData));
                op.storage = opData.storage;
                // if (opData.hasOwnProperty("disabled"))op.setEnabled(!opData.disabled);

                // for (const ipi in opData.portsIn)
                if (opData.portsIn)
                    for (let ipi = 0; ipi < opData.portsIn.length; ipi++)
                    {
                        const objPort = opData.portsIn[ipi];
                        if (objPort && objPort.hasOwnProperty("name"))
                        {
                            const port = op.getPort(objPort.name);

                            if (port && (port.uiAttribs.display == "bool" || port.uiAttribs.type == "bool") && !isNaN(objPort.value)) objPort.value = objPort.value == true ? 1 : 0;
                            if (port && objPort.value !== undefined && port.type != core_port/* Port */.I.TYPE_TEXTURE) port.set(objPort.value);

                            if (port)
                            {
                                port.deSerializeSettings(objPort);
                            }
                            else
                            {

                                /*
                             * if (port.uiAttribs.hasOwnProperty("title"))
                             * {
                             *     op.preservedPortTitles = op.preservedPortTitles || {};
                             *     op.preservedPortTitles[port.name] = port.uiAttribs.title;
                             * }
                             */
                                op.preservedPortValues = op.preservedPortValues || {};
                                op.preservedPortValues[objPort.name] = objPort.value;
                            }
                        }
                    }

                // for (const ipo in opData.portsOut)
                if (opData.portsOut)
                    for (let ipo = 0; ipo < opData.portsOut.length; ipo++)
                    {
                        const objPort = opData.portsOut[ipo];
                        if (objPort && objPort.hasOwnProperty("name"))
                        {
                            const port2 = op.getPort(objPort.name);

                            if (port2)
                            {
                                port2.deSerializeSettings(objPort);

                                if (port2.uiAttribs.hasOwnProperty("title"))
                                {
                                    op.preservedPortTitles = op.preservedPortTitles || {};
                                    op.preservedPortTitles[port2.name] = port2.uiAttribs.title;
                                }

                                if (port2.type != core_port/* Port */.I.TYPE_TEXTURE && objPort.hasOwnProperty("value"))
                                    port2.set(obj.ops[iop].portsOut[ipo].value);

                                if (objPort.expose) port2.setUiAttribs({ "expose": true });
                            }
                        }
                    }
                newOps.push(op);
            }

            const timeused = Math.round(100 * (CABLES.now() - start)) / 100;
            if (!this.silent && timeused > 5) console.log("long op init ", obj.ops[iop].objName, timeused);
        }
        this.logStartup("add ops done");

        // for (const i in this.ops)
        for (let i = 0; i < this.ops.length; i++)
        {
            // deprecated use event
            if (this.ops[i].onLoadedValueSet)
            {
                this.ops[i].onLoadedValueSet(this.ops[i]._origData);
                this.ops[i].onLoadedValueSet = null;
                this.ops[i]._origData = null;
            }

            // this is only emited when the patch is loaded from serializid data, e.g. loading from api
            // NOT when op is created by hand!
            this.ops[i].emitEvent(Patch.EVENT_VALUESSET);
        }

        this.logStartup("creating links");

        if (options.opsCreated)options.opsCreated(addedOps);
        // create links...
        if (obj.ops)
        {
            for (let iop = 0; iop < obj.ops.length; iop++)
            {
                if (obj.ops[iop].portsIn)
                {
                    for (let ipi2 = 0; ipi2 < obj.ops[iop].portsIn.length; ipi2++)
                    {
                        if (obj.ops[iop].portsIn[ipi2] && obj.ops[iop].portsIn[ipi2].links)
                        {
                            for (let ili = 0; ili < obj.ops[iop].portsIn[ipi2].links.length; ili++)
                            {
                                this._addLink(
                                    obj.ops[iop].portsIn[ipi2].links[ili].objIn,
                                    obj.ops[iop].portsIn[ipi2].links[ili].objOut,
                                    obj.ops[iop].portsIn[ipi2].links[ili].portIn,
                                    obj.ops[iop].portsIn[ipi2].links[ili].portOut);

                                /*
                                 * const took = performance.now - startTime;
                                 * if (took > 100)console.log(obj().ops[iop].portsIn[ipi2].links[ili].objIn, obj.ops[iop].portsIn[ipi2].links[ili].objOut, took);
                                 */
                            }
                        }
                    }
                }
                if (obj.ops[iop].portsOut)
                    for (let ipi2 = 0; ipi2 < obj.ops[iop].portsOut.length; ipi2++)
                        if (obj.ops[iop].portsOut[ipi2] && obj.ops[iop].portsOut[ipi2].links)
                        {
                            for (let ili = 0; ili < obj.ops[iop].portsOut[ipi2].links.length; ili++)
                            {
                                if (obj.ops[iop].portsOut[ipi2].links[ili])
                                {
                                    if (obj.ops[iop].portsOut[ipi2].links[ili].subOpRef)
                                    {
                                        // lost link
                                        const outOp = this.getOpById(obj.ops[iop].portsOut[ipi2].links[ili].objOut);
                                        let dstOp = null;
                                        let theSubPatch = 0;

                                        for (let i = 0; i < this.ops.length; i++)
                                        {
                                            if (
                                                this.ops[i].storage &&
                                                this.ops[i].storage.ref == obj.ops[iop].portsOut[ipi2].links[ili].subOpRef &&
                                                outOp.uiAttribs.subPatch == this.ops[i].uiAttribs.subPatch
                                            )
                                            {
                                                theSubPatch = this.ops[i].patchId.get();
                                                break;
                                            }
                                        }

                                        for (let i = 0; i < this.ops.length; i++)
                                        {
                                            if (
                                                this.ops[i].storage &&
                                                this.ops[i].storage.ref == obj.ops[iop].portsOut[ipi2].links[ili].refOp &&
                                                this.ops[i].uiAttribs.subPatch == theSubPatch)
                                            {
                                                dstOp = this.ops[i];
                                                break;
                                            }
                                        }

                                        if (!dstOp) this._log.warn("could not find op for lost link");
                                        else
                                        {
                                            this._addLink(
                                                dstOp.id,
                                                obj.ops[iop].portsOut[ipi2].links[ili].objOut,

                                                obj.ops[iop].portsOut[ipi2].links[ili].portIn,
                                                obj.ops[iop].portsOut[ipi2].links[ili].portOut);
                                        }
                                    }
                                    else
                                    {
                                        const l = this._addLink(obj.ops[iop].portsOut[ipi2].links[ili].objIn, obj.ops[iop].portsOut[ipi2].links[ili].objOut, obj.ops[iop].portsOut[ipi2].links[ili].portIn, obj.ops[iop].portsOut[ipi2].links[ili].portOut);

                                        if (!l)
                                        {
                                            const op1 = this.getOpById(obj.ops[iop].portsOut[ipi2].links[ili].objIn);
                                            const op2 = this.getOpById(obj.ops[iop].portsOut[ipi2].links[ili].objOut);

                                            if (!op1)console.log("could not find link op1");
                                            if (!op2)console.log("could not find link op2");

                                            const p1Name = obj.ops[iop].portsOut[ipi2].links[ili].portIn;

                                            if (op1 && !op1.getPort(p1Name))
                                            {
                                                // console.log("PRESERVE port 1 not found", p1Name);

                                                op1.preservedPortLinks[p1Name] = op1.preservedPortLinks[p1Name] || [];
                                                op1.preservedPortLinks[p1Name].push(obj.ops[iop].portsOut[ipi2].links[ili]);
                                            }

                                            const p2Name = obj.ops[iop].portsOut[ipi2].links[ili].portOut;
                                            if (op2 && !op2.getPort(p2Name))
                                            {
                                                // console.log("PRESERVE port 2 not found", obj.ops[iop].portsOut[ipi2].links[ili].portOut);
                                                op2.preservedPortLinks[p1Name] = op2.preservedPortLinks[p1Name] || [];
                                                op2.preservedPortLinks[p1Name].push(obj.ops[iop].portsOut[ipi2].links[ili]);
                                            }
                                        }
                                    }
                                }
                            }
                        }
            }
        }

        this.logStartup("calling ops onloaded");

        // for (const i in this.ops)
        for (let i = 0; i < this.ops.length; i++)
        {
            if (this.ops[i].onLoaded)
            {
                // TODO: deprecated - use even
                this.ops[i].onLoaded();
                this.ops[i].onLoaded = null;
            }
        }

        this.logStartup("initializing ops...");
        for (let i = 0; i < this.ops.length; i++)
        // for (const i in this.ops)
        {
            if (this.ops[i].init)
            {
                try
                {
                    this.ops[i].init();
                    this.ops[i].init = null;
                }
                catch (e)
                {
                    console.error("op.init crash", e);
                }
            }
        }

        this.logStartup("initializing vars...");

        if (this.config.variables)
            for (const varName in this.config.variables)
                this.setVarValue(varName, this.config.variables[varName]);

        this.logStartup("initializing var ports");

        // for (const i in this.ops)
        for (let i = 0; i < this.ops.length; i++)
        {
            this.ops[i].initVarPorts();
            delete this.ops[i].uiAttribs.pasted;
        }

        setTimeout(() => { this.loading.finished(loadingId); }, 100);

        if (this.config.onPatchLoaded) this.config.onPatchLoaded(this);

        this.emitEvent(Patch.EVENT_PATCHLOADEND, newOps, obj, options.genIds);
    }

    profile(enable)
    {
        this.profiler = new Profiler(this);
        // for (const i in this.ops)
        for (let i = 0; i < this.ops.length; i++)
            this.ops[i].profile();
    }

    // ----------------------

    /**
     * set variable value
     * @function setVariable
     * @memberof Patch
     * @instance
     * @param {String} name of variable
     * @param {Number|String|Boolean} val value
     */
    setVariable(name, val)
    {
        if (this._variables[name] !== undefined)
        {
            this._variables[name].setValue(val);
        }
        else
        {
            this._log.warn("variable " + name + " not found!");
        }
    }

    _sortVars()
    {
        if (!this.isEditorMode()) return;
        const ordered = {};
        Object.keys(this._variables).sort(
            (a, b) =>
            { return a.localeCompare(b, "en", { "sensitivity": "base" }); }
        ).forEach((key) =>
        {
            ordered[key] = this._variables[key];
        });
        this._variables = ordered;
    }

    /**
     * has variable
     * @function hasVariable
     * @memberof Patch
     * @instance
     * @param {String} name of variable
     */
    hasVar(name)
    {
        return this._variables[name] !== undefined;
    }

    // used internally
    setVarValue(name, val, type)
    {
        if (this.hasVar(name))
        {
            this._variables[name].setValue(val);
        }
        else
        {
            this._variables[name] = new PatchVariable(name, val, type);
            this._sortVars();
            this.emitEvent(Patch.EVENT_VARIABLES_CHANGED);
        }
        return this._variables[name];
    }

    // old?
    getVarValue(name, val)
    {
        if (this._variables.hasOwnProperty(name)) return this._variables[name].getValue();
    }

    /**
     * @function getVar
     * @memberof Patch
     * @instance
     * @param {String} name
     * @return {PatchVariable} variable
     */
    getVar(name)
    {
        if (this._variables.hasOwnProperty(name)) return this._variables[name];
    }

    deleteVar(name)
    {
        for (let i = 0; i < this.ops.length; i++)
            for (let j = 0; j < this.ops[i].portsIn.length; j++)
                if (this.ops[i].portsIn[j].getVariableName() == name)
                    this.ops[i].portsIn[j].setVariable(null);

        delete this._variables[name];
        this.emitEvent("variableDeleted", name);
        this.emitEvent("variablesChanged");
    }

    /**
     * @param {number} t
     * @returns {Object}
     */
    getVars(t)
    {
        if (t === undefined) return this._variables;
        if (t === 1) return {};

        const perf = gui.uiProfiler.start("[corepatchetend] getVars");

        const vars = [];
        let tStr = "";
        if (t == core_port/* Port */.I.TYPE_STRING) tStr = "string";
        else if (t == core_port/* Port */.I.TYPE_VALUE) tStr = "number";
        else if (t == core_port/* Port */.I.TYPE_ARRAY) tStr = "array";
        else if (t == core_port/* Port */.I.TYPE_OBJECT) tStr = "object";
        else if (t == core_port/* Port */.I.TYPE_DYNAMIC) tStr = "dynamic";
        else
        {
            console.log("unknown port type", t);
            console.log(new Error().stack);
        }

        for (const i in this._variables)
        {
            if (!this._variables[i].type || this._variables[i].type == tStr || this._variables[i].type == t) vars.push(this._variables[i]);
        }

        perf.finish();

        return vars;
    }

    // getVars(t)
    // {
    //     if (t === undefined) return this._variables;

    //     const vars = [];
    //     let tStr = "";
    //     if (t == Port.TYPE_STRING) tStr = "string";
    //     if (t == Port.TYPE_VALUE) tStr = "number";
    //     if (t == Port.TYPE_ARRAY) tStr = "array";
    //     if (t == Port.TYPE_OBJECT) tStr = "object";

    //     for (const i in this._variables)
    //     {
    //         if (!this._variables[i].type || this._variables[i].type == tStr || this._variables[i].type == t) vars.push(this._variables[i]);
    //     }
    //     return vars;
    // }

    /**
     * @function preRenderOps
     * @memberof Patch
     * @instance
     * @description invoke pre rendering of ops
     * @function
     */
    preRenderOps()
    {
        this._log.log("prerendering...");

        for (let i = 0; i < this.ops.length; i++)
        {
            if (this.ops[i].preRender)
            {
                this.ops[i].preRender();
                this._log.log("prerender " + this.ops[i].objName);
            }
        }
    }

    /**
     * @function dispose
     * @memberof Patch
     * @instance
     * @description stop, dispose and cleanup patch
     */
    dispose()
    {
        this.pause();
        this.clear();
        this.cgl.dispose();
    }

    pushTriggerStack(p)
    {
        this._triggerStack.push(p);
    }

    popTriggerStack()
    {
        this._triggerStack.pop();
    }

    printTriggerStack()
    {
        if (this._triggerStack.length == 0)
        {
            // console.log("stack length", this._triggerStack.length); // eslint-disable-line
            return;
        }
        console.groupCollapsed( // eslint-disable-line
            "trigger port stack " + this._triggerStack[this._triggerStack.length - 1].op.objName + "." + this._triggerStack[this._triggerStack.length - 1].name,
        );

        const rows = [];
        for (let i = 0; i < this._triggerStack.length; i++)
        {
            rows.push(i + ". " + this._triggerStack[i].op.objName + " " + this._triggerStack[i].name);
        }

        console.table(rows); // eslint-disable-line
        console.groupEnd(); // eslint-disable-line
    }

    /**
     * returns document object of the patch could be != global document object when opening canvas ina popout window
     * @function getDocument
     * @memberof Patch
     * @instance
     * @return {Object} document
     */
    getDocument()
    {
        return this.cgl.canvas.ownerDocument;
    }
}

Patch.getOpClass = function (objName)
{
    const parts = objName.split(".");
    let opObj = null;

    try
    {
        if (parts.length == 2) opObj = window[parts[0]][parts[1]];
        else if (parts.length == 3) opObj = window[parts[0]][parts[1]][parts[2]];
        else if (parts.length == 4) opObj = window[parts[0]][parts[1]][parts[2]][parts[3]];
        else if (parts.length == 5) opObj = window[parts[0]][parts[1]][parts[2]][parts[3]][parts[4]];
        else if (parts.length == 6) opObj = window[parts[0]][parts[1]][parts[2]][parts[3]][parts[4]][parts[5]];
        else if (parts.length == 7) opObj = window[parts[0]][parts[1]][parts[2]][parts[3]][parts[4]][parts[5]][parts[6]];
        else if (parts.length == 8) opObj = window[parts[0]][parts[1]][parts[2]][parts[3]][parts[4]][parts[5]][parts[6]][parts[7]];
        else if (parts.length == 9) opObj = window[parts[0]][parts[1]][parts[2]][parts[3]][parts[4]][parts[5]][parts[6]][parts[7]][parts[8]];
        else if (parts.length == 10) opObj = window[parts[0]][parts[1]][parts[2]][parts[3]][parts[4]][parts[5]][parts[6]][parts[7]][parts[8]][parts[9]];
        return opObj;
    }
    catch (e)
    {
        return null;
    }
};

Patch.replaceOpIds = function (json, options)
{
    const opids = {};
    for (const i in json.ops)
    {
        opids[json.ops[i].id] = json.ops[i];
    }

    for (const j in json.ops)
    {
        for (const k in json.ops[j].portsOut)
        {
            const links = json.ops[j].portsOut[k].links;
            if (links)
            {
                let l = links.length;

                while (l--)
                {
                    if (links[l] && (!opids[links[l].objIn] || !opids[links[l].objOut]))
                    {
                        if (!options.doNotUnlinkLostLinks)
                        {
                            links.splice(l, 1);
                        }
                        else
                        {
                            if (options.fixLostLinks)
                            {
                                const op = gui.corePatch().getOpById(links[l].objIn);
                                if (!op) console.log("op not found!");
                                else
                                {
                                    const outerOp = gui.patchView.getSubPatchOuterOp(op.uiAttribs.subPatch);
                                    if (outerOp)
                                    {
                                        op.storage = op.storage || {};
                                        op.storage.ref = op.storage.ref || (0,utils.shortId)();
                                        links[l].refOp = op.storage.ref;
                                        links[l].subOpRef = outerOp.storage.ref;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    for (const i in json.ops)
    {
        const op = json.ops[i];
        const oldId = op.id;
        let newId = (0,utils.shortId)();

        if (options.prefixHash) newId = (0,utils.prefixedHash)(options.prefixHash + oldId);

        else if (options.prefixId) newId = options.prefixId + oldId;
        else if (options.refAsId) // when saving json
        {
            if (op.storage && op.storage.ref)
            {
                newId = op.storage.ref;
                delete op.storage.ref;
            }
            else
            {
                op.storage = op.storage || {};
                op.storage.ref = newId = (0,utils.shortId)();
            }
        }

        const newID = op.id = newId;

        if (options.oldIdAsRef) // when loading json
        {
            op.storage = op.storage || {};
            op.storage.ref = oldId;
        }

        for (const j in json.ops)
        {
            if (json.ops[j].portsIn)
                for (const k in json.ops[j].portsIn)
                {
                    if (json.ops[j].portsIn[k].links)
                    {
                        let l = json.ops[j].portsIn[k].links.length;

                        while (l--) if (json.ops[j].portsIn[k].links[l] === null) json.ops[j].portsIn[k].links.splice(l, 1);

                        for (l in json.ops[j].portsIn[k].links)
                        {
                            if (json.ops[j].portsIn[k].links[l].objIn === oldId) json.ops[j].portsIn[k].links[l].objIn = newID;
                            if (json.ops[j].portsIn[k].links[l].objOut === oldId) json.ops[j].portsIn[k].links[l].objOut = newID;
                        }
                    }
                }

            if (json.ops[j].portsOut)
                for (const k in json.ops[j].portsOut)
                {
                    if (json.ops[j].portsOut[k].links)
                    {
                        let l = json.ops[j].portsOut[k].links.length;

                        while (l--) if (json.ops[j].portsOut[k].links[l] === null) json.ops[j].portsOut[k].links.splice(l, 1);

                        for (l in json.ops[j].portsOut[k].links)
                        {
                            if (json.ops[j].portsOut[k].links[l].objIn === oldId) json.ops[j].portsOut[k].links[l].objIn = newID;
                            if (json.ops[j].portsOut[k].links[l].objOut === oldId) json.ops[j].portsOut[k].links[l].objOut = newID;
                        }
                    }
                }
        }
    }

    // set correct subpatch
    const subpatchIds = [];
    const fixedSubPatches = [];

    for (let i = 0; i < json.ops.length; i++)
    {
        // if (CABLES.Op.isSubPatchOpName(json.ops[i].objName))
        if (json.ops[i].storage && json.ops[i].storage.subPatchVer)
        {
            // for (const k in json.ops[i].portsInckkkkk
            for (let k = 0; k < json.ops[i].portsIn.length; k++)
            {
                if (json.ops[i].portsIn[k].name === "patchId")
                {
                    let newId = (0,utils.shortId)();

                    if (options.prefixHash) newId = (0,utils.prefixedHash)(options.prefixHash + json.ops[i].portsIn[k].value);

                    const oldSubPatchId = json.ops[i].portsIn[k].value;
                    const newSubPatchId = json.ops[i].portsIn[k].value = newId;

                    subpatchIds.push(newSubPatchId);

                    for (let j = 0; j < json.ops.length; j++)
                    {
                        // op has no uiAttribs in export, we don't care about subpatches in export though
                        if (json.ops[j].uiAttribs)
                        {
                            if (json.ops[j].uiAttribs.subPatch === oldSubPatchId)
                            {
                                json.ops[j].uiAttribs.subPatch = newSubPatchId;
                                fixedSubPatches.push(json.ops[j].id);
                            }
                        }
                    }
                }
            }
        }
    }

    for (const kk in json.ops)
    {
        let found = false;
        for (let j = 0; j < fixedSubPatches.length; j++)
        {
            if (json.ops[kk].id === fixedSubPatches[j])
            {
                found = true;
                break;
            }
        }
        // op has no uiAttribs in export, we don't care about subpatches in export though
        if (!found && json.ops[kk].uiAttribs && options.parentSubPatchId != null)
            json.ops[kk].uiAttribs.subPatch = options.parentSubPatchId;
    }

    return json;
};

/**
 * remove an eventlistener
 * @instance
 * @function addEventListener
 * @param {String} name of event
 * @param {function} callback
 */

/**
 * remove an eventlistener
 * @instance
 * @function removeEventListener
 * @param {String} name of event
 * @param {function} callback
 */

/**
 * op added to patch event
 * @event onOpAdd
 *
 * @memberof Patch
 * @type {Object}
 * @property {Op} op new op
 */

/**
 * op deleted from patch
 * @event onOpDelete
 * @memberof Patch
 * @type {Object}
 * @property {Op} op that will be deleted
 */

/**
 * link event - two ports will be linked
 * @event onLink
 * @memberof Patch
 * @type {Object}
 * @property {Port} port1
 * @property {Port} port2
 */

/**
 * unlink event - a link was deleted
 * @event onUnLink
 * @memberof Patch
 * @type {Object}
 */

/**
 * variables has been changed / a variable has been added to the patch
 * @event variablesChanged
 * @memberof Patch
 * @type {Object}
 * @property {Port} port1
 * @property {Port} port2
 */

;// CONCATENATED MODULE: ./src/core/embedding.js



const EMBED = {};

/**
 * add patch into html element (will create canvas and set size to fill containerElement)
 * @name CABLES.EMBED#addPatch
 * @param {object|string} _element containerElement dom element or id of element
 * @param {Object} options patch options
 * @function
 */
EMBED.addPatch = function (_element, options)
{
    let el = _element;
    let id = (0,utils.generateUUID)();
    if (typeof _element == "string")
    {
        id = _element;
        el = document.getElementById(id);

        if (!el)
        {
            console.error(id + " Polyshape Container Element not found!");
            return;
        }
    }

    const canvEl = document.createElement("canvas");
    canvEl.id = "glcanvas_" + id;
    canvEl.width = el.clientWidth;
    canvEl.height = el.clientHeight;

    window.addEventListener(
        "resize",
        function ()
        {
            this.setAttribute("width", el.clientWidth);
            this.height = el.clientHeight;
        }.bind(canvEl),
    );

    el.appendChild(canvEl);

    options = options || {};
    options.glCanvasId = canvEl.id;

    if (!options.onError)
    {
        options.onError = function (err)
        {
            console.error(err);
        };
    }

    CABLES.patch = new Patch(options);
    return canvEl;
};



;// CONCATENATED MODULE: ./src/core/sessionvar.js
// todo: old... remove this from ops...

/**
 * todo: old... remove this from ops...
 *
 * @class
 */
const Variable = function ()
{
    let value = null;
    const changedCallbacks = [];

    this.onChanged = function (f)
    {
        changedCallbacks.push(f);
    };

    this.getValue = function ()
    {
        return value;
    };

    this.setValue = function (v)
    {
        value = v;
        this.emitChanged();
    };

    this.emitChanged = function ()
    {
        for (let i = 0; i < changedCallbacks.length; i++)
        {
            changedCallbacks[i]();
        }
    };
};



// EXTERNAL MODULE: ./src/core/anim_key.js
var anim_key = __webpack_require__(963);
;// CONCATENATED MODULE: ./src/core/index.js


















CABLES = CABLES || {};
CABLES = {
    ...CABLES,
    ...constants/* CONSTANTS */.a.PORT,
    ...constants/* CONSTANTS */.a.PACO,
    ...constants/* CONSTANTS */.a.ANIM,
    ...constants/* CONSTANTS */.a.OP
};

CABLES.EMBED = EMBED;
CABLES.Link = Link;
CABLES.Port = core_port/* Port */.I;
CABLES.Op = Op;
CABLES.Profiler = Profiler;
CABLES.Patch = Patch;
CABLES.Timer = timer/* Timer */.M4;
CABLES.Variable = Variable;
CABLES.LoadingStatus = LoadingStatus;
CABLES.now = timer/* now */.tB;
CABLES.internalNow = timer/* internalNow */.uw;
CABLES.Anim = anim/* Anim */.k;
CABLES.AnimKey = anim_key/* AnimKey */.rA;

CABLES.shortId = utils.shortId;
CABLES.uuid = utils.uuid;
CABLES.getShortOpName = utils.getShortOpName;
CABLES.simpleId = utils.simpleId;
CABLES.clamp = utils.clamp;
CABLES.map = utils.map;
CABLES.shuffleArray = utils.shuffleArray;
CABLES.generateUUID = utils.generateUUID;
CABLES.prefixedHash = utils.prefixedHash;
CABLES.smoothStep = utils.smoothStep;
CABLES.smootherStep = utils.smootherStep;
CABLES.cacheBust = utils.cacheBust;
CABLES.copyArray = utils.copyArray;
CABLES.basename = utils.basename;
CABLES.logStack = utils.logStack;
CABLES.filename = utils.filename;
CABLES.ajax = utils.ajax;
CABLES.request = utils.request;
CABLES.logErrorConsole = utils.logErrorConsole;
CABLES.isNumeric = utils.isNumeric;
CABLES.uniqueArray = utils.uniqueArray;

/** @type {Array<Op>} */
CABLES.OPS = [];
CABLES.utils = utils;
CABLES.CONSTANTS = constants/* CONSTANTS */.a;

CABLES.GLMatrix = esm_namespaceObject;
CABLES.SHARED = {};
CABLES.SHARED.Events = eventtarget/* default */.A;
CABLES.SHARED.Logger = logger/* default */.A;

/* harmony default export */ const core = (CABLES);


if (!(function () { return !this; }())) console.warn("not in strict mode: index core"); // eslint-disable-line


/***/ }),

/***/ 920:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   M4: () => (/* binding */ Timer),
/* harmony export */   tB: () => (/* binding */ now),
/* harmony export */   uw: () => (/* binding */ internalNow)
/* harmony export */ });
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(125);


/**
 * @namespace CABLES
 */

const internalNow = function ()
{
    return window.performance.now();
};

/*
 * current time in milliseconds
 * @memberof CABLES
 * @function now
 * @static
 *
 */
const now = function ()
{
    return internalNow();
};

/**
 * Measuring time
 * @namespace external:CABLES#Timer
 * @hideconstructor
 * @class
 */
class Timer extends cables_shared_client__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A
{
    static EVENT_PLAY_PAUSE = "playPause";
    static EVENT_TIME_CHANGED = "timeChanged";

    constructor()
    {
        super();

        /**
         * @private
         */
        this._timeStart = internalNow();
        this._timeOffset = 0;
        this._currentTime = 0;
        this._lastTime = 0;
        this._paused = true;
        this._delay = 0;
        this.overwriteTime = -1;
    }

    _internalNow()
    {
        if (this._ts) return this._ts;
        return internalNow();
    }

    _getTime()
    {
        this._lastTime = (this._internalNow() - this._timeStart) / 1000;
        return this._lastTime + this._timeOffset;
    }

    /**
     * @param {number} d
     */
    setDelay(d)
    {
        this._delay = d;
        this.emitEvent(Timer.EVENT_TIME_CHANGED);
    }

    /**
     * @function
     * @memberof Timer
     * @instance
     * @description returns true if timer is playing
     * @return {Boolean} value
     */
    isPlaying()
    {
        return !this._paused;
    }

    /**
     * @function
     * @memberof Timer
     * @instance
     * @param {any} ts
     * @description update timer
     * @return {Number} time
     */
    update(ts)
    {
        if (ts) this._ts = ts;
        if (this._paused) return;
        this._currentTime = this._getTime();

        return this._currentTime;
    }

    /**
     * @function
     * @memberof Timer
     * @instance
     * @return {Number} time in milliseconds
     */
    getMillis()
    {
        return this.get() * 1000;
    }

    /**
     * @function
     * @memberof Timer
     * @instance
     * @return {Number} value time in seconds
     */
    get()
    {
        return this.getTime();
    }

    getTime()
    {
        if (this.overwriteTime >= 0) return this.overwriteTime - this._delay;
        return this._currentTime - this._delay;
    }

    /**
     * toggle between play/pause state
     * @function
     * @memberof Timer
     * @instance
     */
    togglePlay()
    {
        if (this._paused) this.play();
        else this.pause();
    }

    /**
     * set current time
     * @function
     * @memberof Timer
     * @instance
     * @param {Number} t
     */
    setTime(t)
    {
        if (isNaN(t) || t < 0) t = 0;
        this._timeStart = this._internalNow();
        this._timeOffset = t;
        this._currentTime = t;
        this.emitEvent((Timer.EVENT_TIME_CHANGED));
    }

    setOffset(val)
    {
        if (this._currentTime + val < 0)
        {
            this._timeStart = this._internalNow();
            this._timeOffset = 0;
            this._currentTime = 0;
        }
        else
        {
            this._timeOffset += val;
            this._currentTime = this._lastTime + this._timeOffset;
        }
        this.emitEvent(Timer.EVENT_TIME_CHANGED);
    }

    /**
     * (re)starts the timer
     * @function
     * @memberof Timer
     * @instance
     */
    play()
    {
        this._timeStart = this._internalNow();
        this._paused = false;
        this.emitEvent(Timer.EVENT_PLAY_PAUSE);
    }

    /**
     * pauses the timer
     * @function
     * @memberof Timer
     * @instance
     */
    pause()
    {
        this._timeOffset = this._currentTime;
        this._paused = true;
        this.emitEvent(Timer.EVENT_PLAY_PAUSE);
    }

    static now()
    {
        return window.performance.now();
    }
}




/***/ }),

/***/ 562:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);

// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  ajax: () => (/* binding */ ajax),
  basename: () => (/* binding */ basename),
  cacheBust: () => (/* binding */ cacheBust),
  clamp: () => (/* binding */ clamp),
  cleanJson: () => (/* binding */ cleanJson),
  copyArray: () => (/* binding */ copyArray),
  escapeHTML: () => (/* binding */ escapeHTML),
  filename: () => (/* binding */ filename),
  float32Concat: () => (/* binding */ float32Concat),
  generateUUID: () => (/* binding */ generateUUID),
  getShortOpName: () => (/* binding */ getShortOpName),
  isNumeric: () => (/* binding */ isNumeric),
  logErrorConsole: () => (/* binding */ logErrorConsole),
  logStack: () => (/* binding */ logStack),
  map: () => (/* binding */ map),
  prefixedHash: () => (/* binding */ prefixedHash),
  request: () => (/* binding */ request),
  shortId: () => (/* binding */ shortId),
  shuffleArray: () => (/* binding */ shuffleArray),
  simpleId: () => (/* binding */ simpleId),
  smoothStep: () => (/* binding */ smoothStep),
  smootherStep: () => (/* binding */ smootherStep),
  uniqueArray: () => (/* binding */ uniqueArray),
  uuid: () => (/* binding */ uuid)
});

// EXTERNAL MODULE: ./src/core/constants.js
var constants = __webpack_require__(440);
;// CONCATENATED MODULE: ./src/core/extendjs.js
/**
 * extend javascript functionality
 */

/**
 * @external Math
 */

/**
 * set random seed for seededRandom()
 * @type Number
 * @static
 */
Math.randomSeed = 1;

/**
 * @function external:Math#setRandomSeed
 * @param {number} seed
 */
Math.setRandomSeed = function (seed)
{
    // https://github.com/cables-gl/cables_docs/issues/622
    Math.randomSeed = seed * 50728129;
    if (seed != 0)
    {
        Math.randomSeed = Math.seededRandom() * 17624813;
        Math.randomSeed = Math.seededRandom() * 9737333;
    }
};

/**
 * generate a seeded random number
 * @function seededRandom
 * @memberof Math
 * @param {Number} max minimum possible random number
 * @param {Number} min maximum possible random number
 * @return {Number} random value
 * @static
 */
Math.seededRandom = function (max, min)
{
    if (Math.randomSeed === 0) Math.randomSeed = Math.random() * 999;
    max = max || 1;
    min = min || 0;

    Math.randomSeed = (Math.randomSeed * 9301 + 49297) % 233280;
    const rnd = Math.randomSeed / 233280.0;

    return min + rnd * (max - min);
};

/**
     * @namespace String
     */

/**
 * append a linebreak to a string
 * @this {String}
 * @returns {string} string with newline appended
*/
String.prototype.endl = function ()
{
    return this + "\n";
};

String.prototype.contains = function (str)
{
    console.warn("string.contains deprecated, use string.includes");
    console.log((new Error()).stack);
    return this.includes(str);

};

function extendJs() {}

;// CONCATENATED MODULE: ./src/core/utils.js
/**
 * @namespace external:CABLES#Utils
 */




extendJs();

/**
 * Merge two Float32Arrays.
 * @function float32Concat
 * @param {Float32Array} first Left-hand side array
 * @param {Float32Array} second Right-hand side array
 * @return {Float32Array}
 * @static
 */
function float32Concat(first, second)
{
    if (!(first instanceof Float32Array)) first = new Float32Array(first);
    if (!(second instanceof Float32Array)) second = new Float32Array(second);

    const result = new Float32Array(first.length + second.length);

    result.set(first);
    result.set(second, first.length);

    return result;
}

/**
 * get op shortname: only last part of fullname and without version
 * @function getShortOpName
 * @memberof CABLES
 * @param {string} fullname full op name
 * @static
 */
const getShortOpName = function (fullname)
{
    let name = fullname.split(".")[fullname.split(".").length - 1];

    if (name.includes(constants/* CONSTANTS */.a.OP.OP_VERSION_PREFIX))
    {
        const n = name.split(constants/* CONSTANTS */.a.OP.OP_VERSION_PREFIX)[1];
        name = name.substring(0, name.length - (constants/* CONSTANTS */.a.OP.OP_VERSION_PREFIX + n).length);
    }
    return name;
};

/**
 * randomize order of an array
 * @function shuffleArray
 * @param {Array|Float32Array} array {Array} original
 * @return {Array|Float32Array} shuffled array
 * @static
 */
const shuffleArray = function (array)
{
    for (let i = array.length - 1; i > 0; i--)
    {
        const j = Math.floor(Math.seededRandom() * (i + 1));
        const temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
    return array;
};

/**
 * generate a short "relativly unique" id
 * @function shortId
 * @return {String} generated ID
 * @static
 */

const _shortIds = {};
const shortId = function ()
{
    let str = Math.random().toString(36).substr(2, 9);

    if (_shortIds.hasOwnProperty(str)) str = shortId();
    _shortIds[str] = true;
    return str;
};

/**
 * @typedef {String} UUID
*/

/**
 * generate a UUID
 * @function uuid
 * @return {UUID} generated UUID
 * @static
 */
const uuid = function ()
{
    let d = new Date().getTime();
    const uuidStr = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) =>
    {
        const r = (d + Math.random() * 16) % 16 | 0;
        d = Math.floor(d / 16);
        return (c == "x" ? r : (r & 0x3) | 0x8).toString(16);
    });
    return uuidStr;
};
const generateUUID = uuid;

function cleanJson(obj)
{
    for (const i in obj)
    {
        if (obj[i] && typeof objValue === "object" && obj[i].constructor === Object) obj[i] = cleanJson(obj[i]);

        if (obj[i] === null || obj[i] === undefined) delete obj[i];
        else if (Array.isArray(obj[i]) && obj[i].length == 0) delete obj[i];
    }

    return obj;
}

/**
 * @see http://stackoverflow.com/q/7616461/940217
 * @param {string} str
 * @param {string} prefix
 * @return {string}
 */
const prefixedHash = function (str, prefix = "id")
{
    let hash = 0;
    if (str.length > 0)
    {
        for (let i = 0; i < str.length; i++)
        {
            let character = str.charCodeAt(i);
            hash = ((hash << 5) - hash) + character;
            hash &= hash; // Convert to 32bit integer
        }
    }
    return prefix + "" + hash;
};

/**
 * generate a simple ID
 * @return {Number} new id
 * @static
 */
let simpleIdCounter = 0;
const simpleId = function ()
{
    simpleIdCounter++;
    return simpleIdCounter;
};

/**
 * smoothStep a value
 * @param {Number} perc value value to be smoothed [0-1]
 * @return {Number} smoothed value
 * @static
 */
const smoothStep = function (perc)
{
    const x = Math.max(0, Math.min(1, (perc - 0) / (1 - 0)));
    perc = x * x * (3 - 2 * x); // smoothstep
    return perc;
};

/**
 * smootherstep a value
 * @param {Number} perc value to be smoothed [0-1]
 * @return {Number} smoothed value
 * @static
 */
const smootherStep = function (perc)
{
    const x = Math.max(0, Math.min(1, (perc - 0) / (1 - 0)));
    perc = x * x * x * (x * (x * 6 - 15) + 10); // smootherstep
    return perc;
};

/**
 * clamp number / make sure its between min/max
 * @param {Number} value value to be mapped
 * @param {Number} min minimum value
 * @param {Number} max maximum value
 * @static
 */
const clamp = function (value, min, max)
{
    return Math.min(Math.max(value, min), max);
};

/**
 * map a value in a range to a value in another range
 * @param {Number} x value to be mapped
 * @param {Number} _oldMin old range minimum value
 * @param {Number} _oldMax old range maximum value
 * @param {Number} _newMin new range minimum value
 * @param {Number} _newMax new range maximum value
 * @param {Number} _easing
 * @return {Number} mapped value
 * @static
 */
const map = function (x, _oldMin, _oldMax, _newMin, _newMax, _easing = 0, clamp = true)
{
    if (clamp)
    {
        if (x >= _oldMax) return _newMax;
        if (x <= _oldMin) return _newMin;
    }

    let reverseInput = false;
    const oldMin = Math.min(_oldMin, _oldMax);
    const oldMax = Math.max(_oldMin, _oldMax);
    if (oldMin != _oldMin) reverseInput = true;

    let reverseOutput = false;
    const newMin = Math.min(_newMin, _newMax);
    const newMax = Math.max(_newMin, _newMax);
    if (newMin != _newMin) reverseOutput = true;

    let portion = 0;
    let r = 0;

    if (reverseInput) portion = ((oldMax - x) * (newMax - newMin)) / (oldMax - oldMin);
    else portion = ((x - oldMin) * (newMax - newMin)) / (oldMax - oldMin);

    if (reverseOutput) r = newMax - portion;
    else r = portion + newMin;

    if (!_easing) return r;
    if (_easing == 1)
    {
        // smoothstep
        x = Math.max(0, Math.min(1, (r - _newMin) / (_newMax - _newMin)));
        return _newMin + x * x * (3 - 2 * x) * (_newMax - _newMin);
    }
    if (_easing == 2)
    {
        // smootherstep
        x = Math.max(0, Math.min(1, (r - _newMin) / (_newMax - _newMin)));
        return _newMin + x * x * x * (x * (x * 6 - 15) + 10) * (_newMax - _newMin);
    }

    return r;
};

// ----------------------------------------------------------------

/**
 * returns true if parameter is a number
 * @param {any} n value The value to check.
 * @return {Boolean}
 * @static
 */
function isNumeric(n)
{
    return !isNaN(parseFloat(n)) && isFinite(n);
}

// ----------------------------------------------------------------

/**
 * append a unique/random parameter to a url, so the browser is forced to reload the file, even if its cached
 * @static
 * @param {String} url The url to append the cachebuster parameter to.
 * @return {String} url with cachebuster parameter
 */
const cacheBust = function (url = "")
{
    if (!url) return "";
    if (url.startsWith("data:")) return;
    if (url.includes("?")) url += "&";
    else url += "?";
    return url + "cache=" + CABLES.uuid();
};

/**
 * copy the content of an array
 * @static
 * @param {Array} src sourceArray
 * @param {Array} dst optional
 * @return {Array} dst
 */
const copyArray = function (src, dst)
{
    if (!src) return null;
    dst = dst || [];
    dst.length = src.length;
    for (let i = 0; i < src.length; i++)
        dst[i] = src[i];

    return dst;
};

/**
 * return the filename part of a url without extension
 * @static
 * @param {String} url
 * @return {String} just the filename
 */
const basename = function (url)
{
    let name = CABLES.filename(url);

    const parts2 = name.split(".");
    name = parts2[0];

    return name;
};

/**
 * output a stacktrace to the console
 * @static
 */
const logStack = function ()
{
    console.log("logstack", (new Error()).stack);
};

/**
 * return the filename part of a url
 * @static
 * @param {String} url
 * @return {String} just the filename
 */
const filename = function (url)
{
    let name = "";
    if (!url) return "";

    if (url.startsWith("data:") && url.includes(":"))
    {
        const parts = url.split(",");
        return parts[0];
    }

    let parts = (url + "").split("/");
    if (parts.length > 0)
    {
        const str = parts[parts.length - 1];
        let parts2 = str.split("?");
        name = parts2[0];
    }

    return name || "";
};

/**
 * make an ajax request
 * @static
 * @function ajax
 * @param url
 * @param cb
 * @param method
 * @param post
 * @param contenttype
 * @param jsonP
 * @param headers
 * @param options
 */
const ajax = function (url, cb, method, post, contenttype, jsonP, headers = {}, options = {})
{
    const requestOptions = {
        "url": url,
        "cb": cb,
        "method": method,
        "data": post,
        "contenttype": contenttype,
        "sync": false,
        "jsonP": jsonP,
        "headers": headers,
    };
    if (options && options.credentials) requestOptions.credentials = options.credentials;
    request(requestOptions);
};

const request = function (options)
{
    if (!options.hasOwnProperty("asynch")) options.asynch = true;

    let xhr;
    try
    {
        xhr = new XMLHttpRequest();
    }
    catch (e) {}

    xhr.onreadystatechange = function ()
    {
        if (xhr.readyState != 4) return;

        if (options.cb)
        {
            if (xhr.status == 200 || xhr.status == 0) options.cb(false, xhr.responseText, xhr);
            else options.cb(true, xhr.responseText, xhr);
        }
    };

    try
    {
        xhr.open(options.method ? options.method.toUpperCase() : "GET", options.url, !options.sync);
    }
    catch (e)
    {
        if (options.cb && e) options.cb(true, e.msg, xhr);
    }

    if (typeof options.headers === "object")
    {
        if (options.headers)
        {
            const keys = Object.keys(options.headers);
            for (let i = 0; i < keys.length; i++)
            {
                const name = keys[i];
                const value = options.headers[name];
                xhr.setRequestHeader(name, value);
            }
        }
    }

    if (options.credentials && options.credentials !== "omit")
    {
        xhr.withCredentials = true;
    }

    try
    {
        if (!options.post && !options.data)
        {
            xhr.send();
        }
        else
        {
            xhr.setRequestHeader(
                "Content-type",
                options.contenttype ? options.contenttype : "application/x-www-form-urlencoded",
            );
            xhr.send(options.data || options.post);
        }
    }
    catch (e)
    {
        if (options.cb) options.cb(true, e.msg, xhr);
    }
};

// ----------------------------------------------------------------

const logErrorConsole = function (initiator)
{
    CABLES.errorConsole = CABLES.errorConsole || { "log": [] };
    CABLES.errorConsole.log.push({ "initiator": initiator, "arguments": arguments });

    if (!CABLES.errorConsole.ele)
    {
        const ele = document.createElement("div");
        ele.id = "cablesErrorConsole";
        ele.style.width = "90%";
        ele.style.height = "300px";
        ele.style.zIndex = "9999999";
        ele.style.display = "inline-block";
        ele.style.position = "absolute";
        ele.style.padding = "10px";
        ele.style.fontFamily = "monospace";
        ele.style.color = "red";
        ele.style.backgroundColor = "#200";

        CABLES.errorConsole.ele = ele;
        document.body.appendChild(ele);
    }

    let logHtml = "ERROR<br/>for more info, open your browsers dev tools console (Ctrl+Shift+I or Command+Alt+I)<br/>";

    for (let l = 0; l < CABLES.errorConsole.log.length; l++)
    {
        logHtml += CABLES.errorConsole.log[l].initiator + " ";
        for (let i = 1; i < CABLES.errorConsole.log[l].arguments.length; i++)
        {
            if (i > 2)logHtml += ", ";
            let arg = CABLES.errorConsole.log[l].arguments[i];
            if (arg.constructor.name.indexOf("Error") > -1 || arg.constructor.name.indexOf("error") > -1)
            {
                let txt = "Uncaught ErrorEvent ";
                if (arg.message)txt += " message: " + arg.message;
                logHtml += txt;
            }
            else if (typeof arg == "string")
                logHtml += arg;
            else if (typeof arg == "number")
                logHtml += String(arg) + " ";
        }
        logHtml += "<br/>";
    }

    CABLES.errorConsole.ele.innerHTML = logHtml;
};

/**
 * @param {Array<any>} arr
 */
function uniqueArray(arr)
{
    const u = {}, a = [];
    for (let i = 0, l = arr.length; i < l; ++i)
    {
        if (!u.hasOwnProperty(arr[i]))
        {
            a.push(arr[i]);
            u[arr[i]] = 1;
        }
    }
    return a;
}

const htmlEscapes = {
    "&": "&amp;",
    "<": "&lt;",
    ">": "&gt;",
    "\"": "&quot;",
    "'": "&#39;",
};

/** Used to match HTML entities and HTML characters. */
const reUnescapedHtml = /[&<>"']/g;
const reHasUnescapedHtml = RegExp(reUnescapedHtml.source);

// from https://github.com/lodash/lodash/blob/master/escape.js
/*  eslint-disable */
const escapeHTML = function(string)
{
    return string && reHasUnescapedHtml.test(string) ?
        string.replace(reUnescapedHtml, function(chr) { return htmlEscapes[chr]; })
        : string || "";
}
/* eslint-enable */


/***/ }),

/***/ 982:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   I: () => (/* binding */ BoundingBox)
/* harmony export */ });
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(329);
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(684);
/* harmony import */ var cables__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(562);





/**
 * bounding box
 *
 * @namespace external:CGL
 * @param {Geometry} geometry or bounding box
 */
class BoundingBox
{

    /**
     * @param {Geometry} [geom]
     */
    constructor(geom)
    {
        this._init();
        this._first = true;
        this._wireMesh = null;

        if (geom) this.applyGeom(geom);
    }

    _init()
    {
        this._max = [-0, -0, -0];
        this._min = [0, 0, 0];
        this._center = [0, 0, 0];
        this._size = [0, 0, 0];
        this._maxAxis = 0.0;
        this._first = true;
    }

    /**
     * get biggest number of maxX,maxY,maxZ
     * @type {Number}
     */
    get maxAxis() { return this._maxAxis || 1; }

    /**
     * size of bounding box
     * @type {vec3}
     */
    get size() { return this._size; }

    /**
     * center of bounding box
     * @type {vec3}
     */
    get center() { return this._center; }

    /**
     * center x
     * @type {Number}
     */
    get x() { return this._center[0]; }

    /**
     * center y
     * @type {Number}
     */
    get y() { return this._center[1]; }

    /**
     * center z
     * @type {Number}
     */
    get z() { return this._center[2]; }

    /**
     * minimum x
     * @type {Number}
     */
    get minX() { return this._min[0]; }

    /**
     * minimum y
     * @type {Number}
     */
    get minY() { return this._min[1]; }

    /**
     * minimum z
     * @type {Number}
     */
    get minZ() { return this._min[2]; }

    /**
     * maximum x
     * @type {Number}
     */
    get maxX() { return this._max[0]; }

    /**
     * maximum y
     * @type {Number}
     */
    get maxY() { return this._max[1]; }

    /**
     * maximum z
     * @type {Number}
     */
    get maxZ() { return this._max[2]; }

    /**
     * @deprecated
     * @param {Geometry} geom
     */
    apply(geom)
    {
        return this.applyGeom(geom);
    }

    /**
     * @param {Geometry} geom
     */
    applyGeom(geom)
    {
        if (!geom) return;

        if (geom instanceof BoundingBox)
        {
            const bb = geom;

            this.applyPos(bb.maxX, bb.maxY, bb.maxZ);
            this.applyPos(bb.minX, bb.minY, bb.minZ);
        }
        else
        {
            if (geom.isGeometry)
                for (let i = 0; i < geom.vertices.length; i += 3)
                    this.applyPos(geom.vertices[i], geom.vertices[i + 1], geom.vertices[i + 2]);
        }
        this.calcCenterSize();
    }

    /**
     * returns a copy of the bounding box
     * @function copy
     * @memberof BoundingBox
     * @instance
     */
    copy()
    {
        return new BoundingBox(this);
    }

    get changed()
    {
        return !(this._max[0] == -Number.MAX_VALUE && this._max[1] == -Number.MAX_VALUE && this._max[2] == -Number.MAX_VALUE);
    }

    /**
     * @param {number} x
     * @param {number} y
     * @param {number} z
     */
    applyPos(x, y, z)
    {
        if (x == Number.MAX_VALUE || x == -Number.MAX_VALUE ||
            y == Number.MAX_VALUE || y == -Number.MAX_VALUE ||
            z == Number.MAX_VALUE || z == -Number.MAX_VALUE) return;

        if (!cables__WEBPACK_IMPORTED_MODULE_0__.isNumeric(x) || !cables__WEBPACK_IMPORTED_MODULE_0__.isNumeric(y) || !cables__WEBPACK_IMPORTED_MODULE_0__.isNumeric(z)) return;

        if (this._first)
        {
            this._max[0] = x;
            this._max[1] = y;
            this._max[2] = z;

            this._min[0] = x;
            this._min[1] = y;
            this._min[2] = z;
            this._first = false;
            return;
        }

        this._max[0] = Math.max(this._max[0], x);
        this._max[1] = Math.max(this._max[1], y);
        this._max[2] = Math.max(this._max[2], z);

        this._min[0] = Math.min(this._min[0], x);
        this._min[1] = Math.min(this._min[1], y);
        this._min[2] = Math.min(this._min[2], z);
    }

    calcCenterSize()
    {
        if (this._first) return;

        this._size[0] = this._max[0] - this._min[0];
        this._size[1] = this._max[1] - this._min[1];
        this._size[2] = this._max[2] - this._min[2];

        this._center[0] = (this._min[0] + this._max[0]) / 2;
        this._center[1] = (this._min[1] + this._max[1]) / 2;
        this._center[2] = (this._min[2] + this._max[2]) / 2;

        this._maxAxis = Math.max(this._size[2], Math.max(this._size[0], this._size[1]));
    }

    /**
     * @param {mat4} m
     */
    mulMat4(m)
    {
        if (this._first)
        {
            this._max[0] = 0;
            this._max[1] = 0;
            this._max[2] = 0;

            this._min[0] = 0;
            this._min[1] = 0;
            this._min[2] = 0;
            this._first = false;
        }
        gl_matrix__WEBPACK_IMPORTED_MODULE_1__.transformMat4(this._max, this._max, m);
        gl_matrix__WEBPACK_IMPORTED_MODULE_1__.transformMat4(this._min, this._min, m);
        this.calcCenterSize();
    }

    /**
     * @param {CglContext} cgl
     * @param {Shader} _shader
     * @param {Op} op
     */
    render(cgl, _shader, op)
    {
        if (!this._wireMesh) this._wireMesh = new CGL.WireCube(cgl);

        cgl.pushModelMatrix();
        gl_matrix__WEBPACK_IMPORTED_MODULE_2__.translate(cgl.mMatrix, cgl.mMatrix, this._center);

        if (CABLES.UI && op)
        {
            CABLES.UI.OverlayMeshes.drawCube(op, this._size[0] / 2, this._size[1] / 2, this._size[2] / 2);
        }

        cgl.popModelMatrix();
    }
}


/***/ }),

/***/ 223:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   f: () => (/* binding */ CgCanvas)
/* harmony export */ });
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(849);


class CgCanvas
{
    hasFocus = false;

    forceAspect = 0;

    /**
     * @param {{ canvasEle: any; cg: any; }} options
     */
    constructor(options)
    {
        this._log = new cables_shared_client__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A("CgCanvas");
        if (!options)
        {
            this._log.error("CgCanvas no options");
        }
        else
        {
            this._canvasEle = options.canvasEle;
        }

        if (!options.cg) this._log.error("CgCanvas options has no cg");
        if (!options.canvasEle) this._log.error("CgCanvas options has no canvasEle");

        this._cg = options.cg;
        this.pixelDensity = 1;
        this.canvasWidth = this.canvasEle.clientWidth;
        this.canvasHeight = this.canvasEle.clientHeight;

        this._oldWidthRp = -1;
        this._oldHeightRp = -1;

        this.setSize(this.canvasWidth, this.canvasHeight);
        this.canvasEle.addEventListener("focus", () => { this.hasFocus = true; });
        this.canvasEle.addEventListener("blur", () => { this.hasFocus = false; });
    }

    get canvasEle() { return this._canvasEle; }

    /**
     * @param {Number} w
     * @param {Number} h
     * @param {any} ignorestyle
     * @returns {any}
     */
    setSize(w, h, ignorestyle = false)
    {
        let offY = 0;
        if (this.forceAspect)
        {
            let nh = w / this.forceAspect;
            if (nh < h)offY = (h - nh) / 2;
            h = nh;
        }

        if (this._oldWidthRp != w * this.pixelDensity || this._oldHeightRp != h * this.pixelDensity)
        {
            this._oldWidthRp = this.canvasEle.width = w * this.pixelDensity;
            this._oldHeightRp = this.canvasEle.height = h * this.pixelDensity;

            if (!ignorestyle)
            {
                this.canvasEle.style.width = w + "px";
                this.canvasEle.style.height = h + "px";
                this.canvasEle.style.marginTop = offY + "px";
            }

            this.updateSize();

            this._cg.emitEvent("resize");
        }
    }

    updateSize()
    {
        this.canvasEle.width = this.canvasWidth = this.canvasEle.clientWidth * this.pixelDensity;
        this.canvasEle.height = this.canvasHeight = this.canvasEle.clientHeight * this.pixelDensity;
    }

    dispose()
    {
        if (this._canvasEle) this._canvasEle.remove();
        this._canvasEle = null;
    }
}


/***/ }),

/***/ 628:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   A: () => (/* binding */ CgContext)
/* harmony export */ });
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(125);
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(849);
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(329);
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(684);
/* harmony import */ var _cg_canvas_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(223);
/* harmony import */ var _cg_matrixstack_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(868);
/* harmony import */ var _cgl_cgl_profiledata_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(460);
/* harmony import */ var _cg_fpscounter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(294);








class CgContext extends cables_shared_client__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A
{

    static API_UNKNOWN = 0;
    static API_WEBGL = 1;
    static API_WEBGPU = 2;

    static EVENT_RESIZE = "resize";

    gApi = 0;

    /**
     * Description
     * @param {Patch} _patch
     */
    constructor(_patch)
    {
        super();

        this._log = new cables_shared_client__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A("cg_context", { "onError": _patch.config.onError });

        /** @type {object} */
        this.tempData = this.frameStore = this.frameStore || {};
        this.fpsCounter = new _cg_fpscounter_js__WEBPACK_IMPORTED_MODULE_2__/* .FpsCounter */ .K();
        this._identView = gl_matrix__WEBPACK_IMPORTED_MODULE_3__.create();
        this._ident = gl_matrix__WEBPACK_IMPORTED_MODULE_3__.create();
        gl_matrix__WEBPACK_IMPORTED_MODULE_3__.set(this._identView, 0, 0, -2);
        gl_matrix__WEBPACK_IMPORTED_MODULE_3__.set(this._ident, 0, 0, 0);
        this._onetimeCallbacks = [];
        this.maxTexSize = 2048;
        this._viewPort = [0, 0, 1, 1];
        this._viewPortStack = [];
        this.patch = _patch;
        this.autoReSize = true;

        this.DEPTH_COMPARE_FUNC_NEVER = 0;
        this.DEPTH_COMPARE_FUNC_LESS = 1;
        this.DEPTH_COMPARE_FUNC_EQUAL = 2;
        this.DEPTH_COMPARE_FUNC_LESSEQUAL = 3;
        this.DEPTH_COMPARE_FUNC_GREATER = 4;
        this.DEPTH_COMPARE_FUNC_NOTEQUAL = 5;
        this.DEPTH_COMPARE_FUNC_GREATEREQUAL = 6;
        this.DEPTH_COMPARE_FUNC_ALWAYS = 7;

        this.profileData = new _cgl_cgl_profiledata_js__WEBPACK_IMPORTED_MODULE_4__/* .ProfileData */ .E(this);

        /**
         * Current projection matrix
         * @memberof Context
         * @instance
         * @type {mat4}
         */
        this.pMatrix = gl_matrix__WEBPACK_IMPORTED_MODULE_5__.create();

        /**
         * Current model matrix
         * @memberof Context
         * @instance
         * @type {mat4}
         */
        this.mMatrix = gl_matrix__WEBPACK_IMPORTED_MODULE_5__.create();

        /**
         * Current view matrix
         * @memberof Context
         * @instance
         * @type {mat4}
         */
        this.vMatrix = gl_matrix__WEBPACK_IMPORTED_MODULE_5__.create();
        this._textureslots = [];

        this._pMatrixStack = new _cg_matrixstack_js__WEBPACK_IMPORTED_MODULE_6__/* .MatrixStack */ .u();
        this._mMatrixStack = new _cg_matrixstack_js__WEBPACK_IMPORTED_MODULE_6__/* .MatrixStack */ .u();
        this._vMatrixStack = new _cg_matrixstack_js__WEBPACK_IMPORTED_MODULE_6__/* .MatrixStack */ .u();

        this.canvasScale = 1;

        gl_matrix__WEBPACK_IMPORTED_MODULE_5__.identity(this.mMatrix);
        gl_matrix__WEBPACK_IMPORTED_MODULE_5__.identity(this.vMatrix);

        window.matchMedia("screen and (min-resolution: 2dppx)").addEventListener("change", () =>
        {
            this.emitEvent("resize");
        });

    }

    get canvasWidth()
    {
        return this.cgCanvas.canvasWidth;
    }

    get canvasHeight()
    {
        return this.cgCanvas.canvasHeight;
    }

    set pixelDensity(p)
    {
        if (this.cgCanvas.pixelDensity != p)
        {
            this.cgCanvas.pixelDensity = p;
            this.cgCanvas.updateSize();
            this.emitEvent("resize");
        }
    }

    get pixelDensity()
    {
        return this.cgCanvas.pixelDensity;
    }

    getGApiName()
    {
        return ["unknown", "WebGL", "WebGPU"][this.gApi];
    }

    get canvas()
    {
        return this.cgCanvas.canvasEle;
    }

    get viewPort()
    {
        // TODO: add stack...
        return [0, 0, this.canvasWidth, this.canvasHeight];
    }

    /**
     * @param {HTMLElement} canvEle
     */
    setCanvas(canvEle)
    {
        if (this.cgCanvas && canvEle == this.cgCanvas.canvasEle) return;
        if (typeof canvEle === "string") canvEle = document.getElementById(canvEle);

        this.cgCanvas = new _cg_canvas_js__WEBPACK_IMPORTED_MODULE_7__/* .CgCanvas */ .f({ "canvasEle": canvEle, "cg": this });

        canvEle.parentElement.classList.add("cablesContainer");
        if (this._setCanvas) this._setCanvas(canvEle);

        this.updateSize();
    }

    /**
     * @param {HTMLElement} _canvEle
     */
    _setCanvas(_canvEle)
    {
    }

    updateSize()
    {
        this.cgCanvas.updateSize();
    }

    /**
     * @param {number} w
     * @param {number} h
     * @param {boolean} ignorestyle
     */
    setSize(w, h, ignorestyle = false)
    {
        this.cgCanvas.setSize(w, h, ignorestyle);
    }

    _resizeToWindowSize()
    {
        if (this.autoReSize)
        {
            this.setSize(window.innerWidth, window.innerHeight);
            this.updateSize();
        }
    }

    _resizeToParentSize()
    {
        if (this.autoReSize)
        {
            const p = this.canvas.parentElement;
            if (!p)
            {
                this._log.error("cables: can not resize to container element");
                return;
            }

            this.setSize(p.clientWidth, p.clientHeight);
            this.updateSize();
        }
    }

    setAutoResize(parent)
    {
        window.removeEventListener("resize", this._resizeToWindowSize.bind(this));
        window.removeEventListener("resize", this._resizeToParentSize.bind(this));

        if (parent == "window")
        {
            window.addEventListener("resize", this._resizeToWindowSize.bind(this));
            window.addEventListener("orientationchange", this._resizeToWindowSize.bind(this));
            this._resizeToWindowSize();
        }
        if (parent == "parent")
        {
            window.addEventListener("resize", this._resizeToParentSize.bind(this));
            this._resizeToParentSize();
        }
    }

    /**
     * push a matrix to the projection matrix stack
     * @function pushPMatrix
     * @memberof Context
     * @instance
     */
    pushPMatrix()
    {
        this.pMatrix = this._pMatrixStack.push(this.pMatrix);
    }

    /**
      * pop projection matrix stack
      * @function popPMatrix
      * @memberof Context
      * @instance
      * @returns {mat4} current projectionmatrix
      */
    popPMatrix()
    {
        this.pMatrix = this._pMatrixStack.pop();
        return this.pMatrix;
    }

    getProjectionMatrixStateCount()
    {
        return this._pMatrixStack.stateCounter;
    }

    /**
      * push a matrix to the model matrix stack
      * @function pushModelMatrix
      * @memberof Context
      * @instance
      * @example
      * // see source code of translate op:
      * cgl.pushModelMatrix();
      * mat4.translate(cgl.mMatrix,cgl.mMatrix, vec);
      * trigger.trigger();
      * cgl.popModelMatrix();
      */
    pushModelMatrix()
    {
        this.mMatrix = this._mMatrixStack.push(this.mMatrix);
    }

    /**
      * pop model matrix stack
      * @function popModelMatrix
      * @memberof Context
      * @instance
      * @returns {mat4} current modelmatrix
      */
    popModelMatrix()
    {
        // todo: DEPRECATE
        // if (this._mMatrixStack.length === 0) throw "Invalid modelview popMatrix!";
        this.mMatrix = this._mMatrixStack.pop();
        return this.mMatrix;
    }

    /**
      * get model matrix
      * @function modelMatrix
      * @memberof Context
      * @instance
      * @returns {mat4} current modelmatrix
      */
    modelMatrix()
    {
        return this.mMatrix;
    }

    /**
     * push a matrix to the view matrix stack
     * @function pushviewMatrix
     * @memberof Context
     * @instance
     */
    pushViewMatrix()
    {
        this.vMatrix = this._vMatrixStack.push(this.vMatrix);
    }

    /**
      * pop view matrix stack
      * @function popViewMatrix
      * @memberof Context
      * @instance
      * @returns {mat4} current viewmatrix
      * @function
      */
    popViewMatrix()
    {
        this.vMatrix = this._vMatrixStack.pop();
    }

    getViewMatrixStateCount()
    {
        return this._vMatrixStack.stateCounter;
    }

    /**
     * @param {vec3} identTranslate
     * @param {vec3} identTranslateView
     */
    _startMatrixStacks(identTranslate, identTranslateView)
    {
        identTranslate = identTranslate || this._ident;
        identTranslateView = identTranslateView || this._identView;

        gl_matrix__WEBPACK_IMPORTED_MODULE_5__.perspective(this.pMatrix, 45, this.canvasWidth / this.canvasHeight, 0.1, 1000.0);

        gl_matrix__WEBPACK_IMPORTED_MODULE_5__.identity(this.mMatrix);
        gl_matrix__WEBPACK_IMPORTED_MODULE_5__.identity(this.vMatrix);
        gl_matrix__WEBPACK_IMPORTED_MODULE_5__.translate(this.mMatrix, this.mMatrix, identTranslate);
        gl_matrix__WEBPACK_IMPORTED_MODULE_5__.translate(this.vMatrix, this.vMatrix, identTranslateView);

        this.pushPMatrix();
        this.pushModelMatrix();
        this.pushViewMatrix();
    }

    _endMatrixStacks()
    {
        this.popViewMatrix();
        this.popModelMatrix();
        this.popPMatrix();
    }

    dispose()
    {
        this.aborted = true;
        if (this.cgCanvas) this.cgCanvas.dispose();
        if (this._dispose) this._dispose();
    }

    _dispose()
    {
    }

    /**
     * @param {any} _op
     */
    shouldDrawHelpers(_op)
    {
        return false;
    }

    /**
     * execute the callback next frame, once
     * @param {function} cb
     */
    addNextFrameOnceCallback(cb)
    {
        if (cb && this._onetimeCallbacks.indexOf(cb) == -1) this._onetimeCallbacks.push(cb);
    }

    _execOneTimeCallbacks()
    {
        if (this._onetimeCallbacks.length > 0)
        {
            for (let i = 0; i < this._onetimeCallbacks.length; i++) this._onetimeCallbacks[i]();
            this._onetimeCallbacks.length = 0;
        }
    }

    /**
     * @param {number} x
     */
    checkTextureSize(x)
    {
        x = x || 1;
        x = Math.floor(x);
        x = Math.min(x, this.maxTexSize);
        x = Math.max(x, 1);
        return x;
    }

    // should be overwritten...
    screenShot(cb, doScreenshotClearAlpha, mimeType, quality)
    {
        console.log("no screenshot function implemented");
    }

    /**
     * @param {string} [filename]
     * @param {function} [cb]
     * @param {number} [pw]
     * @param {number} [ph]
     * @param {boolean} [_noclearalpha]
     */
    saveScreenshot(filename, cb, pw, ph, _noclearalpha)
    {
        this.patch.renderOneFrame();

        let w = this.canvas.clientWidth * this.pixelDensity;
        let h = this.canvas.clientHeight * this.pixelDensity;

        if (pw)
        {
            this.canvas.width = pw;
            w = pw;
        }
        if (ph)
        {
            this.canvas.height = ph;
            h = ph;
        }

        function padLeft(nr, n, str)
        {
            return Array(n - String(nr).length + 1).join(str || "0") + nr;
        }

        const d = new Date();
        const dateStr = "".concat(String(d.getFullYear()) + String(d.getMonth() + 1) + String(d.getDate()), "_").concat(padLeft(d.getHours(), 2)).concat(padLeft(d.getMinutes(), 2)).concat(padLeft(d.getSeconds(), 2));

        if (!filename) filename = "cables_" + dateStr + ".png";
        else filename += ".png";

        this.screenShot((blob) =>
        {
            this.canvas.width = w;
            this.canvas.height = h;

            if (blob)
            {
                const anchor = document.createElement("a");

                anchor.download = filename;
                anchor.href = URL.createObjectURL(blob);

                console.log("scrrenshot");
                setTimeout(function ()
                {
                    anchor.click();
                    if (cb) cb(blob);
                }, 100);
            }
            else
            {
                this._log.log("screenshot: no blob");
            }
        });
    }

    hasFocus()
    {
        return this.cgCanvas.hasFocus;

    }

}


/***/ }),

/***/ 294:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   K: () => (/* binding */ FpsCounter)
/* harmony export */ });
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(125);
/* harmony import */ var cables__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(920);



class FpsCounter extends cables_shared_client__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A
{
    constructor()
    {
        super();
        this._timeStartFrame = 0;
        this._timeStartSecond = 0;
        this._fpsCounter = 0;
        this._msCounter = 0;
        this._frameCount = 0;
        this.logFps = false;

        this.stats = { "ms": 0, "fps": 0 };
    }

    get frameCount()
    {
        return this._frameCount;
    }

    startFrame()
    {
        this._timeStartFrame = (0,cables__WEBPACK_IMPORTED_MODULE_1__/* .now */ .tB)();
    }

    endFrame()
    {
        this._frameCount++;
        this._fpsCounter++;

        const timeFrame = (0,cables__WEBPACK_IMPORTED_MODULE_1__/* .now */ .tB)() - this._timeStartFrame;
        this._msCounter += timeFrame;

        if ((0,cables__WEBPACK_IMPORTED_MODULE_1__/* .now */ .tB)() - this._timeStartSecond > 1000) this.endSecond();
    }

    endSecond()
    {
        this.stats.fps = this._fpsCounter;
        this.stats.ms = Math.round(this._msCounter / this._fpsCounter * 100) / 100;

        this.emitEvent("performance", this.stats);
        if (this.logFps)console.log(this.stats);

        // reset
        this._fpsCounter = 0;
        this._msCounter = 0;
        this._timeStartSecond = (0,cables__WEBPACK_IMPORTED_MODULE_1__/* .now */ .tB)();
    }
}


/***/ }),

/***/ 331:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   V: () => (/* binding */ Geometry)
/* harmony export */ });
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(849);
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(329);
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(842);
/* harmony import */ var cables__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(562);
/* harmony import */ var _cg_boundingbox_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(982);





/**
 * a geometry contains all information about a mesh, vertices, texturecoordinates etc. etc.
 * @param {String} name
 * @example
 * // create a triangle with all attributes
 * const geom=new Geometry("triangle"),
 *
 * geom.vertices = [
 *      0.0,           sizeH.get(),  0.0,
 *     -sizeW.get(),  -sizeH.get(),  0.0,
 *      sizeW.get(),  -sizeH.get(),  0.0 ];
 *
 * geom.vertexNormals = [
 *      0.0,  0.0,  1.0,
 *      0.0,  0.0,  1.0,
 *      0.0,  0.0,  1.0 ];
 *
 * geom.tangents = [
 *     1,0,0,
 *     1,0,0,
 *     1,0,0 ];
 *
 * geom.biTangents = [
 *     0,1,0,
 *     0,1,0,
 *     0,1,0 ];
 *
 * geom.texCoords = [
 *      0.5,  0.0,
 *      1.0,  1.0,
 *      0.0,  1.0, ];
 *
 * geom.verticesIndices = [
 *     0, 1, 2 ];
 *
 */

class Geometry
{
    isGeometry = true;

    /**
     * @param {String} name
    */
    constructor(name)
    {
        this.name = name || "unknown";
        this._log = new cables_shared_client__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A("cgl_geometry");

        this.faceVertCount = 3;
        this.glPrimitive = null;
        this._attributes = {};

        /** @type {Array|Float32Array} */
        this._vertices = [];

        /** @type {Array} */
        this.verticesIndices = [];

        this.morphTargets = [];
    }

    get vertices()
    {
        return this._vertices;
    }

    set vertices(v)
    {
        this.setVertices(v);
    }

    get texCoords()
    {
        const att = this.getAttribute("texCoords");
        if (!att) return [];
        return att.data;
    }

    set texCoords(v)
    {
        this.setAttribute("texCoords", v, 2);
    }

    get vertexNormals()
    {
        const att = this.getAttribute("vertexNormals");
        if (!att) return [];
        return att.data;
    }

    set vertexNormals(v)
    {
        this.setAttribute("vertexNormals", v, 3);
    }

    get tangents()
    {
        const att = this.getAttribute("tangents");
        if (!att) return [];
        return att.data;
    }

    set tangents(v)
    {
        this.setAttribute("tangents", v, 3);
    }

    get biTangents()
    {
        const att = this.getAttribute("biTangents");
        if (!att) return [];
        return att.data;
    }

    set biTangents(v)
    {
        this.setAttribute("biTangents", v, 3);
    }

    get vertexColors()
    {
        const att = this.getAttribute("vertexColors");
        if (!att) return [];
        return att.data;
    }

    set vertexColors(v)
    {
        this.setAttribute("vertexColors", v, 4);
    }

    /**
     * @description clear all buffers/set them to length 0
     */
    clear()
    {
        this._vertices = new Float32Array([]);
        this.verticesIndices = [];
        this.texCoords = new Float32Array([]);
        this.vertexNormals = new Float32Array([]);
        this.tangents = [];
        this.biTangents = [];
        this._attributes = {};
    }

    /**
    * @return {Object} returns array of attribute objects
    */
    getAttributes()
    {
        return this._attributes;
    }

    /**
     * @function getAttribute
     * @memberof Geometry
     * @instance
     * @param {String} name
     * @return {Object}
     */
    getAttribute(name)
    {
        for (const i in this._attributes)
        {
            if (this._attributes[i].name == name) return this._attributes[i];
        }
        return null;
    }

    /**
     * @function setAttribute
     * @description create an attribute
     * @memberof Geometry
     * @instance
     * @param {String} name
     * @param {Array} arr
     * @param {Number} itemSize
     */
    setAttribute(name, arr, itemSize)
    {
        let attrType = "";
        if (!itemSize || itemSize > 4)
        {
            this._log.warn("itemsize wrong?", itemSize, name);
            this._log.stack("itemsize");

            itemSize = 3;
        }

        if (itemSize == 1) attrType = "float";
        else if (itemSize == 2) attrType = "vec2";
        else if (itemSize == 3) attrType = "vec3";
        else if (itemSize == 4) attrType = "vec4";

        const attr = {
            "name": name,
            "data": arr,
            "itemSize": itemSize,
            "type": attrType,
        };

        this._attributes[name] = attr;
    }

    /**
     * @param {string} name
     * @param {Geometry} newgeom
     */
    copyAttribute(name, newgeom)
    {
        const attr = this.getAttribute(name);
        newgeom.setAttribute(name, new Float32Array(attr.data), attr.itemSize);
    }

    /**
     * @function setVertices
     * @memberof Geometry
     * @instance
     * @description set vertices
     * @param {Array|Float32Array} arr [x,y,z,x,y,z,...]
     */
    setVertices(arr)
    {
        if (arr instanceof Float32Array) this._vertices = arr;
        else this._vertices = new Float32Array(arr);
    }

    /**
     * set texcoords
     * @param {Array|Float32Array} arr [u,v,u,v,...]
     */
    setTexCoords(arr)
    {
        if (arr instanceof Float32Array) this.texCoords = arr;
        else this.texCoords = new Float32Array(arr);
    }

    // deprecated
    calcNormals(smooth)
    {
        const options = { "smooth": smooth };
        this.calculateNormals(options);
    }

    /**
     * @param {number} x
     * @param {number} y
     * @param {number} z
     */
    flipNormals(x, y, z)
    {
        let vec = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();

        if (x == undefined)x = 1;
        if (y == undefined)y = 1;
        if (z == undefined)z = 1;

        for (let i = 0; i < this.vertexNormals.length; i += 3)
        {
            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.set(vec,
                this.vertexNormals[i + 0],
                this.vertexNormals[i + 1],
                this.vertexNormals[i + 2]);

            vec[0] *= -x;
            vec[1] *= -y;
            vec[2] *= -z;

            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.normalize(vec, vec);

            this.vertexNormals[i + 0] = vec[0];
            this.vertexNormals[i + 1] = vec[1];
            this.vertexNormals[i + 2] = vec[2];
        }
    }

    getNumTriangles()
    {
        if (this.verticesIndices && this.verticesIndices.length) return this.verticesIndices.length / 3;
        return this.vertices.length / 3;
    }

    /**
     * flip order of vertices in geom faces
     */
    flipVertDir()
    {
        const newInd = [];
        newInd.length = this.verticesIndices.length;
        for (let i = 0; i < this.verticesIndices.length; i += 3)
        {
            newInd[i] = this.verticesIndices[i + 2];
            newInd[i + 1] = this.verticesIndices[i + 1];
            newInd[i + 2] = this.verticesIndices[i];
        }
        this.verticesIndices = newInd;
    }

    /**
     * @param {Array} verts
     */
    setPointVertices(verts)
    {
        if (verts.length % 3 !== 0)
        {
            this._log.error("SetPointVertices: Array must be multiple of three.");
            return;
        }

        if (!(verts instanceof Float32Array)) this.vertices = new Float32Array(verts);
        else this.vertices = verts;

        if (!(this.texCoords instanceof Float32Array)) this.texCoords = new Float32Array((verts.length / 3) * 2);

        // this.texCoords.length=verts.length/3*2;
        this.verticesIndices.length = verts.length / 3;
        // this.verticesIndices=[];

        for (let i = 0; i < verts.length / 3; i++)
        {
            this.verticesIndices[i] = i;
            this.texCoords[i * 2] = 0;
            this.texCoords[i * 2 + 1] = 0;
        }
    }

    /**
     * merge a different geometry into the this geometry
     * @param {Geometry} geom
     */
    merge(geom)
    {
        if (!geom) return;

        if (this.isIndexed() != geom.isIndexed())
        {
            if (this.isIndexed())
            {
                this.unIndex(false, true);
            }
            if (geom.isIndexed())
            {
                const g = geom.copy();
                g.unIndex(false, true);
                geom = g;
            }
        }

        const oldIndizesLength = this.verticesIndices.length;
        const vertLength = this._vertices.length / 3;

        this.verticesIndices.length += geom.verticesIndices.length;
        for (let i = 0; i < geom.verticesIndices.length; i++)
            this.verticesIndices[oldIndizesLength + i] = geom.verticesIndices[i] + vertLength;

        this.vertices = cables__WEBPACK_IMPORTED_MODULE_2__.float32Concat(this._vertices, geom.vertices);
        this.texCoords = cables__WEBPACK_IMPORTED_MODULE_2__.float32Concat(this.texCoords, geom.texCoords);
        this.vertexNormals = cables__WEBPACK_IMPORTED_MODULE_2__.float32Concat(this.vertexNormals, geom.vertexNormals);
        this.tangents = cables__WEBPACK_IMPORTED_MODULE_2__.float32Concat(this.tangents, geom.tangents);
        this.biTangents = cables__WEBPACK_IMPORTED_MODULE_2__.float32Concat(this.biTangents, geom.biTangents);
    }

    /**
     *   a copy of the geometry
     * @function copy
     * @memberof Geometry
     * @instance
     */
    copy()
    {
        const geom = new Geometry(this.name + " copy");
        geom.faceVertCount = this.faceVertCount;
        geom.glPrimitive = this.glPrimitive;

        geom.setVertices(this._vertices.slice(0));

        if (this.verticesIndices)
        {
            geom.verticesIndices.length = this.verticesIndices.length;
            for (let i = 0; i < this.verticesIndices.length; i++) geom.verticesIndices[i] = this.verticesIndices[i];
        }

        for (let i in this._attributes) this.copyAttribute(i, geom);

        geom.morphTargets.length = this.morphTargets.length;
        for (let i = 0; i < this.morphTargets.length; i++) geom.morphTargets[i] = this.morphTargets[i];

        return geom;
    }

    /**
     * Calculaten normals
     * @function calculateNormals
     * @param {{ smooth?: any; forceZUp?: any; }} options
     */
    calculateNormals(options = null)
    {
        // todo: should check angle of normals to get edges    https://community.khronos.org/t/calculating-accurate-vertex-normals/28152
        options = options || {};
        if (options.smooth === false) this.unIndex();

        const u = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();
        const v = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();
        const n = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();

        function calcNormal(triangle)
        {
            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.subtract(u, triangle[0], triangle[1]);
            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.subtract(v, triangle[0], triangle[2]);
            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.cross(n, u, v);
            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.normalize(n, n);

            if (options && options.forceZUp)
            {
                if (n[2] < 0)
                {
                    n[0] *= -1;
                    n[1] *= -1;
                    n[2] *= -1;
                }
            }
            return n;
        }

        this.getVertexVec = function (which)
        {
            const vec = [0, 0, 0];
            vec[0] = this.vertices[which * 3 + 0];
            vec[1] = this.vertices[which * 3 + 1];
            vec[2] = this.vertices[which * 3 + 2];
            return vec;
        };

        if (!(this.vertexNormals instanceof Float32Array) || this.vertexNormals.length != this.vertices.length) this.vertexNormals = new Float32Array(this.vertices.length);

        for (let i = 0; i < this.vertices.length; i++)
        {
            this.vertexNormals[i] = 0;
        }

        if (!this.isIndexed())
        {
            const norms = [];
            for (let i = 0; i < this.vertices.length; i += 9)
            {
                const triangle = [[this.vertices[i + 0], this.vertices[i + 1], this.vertices[i + 2]], [this.vertices[i + 3], this.vertices[i + 4], this.vertices[i + 5]], [this.vertices[i + 6], this.vertices[i + 7], this.vertices[i + 8]]];
                const nn = calcNormal(triangle);
                norms.push(nn[0], nn[1], nn[2], nn[0], nn[1], nn[2], nn[0], nn[1], nn[2]);
            }
            this.vertexNormals = norms;
        }
        else
        {
            const faceNormals = [];

            faceNormals.length = Math.floor(this.verticesIndices.length / 3);

            for (let i = 0; i < this.verticesIndices.length; i += 3)
            {
                const triangle = [this.getVertexVec(this.verticesIndices[i + 0]), this.getVertexVec(this.verticesIndices[i + 1]), this.getVertexVec(this.verticesIndices[i + 2])];

                faceNormals[i / 3] = calcNormal(triangle);

                this.vertexNormals[this.verticesIndices[i + 0] * 3 + 0] += faceNormals[i / 3][0];
                this.vertexNormals[this.verticesIndices[i + 0] * 3 + 1] += faceNormals[i / 3][1];
                this.vertexNormals[this.verticesIndices[i + 0] * 3 + 2] += faceNormals[i / 3][2];

                this.vertexNormals[this.verticesIndices[i + 1] * 3 + 0] += faceNormals[i / 3][0];
                this.vertexNormals[this.verticesIndices[i + 1] * 3 + 1] += faceNormals[i / 3][1];
                this.vertexNormals[this.verticesIndices[i + 1] * 3 + 2] += faceNormals[i / 3][2];

                this.vertexNormals[this.verticesIndices[i + 2] * 3 + 0] += faceNormals[i / 3][0];
                this.vertexNormals[this.verticesIndices[i + 2] * 3 + 1] += faceNormals[i / 3][1];
                this.vertexNormals[this.verticesIndices[i + 2] * 3 + 2] += faceNormals[i / 3][2];
            }

            for (let i = 0; i < this.verticesIndices.length; i += 3) // faces
            {
                for (let k = 0; k < 3; k++) // triangles
                {
                    const vv = [this.vertexNormals[this.verticesIndices[i + k] * 3 + 0], this.vertexNormals[this.verticesIndices[i + k] * 3 + 1], this.vertexNormals[this.verticesIndices[i + k] * 3 + 2]];
                    gl_matrix__WEBPACK_IMPORTED_MODULE_1__.normalize(vv, vv);
                    this.vertexNormals[this.verticesIndices[i + k] * 3 + 0] = vv[0];
                    this.vertexNormals[this.verticesIndices[i + k] * 3 + 1] = vv[1];
                    this.vertexNormals[this.verticesIndices[i + k] * 3 + 2] = vv[2];
                }
            }
        }
    }

    /**
     * Calculates tangents & bitangents with the help of uv-coordinates. Adapted from
     * Lengyel, Eric. “Computing Tangent Space Basis Vectors for an Arbitrary Mesh”.
     * Terathon Software 3D Graphics Library.
     * https://fenix.tecnico.ulisboa.pt/downloadFile/845043405449073/Tangent%20Space%20Calculation.pdf
     *
     * @function calcTangentsBitangents
     */
    calcTangentsBitangents()
    {
        if (!this.vertices.length)
        {
            // this._log.error("Cannot calculate tangents/bitangents without vertices.");
            return;
        }
        if (!this.vertexNormals.length)
        {
            // this._log.error("Cannot calculate tangents/bitangents without normals.");
            return;
        }
        if (!this.texCoords.length)
        {
            const texCoordLength = (this.vertices.length / 3) * 2;
            this.texCoords = new Float32Array(texCoordLength);
            for (let i = 0; i < texCoordLength; i += 1) this.texCoords[i] = 0;
        }
        if (!this.verticesIndices || !this.verticesIndices.length)
        {
            // this._log.error("Cannot calculate tangents/bitangents without vertex indices.");
            return;
        }
        // this code assumes that we have three indices per triangle
        if (this.verticesIndices.length % 3 !== 0)
        {
            this._log.error("Vertex indices mismatch!");
            return;
        }

        const triangleCount = this.verticesIndices.length / 3;
        const vertexCount = this.vertices.length / 3;

        this.tangents = new Float32Array(this.vertexNormals.length);
        this.biTangents = new Float32Array(this.vertexNormals.length);

        // temporary buffers
        const tempVertices = [];
        tempVertices.length = vertexCount * 2;
        const v1 = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();
        const v2 = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();
        const v3 = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();

        const w1 = gl_matrix__WEBPACK_IMPORTED_MODULE_3__.create();
        const w2 = gl_matrix__WEBPACK_IMPORTED_MODULE_3__.create();
        const w3 = gl_matrix__WEBPACK_IMPORTED_MODULE_3__.create();

        const sdir = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();
        const tdir = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();

        // for details on calculation, see article referenced above
        for (let tri = 0; tri < triangleCount; tri += 1)
        {
            // indices of the three vertices for a triangle
            const i1 = this.verticesIndices[tri * 3];
            const i2 = this.verticesIndices[tri * 3 + 1];
            const i3 = this.verticesIndices[tri * 3 + 2];

            // vertex position as vec3
            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.set(v1, this.vertices[i1 * 3], this.vertices[i1 * 3 + 1], this.vertices[i1 * 3 + 2]);
            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.set(v2, this.vertices[i2 * 3], this.vertices[i2 * 3 + 1], this.vertices[i2 * 3 + 2]);
            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.set(v3, this.vertices[i3 * 3], this.vertices[i3 * 3 + 1], this.vertices[i3 * 3 + 2]);

            // texture coordinate as vec2
            gl_matrix__WEBPACK_IMPORTED_MODULE_3__.set(w1, this.texCoords[i1 * 2], this.texCoords[i1 * 2 + 1]);
            gl_matrix__WEBPACK_IMPORTED_MODULE_3__.set(w2, this.texCoords[i2 * 2], this.texCoords[i2 * 2 + 1]);
            gl_matrix__WEBPACK_IMPORTED_MODULE_3__.set(w3, this.texCoords[i3 * 2], this.texCoords[i3 * 2 + 1]);

            const x1 = v2[0] - v1[0];
            const x2 = v3[0] - v1[0];
            const y1 = v2[1] - v1[1];
            const y2 = v3[1] - v1[1];
            const z1 = v2[2] - v1[2];
            const z2 = v3[2] - v1[2];

            const s1 = w2[0] - w1[0];
            const s2 = w3[0] - w1[0];
            const t1 = w2[1] - w1[1];
            const t2 = w3[1] - w1[1];

            const r = 1.0 / (s1 * t2 - s2 * t1);

            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.set(sdir, (t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.set(tdir, (s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);

            tempVertices[i1] = sdir;
            tempVertices[i2] = sdir;
            tempVertices[i3] = sdir;

            tempVertices[i1 + vertexCount] = tdir;
            tempVertices[i2 + vertexCount] = tdir;
            tempVertices[i3 + vertexCount] = tdir;
        }

        const normal = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();
        const tempVert = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();
        const tan = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();
        const bitan = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();
        const temp1 = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();
        const temp2 = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();
        const crossPd = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();
        const normalized = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.create();

        for (let vert = 0; vert < vertexCount; vert += 1)
        {
            // NOTE: some meshes don't have index 0 - n in their indexbuffer, if this is the case, skip calculation of this vertex
            if (!tempVertices[vert]) continue;

            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.set(normal, this.vertexNormals[vert * 3], this.vertexNormals[vert * 3 + 1], this.vertexNormals[vert * 3 + 2]);
            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.set(tempVert, tempVertices[vert][0], tempVertices[vert][1], tempVertices[vert][2]);

            // Gram-Schmidt orthagonalize
            const _dp = gl_matrix__WEBPACK_IMPORTED_MODULE_1__.dot(normal, tempVert);
            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.scale(temp1, normal, _dp);
            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.subtract(temp2, tempVert, temp1);

            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.normalize(normalized, temp2);
            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.cross(crossPd, normal, tempVert);

            // const intermDot = vec3.dot(crossPd, tempVertices[vert + vertexCount]);
            const w = 1.0;// intermDot < 0.0 ? -1.0 : 1.0;

            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.scale(tan, normalized, 1 / w);
            gl_matrix__WEBPACK_IMPORTED_MODULE_1__.cross(bitan, normal, tan);

            this.tangents[vert * 3 + 0] = tan[0];
            this.tangents[vert * 3 + 1] = tan[1];
            this.tangents[vert * 3 + 2] = tan[2];
            this.biTangents[vert * 3 + 0] = bitan[0];
            this.biTangents[vert * 3 + 1] = bitan[1];
            this.biTangents[vert * 3 + 2] = bitan[2];
        }
    }

    isIndexed()
    {
        if (this._vertices.length == 0) return true;
        return this.verticesIndices.length != 0;
    }

    /**
     * @function unIndex
     * @memberof Geometry
     * @instance
     * @description remove all vertex indizes, vertices array will contain 3*XYZ for every triangle
     * @param {boolean} reIndex
     * @param {boolean} dontCalcNormals
     */
    unIndex(reIndex = false, dontCalcNormals = false)
    {
        const newVerts = [];
        const newIndizes = [];
        let count = 0;

        for (let j in this._attributes)
        {
            const attr = this._attributes[j];
            let na = [];

            for (let i = 0; i < this.verticesIndices.length; i += 3)
            {
                for (let s = 0; s < 3; s++)
                {
                    if (attr.itemSize == 3)
                        na.push(
                            attr.data[this.verticesIndices[i + s] * 3 + 0],
                            attr.data[this.verticesIndices[i + s] * 3 + 1],
                            attr.data[this.verticesIndices[i + s] * 3 + 2]);
                    else if (attr.itemSize == 4)
                        na.push(
                            attr.data[this.verticesIndices[i + s] * 4 + 0],
                            attr.data[this.verticesIndices[i + s] * 4 + 1],
                            attr.data[this.verticesIndices[i + s] * 4 + 2],
                            attr.data[this.verticesIndices[i + s] * 4 + 3]);
                    else if (attr.itemSize == 2)
                        na.push(
                            attr.data[this.verticesIndices[i + s] * 2 + 0],
                            attr.data[this.verticesIndices[i + s] * 2 + 1]);
                    else if (attr.itemSize == 1)
                        na.push(
                            attr.data[this.verticesIndices[i + s]]);
                    else this._log.warn("unknown attr", attr);
                }
            }
            this.setAttribute(attr.name, na, attr.itemSize);
        }

        for (let i = 0; i < this.verticesIndices.length; i += 3)
        {
            newVerts.push(
                this.vertices[this.verticesIndices[i + 0] * 3 + 0],
                this.vertices[this.verticesIndices[i + 0] * 3 + 1],
                this.vertices[this.verticesIndices[i + 0] * 3 + 2]);

            newIndizes.push(count);
            count++;

            newVerts.push(
                this.vertices[this.verticesIndices[i + 1] * 3 + 0],
                this.vertices[this.verticesIndices[i + 1] * 3 + 1],
                this.vertices[this.verticesIndices[i + 1] * 3 + 2]);

            newIndizes.push(count);
            count++;

            newVerts.push(
                this.vertices[this.verticesIndices[i + 2] * 3 + 0],
                this.vertices[this.verticesIndices[i + 2] * 3 + 1],
                this.vertices[this.verticesIndices[i + 2] * 3 + 2]);

            newIndizes.push(count);
            count++;
        }

        this.vertices = newVerts;

        this.verticesIndices = [];
        if (reIndex) this.verticesIndices = newIndizes;

        if (!dontCalcNormals) this.calculateNormals();
    }

    calcBarycentric()
    {
        let barycentrics = [];
        barycentrics.length = this.vertices.length;
        for (let i = 0; i < this.vertices.length; i++) barycentrics[i] = 0;

        let count = 0;
        for (let i = 0; i < this.vertices.length; i += 3)
        {
            barycentrics[i + count] = 1;
            count++;
            if (count == 3) count = 0;
        }

        this.setAttribute("attrBarycentric", barycentrics, 3);
    }

    getBounds()
    {
        return new _cg_boundingbox_js__WEBPACK_IMPORTED_MODULE_4__/* .BoundingBox */ .I(this);
    }

    /**
     * @param {boolean} x
     * @param {boolean} y
     * @param {boolean} z
     * @returns {Array} offset
     */
    center(x, y, z)
    {
        if (x === undefined)
        {
            x = true;
            y = true;
            z = true;
        }

        let i = 0;
        const bounds = this.getBounds();
        const offset = [bounds.minX + (bounds.maxX - bounds.minX) / 2, bounds.minY + (bounds.maxY - bounds.minY) / 2, bounds.minZ + (bounds.maxZ - bounds.minZ) / 2];

        for (i = 0; i < this.vertices.length; i += 3)
        {
            if (this.vertices[i + 0] == this.vertices[i + 0])
            {
                if (x) this.vertices[i + 0] -= offset[0];
                if (y) this.vertices[i + 1] -= offset[1];
                if (z) this.vertices[i + 2] -= offset[2];
            }
        }

        return offset;
    }

    mapTexCoords2d()
    {
        const bounds = this.getBounds();
        const num = this.vertices.length / 3;

        this.texCoords = new Float32Array(num * 2);

        for (let i = 0; i < num; i++)
        {
            const vertX = this.vertices[i * 3 + 0];
            const vertY = this.vertices[i * 3 + 1];
            this.texCoords[i * 2 + 0] = vertX / (bounds.maxX - bounds.minX) + 0.5;
            this.texCoords[i * 2 + 1] = 1.0 - vertY / (bounds.maxY - bounds.minY) + 0.5;
        }
    }

    getInfoOneLine()
    {
        let txt = "";
        if (this.faceVertCount == 3 && this.verticesIndices)txt += this.verticesIndices.length / 3;
        else txt += 0;

        txt += " tris ";

        if (this.vertices)txt += this.vertices.length / 3;
        else txt += 0;

        txt += " verts";

        return txt;
    }

    getInfo()
    {
        const info = {};

        info.name = this.name;
        info.class = this.constructor.name;

        if (this.faceVertCount == 3 && this.verticesIndices)info.numFaces = this.verticesIndices.length / 3;
        else info.numFaces = 0;

        if (this.verticesIndices && this.verticesIndices.length)info.indices = this.verticesIndices.length;

        if (this.vertices)info.numVerts = this.vertices.length / 3;
        else info.numVerts = 0;

        if (this.vertexNormals) info.numNormals = this.vertexNormals.length / 3;
        else info.numNormals = 0;

        if (this.texCoords) info.numTexCoords = this.texCoords.length / 2;
        else info.numTexCoords = 0;

        if (this.tangents) info.numTangents = this.tangents.length / 3;
        else info.numTangents = 0;

        if (this.biTangents) info.numBiTangents = this.biTangents.length / 3;
        else info.numBiTangents = 0;

        if (this.biTangents) info.numBiTangents = this.biTangents.length / 3;
        else info.numBiTangents = 0;

        if (this.vertexColors) info.numVertexColors = this.vertexColors.length / 4;
        else info.numVertexColors = 0;

        if (this.getAttributes()) info.numAttribs = Object.keys(this.getAttributes()).length;
        else info.numAttribs = 0;

        info.isIndexed = this.isIndexed();

        return info;
    }

    // -----------------
}

// TODO : rewritwe circle op 1
/** @deprecated */
Geometry.buildFromFaces = function (arr, name, optimize)
{
    const vertices = [];
    const verticesIndices = [];

    for (let i = 0; i < arr.length; i += 3)
    {
        const a = arr[i + 0];
        const b = arr[i + 1];
        const c = arr[i + 2];
        const face = [-1, -1, -1];

        if (optimize)
            for (let iv = 0; iv < vertices.length; iv += 3)
            {
                if (vertices[iv + 0] == a[0] && vertices[iv + 1] == a[1] && vertices[iv + 2] == a[2]) face[0] = iv / 3;
                if (vertices[iv + 0] == b[0] && vertices[iv + 1] == b[1] && vertices[iv + 2] == b[2]) face[1] = iv / 3;
                if (vertices[iv + 0] == c[0] && vertices[iv + 1] == c[1] && vertices[iv + 2] == c[2]) face[2] = iv / 3;
            }

        if (face[0] == -1)
        {
            vertices.push(a[0], a[1], a[2]);
            face[0] = (vertices.length - 1) / 3;
        }

        if (face[1] == -1)
        {
            vertices.push(b[0], b[1], b[2]);
            face[1] = (vertices.length - 1) / 3;
        }

        if (face[2] == -1)
        {
            vertices.push(c[0], c[1], c[2]);
            face[2] = (vertices.length - 1) / 3;
        }

        verticesIndices.push(face[0]);
        verticesIndices.push(face[1]);
        verticesIndices.push(face[2]);
    }

    const geom = new Geometry(name);
    geom.name = name;
    geom.vertices = vertices;
    geom.verticesIndices = verticesIndices;

    return geom;
};


/***/ }),

/***/ 868:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   u: () => (/* binding */ MatrixStack)
/* harmony export */ });
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(684);


class MatrixStack
{
    constructor()
    {
        this._arr = [gl_matrix__WEBPACK_IMPORTED_MODULE_0__.create()];
        this._index = 0;
        this.stateCounter = 0;
    }

    /**
     * @param {mat4} m
     */
    push(m)
    {
        this._index++;
        this.stateCounter++;

        if (this._index == this._arr.length)
        {
            const copy = gl_matrix__WEBPACK_IMPORTED_MODULE_0__.create();
            this._arr.push(copy);
        }

        gl_matrix__WEBPACK_IMPORTED_MODULE_0__.copy(this._arr[this._index], m || this._arr[this._index - 1]);

        return this._arr[this._index];
    }

    pop()
    {
        this.stateCounter++;

        this._index--;
        if (this._index < 0) this._index = 0;

        return this._arr[this._index];
    }

    length()
    {
        return this._index;
    }
}


/***/ }),

/***/ 434:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   w: () => (/* binding */ CgMesh)
/* harmony export */ });
class CgMesh
{
    _name = "unknown";

    constructor()
    {
    }

}


/***/ }),

/***/ 694:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   U: () => (/* binding */ CgShader)
/* harmony export */ });
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(125);
/* harmony import */ var cables__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(562);



/**
 * @typedef ShaderModule
 * @property {String} title
 * @property {String} name
 * @property {Number} id
 * @property {Number} numId
 * @property {String} group
 * @property {String} prefix
 * @property {Number} priority
 * @property {Number} num
 * @property {String} attributes
 * @property {String} srcBodyFrag
 * @property {String} srcBodyVert
 * @property {String} srcHeadFrag
 * @property {String} srcHeadVert
  */

class CgShader extends cables_shared_client__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A
{
    id = cables__WEBPACK_IMPORTED_MODULE_1__.simpleId();
    _isValid = true;

    /** @type {Array<Array<String>>} */
    _defines = [];

    /** @type {Array<String>} */
    _moduleNames = [];

    _moduleNumId = 0;
    _needsRecompile = true;
    _compileReason = "initial";

    /** @type {Array<ShaderModule>} */
    _modules = [];

    _compileCount = 0;

    logError = true;
    num = -1;
    lastCompile = 0;

    constructor()
    {
        super();
    }

    /**
     * @param {string} reason
     */
    setWhyCompile(reason)
    {
        this._compileReason = reason;
        this._needsRecompile = true;
    }

    getWhyCompile()
    {
        return this._compileReason;
    }

    needsRecompile()
    {
        return this._needsRecompile;
    }

    /**
     * @param {string} name
     */
    removeUniform(name)
    {
        for (let i = 0; i < this._uniforms.length; i++)
        {
            if (this._uniforms[i].getName() == name)
            {
                this._uniforms.splice(i, 1);
            }
        }
        this.setWhyCompile("remove uniform " + name);
    }

    /**
     * @param {String} name
     * @param {number} stage
     */
    hasUniformInStage(name, stage)
    {

        let binding = this.defaultUniBindingFrag;
        if (stage == GPUShaderStage.VERTEX) binding = this.defaultUniBindingVert;
        if (stage == GPUShaderStage.COMPUTE) binding = this.defaultUniBindingCompute;

        for (let i = 0; i < this._uniforms.length; i++)
        {

            console.log("hasuniiiiiiiiiiiiiii", this._uniforms[i].getName(), name);
            if (this._uniforms[i].getName() == name) return true;
        }
        return false;
    }

    /**
     * @param {String} name
     */
    hasUniform(name)
    {
    }

    /**
     * easily enable/disable a define without a value
     * @param {String} name
     * @param {Port|boolean} enabled value or port
     */
    toggleDefine(name, enabled)
    {
        if (enabled && typeof (enabled) == "object" && enabled.addEventListener) // port
        {
            if (enabled.changeListener)enabled.off(enabled.changeListener);

            enabled.onToggleDefine = (v) =>
            {
                this.toggleDefine(name, v);
            };

            enabled.changeListener = enabled.on("change", enabled.onToggleDefine);
            enabled = enabled.get();
        }

        if (enabled) this.define(name);
        else this.removeDefine(name);
    }

    /**
     * add a define to a shader, e.g.  #define DO_THIS_THAT 1
     * @param {String} name
     * @param {any} value (can be empty)
     */
    define(name, value = "")
    {
        if (value === null || value === undefined) value = "";

        if (typeof (value) == "object") // port
        {
            value.removeEventListener("change", value.onDefineChange);
            value.onDefineChange = (v) =>
            {
                this.define(name, v);
            };
            value.on("change", value.onDefineChange);

            value = value.get();
        }

        for (let i = 0; i < this._defines.length; i++)
        {
            if (this._defines[i][0] == name && this._defines[i][1] == value) return;
            if (this._defines[i][0] == name)
            {
                this._defines[i][1] = value;
                this.setWhyCompile("define " + name + " " + value);
                return;
            }
        }
        this.setWhyCompile("define " + name + " " + value);

        this._defines.push([name, value]);
    }

    getDefines()
    {
        return this._defines;
    }

    /**
     * @param {string} name
     */
    getDefine(name)
    {
        for (let i = 0; i < this._defines.length; i++)
            if (this._defines[i][0] == name) return this._defines[i][1];
        return null;
    }

    /**
     * return true if shader has define
     * @function hasDefine
     * @memberof Shader
     * @instance
     * @param {String} name
     * @return {Boolean}
     */
    hasDefine(name)
    {
        for (let i = 0; i < this._defines.length; i++)
            if (this._defines[i][0] == name) return true;
    }

    /**
     * remove a define from a shader
     * @param {string} name
     */
    removeDefine(name)
    {
        for (let i = 0; i < this._defines.length; i++)
        {
            if (this._defines[i][0] == name)
            {
                this._defines.splice(i, 1);
                this.setWhyCompile("define removed:" + name);
                return;
            }
        }
    }

    /**
     * @param {any} modId
     */
    hasModule(modId)
    {
        for (let i = 0; i < this._modules.length; i++)
            if (this._modules[i].id == modId) return true;

        return false;
    }

    /**
     *
     * @param {Array<String>} names
     */
    setModules(names)
    {
        this._moduleNames = names;
    }

    /**
     * remove a module from shader
     * @param {ShaderModule} mod the module to be removed
     */
    removeModule(mod)
    {
        for (let i = 0; i < this._modules.length; i++)
        {
            if (mod && mod.id)
            {
                if (this._modules[i].id == mod.id || !this._modules[i])
                {
                    let found = true;
                    while (found)
                    {
                        found = false;
                        for (let j = 0; j < this._uniforms.length; j++)
                        {
                            if (this._uniforms[j].getName().startsWith(mod.prefix))
                            {
                                this._uniforms.splice(j, 1);
                                found = true;
                                continue;
                            }
                        }
                    }

                    this.setWhyCompile("remove module " + mod.title);
                    this._modules.splice(i, 1);
                    break;
                }
            }
        }
    }

    getNumModules()
    {
        return this._modules.length;
    }

    getCurrentModules() { return this._modules; }

    /**
     * add a module
     * @param {ShaderModule} mod the module to be added
     * @param {ShaderModule} [sibling] sibling module, new module will share the same group
     */
    addModule(mod, sibling)
    {
        if (this.hasModule(mod.id)) return;
        if (!mod.id) mod.id = cables__WEBPACK_IMPORTED_MODULE_1__.simpleId();
        if (!mod.numId) mod.numId = this._moduleNumId;
        if (!mod.num)mod.num = this._modules.length;
        if (sibling && !sibling.group) sibling.group = cables__WEBPACK_IMPORTED_MODULE_1__.simpleId();

        if (!mod.group)
            if (sibling) mod.group = sibling.group;
            else mod.group = cables__WEBPACK_IMPORTED_MODULE_1__.simpleId();

        mod.prefix = "mod" + mod.group + "_";
        this._modules.push(mod);

        this.setWhyCompile("add module " + mod.title);
        this._moduleNumId++;

        return mod;
    }

    isValid()
    {
        return this._isValid;
    }

}


/***/ }),

/***/ 356:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   U: () => (/* binding */ CgTexture)
/* harmony export */ });
/* harmony import */ var cables__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(562);


const DEFAULT_TEXTURE_SIZE = 8;

/**
 * @typedef {Object} CglTextureOptions
 * @property {number} [width]
 * @property {number} [height]
 * @property {string} [pixelformat]
 */
class CgTexture
{

    /**
     * @param {CglTextureOptions} options={}
     */
    constructor(options = {})
    {
        this.id = cables__WEBPACK_IMPORTED_MODULE_0__.uuid();
        this.width = 0;
        this.height = 0;
        this.name = "unknown";

        options = options || {};
        this.pixelFormat = options.pixelFormat || CgTexture.PFORMATSTR_RGBA8UB;

        this.name = options.name || "unknown";

        if (!options.width) options.width = DEFAULT_TEXTURE_SIZE;
        if (!options.height) options.height = DEFAULT_TEXTURE_SIZE;
    }
}

CgTexture.getDefaultTextureData = (name, size, options = {}) =>
{
    if (name == "empty")
    {
        return new Uint8Array(size * size * 4).fill(0);
    }
    else
    if (name == "color")
    {
        const data = new Uint8Array(size * size * 4);
        let r = options.r || 1;
        let g = options.g || 1;
        let b = options.b || 1;

        for (let x = 0; x < size * size; x++)
        {
            data[x * 4 + 0] = r;
            data[x * 4 + 1] = g;
            data[x * 4 + 2] = b;
            data[x * 4 + 3] = 255;
        }
        return data;
    }
    else
    if (name == "randomUInt")
    {
        const data = new Uint8Array(size * size * 4);

        for (let x = 0; x < size * size; x++)
        {
            data[x * 4 + 0] = Math.random() * 255;
            data[x * 4 + 1] = Math.random() * 255;
            data[x * 4 + 2] = Math.random() * 255;
            data[x * 4 + 3] = 255;
        }
        return data;
    }
    else
    if (name == "random" || name == "randomFloat")
    {
        const data = new Float32Array(size * size * 4);

        for (let x = 0; x < size * size; x++)
        {
            data[x * 4 + 0] = (Math.random() - 0.5) * 2.0;
            data[x * 4 + 1] = (Math.random() - 0.5) * 2.0;
            data[x * 4 + 2] = (Math.random() - 0.5) * 2.0;
            data[x * 4 + 3] = 1;
        }
        return data;
    }
    else
    if (name == "stripes")
    {
        const arr = [];

        let r = options.r;
        let g = options.g;
        let b = options.b;

        if (r === undefined)r = 1;
        if (g === undefined)g = 1;
        if (b === undefined)b = 1;

        for (let y = 0; y < size; y++)
        {
            for (let x = 0; x < size; x++)
            {
                if ((x + y) % 64 < 32)
                {
                    arr.push((200 + (y / size) * 25 + (x / size) * 25) * r);
                    arr.push((200 + (y / size) * 25 + (x / size) * 25) * g);
                    arr.push((200 + (y / size) * 25 + (x / size) * 25) * b);
                }
                else
                {
                    arr.push((40 + (y / size) * 25 + (x / size) * 25) * r);
                    arr.push((40 + (y / size) * 25 + (x / size) * 25) * g);
                    arr.push((40 + (y / size) * 25 + (x / size) * 25) * b);
                }
                arr.push(255);
            }
        }

        return new Uint8Array(arr);
    }
    else
    {
        console.warn("unknown default texture", name);
        return CgTexture.getDefaultTextureData("stripes", size, { "r": 1, "g": 0, "b": 0 });
    }
};

CgTexture.FILTER_NEAREST = 0;
CgTexture.FILTER_LINEAR = 1;
CgTexture.FILTER_MIPMAP = 2;

CgTexture.WRAP_REPEAT = 0;
CgTexture.WRAP_MIRRORED_REPEAT = 1;
CgTexture.WRAP_CLAMP_TO_EDGE = 2;

CgTexture.TYPE_DEFAULT = 0;
CgTexture.TYPE_DEPTH = 1;
CgTexture.TYPE_FLOAT = 2;

CgTexture.PFORMATSTR_RGB565 = "RGB 5/6/5bit ubyte";

CgTexture.PFORMATSTR_R8UB = "R 8bit ubyte";
CgTexture.PFORMATSTR_RG8UB = "RG 8bit ubyte";
CgTexture.PFORMATSTR_RGB8UB = "RGB 8bit ubyte";
CgTexture.PFORMATSTR_RGBA8UB = "RGBA 8bit ubyte";

CgTexture.PFORMATSTR_SRGBA8 = "SRGBA 8bit ubyte";

CgTexture.PFORMATSTR_R11FG11FB10F = "RGB 11/11/10bit float";

CgTexture.PFORMATSTR_R16F = "R 16bit float";
CgTexture.PFORMATSTR_RG16F = "RG 16bit float";
CgTexture.PFORMATSTR_RGB16F = "RGB 16bit float";
CgTexture.PFORMATSTR_RGBA16F = "RGBA 16bit float";

CgTexture.PFORMATSTR_R32F = "R 32bit float";
CgTexture.PFORMATSTR_RG32F = "RG 32bit float";
CgTexture.PFORMATSTR_RGB32F = "RGB 32bit float";
CgTexture.PFORMATSTR_RGBA32F = "RGBA 32bit float";

CgTexture.PFORMATSTR_DEPTH = "DEPTH";

CgTexture.PIXELFORMATS = [

    CgTexture.PFORMATSTR_RGB565,

    CgTexture.PFORMATSTR_R8UB,
    CgTexture.PFORMATSTR_RG8UB,
    CgTexture.PFORMATSTR_RGB8UB,
    CgTexture.PFORMATSTR_RGBA8UB,

    CgTexture.PFORMATSTR_SRGBA8,

    CgTexture.PFORMATSTR_R11FG11FB10F,
    CgTexture.PFORMATSTR_R16F,
    CgTexture.PFORMATSTR_RG16F,
    CgTexture.PFORMATSTR_RGBA16F,

    CgTexture.PFORMATSTR_R32F,
    CgTexture.PFORMATSTR_RGBA32F

];


/***/ }),

/***/ 475:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   v: () => (/* binding */ CgUniform)
/* harmony export */ });
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(849);
/* harmony import */ var cables__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(50);




class CgUniform
{

    /**
     * Description
     * @param {CgShader|CgpShader|Shader} __shader
     * @param {string} __type
     * @param {string} __name
     * @param {Number|Port} _value
     * @param {Port} _port2
     * @param {Port} _port3
     * @param {Port} _port4
     */
    constructor(__shader, __type, __name, _value, _port2, _port3, _port4, _structUniformName, _structName, _propertyName)
    {
        this._log = new cables_shared_client__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A("cg_uniform");
        this._type = __type;
        this._name = __name;

        /** @type {CgShader} */
        this._shader = __shader;
        this._value = 0.00001;
        this._oldValue = null;
        this._port = null;

        this._structName = _structName;
        this._structUniformName = _structUniformName;
        this._propertyName = _propertyName;

        if (this._shader._addUniform) this._shader._addUniform(this);
        this.needsUpdate = true;
        this.shaderType = null;
        this.comment = null;

        if (__type == "f")
        {
            this.set = this.setValue = this.setValueF.bind(this);
            this.updateValue = this.updateValueF.bind(this);
        }
        else if (__type == "f[]")
        {
            this.set = this.setValue = this.setValueArrayF.bind(this);
            this.updateValue = this.updateValueArrayF.bind(this);
        }
        else if (__type == "2f[]")
        {
            this.set = this.setValue = this.setValueArray2F.bind(this);
            this.updateValue = this.updateValueArray2F.bind(this);
        }
        else if (__type == "3f[]")
        {
            this.set = this.setValue = this.setValueArray3F.bind(this);
            this.updateValue = this.updateValueArray3F.bind(this);
        }
        else if (__type == "4f[]")
        {
            this.set = this.setValue = this.setValueArray4F.bind(this);
            this.updateValue = this.updateValueArray4F.bind(this);
        }
        else if (__type == "i")
        {
            this.set = this.setValue = this.setValueI.bind(this);
            this.updateValue = this.updateValueI.bind(this);
        }
        else if (__type == "2i")
        {
            this.set = this.setValue = this.setValue2I.bind(this);
            this.updateValue = this.updateValue2I.bind(this);
        }
        else if (__type == "3i")
        {
            this.set = this.setValue = this.setValue3I.bind(this);
            this.updateValue = this.updateValue3I.bind(this);
        }
        else if (__type == "4i")
        {
            this.set = this.setValue = this.setValue4I.bind(this);
            this.updateValue = this.updateValue4I.bind(this);
        }
        else if (__type == "b")
        {
            this.set = this.setValue = this.setValueBool.bind(this);
            this.updateValue = this.updateValueBool.bind(this);
        }
        else if (__type == "4f")
        {
            this.set = this.setValue = this.setValue4F.bind(this);
            this.updateValue = this.updateValue4F.bind(this);
        }
        else if (__type == "3f")
        {
            this.set = this.setValue = this.setValue3F.bind(this);
            this.updateValue = this.updateValue3F.bind(this);
        }
        else if (__type == "2f")
        {
            this.set = this.setValue = this.setValue2F.bind(this);
            this.updateValue = this.updateValue2F.bind(this);
        }
        else if (__type == "t")
        {
            this.set = this.setValue = this.setValueT.bind(this);
            this.updateValue = this.updateValueT.bind(this);
        }
        else if (__type == "sampler")
        {
            if (this.setValueAny)
            {
                this.set = this.setValue = this.setValueAny.bind(this);
                this.updateValue = this.updateValueAny.bind(this);
            }
        }
        else if (__type == "tc")
        {
            this.set = this.setValue = this.setValueT.bind(this);
            this.updateValue = this.updateValueT.bind(this);
        }
        else if (__type == "t[]")
        {
            this.set = this.setValue = this.setValueArrayT.bind(this);
            this.updateValue = this.updateValueArrayT.bind(this);
        }
        else if (__type == "m4" || __type == "m4[]")
        {
            this.set = this.setValue = this.setValueM4.bind(this);
            this.updateValue = this.updateValueM4.bind(this);
        }
        else
        {
            // console.error("unknown");
            this._log.error("Unknown uniform type " + __type, __name, typeof this._shader);
        }

        if (typeof _value == "object" && _value instanceof cables__WEBPACK_IMPORTED_MODULE_1__/* .Port */ .I)
        {
            this._port = _value;
            this._value = this._port.get();

            if (_port2 && _port3 && _port4)
            {
                if (!(_port2 instanceof cables__WEBPACK_IMPORTED_MODULE_1__/* .Port */ .I) || !(_port3 instanceof cables__WEBPACK_IMPORTED_MODULE_1__/* .Port */ .I) || !(_port4 instanceof cables__WEBPACK_IMPORTED_MODULE_1__/* .Port */ .I))
                {
                    this._log.error("[cgl_uniform] mixed port/value parameter for vec4 ", this._name);
                }

                this._value = [0, 0, 0, 0];
                this._port2 = _port2;
                this._port3 = _port3;
                this._port4 = _port4;

                this._port.on("change", this.updateFromPort4f.bind(this));
                this._port2.on("change", this.updateFromPort4f.bind(this));
                this._port3.on("change", this.updateFromPort4f.bind(this));
                this._port4.on("change", this.updateFromPort4f.bind(this));

                // this._port.onChange = this._port2.onChange = this._port3.onChange = this._port4.onChange = this.updateFromPort4f.bind(this);
                this.updateFromPort4f();
            }
            else if (_port2 && _port3)
            {
                if (!(_port2 instanceof cables__WEBPACK_IMPORTED_MODULE_1__/* .Port */ .I) || !(_port3 instanceof cables__WEBPACK_IMPORTED_MODULE_1__/* .Port */ .I))
                {
                    this._log.error("[cgl_uniform] mixed port/value parameter for vec4 ", this._name);
                }

                this._value = [0, 0, 0];
                this._port2 = _port2;
                this._port3 = _port3;
                // this._port.onChange = this._port2.onChange = this._port3.onChange = this.updateFromPort3f.bind(this);
                this._port.on("change", this.updateFromPort3f.bind(this));
                this._port2.on("change", this.updateFromPort3f.bind(this));
                this._port3.on("change", this.updateFromPort3f.bind(this));

                this.updateFromPort3f();
            }
            else if (_port2)
            {
                if (!(_port2 instanceof cables__WEBPACK_IMPORTED_MODULE_1__/* .Port */ .I))
                {
                    this._log.error("[cgl_uniform] mixed port/value parameter for vec4 ", this._name);
                }

                this._value = [0, 0];
                this._port2 = _port2;
                // this._port.onChange = this._port2.onChange = this.updateFromPort2f.bind(this);
                this._port.on("change", this.updateFromPort2f.bind(this));
                this._port2.on("change", this.updateFromPort2f.bind(this));

                this.updateFromPort2f();
            }
            else
            {
                // this._port.on = this.updateFromPort.bind(this);
                this._port.on("change", this.updateFromPort.bind(this));
            }
        }
        else this._value = _value;

        if (this._value == undefined)
        {
            this._value = 0;
        }

        this.setValue(this._value);

        this.needsUpdate = true;
    }

    getType()
    {
        return this._type;
    }

    get type()
    {
        return this._type;
    }

    get name()
    {
        return this._name;
    }

    getName()
    {
        return this._name;
    }

    getValue()
    {
        return this._value;
    }

    getShaderType()
    {
        return this.shaderType;
    }

    isStructMember()
    {
        return !!this._structName;
    }

    updateFromPort4f()
    {
        this._value[0] = this._port.get();
        this._value[1] = this._port2.get();
        this._value[2] = this._port3.get();
        this._value[3] = this._port4.get();
        this.setValue(this._value);
    }

    updateFromPort3f()
    {
        this._value[0] = this._port.get();
        this._value[1] = this._port2.get();
        this._value[2] = this._port3.get();
        this.setValue(this._value);
    }

    updateFromPort2f()
    {
        this._value[0] = this._port.get();
        this._value[1] = this._port2.get();
        this.setValue(this._value);
    }

    updateFromPort()
    {
        this.setValue(this._port.get());
    }

    get port()
    {
        return this._port;
    }
}


/***/ }),

/***/ 748:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* unused harmony export CG */
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(823);
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(522);
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(964);
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(409);
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(684);
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(221);
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(991);
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(842);
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(329);
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(796);
/* harmony import */ var _cg_boundingbox_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(982);
/* harmony import */ var _cg_canvas_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(223);
/* harmony import */ var _cg_geom_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(331);
/* harmony import */ var _cg_fpscounter_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(294);












const CG = {

    "DEPTH_COMPARE_NEVER": 0,
    "DEPTH_COMPARE_LESS": 1,
    "DEPTH_COMPARE_EQUAL": 2,
    "DEPTH_COMPARE_LESSEQUAL": 3,
    "DEPTH_COMPARE_GREATER": 4,
    "DEPTH_COMPARE_NOTEQUAL": 5,
    "DEPTH_COMPARE_GREATEREQUAL": 6,
    "DEPTH_COMPARE_ALWAYS": 7,

    "CULL_NONE": 0,
    "CULL_BACK": 1,
    "CULL_FRONT": 2,
    "CULL_BOTH": 3,

    "Geometry": _cg_geom_js__WEBPACK_IMPORTED_MODULE_0__/* .Geometry */ .V,
    "BoundingBox": _cg_boundingbox_js__WEBPACK_IMPORTED_MODULE_1__/* .BoundingBox */ .I,
    "FpsCounter": _cg_fpscounter_js__WEBPACK_IMPORTED_MODULE_2__/* .FpsCounter */ .K,

    "CgCanvas": _cg_canvas_js__WEBPACK_IMPORTED_MODULE_3__/* .CgCanvas */ .f
};

window.CABLES = window.CABLES || {};
window.CABLES.CG = window.CABLES.CG || CG;
window.CG = window.CG || CG;

window.glMatrix = gl_matrix__WEBPACK_IMPORTED_MODULE_4__;
window.mat2 = gl_matrix__WEBPACK_IMPORTED_MODULE_5__;
window.mat2d = gl_matrix__WEBPACK_IMPORTED_MODULE_6__;
window.mat3 = gl_matrix__WEBPACK_IMPORTED_MODULE_7__;
window.mat4 = gl_matrix__WEBPACK_IMPORTED_MODULE_8__;
window.quat = gl_matrix__WEBPACK_IMPORTED_MODULE_9__;
window.quat2 = gl_matrix__WEBPACK_IMPORTED_MODULE_10__;
window.vec2 = gl_matrix__WEBPACK_IMPORTED_MODULE_11__;

window.vec3 = gl_matrix__WEBPACK_IMPORTED_MODULE_12__;
window.vec4 = gl_matrix__WEBPACK_IMPORTED_MODULE_13__;




/***/ }),

/***/ 264:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   C: () => (/* binding */ MESH),
/* harmony export */   e: () => (/* binding */ Mesh)
/* harmony export */ });
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(849);
/* harmony import */ var cables__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(562);
/* harmony import */ var _cgl_shader_uniform_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(923);
/* harmony import */ var _constants_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(997);
/* harmony import */ var _cg_cg_mesh_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(434);










const MESH = {};
MESH.lastMesh = null;

/**
 * @typedef {Object} CglMeshAttributeOptions
 * @property {boolean} [instanced]
 * @property {Function} [cb]
 * @property {Function} [type]
 */

/**
 * @type Object
 * @typedef CglMeshOptions
 * @property {Number} [glPrimitive]
 * @property {String} [opId]
 */

/**
 * webgl renderable 3d object
 * @class
 * @namespace external:CGL
 * @hideconstructor
 * @example
 * const cgl=this._cgl
 * const mesh=new CGL.Mesh(cgl, geometry);
 *
 * function render()
 * {
 *   mesh.render(cgl.getShader());
 * }
 *
 */
class Mesh extends _cg_cg_mesh_js__WEBPACK_IMPORTED_MODULE_0__/* .CgMesh */ .w
{

    /** @type {CglContext} */
    #cgl = null;

    /** @type {Geometry} */
    #geom = null;

    /** @type {WebGLBuffer} */
    #bufVerticesIndizes = null;

    /**
     * @param {CglContext} _cgl cgl
     * @param {Geometry} __geom geometry
     * @param {CglMeshOptions} _options
     */
    constructor(_cgl, __geom, _options = {})
    {
        super();
        this.#cgl = _cgl;

        let options = _options || {};
        if (cables__WEBPACK_IMPORTED_MODULE_1__.isNumeric(options))options = { "glPrimitive": _options }; // old constructor fallback...
        this._log = new cables_shared_client__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A("cgl_mesh");
        this._bufVertexAttrib = null;
        this.#bufVerticesIndizes = this.#cgl.gl.createBuffer();
        this._indexType = this.#cgl.gl.UNSIGNED_SHORT;
        this._attributes = [];
        this._attribLocs = {};

        this._lastShader = null;
        this._numInstances = 0;
        this._glPrimitive = options.glPrimitive;

        this.opId = options.opId || "";
        this._preWireframeGeom = null;
        this.addVertexNumbers = false;

        this.feedBackAttributes = [];
        this.setGeom(__geom);

        this._feedBacks = [];
        this._feedBacksChanged = false;
        this._transformFeedBackLoc = -1;
        this._lastAttrUpdate = 0;

        this.memFreed = false;

        this.#cgl.profileData.addHeavyEvent("mesh constructed", this._name);

        this._queryExt = null;
    }

    get geom()
    {
        return this.#geom;
    }

    get numInstances()
    {
        return this._numInstances;
    }

    set numInstances(v)
    {
        this.setNumInstances(v);
    }

    freeMem()
    {
        this.memFreed = true;

        for (let i = 0; i < this._attributes.length; i++)
            this._attributes[i].floatArray = null;
    }

    /**
     * @function updateVertices
     * @memberof Mesh
     * @instance
     * @description update vertices only from a geometry
     * @param {Geometry} geom
     */
    updateVertices(geom)
    {
        this.setAttribute(_constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.SHADER.SHADERVAR_VERTEX_POSITION, geom.vertices, 3);
        this._numVerts = geom.vertices.length / 3;
    }

    /**
     * @param {String} attrName
     * @param {String} name
     * @param {Number} stride
     * @param {Number} offset
      */
    setAttributePointer(attrName, name, stride, offset)
    {
        for (let i = 0; i < this._attributes.length; i++)
        {
            if (this._attributes[i].name == attrName)
            {
                if (!this._attributes[i].pointer) this._attributes[i].pointer = [];

                this._attributes[i].pointer.push(
                    {
                        "loc": -1,
                        "name": name,
                        "stride": stride,
                        "offset": offset,
                        "instanced": attrName == _constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.SHADER.SHADERVAR_INSTANCE_MMATRIX,
                    }
                );
            }
        }
    }

    /**
     * @param {String} name
     * @returns {AttributeObject}
     */
    getAttribute(name)
    {
        for (let i = 0; i < this._attributes.length; i++) if (this._attributes[i].name == name) return this._attributes[i];
    }

    setAttributeRange(attr, array, start, end)
    {
        if (!attr) return;
        if (!start && !end) return;

        if (!attr.name)
            this._log.stack("no attrname?!");

        const gl = this.#cgl.gl;

        gl.bindBuffer(gl.ARRAY_BUFFER, attr.buffer);
        this.#cgl.profileData.profileMeshAttributes += (end - start) || 0;

        this.#cgl.profileData.profileSingleMeshAttribute[this._name] = this.#cgl.profileData.profileSingleMeshAttribute[this._name] || 0;
        this.#cgl.profileData.profileSingleMeshAttribute[this._name] += (end - start) || 0;

        if (attr.numItems < array.length / attr.itemSize)
        {
            this._resizeAttr(array, attr);
        }

        if (end > array.length && !this.warned)
        {
            this.warned = true;
            this._log.warn(this.#cgl.canvas.id + " " + attr.name + " buffersubdata out of bounds ?", array.length, end, start, attr);
            return;
        }

        // if (glVersion == 1) gl.bufferSubData(gl.ARRAY_BUFFER, 0, array); // probably slow/ maybe create and array with only changed size ??
        // else
        gl.bufferSubData(gl.ARRAY_BUFFER, start * 4, array, start, (end - start));
    }

    _resizeAttr(array, attr)
    {
        const gl = this.#cgl.gl;

        if (attr.buffer)
            gl.deleteBuffer(attr.buffer);

        attr.buffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, attr.buffer);
        this._bufferArray(array, attr);
        attr.numItems = array.length / attr.itemSize;// numItems;
    }

    _bufferArray(array, attr)
    {
        let floatArray = attr.floatArray || null;
        if (!array) return;

        if (this.#cgl.debugOneFrame)
        {
        console.log("_bufferArray", array.length, attr.name); // eslint-disable-line
        }

        if (!(array instanceof Float32Array))
        {
            if (attr && floatArray && floatArray.length == array.length)
            {
                floatArray.set(array);
            }
            else
            {
                floatArray = new Float32Array(array);

                if (this.#cgl.debugOneFrame)
                {
                console.log("_bufferArray create new float32array", array.length, attr.name); // eslint-disable-line
                }

                if (array.length > 10000)
                {
                    this.#cgl.profileData.profileNonTypedAttrib++;
                    this.#cgl.profileData.profileNonTypedAttribNames = "(" + this._name + ":" + attr.name + ")";
                }
            }
        }
        else floatArray = array;

        attr.arrayLength = floatArray.length;
        attr.floatArray = null;// floatArray;

        this.#cgl.gl.bufferData(this.#cgl.gl.ARRAY_BUFFER, floatArray, this.#cgl.gl.DYNAMIC_DRAW);
    }

    /**
     * @function setAttribute
     * @description update attribute
     * @memberof Mesh
     * @instance
     * @param {String} name
     * @param {Array} array
     * @param {Number} itemSize
     * @param {Object} options
     */
    addAttribute(name, array, itemSize, options)
    {
        this.setAttribute(name, array, itemSize, options);
    }

    /**
     * @param {String} name
     * @param {Array|Float32Array} array
     * @param {Number} itemSize Integer
     * @param {CglMeshAttributeOptions} options
     */
    setAttribute(name, array, itemSize, options = {})
    {
        if (!array)
        {
            this._log.error("mesh addAttribute - no array given! " + name);
            throw new Error();
        }
        let cb = null;
        let instanced = false;
        let i = 0;
        const numItems = array.length / itemSize;

        this.#cgl.profileData.profileMeshAttributes += numItems || 0;

        if (typeof options == "function")
        {
            cb = options;
        }

        if (typeof options == "object")
        {
            if (options.cb) cb = options.cb;
            if (options.instanced) instanced = options.instanced;
        }

        if (name == _constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.SHADER.SHADERVAR_INSTANCE_MMATRIX) instanced = true;

        for (i = 0; i < this._attributes.length; i++)
        {
            const attr = this._attributes[i];
            if (attr.name == name)
            {
                if (attr.numItems === numItems)
                {
                }
                else
                {
                    this._resizeAttr(array, attr);
                }

                this.#cgl.gl.bindBuffer(this.#cgl.gl.ARRAY_BUFFER, attr.buffer);
                this._bufferArray(array, attr);

                return attr;
            }
        }

        // create new buffer...

        const buffer = this.#cgl.gl.createBuffer();

        this.#cgl.gl.bindBuffer(this.#cgl.gl.ARRAY_BUFFER, buffer);
        // this._cgl.gl.bufferData(this._cgl.gl.ARRAY_BUFFER, floatArray, this._cgl.gl.DYNAMIC_DRAW);

        let type = this.#cgl.gl.FLOAT;
        if (options && options.type) type = options.type;
        const attr = {
            "buffer": buffer,
            "name": name,
            "cb": cb,
            "itemSize": itemSize,
            "numItems": numItems,
            "startItem": 0,
            "instanced": instanced,
            "type": type
        };

        this._bufferArray(array, attr);

        if (name == _constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.SHADER.SHADERVAR_VERTEX_POSITION) this._bufVertexAttrib = attr;
        this._attributes.push(attr);
        this._attribLocs = {};

        return attr;
    }

    getAttributes()
    {
        return this._attributes;
    }

    /**
     * @function updateTexCoords
     * @description update texture coordinates only from a geometry
     * @memberof Mesh
     * @instance
     * @param {Geometry} geom
     */
    updateTexCoords(geom)
    {
        if (geom.texCoords && geom.texCoords.length > 0)
        {
            this.setAttribute(_constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.SHADER.SHADERVAR_VERTEX_TEXCOORD, geom.texCoords, 2);
        }
        else
        {
            const tcBuff = new Float32Array(Math.round((geom.vertices.length / 3) * 2));
            this.setAttribute(_constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.SHADER.SHADERVAR_VERTEX_TEXCOORD, tcBuff, 2);
        }
    }

    /**
     * @function updateNormals
     * @description update normals only from a geometry
     * @memberof Mesh
     * @instance
     * @param {Geometry} geom
     */
    updateNormals(geom)
    {
        if (geom.vertexNormals && geom.vertexNormals.length > 0)
        {
            this.setAttribute(_constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.SHADER.SHADERVAR_VERTEX_NORMAL, geom.vertexNormals, 3);
        }
        else
        {
            const tcBuff = new Float32Array(Math.round((geom.vertices.length)));
            this.setAttribute(_constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.SHADER.SHADERVAR_VERTEX_NORMAL, tcBuff, 3);
        }
    }

    /**
     * @param {Array} [arr]
     */
    _setVertexNumbers(arr = null)
    {
        if (!this._verticesNumbers || this._verticesNumbers.length != this._numVerts || arr)
        {
            if (arr) this._verticesNumbers = arr;
            else
            {
                this._verticesNumbers = new Float32Array(this._numVerts);
                for (let i = 0; i < this._numVerts; i++) this._verticesNumbers[i] = i;
            }

            this.setAttribute(_constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.SHADER.SHADERVAR_VERTEX_NUMBER, this._verticesNumbers, 1, (_attr, _geom, shader) =>
            {
                if (!shader.uniformNumVertices) shader.uniformNumVertices = new _cgl_shader_uniform_js__WEBPACK_IMPORTED_MODULE_4__/* .Uniform */ .n(shader, "f", "numVertices", this._numVerts);
                shader.uniformNumVertices.setValue(this._numVerts);
            });
        }
    }

    /**
     * @function setVertexIndices
     * @description update vertex indices / faces
     * @memberof Mesh
     * @instance
     * @param {array} vertIndices
     */
    setVertexIndices(vertIndices)
    {
        if (!this.#bufVerticesIndizes)
        {
            this._log.warn("no bufVerticesIndizes: " + this._name);
            return;
        }
        if (vertIndices.length > 0)
        {
            if (vertIndices instanceof Float32Array) this._log.warn("vertIndices float32Array: " + this._name);

            for (let i = 0; i < vertIndices.length; i++)
            {
                if (vertIndices[i] >= this._numVerts)
                {
                    this._log.warn("invalid index in " + this._name, i, vertIndices[i]);
                    return;
                }
            }

            this.#cgl.gl.bindBuffer(this.#cgl.gl.ELEMENT_ARRAY_BUFFER, this.#bufVerticesIndizes);

            /*
             * todo cache this ?
             * if(!this.vertIndicesTyped || this.vertIndicesTyped.length!=this._geom.verticesIndices.length)
             */

            if (vertIndices.length > 65535)
            {
                this.vertIndicesTyped = new Uint32Array(vertIndices);
                this._indexType = this.#cgl.gl.UNSIGNED_INT;
            }
            else
            if (vertIndices instanceof Uint32Array)
            {
                this.vertIndicesTyped = vertIndices;
                this._indexType = this.#cgl.gl.UNSIGNED_INT;
            }
            else
            if (!(vertIndices instanceof Uint16Array))
            {
                this.vertIndicesTyped = new Uint16Array(vertIndices);
                this._indexType = this.#cgl.gl.UNSIGNED_SHORT;
            }
            else this.vertIndicesTyped = vertIndices;

            this.#cgl.gl.bufferData(this.#cgl.gl.ELEMENT_ARRAY_BUFFER, this.vertIndicesTyped, this.#cgl.gl.DYNAMIC_DRAW);
            this.#bufVerticesIndizes.itemSize = 1;
            this.#bufVerticesIndizes.numItems = vertIndices.length;
        }
        else this.#bufVerticesIndizes.numItems = 0;
    }

    /**
     * @function setGeom
     * @memberof Mesh
     * @instance
     * @description set geometry for mesh
     * @param {Geometry} geom
     * @param {boolean} removeRef
     */
    setGeom(geom, removeRef = false)
    {
        this.#geom = geom;
        if (geom.glPrimitive != null) this._glPrimitive = geom.glPrimitive;
        if (this.#geom && this.#geom.name) this._name = "mesh " + this.#geom.name;

        MESH.lastMesh = null;
        this.#cgl.profileData.profileMeshSetGeom++;

        this._disposeAttributes();

        this.updateVertices(this.#geom);
        this.setVertexIndices(this.#geom.verticesIndices);

        if (this.addVertexNumbers) this._setVertexNumbers();

        const geomAttribs = this.#geom.getAttributes();

        const attribAssoc = {
            "texCoords": _constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.SHADER.SHADERVAR_VERTEX_TEXCOORD,
            "vertexNormals": _constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.SHADER.SHADERVAR_VERTEX_NORMAL,
            "vertexColors": _constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.SHADER.SHADERVAR_VERTEX_COLOR,
            "tangents": "attrTangent",
            "biTangents": "attrBiTangent",
        };

        for (const index in geomAttribs)
            if (geomAttribs[index].data && geomAttribs[index].data.length)
                this.setAttribute(attribAssoc[index] || index, geomAttribs[index].data, geomAttribs[index].itemSize);

        if (removeRef)
        {
            this.#geom = null;
        }
    }

    _preBind(shader)
    {
        for (let i = 0; i < this._attributes.length; i++)
            if (this._attributes[i].cb)
                this._attributes[i].cb(this._attributes[i], this.#geom, shader);
    }

    _checkAttrLengths()
    {
        if (this.memFreed) return;
        // check length
        for (let i = 0; i < this._attributes.length; i++)
        {
            if (this._attributes[i].arrayLength / this._attributes[i].itemSize < this._attributes[0].arrayLength / this._attributes[0].itemSize)
            {
                let name = "unknown";
                if (this.#geom)name = this.#geom.name;

            /*
             * this._log.warn(
             *     name + ": " + this._attributes[i].name +
             *     " wrong attr length. is:", this._attributes[i].arrayLength / this._attributes[i].itemSize,
             *     " should be:", this._attributes[0].arrayLength / this._attributes[0].itemSize,
             * );
             */
            }
        }
    }

    _bind(shader)
    {
        if (!shader) return;
        if (!shader.isValid()) return;

        let attrLocs = [];
        if (this._attribLocs[shader.id]) attrLocs = this._attribLocs[shader.id];
        else this._attribLocs[shader.id] = attrLocs;

        this._lastShader = shader;
        if (shader.lastCompile > this._lastAttrUpdate || attrLocs.length != this._attributes.length)
        {
            this._lastAttrUpdate = shader.lastCompile;
            for (let i = 0; i < this._attributes.length; i++) attrLocs[i] = -1;
        }

        for (let i = 0; i < this._attributes.length; i++)
        {
            const attribute = this._attributes[i];
            if (attrLocs[i] == -1)
            {
                if (attribute._attrLocationLastShaderTime != shader.lastCompile)
                {
                    attribute._attrLocationLastShaderTime = shader.lastCompile;
                    attrLocs[i] = this.#cgl.glGetAttribLocation(shader.getProgram(), attribute.name);
                    // this._log.log('attribloc',attribute.name,attrLocs[i]);
                    this.#cgl.profileData.profileAttrLoc++;
                }
            }

            if (attrLocs[i] != -1)
            {
                this.#cgl.gl.enableVertexAttribArray(attrLocs[i]);
                this.#cgl.gl.bindBuffer(this.#cgl.gl.ARRAY_BUFFER, attribute.buffer);

                if (attribute.instanced)
                {
                // todo: easier way to fill mat4 attribs...
                    if (attribute.itemSize <= 4)
                    {
                        if (!attribute.itemSize || attribute.itemSize == 0) this._log.warn("instanced attrib itemsize error", this.#geom.name, attribute);

                        this.#cgl.gl.vertexAttribPointer(attrLocs[i], attribute.itemSize, attribute.type, false, attribute.itemSize * 4, 0);
                        this.#cgl.gl.vertexAttribDivisor(attrLocs[i], 1);
                    }
                    else if (attribute.itemSize == 16)
                    {
                        const stride = 16 * 4;

                        this.#cgl.gl.vertexAttribPointer(attrLocs[i], 4, attribute.type, false, stride, 0);
                        this.#cgl.gl.enableVertexAttribArray(attrLocs[i] + 1);
                        this.#cgl.gl.vertexAttribPointer(attrLocs[i] + 1, 4, attribute.type, false, stride, 4 * 4 * 1);
                        this.#cgl.gl.enableVertexAttribArray(attrLocs[i] + 2);
                        this.#cgl.gl.vertexAttribPointer(attrLocs[i] + 2, 4, attribute.type, false, stride, 4 * 4 * 2);
                        this.#cgl.gl.enableVertexAttribArray(attrLocs[i] + 3);
                        this.#cgl.gl.vertexAttribPointer(attrLocs[i] + 3, 4, attribute.type, false, stride, 4 * 4 * 3);

                        this.#cgl.gl.vertexAttribDivisor(attrLocs[i], 1);
                        this.#cgl.gl.vertexAttribDivisor(attrLocs[i] + 1, 1);
                        this.#cgl.gl.vertexAttribDivisor(attrLocs[i] + 2, 1);
                        this.#cgl.gl.vertexAttribDivisor(attrLocs[i] + 3, 1);
                    }
                    else
                    {
                        this._log.warn("unknown instance attrib size", attribute.name);
                    }
                }
                else
                {
                    if (!attribute.itemSize || attribute.itemSize == 0) this._log.warn("attrib itemsize error", this._name, attribute);
                    this.#cgl.gl.vertexAttribPointer(attrLocs[i], attribute.itemSize, attribute.type, false, attribute.itemSize * 4, 0);

                    if (attribute.pointer)
                    {
                        for (let ip = 0; ip < attribute.pointer.length; ip++)
                        {
                            const pointer = attribute.pointer[ip];

                            if (pointer.loc == -1)
                                pointer.loc = this.#cgl.glGetAttribLocation(shader.getProgram(), pointer.name);

                            this.#cgl.profileData.profileAttrLoc++;

                            this.#cgl.gl.enableVertexAttribArray(pointer.loc);
                            this.#cgl.gl.vertexAttribPointer(pointer.loc, attribute.itemSize, attribute.type, false, pointer.stride, pointer.offset);
                        }
                    }
                    if (this.bindFeedback) this.bindFeedback(attribute);
                }
            }
        }

        if (this.#bufVerticesIndizes && this.#bufVerticesIndizes.numItems !== 0) this.#cgl.gl.bindBuffer(this.#cgl.gl.ELEMENT_ARRAY_BUFFER, this.#bufVerticesIndizes);
    }

    unBind()
    {
        const shader = this._lastShader;
        this._lastShader = null;
        if (!shader) return;

        let attrLocs = [];
        if (this._attribLocs[shader.id]) attrLocs = this._attribLocs[shader.id];
        else this._attribLocs[shader.id] = attrLocs;

        MESH.lastMesh = null;

        for (let i = 0; i < this._attributes.length; i++)
        {
            if (this._attributes[i].instanced)
            {
            // todo: easier way to fill mat4 attribs...
                if (this._attributes[i].itemSize <= 4)
                {
                    if (attrLocs[i] != -1) this.#cgl.gl.vertexAttribDivisor(attrLocs[i], 0);
                    if (attrLocs[i] >= 0) this.#cgl.gl.disableVertexAttribArray(attrLocs[i]);
                }
                else
                {
                    this.#cgl.gl.vertexAttribDivisor(attrLocs[i], 0);
                    this.#cgl.gl.vertexAttribDivisor(attrLocs[i] + 1, 0);
                    this.#cgl.gl.vertexAttribDivisor(attrLocs[i] + 2, 0);
                    this.#cgl.gl.vertexAttribDivisor(attrLocs[i] + 3, 0);
                    this.#cgl.gl.disableVertexAttribArray(attrLocs[i] + 1);
                    this.#cgl.gl.disableVertexAttribArray(attrLocs[i] + 2);
                    this.#cgl.gl.disableVertexAttribArray(attrLocs[i] + 3);
                }
            }

            if (attrLocs[i] != -1) this.#cgl.gl.disableVertexAttribArray(attrLocs[i]);

        }
    }

    meshChanged()
    {
        return this.#cgl.lastMesh && this.#cgl.lastMesh != this;
    }

    printDebug()
    {
        console.log("--attributes");
        for (let i = 0; i < this._attributes.length; i++)
        {
            console.log("attribute " + i + " " + this._attributes[i].name);
        }
    }

    /**
     * @param {Number} num
     */
    setNumVertices(num)
    {
        // this._bufVerticesIndizes.numItems = num;
        this._bufVertexAttrib.numItems = num;
    }

    /**
     * @returns {Number}
     */
    getNumVertices()
    {
        // return this._bufVerticesIndizes.numItems;
        return this._bufVertexAttrib.numItems;
    }

    /**
     * @param {Number} num
     */
    setNumIndices(num)
    {
        this.#bufVerticesIndizes.numItems = num;
    }

    /**
     * @returns {Number}
     */
    getNumIndices()
    {
        return this.#bufVerticesIndizes.numItems;
    }

    /**
     * @function render
     * @memberof Mesh
     * @instance
     * @description draw mesh to screen
     * @param {CgShader} shader
     */
    render(shader)
    {
        // TODO: enable/disablevertex only if the mesh has changed... think drawing 10000x the same mesh

        if (this.#cgl.aborted) return;
        shader = shader || this.#cgl.getShader();

        if (!shader)
        {
            return console.log("shadern not valid");
        }

        if (!shader.isValid())
        {
            shader = this.#cgl.getErrorShader();
        }

        this._checkAttrLengths();

        if (this.#geom)
        {
            if (this._preWireframeGeom && !shader.wireframe && !this.#geom.isIndexed())
            {
                this.setGeom(this._preWireframeGeom);
                this._preWireframeGeom = null;
            }

            if (shader.wireframe)
            {
                let changed = false;

                if (this.#geom.isIndexed())
                {
                    if (!this._preWireframeGeom)
                    {
                        this._preWireframeGeom = this.#geom;
                        this.#geom = this.#geom.copy();
                    }

                    this.#geom.unIndex();
                    changed = true;
                }

                if (!this.#geom.getAttribute("attrBarycentric"))
                {
                    if (!this._preWireframeGeom)
                    {
                        this._preWireframeGeom = this.#geom;
                        this.#geom = this.#geom.copy();
                    }
                    changed = true;

                    this.#geom.calcBarycentric();
                }
                if (changed) this.setGeom(this.#geom);
            }
        }

        let needsBind = false;
        if (MESH.lastMesh != this)
        {
            if (MESH.lastMesh) MESH.lastMesh.unBind();
            needsBind = true;
        }

        if (needsBind) this._preBind(shader);

        if (!shader.bind()) return;

        this._bind(shader);
        if (this.addVertexNumbers) this._setVertexNumbers();

        MESH.lastMesh = this;

        let prim = this.#cgl.gl.TRIANGLES;
        if (this._glPrimitive !== undefined) prim = this._glPrimitive;
        if (shader.glPrimitive !== null) prim = shader.glPrimitive;

        let elementDiv = 1;
        let doQuery = this.#cgl.profileData.doProfileGlQuery;
        let queryStarted = false;
        if (doQuery)
        {
            let id = this._name + " - " + shader.getName() + " #" + shader.id;
            if (this._numInstances) id += " instanced " + this._numInstances + "x";

            let queryProfilerData = this.#cgl.profileData.glQueryData[id];

            if (!queryProfilerData) queryProfilerData = { "id": id, "num": 0 };

            if (shader.opId)queryProfilerData.shaderOp = shader.opId;
            if (this.opId)queryProfilerData.meshOp = this.opId;

            this.#cgl.profileData.glQueryData[id] = queryProfilerData;

            if (!this._queryExt && this._queryExt !== false) this._queryExt = this.#cgl.enableExtension("EXT_disjoint_timer_query_webgl2") || false;
            if (this._queryExt)
            {
                if (queryProfilerData._drawQuery)
                {
                    const available = this.#cgl.gl.getQueryParameter(queryProfilerData._drawQuery, this.#cgl.gl.QUERY_RESULT_AVAILABLE);
                    if (available)
                    {
                        const elapsedNanos = this.#cgl.gl.getQueryParameter(queryProfilerData._drawQuery, this.#cgl.gl.QUERY_RESULT);
                        const currentTimeGPU = elapsedNanos / 1000000;

                        queryProfilerData._times = queryProfilerData._times || 0;
                        queryProfilerData._times += currentTimeGPU;
                        queryProfilerData._numcount++;
                        queryProfilerData.when = performance.now();
                        queryProfilerData._drawQuery = null;
                        queryProfilerData.queryStarted = false;
                    }
                }

                if (!queryProfilerData.queryStarted)
                {
                    queryProfilerData._drawQuery = this.#cgl.gl.createQuery();
                    this.#cgl.gl.beginQuery(this._queryExt.TIME_ELAPSED_EXT, queryProfilerData._drawQuery);
                    queryStarted = queryProfilerData.queryStarted = true;
                }
            }
        }

        if (this.hasFeedbacks && this.hasFeedbacks()) this.drawFeedbacks(shader, prim);
        else if (!this.#bufVerticesIndizes || this.#bufVerticesIndizes.numItems === 0)
        {

            /*
             * for (let i = 0; i < this._attributes.length; i++)
             * {
             *     if (this._attributes[i].arrayLength / this._attributes[i].itemSize != this._bufVertexAttrib.floatArray.length / 3)
             *     {
             *         this._log.warn("attrib buffer length wrong! ", this._attributes[i].name, this._attributes[i].arrayLength / this._attributes[i].itemSize, this._bufVertexAttrib.floatArray.length / 3, this._attributes[i].itemSize);
             *         // this._log.log(this);
             *         // debugger;
             *         return;
             *     }
             * }
             */

            if (prim == this.#cgl.gl.TRIANGLES)elementDiv = 3;

            if (this._numInstances === 0) this.#cgl.gl.drawArrays(prim, this._bufVertexAttrib.startItem, this._bufVertexAttrib.numItems - this._bufVertexAttrib.startItem);
            else this.#cgl.gl.drawArraysInstanced(prim, this._bufVertexAttrib.startItem, this._bufVertexAttrib.numItems, this._numInstances);
        }
        else
        {
            if (prim == this.#cgl.gl.TRIANGLES)elementDiv = 3;
            if (this._numInstances === 0)
            {
                this.#cgl.gl.drawElements(prim, this.#bufVerticesIndizes.numItems, this._indexType, 0);
            }
            else
            {
                this.#cgl.gl.drawElementsInstanced(prim, this.#bufVerticesIndizes.numItems, this._indexType, 0, this._numInstances);
            }
        }

        if (this.#cgl.debugOneFrame && this.#cgl.gl.getError() != this.#cgl.gl.NO_ERROR)
        {
            this._log.error("mesh draw gl error");
            this._log.error("mesh", this);
            this._log.error("shader", shader);

            const attribNames = [];
            for (let i = 0; i < this.#cgl.gl.getProgramParameter(shader.getProgram(), this.#cgl.gl.ACTIVE_ATTRIBUTES); i++)
            {
                const name = this.#cgl.gl.getActiveAttrib(shader.getProgram(), i).name;
                this._log.error("attrib ", name);
            }
        }

        this.#cgl.profileData.profileMeshNumElements += (this._bufVertexAttrib.numItems / elementDiv) * (this._numInstances || 1);
        this.#cgl.profileData.profileMeshDraw++;

        if (doQuery && queryStarted)
        {
            this.#cgl.gl.endQuery(this._queryExt.TIME_ELAPSED_EXT);
        }

        this.#cgl.printError("mesh render " + this._name);

        this.unBind();
    }

    setNumInstances(n)
    {
        n = Math.max(0, n);
        if (this._numInstances != n)
        {
            this._numInstances = n;
            const indexArr = new Float32Array(n);
            for (let i = 0; i < n; i++) indexArr[i] = i;
            this.setAttribute(_constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.SHADER.SHADERVAR_INSTANCE_INDEX, indexArr, 1, { "instanced": true });
        }
    }

    _disposeAttributes()
    {
        if (!this._attributes) return;

        for (let i = 0; i < this._attributes.length; i++)
        {
            if (this._attributes[i].buffer)
            {
                this.#cgl.gl.deleteBuffer(this._attributes[i].buffer);
                this._attributes[i].buffer = null;
            }
        }
        this._attributes.length = 0;
    }

    dispose()
    {
        if (this.#cgl.aborted) return;
        if (this._bufVertexAttrib && this._bufVertexAttrib.buffer) this.#cgl.gl.deleteBuffer(this._bufVertexAttrib.buffer);
        if (this.#bufVerticesIndizes) this.#cgl.gl.deleteBuffer(this.#bufVerticesIndizes);
        this.#bufVerticesIndizes = null;

        this._disposeAttributes();
    }
}




/***/ }),

/***/ 460:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   E: () => (/* binding */ ProfileData)
/* harmony export */ });
class ProfileData
{
    constructor(cgl)
    {
        this._cgl = cgl;
        this._lastTime = 0;
        this.pause = false;
        this.profileUniformCount = 0;
        this.profileShaderBinds = 0;
        this.profileUniformCount = 0;
        this.profileShaderCompiles = 0;
        this.profileVideosPlaying = 0;
        this.profileMVPMatrixCount = 0;
        this.profileEffectBuffercreate = 0;
        this.profileShaderGetUniform = 0;
        this.profileFrameBuffercreate = 0;
        this.profileMeshSetGeom = 0;
        this.profileTextureNew = 0;
        this.profileGenMipMap = 0;
        this.profileOnAnimFrameOps = 0;

        this.profileFencedPixelRead = 0;
        this.profileMainloopMs = 0;
        this.profileMeshDraw = 0;
        this.profileTextureEffect = 0;
        this.profileTexPreviews = 0;
        this.shaderCompileTime = 0;
        this.profileMeshNumElements = 0;
        this.profileMeshAttributes = 0;
        this.profileSingleMeshAttribute = [];
        this.heavyEvents = [];

        this.doProfileGlQuery = false;
        this.glQueryData = {};
        this.counts = {};
    }

    clear()
    {
        this.counts = {};
        this.profileSingleMeshAttribute = {};
        this.profileMeshAttributes = 0;
        this.profileUniformCount = 0;
        this.profileShaderGetUniform = 0;
        this.profileShaderCompiles = 0;
        this.profileShaderBinds = 0;
        this.profileTextureResize = 0;
        this.profileFrameBuffercreate = 0;
        this.profileEffectBuffercreate = 0;
        this.profileTextureDelete = 0;
        this.profileMeshSetGeom = 0;
        this.profileVideosPlaying = 0;
        this.profileMVPMatrixCount = 0;
        this.profileNonTypedAttrib = 0;
        this.profileNonTypedAttribNames = "";
        this.profileTextureNew = 0;
        this.profileGenMipMap = 0;
        this.profileFramebuffer = 0;
        this.profileMeshDraw = 0;
        this.profileTextureEffect = 0;
        this.profileTexPreviews = 0;
        this.profileMeshNumElements = 0;
        this.profileFencedPixelRead = 0;
    }

    clearGlQuery()
    {
        for (let i in this.glQueryData)
        {
            if (!this.glQueryData[i].lastClear || performance.now() - this.glQueryData[i].lastClear > 1000)
            {
                this.glQueryData[i].time = this.glQueryData[i]._times / this.glQueryData[i]._numcount;
                this.glQueryData[i].num = this.glQueryData[i]._numcount;

                this.glQueryData[i]._times = 0;
                this.glQueryData[i]._numcount = 0;
                this.glQueryData[i].lastClear = performance.now();
            }
        }
    }

    /**
     * @param {string} event
     * @param {string} name
     */
    count(event, name)
    {
        this.counts[event] = this.counts[event] || [];
        this.counts[event].push(name);
    }

    /**
     * @param {string} event
     * @param {string} name
     * @param {string} [info]
     */
    addHeavyEvent(event, name, info)
    {
        const e = { "event": event, "name": name, "info": info, "date": performance.now() };
        this.heavyEvents.push(e);
        this._cgl.emitEvent("heavyEvent", e);
    }
}


/***/ }),

/***/ 24:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   M: () => (/* binding */ CglShader)
/* harmony export */ });
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(849);
/* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(684);
/* harmony import */ var cables__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(920);
/* harmony import */ var _cgl_shader_lib_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(960);
/* harmony import */ var _cgl_mesh_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(264);
/* harmony import */ var _constants_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(997);
/* harmony import */ var _cg_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(694);
/* harmony import */ var _cgl_texture_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(70);
/* harmony import */ var _cgl_shader_uniform_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(923);











// ---------------------------------------------------------------------------

/*

proposal default shader variable names:

attrVertex - currently: vPosition
attrVertexIndex - currently: attrVertIndex
attrTexCoord
attrInstMat - currently: instMat
attrVertColor
attrTangent
attrBiTangent

uProjMatrix - currently: projMatrix
uModelMatrix - currently: modelMatrix
uNormalMatrix - currently: normalMatrix
uCamPosition - currently: camPos

*/

// ---------------------------------------------------------------------------

// eslint-disable-next-line no-restricted-syntax
const defaultShaderSrcVert = `
{{MODULES_HEAD}}
IN vec3 vPosition; //!@
IN vec2 attrTexCoord;
IN vec3 attrVertNormal;
IN vec3 attrTangent,attrBiTangent;

IN float attrVertIndex;

OUT vec2 texCoord;
OUT vec3 norm;
UNI mat4 projMatrix;
UNI mat4 viewMatrix;
UNI mat4 modelMatrix;

void main()
{
    texCoord=attrTexCoord;
    norm=attrVertNormal;
    vec4 pos=vec4(vPosition,  1.0);
    vec3 tangent=attrTangent;
    vec3 bitangent=attrBiTangent;
    mat4 mMatrix=modelMatrix;
    gl_PointSize=10.0;

    {{MODULE_VERTEX_POSITION}}

    mat4 modelViewMatrix=viewMatrix*mMatrix;
    {{MODULE_VERTEX_MODELVIEW}}

    gl_Position = projMatrix * modelViewMatrix * pos;
}
`;
let materialIdCounter = 0;

function getDefaultVertexShader()
{
    return defaultShaderSrcVert;
}

/**
 * @param {number} [r]
 * @param {number} [g]
 * @param {number} [b]
 */
function getDefaultFragmentShader(r, g, b)
{
    if (r == undefined)
    {
        r = 0.5;
        g = 0.5;
        b = 0.5;
    }
    return ""
        + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "IN vec2 texCoord;"
        + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "{{MODULES_HEAD}}"
        + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "void main()"
        + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "{"

        + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "    vec4 col=vec4(" + r + "," + g + "," + b + ",1.0);"
        + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "    {{MODULE_COLOR}}"
        + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "    outColor = col;"
        + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "}";
}

/**
 * @class
 * @namespace external:CGL
 * @hideconstructor
 * @param _cgl
 * @param _name
 * @param _op
 * @example
 * var shader=new CGL.Shader(cgl,'MinimalMaterial');
 * shader.setSource(attachments.shader_vert,attachments.shader_frag);
 */
class CglShader extends _cg_index_js__WEBPACK_IMPORTED_MODULE_1__/* .CgShader */ .U
{

    /** @type {Uniform[]} */
    _uniforms = [];

    /**
     * @param {CglContext} _cgl
     * @param {string} _name
     * @param {Op} [_op]
     */
    constructor(_cgl, _name, _op)
    {
        super();
        if (!_cgl) throw new Error("shader constructed without cgl " + _name);

        this._log = new cables_shared_client__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A("cgl_shader");
        this._cgl = _cgl;

        if (!_name) this._log.stack("no shader name given");
        this._name = _name || "unknown";

        if (_op) this.opId = _op.id;
        this.glslVersion = 0;
        if (_cgl.glVersion > 1) this.glslVersion = 300;

        this._materialId = ++materialIdCounter;

        this._program = null;
        this._drawBuffers = [true];
        this.error = null;

        this.ignoreMissingUniforms = false;
        this._projMatrixUniform = null;
        this._mvMatrixUniform = null;
        this._mMatrixUniform = null;
        this._vMatrixUniform = null;
        this._camPosUniform = null;
        this._normalMatrixUniform = null;
        this._inverseViewMatrixUniform = null;
        this._fromUserInteraction = false;

        this._attrVertexPos = -1;
        this.precision = _cgl.patch.config.glslPrecision || "highp";

        this._pMatrixState = -1;
        this._vMatrixState = -1;

        this._countMissingUniforms = 0;
        this._modGroupCount = 0; // not needed anymore...
        this._feedBackNames = [];
        this._attributes = [];

        this.glPrimitive = null;
        this.offScreenPass = false;
        this._extensions = [];
        this.srcVert = getDefaultVertexShader();
        this.srcFrag = getDefaultFragmentShader();
        this.lastCompile = 0;

        this._libs = [];
        this._structNames = [];
        this._structUniformNames = [];
        this._textureStackUni = [];
        this._textureStackTex = [];
        this._textureStackType = [];
        this._textureStackTexCgl = [];

        this._tempNormalMatrix = gl_matrix__WEBPACK_IMPORTED_MODULE_3__.create();
        this._tempCamPosMatrix = gl_matrix__WEBPACK_IMPORTED_MODULE_3__.create();
        this._tempInverseViewMatrix = gl_matrix__WEBPACK_IMPORTED_MODULE_3__.create();
        this._tempInverseProjMatrix = gl_matrix__WEBPACK_IMPORTED_MODULE_3__.create();

        this.setModules(["MODULE_VERTEX_POSITION", "MODULE_COLOR", "MODULE_NORMAL", "MODULE_BEGIN_FRAG", "MODULE_VERTEX_MODELVIEW"]);
    }

    isValid()
    {
        return this._isValid;
    }

    getCgl()
    {
        return this._cgl;
    }

    getName()
    {
        return this._name;
    }

    /**
     * @param {string} name
     */
    enableExtension(name)
    {
        this.setWhyCompile("enable extension " + name);

        this._extensions.push(name);
    }

    getAttrVertexPos()
    {
        return this._attrVertexPos;
    }

    hasTextureUniforms()
    {
        for (let i = 0; i < this._uniforms.length; i++)
            if (this._uniforms[i].getType() == "t") return true;
        return false;
    }

    /**
     * copy all uniform values from another shader
     * @param {CglShader} origShader uniform values will be copied from this shader
     */
    copyUniformValues(origShader)
    {
        for (let i = 0; i < origShader._uniforms.length; i++)
        {
            if (!this._uniforms[i])
            {
                this._log.log("unknown uniform?!");
                continue;
            }

            this.getUniform(origShader._uniforms[i].getName()).set(origShader._uniforms[i].getValue());
        }

        this.popTextures();
        for (let i = 0; i < origShader._textureStackUni.length; i++)
        {
            this._textureStackUni[i] = origShader._textureStackUni[i];
            this._textureStackTex[i] = origShader._textureStackTex[i];
            this._textureStackType[i] = origShader._textureStackType[i];
            this._textureStackTexCgl[i] = origShader._textureStackTexCgl[i];
        }

    }

    /**
     * copy current shader
     * @returns {CglShader} newShader
     */
    copy()
    {
        const shader = new CglShader(this._cgl, this._name + " copy");
        shader.setSource(this.srcVert, this.srcFrag);

        shader._modules = JSON.parse(JSON.stringify(this._modules));
        shader._defines = JSON.parse(JSON.stringify(this._defines));

        shader._modGroupCount = this._modGroupCount;
        shader._moduleNames = this._moduleNames;
        shader.glPrimitive = this.glPrimitive;
        shader.offScreenPass = this.offScreenPass;
        shader._extensions = this._extensions;
        shader.wireframe = this.wireframe;
        shader._attributes = this._attributes;

        for (let i = 0; i < this._uniforms.length; i++)
        {
            const u = this._uniforms[i].copy(shader);
            u.resetLoc();
        }

        shader.setWhyCompile("copy");
        return shader;
    }

    /**
     * set shader source code
     * @param {String} srcVert
     * @param {String} srcFrag
     * @param {Boolean} fromUserInteraction
     */
    setSource(srcVert, srcFrag, fromUserInteraction = false)
    {
        this._fromUserInteraction = fromUserInteraction;
        this.srcVert = srcVert;
        this.srcFrag = srcFrag;
        this.setWhyCompile("Source changed");
        this._isValid = true;
    }

    _addLibs(src)
    {
        for (const id in _cgl_shader_lib_js__WEBPACK_IMPORTED_MODULE_4__/* .ShaderLibMods */ .y)
        {
            if (src.includes(id))
            {
                const lib = new _cgl_shader_lib_js__WEBPACK_IMPORTED_MODULE_4__/* .ShaderLibMods */ .y[id]();
                src = src.replace("{{" + id + "}}", lib.srcHeadFrag);
                this._libs.push(lib);
                if (lib.initUniforms)lib.initUniforms(this);
            }
        }

        return src;
    }

    createStructUniforms()
    {
        // * create structs
        let structStrFrag = "";
        let structStrVert = ""; // TODO: not used yet

        this._structNames = [];
        // * reset the arrays holding the value each recompile so we don't skip structs
        // * key value mapping so the same struct can be added twice (two times the same modifier)
        this._injectedStringsFrag = {};
        this._injectedStringsVert = {};

        this._structUniformNamesIndicesFrag = [];
        this._structUniformNamesIndicesVert = [];

        for (let i = 0; i < this._uniforms.length; i++)
        {
            // * only add uniforms to struct that are a member of a struct
            if (this._uniforms[i].isStructMember())
            {
                const injectionString = "{{INJECTION_POINT_STRUCT_" + this._uniforms[i]._structName + "}}";

                // * check if struct is not already part of shader
                if (!this._structNames.includes(this._uniforms[i]._structName))
                {
                    // * create struct definition with placeholder string to inject
                    const structDefinition = "struct "
                        + this._uniforms[i]._structName + " {" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl
                        + injectionString
                        + "};" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;

                    if (this._uniforms[i].getShaderType() === "both" || this._uniforms[i].getShaderType() === "frag")
                        structStrFrag = structStrFrag.concat(structDefinition);

                    if (this._uniforms[i].getShaderType() === "both" || this._uniforms[i].getShaderType() === "vert")
                        structStrVert = structStrVert.concat(structDefinition);

                    this._structNames.push(this._uniforms[i]._structName);
                    this._injectedStringsFrag[this._uniforms[i]._structName] = [];
                    this._injectedStringsVert[this._uniforms[i]._structName] = [];
                }

                // * create member & comment
                let comment = "";
                if (this._uniforms[i].comment) comment = " // " + this._uniforms[i].comment;

                let stringToInsert = "";
                if (this._uniforms[i].getGlslTypeString() == undefined)stringToInsert += "//";
                stringToInsert += "  " + this._uniforms[i].getGlslTypeString()
                        + " " + this._uniforms[i]._propertyName + ";"
                        + comment;

                if (this._uniforms[i].getShaderType() === "both")
                {
                    // * inject member before {injectionString}
                    if (
                        !this._injectedStringsFrag[this._uniforms[i]._structName].includes(stringToInsert)
                    && !this._injectedStringsVert[this._uniforms[i]._structName].includes(stringToInsert))
                    {
                        const insertionIndexFrag = structStrFrag.lastIndexOf(injectionString);
                        const insertionIndexVert = structStrVert.lastIndexOf(injectionString);

                        structStrFrag =
                            structStrFrag.slice(0, insertionIndexFrag)
                            + stringToInsert + structStrFrag.slice(insertionIndexFrag - 1);

                        structStrVert =
                            structStrVert.slice(0, insertionIndexVert)
                            + stringToInsert + structStrVert.slice(insertionIndexVert - 1);

                        this._injectedStringsFrag[this._uniforms[i]._structName].push(stringToInsert);
                        this._injectedStringsVert[this._uniforms[i]._structName].push(stringToInsert);
                    }

                    if (!this._structUniformNamesIndicesFrag.includes(i)) this._structUniformNamesIndicesFrag.push(i);
                    if (!this._structUniformNamesIndicesVert.includes(i)) this._structUniformNamesIndicesVert.push(i);
                }
                else if (this._uniforms[i].getShaderType() === "frag")
                {
                    // * inject member before {injectionString}
                    if (!this._injectedStringsFrag[this._uniforms[i]._structName].includes(stringToInsert)) //
                    {
                        const insertionIndexFrag = structStrFrag.lastIndexOf(injectionString);

                        structStrFrag =
                            structStrFrag.slice(0, insertionIndexFrag)
                            + stringToInsert + structStrFrag.slice(insertionIndexFrag - 1);

                        this._injectedStringsFrag[this._uniforms[i]._structName].push(stringToInsert);
                    }

                    if (!this._structUniformNamesIndicesFrag.includes(i)) this._structUniformNamesIndicesFrag.push(i);
                }
                else if (this._uniforms[i].getShaderType() === "vert")
                {
                    // * inject member before {injectionString}
                    if (!this._injectedStringsVert[this._uniforms[i]._structName].includes(stringToInsert))
                    {
                        const insertionIndexVert = structStrVert.lastIndexOf(injectionString);

                        structStrVert =
                            structStrVert.slice(0, insertionIndexVert)
                            + stringToInsert + structStrVert.slice(insertionIndexVert - 1);

                        this._injectedStringsVert[this._uniforms[i]._structName].push(stringToInsert);
                    }

                    if (!this._structUniformNamesIndicesVert.includes(i)) this._structUniformNamesIndicesVert.push(i);
                }
            }
        }

        // * dedupe injected uni declarations
        this._uniDeclarationsFrag = [];
        this._uniDeclarationsVert = [];

        // * remove struct injection points and add uniform in fragment
        for (let i = 0; i < this._structUniformNamesIndicesFrag.length; i += 1)
        {
            const index = this._structUniformNamesIndicesFrag[i];
            const uniDeclarationString = "UNI " + this._uniforms[index]._structName + " " + this._uniforms[index]._structUniformName + ";" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;

            if (!this._uniDeclarationsFrag.includes(uniDeclarationString))
            {
                const injectionString = "{{INJECTION_POINT_STRUCT_" + this._uniforms[index]._structName + "}}";

                structStrFrag = structStrFrag.replace(injectionString, "");
                structStrFrag += uniDeclarationString;

                this._uniDeclarationsFrag.push(uniDeclarationString);
            }
        }

        // * remove struct injection points and add uniform in vertex
        for (let i = 0; i < this._structUniformNamesIndicesVert.length; i += 1)
        {
            const index = this._structUniformNamesIndicesVert[i];
            const uniDeclarationString = "UNI " + this._uniforms[index]._structName + " " + this._uniforms[index]._structUniformName + ";" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;

            if (!this._uniDeclarationsVert.includes(uniDeclarationString))
            {
                const injectionString = "{{INJECTION_POINT_STRUCT_" + this._uniforms[index]._structName + "}}";

                structStrVert = structStrVert.replace(injectionString, "");
                structStrVert += uniDeclarationString;
                this._uniDeclarationsVert.push(uniDeclarationString);
            }
        }

        return [structStrVert, structStrFrag];
    }

    _getAttrSrc(attr, firstLevel)
    {
        const r = {};
        if (attr.name && attr.type)
        {
            r.srcHeadVert = "";
            if (!firstLevel) r.srcHeadVert += "#ifndef ATTRIB_" + attr.name + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
            r.srcHeadVert += "#define ATTRIB_" + attr.name + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
            r.srcHeadVert += "IN " + attr.type + " " + attr.name + ";" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
            if (!firstLevel) r.srcHeadVert += "#endif" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;

            if (attr.nameFrag)
            {
                r.srcHeadVert += "";
                if (!firstLevel) r.srcHeadVert += "#ifndef ATTRIB_" + attr.nameFrag + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
                r.srcHeadVert += "#define ATTRIB_" + attr.nameFrag + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
                r.srcHeadVert += "OUT " + attr.type + " " + attr.nameFrag + ";" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
                if (!firstLevel) r.srcHeadVert += "#endif" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;

                r.srcVert = "" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + attr.nameFrag + "=" + attr.name + ";";

                r.srcHeadFrag = "";
                if (!firstLevel) r.srcHeadFrag += "#ifndef ATTRIB_" + attr.nameFrag + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
                r.srcHeadFrag += "#define ATTRIB_" + attr.nameFrag + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
                r.srcHeadFrag += "IN " + attr.type + " " + attr.nameFrag + ";" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
                if (!firstLevel) r.srcHeadFrag += "#endif" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
            }
        }
        return r;
    }

    compile()
    {
        if (this._cgl.aborted) return;
        const startTime = performance.now();

        this._cgl.profileData.profileShaderCompiles++;
        this._cgl.profileData.profileShaderCompileName = this._name + " [" + this._compileReason + "]";

        let extensionString = "";
        if (this._extensions)
            for (let i = 0; i < this._extensions.length; i++)
                extensionString += "#extension " + this._extensions[i] + " : enable" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;

        let definesStr = "";
        if (this._defines.length) definesStr = "\n// cgl generated" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
        for (let i = 0; i < this._defines.length; i++)
            definesStr += "#define " + this._defines[i][0] + " " + this._defines[i][1] + "" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;

        const structStrings = this.createStructUniforms();
        this._cgl.profileData.addHeavyEvent("shader compile", this._name + " [" + this._compileReason + "]");
        this._compileReason = "";

        if (this._uniforms)
        {
            // * we create an array of the uniform names to check our indices & an array to save them
            const uniNames = this._uniforms.map((uni) => { return uni._name; });
            const indicesToRemove = [];

            // * we go through our uniforms and check if the same name is contained somewhere further in the array
            // * if so, we add the current index to be removed later
            for (let i = 0; i < this._uniforms.length; i++)
            {
                const uni = this._uniforms[i];
                const nextIndex = uniNames.indexOf(uni._name, i + 1);
                if (nextIndex > -1) indicesToRemove.push(i);
            }

            // * after that, we go through the uniforms backwards (so we keep the order) and remove the indices
            // * also, we reset the locations of all the other valid uniforms
            for (let j = this._uniforms.length - 1; j >= 0; j -= 1)
            {
                if (indicesToRemove.includes(j)) this._uniforms.splice(j, 1);
                else this._uniforms[j].resetLoc();
            }
        }

        this._cgl.printError("uniform resets");

        this._compileCount++;
        if (this.hasTextureUniforms()) definesStr += "#define HAS_TEXTURES" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;

        let vs = "";
        let fs = "";

        if (!this.srcFrag)
        {
            this._log.warn("[cgl shader] has no fragment source!", this._name, this);
            this.srcVert = getDefaultVertexShader();
            this.srcFrag = getDefaultFragmentShader();
        }

        vs = "#version 300 es"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "// "
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "// vertex shader " + this._name
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "// "
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "precision " + this.precision + " float;"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "precision " + this.precision + " sampler2D;"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + ""
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "#define WEBGL2"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "#define texture2D texture"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "#define UNI uniform"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "#define IN in"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "#define OUT out"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;

        fs = "#version 300 es"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "// "
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "// fragment shader " + this._name
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "// "
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "precision " + this.precision + " float;"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "precision " + this.precision + " sampler2D;"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + ""
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "#define WEBGL2"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "#define texture2D texture"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "#define IN in"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "#define OUT out"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "#define UNI uniform"
            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "{{DRAWBUFFER}}"

            + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;

        let uniformsStrVert = "\n// cgl generated" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
        let uniformsStrFrag = "\n// cgl generated" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;

        fs += "\n// active mods: --------------- ";
        vs += "\n// active mods: --------------- ";

        let foundModsFrag = false;
        let foundModsVert = false;
        for (let i = 0; i < this._moduleNames.length; i++)
        {
            for (let j = 0; j < this._modules.length; j++)
            {
                if (this._modules[j].name == this._moduleNames[i])
                {
                    if (this._modules[j].srcBodyFrag || this._modules[j].srcHeadFrag)
                    {
                        foundModsFrag = true;
                        fs += "\n// " + i + "." + j + ". " + this._modules[j].title + " (" + this._modules[j].name + ")";
                    }
                    if (this._modules[j].srcBodyVert || this._modules[j].srcHeadVert)
                    {
                        vs += "\n// " + i + "." + j + ". " + this._modules[j].title + " (" + this._modules[j].name + ")";
                        foundModsVert = true;
                    }
                }
            }
        }
        if (!foundModsVert)fs += "\n// no mods used...";
        if (!foundModsFrag)fs += "\n// no mods used...";
        fs += "\n";
        vs += "\n";

        for (let i = 0; i < this._uniforms.length; i++)
        {
            if (this._uniforms[i].shaderType && !this._uniforms[i].isStructMember())
            {
                let uniStr = "";
                if (!this._uniforms[i].getGlslTypeString())uniStr += "// ";
                uniStr += "UNI " + this._uniforms[i].getGlslTypeString() + " " + this._uniforms[i].getName();
                let comment = "";
                if (this._uniforms[i].comment) comment = " // " + this._uniforms[i].comment;

                if (this._uniforms[i].shaderType == "vert" || this._uniforms[i].shaderType == "both")
                    if (!this.srcVert.includes(uniStr) && !this.srcVert.includes("uniform " + this._uniforms[i].getGlslTypeString() + " " + this._uniforms[i].getName()))
                        uniformsStrVert += uniStr + ";" + comment + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;

                if (this._uniforms[i].shaderType == "frag" || this._uniforms[i].shaderType == "both")
                    if (!this.srcFrag.includes(uniStr) && !this.srcFrag.includes("uniform " + this._uniforms[i].getGlslTypeString() + " " + this._uniforms[i].getName()))
                        uniformsStrFrag += uniStr + ";" + comment + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
            }
        }

        let countUniFrag = 0;
        let countUniVert = 0;
        for (let i = 0; i < this._uniforms.length; i++)
        {
            if (this._uniforms[i].shaderType && !this._uniforms[i].isStructMember())
            {
                if (this._uniforms[i].shaderType == "vert" || this._uniforms[i].shaderType == "both") countUniVert++;
                if (this._uniforms[i].shaderType == "frag" || this._uniforms[i].shaderType == "both") countUniFrag++;
            }
        }
        if (countUniFrag >= this._cgl.maxUniformsFrag) this._log.warn("[cgl_shader] num uniforms frag: " + countUniFrag + " / " + this._cgl.maxUniformsFrag);
        if (countUniVert >= this._cgl.maxUniformsVert) this._log.warn("[cgl_shader] num uniforms vert: " + countUniVert + " / " + this._cgl.maxUniformsVert);

        if (!fs.includes("precision")) fs = "precision " + this.precision + " float;" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + fs;
        if (!vs.includes("precision")) vs = "precision " + this.precision + " float;" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + vs;
        if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent))
        {
            fs += "#define MOBILE" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
            vs += "#define MOBILE" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
        }
        vs = extensionString + vs + definesStr + structStrings[0] + uniformsStrVert + "\n// -- \n" + this.srcVert;
        fs = extensionString + fs + definesStr + structStrings[1] + uniformsStrFrag + "\n// -- \n" + this.srcFrag;

        let srcHeadVert = "";
        let srcHeadFrag = "";

        this._modules.sort(function (a, b)
        {
            return a.priority || 0 - b.priority || 0;
        });

        let addedAttribs = false;

        for (let i = 0; i < this._moduleNames.length; i++)
        {
            let srcVert = "";
            let srcFrag = "";

            if (!addedAttribs)
            {
                addedAttribs = true;

                for (let k = 0; k < this._attributes.length; k++)
                {
                    const r = this._getAttrSrc(this._attributes[k], true);
                    if (r.srcHeadVert)srcHeadVert += r.srcHeadVert;
                    if (r.srcVert)srcVert += r.srcVert;
                    if (r.srcHeadFrag)srcHeadFrag += r.srcHeadFrag;
                }
            }

            for (let j = 0; j < this._modules.length; j++)
            {
                const mod = this._modules[j];
                if (mod.name == this._moduleNames[i])
                {
                    srcHeadVert += "\n//---- MOD: group:" + mod.group + ": idx:" + j + " - prfx:" + mod.prefix + " - " + mod.title + " ------\n";
                    srcHeadFrag += "\n//---- MOD: group:" + mod.group + ": idx:" + j + " - prfx:" + mod.prefix + " - " + mod.title + " ------\n";

                    srcVert += "\n\n//---- MOD: " + mod.title + " / " + mod.priority + " ------\n";
                    srcFrag += "\n\n//---- MOD: " + mod.title + " / " + mod.priority + " ------\n";

                    if (mod.attributes)
                        for (let k = 0; k < mod.attributes.length; k++)
                        {
                            const r = this._getAttrSrc(mod.attributes[k], false);
                            if (r.srcHeadVert)srcHeadVert += r.srcHeadVert;
                            if (r.srcVert)srcVert += r.srcVert;
                            if (r.srcHeadFrag)srcHeadFrag += r.srcHeadFrag;
                        }

                    srcHeadVert += mod.srcHeadVert || "";
                    srcHeadFrag += mod.srcHeadFrag || "";
                    srcVert += mod.srcBodyVert || "";
                    srcFrag += mod.srcBodyFrag || "";

                    srcHeadVert += "\n//---- end mod ------\n";
                    srcHeadFrag += "\n//---- end mod ------\n";

                    srcVert += "\n//---- end mod ------\n";
                    srcFrag += "\n//---- end mod ------\n";

                    srcVert = srcVert.replace(/{{mod}}/g, mod.prefix);
                    srcFrag = srcFrag.replace(/{{mod}}/g, mod.prefix);
                    srcHeadVert = srcHeadVert.replace(/{{mod}}/g, mod.prefix);
                    srcHeadFrag = srcHeadFrag.replace(/{{mod}}/g, mod.prefix);

                    srcVert = srcVert.replace(/MOD_/g, mod.prefix);
                    srcFrag = srcFrag.replace(/MOD_/g, mod.prefix);
                    srcHeadVert = srcHeadVert.replace(/MOD_/g, mod.prefix);
                    srcHeadFrag = srcHeadFrag.replace(/MOD_/g, mod.prefix);
                }
            }

            vs = vs.replace("{{" + this._moduleNames[i] + "}}", srcVert);
            fs = fs.replace("{{" + this._moduleNames[i] + "}}", srcFrag);
        }

        vs = vs.replace("{{MODULES_HEAD}}", srcHeadVert);
        fs = fs.replace("{{MODULES_HEAD}}", srcHeadFrag);

        vs = this._addLibs(vs);
        fs = this._addLibs(fs);

        // SETUP draw buffers / multi texture render targets

        let drawBufferStr = "";
        for (let i = 0; i < 16; i++)
            if (fs.includes("outColor" + i)) this._drawBuffers[i] = true;

        if (this._drawBuffers.length == 1)
        {
            drawBufferStr = "out vec4 outColor;" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
            drawBufferStr += "#define gl_FragColor outColor" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
        }
        else
        {
            drawBufferStr += "#define MULTI_COLORTARGETS" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
            drawBufferStr += "vec4 outColor;" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;

            let count = 0;
            for (let i = 0; i < this._drawBuffers.length; i++)
            {
                if (count == 0) drawBufferStr += "#define gl_FragColor outColor" + i + "" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
                drawBufferStr += "layout(location = " + i + ") out vec4 outColor" + i + ";" + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl;
                count++;
            }
        }

        fs = fs.replace("{{DRAWBUFFER}}", drawBufferStr);
        // //////

        if (!this._program)
        {
            this._program = this._createProgram(vs, fs);
        }
        else
        {
            // this.vshader=createShader(vs, gl.VERTEX_SHADER, this.vshader );
            // this.fshader=createShader(fs, gl.FRAGMENT_SHADER, this.fshader );
            // linkProgram(program);
            this._program = this._createProgram(vs, fs);

            this._projMatrixUniform = null;

            for (let i = 0; i < this._uniforms.length; i++) this._uniforms[i].resetLoc();
        }

        this.finalShaderFrag = fs;
        this.finalShaderVert = vs;

        _cgl_mesh_js__WEBPACK_IMPORTED_MODULE_5__/* .MESH */ .C.lastMesh = null;
        _cgl_mesh_js__WEBPACK_IMPORTED_MODULE_5__/* .MESH */ .C.lastShader = null;

        this._countMissingUniforms = 0;
        this._needsRecompile = false;
        this.lastCompile = (0,cables__WEBPACK_IMPORTED_MODULE_6__/* .now */ .tB)();

        this._cgl.profileData.shaderCompileTime += performance.now() - startTime;
    }

    bind()
    {
        if (!this._isValid || this._cgl.aborted) return;

        _cgl_mesh_js__WEBPACK_IMPORTED_MODULE_5__/* .MESH */ .C.lastShader = this;

        if (!this._program || this.needsRecompile()) this.compile();
        if (!this._isValid) return;

        if (!this._projMatrixUniform && !this.ignoreMissingUniforms)
        {
            this._countMissingUniforms++;
            // if (this._countMissingUniforms == 10)this._log.log("stopping getlocation of missing uniforms...", this._name);
            if (this._countMissingUniforms < 10)
            {
                this._projMatrixUniform = this._cgl.gl.getUniformLocation(this._program, _constants_js__WEBPACK_IMPORTED_MODULE_0__/* .CONSTANTS */ .a.SHADER.SHADERVAR_UNI_PROJMAT);
                this._attrVertexPos = this._cgl.glGetAttribLocation(this._program, _constants_js__WEBPACK_IMPORTED_MODULE_0__/* .CONSTANTS */ .a.SHADER.SHADERVAR_VERTEX_POSITION);
                this._mvMatrixUniform = this._cgl.gl.getUniformLocation(this._program, "mvMatrix");
                this._vMatrixUniform = this._cgl.gl.getUniformLocation(this._program, _constants_js__WEBPACK_IMPORTED_MODULE_0__/* .CONSTANTS */ .a.SHADER.SHADERVAR_UNI_VIEWMAT);
                this._mMatrixUniform = this._cgl.gl.getUniformLocation(this._program, _constants_js__WEBPACK_IMPORTED_MODULE_0__/* .CONSTANTS */ .a.SHADER.SHADERVAR_UNI_MODELMAT);
                this._camPosUniform = this._cgl.gl.getUniformLocation(this._program, _constants_js__WEBPACK_IMPORTED_MODULE_0__/* .CONSTANTS */ .a.SHADER.SHADERVAR_UNI_VIEWPOS);
                this._normalMatrixUniform = this._cgl.gl.getUniformLocation(this._program, _constants_js__WEBPACK_IMPORTED_MODULE_0__/* .CONSTANTS */ .a.SHADER.SHADERVAR_UNI_NORMALMAT);
                this._inverseViewMatrixUniform = this._cgl.gl.getUniformLocation(this._program, _constants_js__WEBPACK_IMPORTED_MODULE_0__/* .CONSTANTS */ .a.SHADER.SHADERVAR_UNI_INVVIEWMAT);
                this._inverseProjMatrixUniform = this._cgl.gl.getUniformLocation(this._program, _constants_js__WEBPACK_IMPORTED_MODULE_0__/* .CONSTANTS */ .a.SHADER.SHADERVAR_UNI_INVPROJMAT);
                this._materialIdUniform = this._cgl.gl.getUniformLocation(this._program, _constants_js__WEBPACK_IMPORTED_MODULE_0__/* .CONSTANTS */ .a.SHADER.SHADERVAR_UNI_MATERIALID);
                this._objectIdUniform = this._cgl.gl.getUniformLocation(this._program, _constants_js__WEBPACK_IMPORTED_MODULE_0__/* .CONSTANTS */ .a.SHADER.SHADERVAR_UNI_OBJECTID);

                for (let i = 0; i < this._uniforms.length; i++) this._uniforms[i].needsUpdate = true;
            }
        }

        if (this._cgl.currentProgram != this._program)
        {
            this._cgl.profileData.profileShaderBinds++;
            this._cgl.gl.useProgram(this._program);
            this._cgl.currentProgram = this._program;
        }

        for (let i = 0; i < this._uniforms.length; i++)
            if (this._uniforms[i].needsUpdate) this._uniforms[i].updateValue();

        if (this._pMatrixState != this._cgl.getProjectionMatrixStateCount())
        {
            this._pMatrixState = this._cgl.getProjectionMatrixStateCount();
            this._cgl.gl.uniformMatrix4fv(this._projMatrixUniform, false, this._cgl.pMatrix);
            this._cgl.profileData.profileMVPMatrixCount++;
        }

        if (this._objectIdUniform)
            this._cgl.gl.uniform1f(this._objectIdUniform, ++this._cgl.tempData.objectIdCounter);

        if (this._materialIdUniform)
            this._cgl.gl.uniform1f(this._materialIdUniform, this._materialId);

        if (this._vMatrixUniform)
        {
            if (this._vMatrixState != this._cgl.getViewMatrixStateCount())
            {
                this._cgl.gl.uniformMatrix4fv(this._vMatrixUniform, false, this._cgl.vMatrix);
                this._cgl.profileData.profileMVPMatrixCount++;
                this._vMatrixState = this._cgl.getViewMatrixStateCount();

                if (this._inverseViewMatrixUniform)
                {
                    gl_matrix__WEBPACK_IMPORTED_MODULE_3__.invert(this._tempInverseViewMatrix, this._cgl.vMatrix);
                    this._cgl.gl.uniformMatrix4fv(this._inverseViewMatrixUniform, false, this._tempInverseViewMatrix);
                    this._cgl.profileData.profileMVPMatrixCount++;
                }
                if (this._inverseProjMatrixUniform)
                {
                    gl_matrix__WEBPACK_IMPORTED_MODULE_3__.invert(this._tempInverseProjMatrix, this._cgl.pMatrix);
                    this._cgl.gl.uniformMatrix4fv(this._inverseProjMatrixUniform, false, this._tempInverseProjMatrix);
                    this._cgl.profileData.profileMVPMatrixCount++;
                }
            }
            this._cgl.gl.uniformMatrix4fv(this._mMatrixUniform, false, this._cgl.mMatrix);
            this._cgl.profileData.profileMVPMatrixCount++;

            if (this._camPosUniform)
            {
                gl_matrix__WEBPACK_IMPORTED_MODULE_3__.invert(this._tempCamPosMatrix, this._cgl.vMatrix);
                this._cgl.gl.uniform3f(this._camPosUniform, this._tempCamPosMatrix[12], this._tempCamPosMatrix[13], this._tempCamPosMatrix[14]);
                this._cgl.profileData.profileMVPMatrixCount++;
            }
        }
        else
        {
            // mvmatrix deprecated....
            const tempmv = gl_matrix__WEBPACK_IMPORTED_MODULE_3__.create();

            gl_matrix__WEBPACK_IMPORTED_MODULE_3__.mul(tempmv, this._cgl.vMatrix, this._cgl.mMatrix);
            this._cgl.gl.uniformMatrix4fv(this._mvMatrixUniform, false, tempmv);
            this._cgl.profileData.profileMVPMatrixCount++;
        }

        if (this._normalMatrixUniform)
        {
            // mat4.mul(this._tempNormalMatrix, this._cgl.vMatrix, this._cgl.mMatrix);
            gl_matrix__WEBPACK_IMPORTED_MODULE_3__.invert(this._tempNormalMatrix, this._cgl.mMatrix);
            gl_matrix__WEBPACK_IMPORTED_MODULE_3__.transpose(this._tempNormalMatrix, this._tempNormalMatrix);

            this._cgl.gl.uniformMatrix4fv(this._normalMatrixUniform, false, this._tempNormalMatrix);
            this._cgl.profileData.profileMVPMatrixCount++;
        }

        for (let i = 0; i < this._libs.length; i++)
        {
            if (this._libs[i].onBind) this._libs[i].onBind.bind(this._libs[i])(this._cgl, this);
        }

        this._bindTextures();

        return this._isValid;
    }

    unBind()
    {
    }

    dispose()
    {

        if (this._program && this._cgl && this._cgl.gl) this._cgl.gl.deleteProgram(this._program);
        this._program = null;
    }

    setDrawBuffers(arr)
    {
        this._log.warn("useless drawbuffers...?!");
    }

    getUniforms()
    {
        return this._uniforms;
    }

    getUniform(name)
    {
        for (let i = 0; i < this._uniforms.length; i++)
            if (this._uniforms[i].getName() == name)
                return this._uniforms[i];
        return null;
    }

    removeAllUniforms()
    {
        this._uniforms = [];
        // for (let i = 0; i < this._uniforms.length; i++)
        //     this.removeUniform(this._uniforms[i].name);
    }

    _addUniform(uni)
    {
        this._uniforms.push(uni);
        this.setWhyCompile("add uniform " + name);
    }

    /**
     * add a uniform to the fragment shader
     * @param {String} type ['f','t', etc]
     * @param {String} name
     * @param {any} valueOrPort value or port
     * @param p2
     * @param p3
     * @param p4
     * @returns {Uniform}
     */
    addUniformFrag(type, name, valueOrPort, p2, p3, p4)
    {
        const uni = new _cgl_shader_uniform_js__WEBPACK_IMPORTED_MODULE_7__/* .Uniform */ .n(this, type, name, valueOrPort, p2, p3, p4);
        uni.shaderType = "frag";
        return uni;
    }

    /**
     * add a uniform to the vertex shader
     * @param {String} type ['f','t', etc]
     * @param {String} name
     * @param {any} valueOrPort value or port
     * @param p2
     * @param p3
     * @param p4
     * @returns {Uniform}
     */
    addUniformVert(type, name, valueOrPort, p2, p3, p4)
    {
        const uni = new _cgl_shader_uniform_js__WEBPACK_IMPORTED_MODULE_7__/* .Uniform */ .n(this, type, name, valueOrPort, p2, p3, p4);
        uni.shaderType = "vert";
        return uni;
    }

    /**
     * add a uniform to both shaders
     * @param {String} type ['f','t', etc]
     * @param {String} name
     * @param {any} valueOrPort value or port
     * @param p2
     * @param p3
     * @param p4
     * @returns {Uniform}
     */
    addUniformBoth(type, name, valueOrPort, p2, p3, p4)
    {
        const uni = new _cgl_shader_uniform_js__WEBPACK_IMPORTED_MODULE_7__/* .Uniform */ .n(this, type, name, valueOrPort, p2, p3, p4);
        uni.shaderType = "both";
        return uni;
    }

    /**
     * add a struct & its uniforms to the fragment shader
     * @param {String} structName name of the struct, i.e.: LightStruct
     * @param {String} uniformName name of the struct uniform in the shader, i.e.: lightUni
     * @param {Array} members array of objects containing the struct members. see example for structure

     * @returns {Object}
     * @example
     * const shader = new CGL.Shader(cgl, 'MinimalMaterial');
     * shader.setSource(attachments.shader_vert, attachments.shader_frag);
     * shader.addUniformStructFrag("Light", "uniformLight", [
     * { "type": "3f", "name": "position", "v1": null },
     * { "type": "4f", "name": "color", "v1": inR, v2: inG, v3: inB, v4: inAlpha }
     * ]);
     */
    addUniformStructFrag(structName, uniformName, members)
    {
        const uniforms = {};

        if (!members) return uniforms;

        for (let i = 0; i < members.length; i += 1)
        {
            const member = members[i];
            if (!this.hasUniform(uniformName + "." + member.name))
            {
                const uni = new _cgl_shader_uniform_js__WEBPACK_IMPORTED_MODULE_7__/* .Uniform */ .n(this, member.type, uniformName + "." + member.name, member.v1, member.v2, member.v3, member.v4, uniformName, structName, member.name);
                uni.shaderType = "frag";
                uniforms[uniformName + "." + member.name] = uni;
            }
        }

        return uniforms;
    }

    /**
     * add a struct & its uniforms to the vertex shader
     * @param {String} structName name of the struct, i.e.: LightStruct
     * @param {String} uniformName name of the struct uniform in the shader, i.e.: lightUni
     * @param {Array} members array of objects containing the struct members. see example for structure
     * @returns {object}
     * @example
     * const shader = new CGL.Shader(cgl, 'MinimalMaterial');
     * shader.setSource(attachments.shader_vert, attachments.shader_frag);
     * shader.addUniformStructVert("Light", "uniformLight", [
     * { "type": "3f", "name": "position", "v1": null },
     * { "type": "4f", "name": "color", "v1": inR, v2: inG, v3: inB, v4: inAlpha }
     * ]);
     */
    addUniformStructVert(structName, uniformName, members)
    {
        const uniforms = {};

        if (!members) return uniforms;

        for (let i = 0; i < members.length; i += 1)
        {
            const member = members[i];
            if (!this.hasUniform(uniformName + "." + member.name))
            {
                const uni = new _cgl_shader_uniform_js__WEBPACK_IMPORTED_MODULE_7__/* .Uniform */ .n(this, member.type, uniformName + "." + member.name, member.v1, member.v2, member.v3, member.v4, uniformName, structName, member.name);
                uni.shaderType = "vert";
                uniforms[uniformName + "." + member.name] = uni;
            }
        }

        return uniforms;
    }

    /**
     * add a struct & its uniforms to the both shaders. PLEASE NOTE: it is not possible to add the same struct to both shaders when it contains ANY integer members.
     * @param {String} structName name of the struct, i.e.: LightStruct
     * @param {String} uniformName name of the struct uniform in the shader, i.e.: lightUni
     * @param {Array} members array of objects containing the struct members. see example for structure

     * @returns {Object}
     * @example
     * const shader = new CGL.Shader(cgl, 'MinimalMaterial');
     * shader.setSource(attachments.shader_vert, attachments.shader_frag);
     * shader.addUniformStructBoth("Light", "uniformLight", [
     * { "type": "3f", "name": "position", "v1": null },
     * { "type": "4f", "name": "color", "v1": inR, v2: inG, v3: inB, v4: inAlpha }
     * ]);
     */
    addUniformStructBoth(structName, uniformName, members)
    {
        const uniforms = {};

        if (!members) return uniforms;

        for (let i = 0; i < members.length; i += 1)
        {
            const member = members[i];
            if ((member.type === "2i" || member.type === "i" || member.type === "3i"))
                this._log.error("Adding an integer struct member to both shaders can potentially error. Please use different structs for each shader. Error occured in struct:", structName, " with member:", member.name, " of type:", member.type, ".");
            if (!this.hasUniform(uniformName + "." + member.name))
            {
                const uni = new _cgl_shader_uniform_js__WEBPACK_IMPORTED_MODULE_7__/* .Uniform */ .n(this, member.type, uniformName + "." + member.name, member.v1, member.v2, member.v3, member.v4, uniformName, structName, member.name);
                uni.shaderType = "both";
                uniforms[uniformName + "." + member.name] = uni;
            }
        }

        return uniforms;
    }

    /**
     * @param {String} vstr
     * @param {String} fstr
     */
    _createProgram(vstr, fstr)
    {
        this._cgl.printError("before _createprogram");

        const program = this._cgl.gl.createProgram();

        this.vshader = CglShader.createShader(this._cgl, vstr, this._cgl.gl.VERTEX_SHADER, this);
        this.fshader = CglShader.createShader(this._cgl, fstr, this._cgl.gl.FRAGMENT_SHADER, this);

        if (this.vshader && this.fshader)
        {
            this._cgl.gl.attachShader(program, this.vshader);
            this._cgl.gl.attachShader(program, this.fshader);

            this._linkProgram(program, vstr, fstr);
        }
        else
        {
            this._isValid = false;
            this._cgl.printError("shader _createProgram");
            this._log.error("could not link shaderprogram");
            return null;
        }

        this._cgl.printError("shader _createProgram");
        return program;
    }

    hasErrors()
    {
        return this._hasErrors;
    }

    /**
     * @param {any} program
     * @param {string} vstr
     * @param {string} fstr
     */
    _linkProgram(program, vstr, fstr)
    {
        this._cgl.printError("before _linkprogram");

        if (this._feedBackNames.length > 0)
        {
            this._cgl.gl.transformFeedbackVaryings(program, this._feedBackNames, this._cgl.gl.SEPARATE_ATTRIBS);
            // INTERLEAVED_ATTRIBS
            // SEPARATE_ATTRIBS
        }

        this._cgl.gl.linkProgram(program);
        this._cgl.printError("gl.linkprogram");
        this._isValid = true;
        this._hasErrors = false;

        if (this._cgl.patch.config.glValidateShader !== false)
        {
            this._cgl.gl.validateProgram(program);

            if (!this._cgl.gl.getProgramParameter(program, this._cgl.gl.VALIDATE_STATUS))
            {
                // validation failed
                this._log.log("shaderprogram validation failed...");

                this._cgl.gl.getProgramInfoLog(program);
            }

            if (!this._cgl.gl.getProgramParameter(program, this._cgl.gl.LINK_STATUS))
            {
                this._hasErrors = true;

                const infoLogFrag = this._cgl.gl.getShaderInfoLog(this.fshader);
                const infoLogVert = this._cgl.gl.getShaderInfoLog(this.vshader);

                if (this.logError)
                    this._log.error(this._name + " shader linking fail...");
                else
                    this._log.warn(this._name + " shader linking fail...");

                if (infoLogFrag) this._log.warn(this._cgl.gl.getShaderInfoLog(this.fshader));
                if (infoLogVert) this._log.warn(this._cgl.gl.getShaderInfoLog(this.vshader));

                this._cgl.gl.getProgramInfoLog(program);
                if (!CABLES.UI) this._log.log(this);
                this._isValid = false;

                this._cgl.printError("shader link err");
            }
        }
    }

    getProgram()
    {
        return this._program;
    }

    /**
     * @param {any[]} names
     */
    setFeedbackNames(names)
    {
        this.setWhyCompile("setFeedbackNames");
        this._feedBackNames = names;
    }

    /**
      * adds attribute definition to shader header without colliding with other shader modules...
     * when attrFrag is defined, vertex shader will output this attribute to the fragment shader
     * @param {Object} attr {type:x,name:x,[nameFrag:x]}
     * @return {Object}
     */
    addAttribute(attr)
    {
        for (let i = 0; i < this._attributes.length; i++)
        {
            if (this._attributes[i].name == attr.name && this._attributes[i].nameFrag == attr.nameFrag) return;
        }
        this._attributes.push(attr);

        this.setWhyCompile("addAttribute");
    }

    bindTextures()
    {
        this._bindTextures();
    }

    _bindTextures()
    {
        if (this._textureStackTex.length > this._cgl.maxTextureUnits)
        {
            this._log.warn("[shader._bindTextures] too many textures bound", this._textureStackTex.length + "/" + this._cgl.maxTextureUnits);
        }

        // for (let i = this._textureStackTex.length + 1; i < this._cgl.maxTextureUnits; i++) this._cgl.setTexture(i, null);

        for (let i = 0; i < this._textureStackTex.length; i++)
        {
            // this._log.log(this._textureStackTex.length, i);
            if (!this._textureStackTex[i] && !this._textureStackTexCgl[i])
            {
                this._log.warn("no texture for pushtexture", this._name);
            }
            else
            {
                let t = this._textureStackTex[i];
                if (this._textureStackTexCgl[i])
                {
                    t = this._textureStackTexCgl[i].tex || CGL.Texture.getEmptyTexture(this._cgl).tex;
                }

                let bindOk = true;

                if (!this._textureStackUni[i])
                {
                    // throw(new Error('no uniform given to texturestack'));
                    this._log.warn("no uniform for pushtexture", this._name);
                    bindOk = this._cgl.setTexture(i, t, this._textureStackType[i]);
                }
                else
                {
                    this._textureStackUni[i].setValue(i);
                    bindOk = this._cgl.setTexture(i, t, this._textureStackType[i]);

                    // this._log.log(bindOk, i, t, this._textureStackType[i]);
                }
                if (!bindOk) this._log.warn("tex bind failed", this.getName(), this._textureStackUni[i]);
            }
        }
    }

    /**
     * @param {Uniform} uni
     * @param {Texture} tex
     */
    setUniformTexture(uni, tex)
    {
        tex = tex || _cgl_texture_js__WEBPACK_IMPORTED_MODULE_8__/* .Texture */ .g.getTempTexture(this._cgl);
        for (let i = 0; i < this._textureStackUni.length; i++)
            if (this._textureStackUni[i] == uni)
            {
                const old = this._textureStackTex[i] || this._textureStackTexCgl[i];
                if (tex.hasOwnProperty("tex"))
                {
                    this._textureStackTexCgl[i] = tex;
                    this._textureStackTex[i] = null;
                }
                else
                {
                    this._textureStackTexCgl[i] = null;
                    this._textureStackTex[i] = tex;
                }

                // this._textureStackTex[i] = tex;
                // this._cgl.setTexture(i, tex, this._textureStackType[i]);
                return old;
            }
        return null;
    }

    /**
     * push a texture on the stack. those textures will be bound when binding the shader. texture slots are automatically set
     * @param {Uniform} uniform texture uniform
     * @param {Texture} t texture
     * @param {number} type texture type, can be ignored when TEXTURE_2D
     */
    pushTexture(uniform, t, type)
    {
        if (!uniform)
        {
            // this._log.log("pushtexture: no uniform given to texturestack", "shader:"+this._name,uniform,t,type);
            return;
        }
        if (!t)
        {
            // if(uniform)this._log.warn("pushtexture: no tex","shader:"+this._name," uniform:"+uniform.name);
            return;
        }
        if (!t.hasOwnProperty("tex") && !(t instanceof WebGLTexture))
        {
            this._log.warn(new Error("invalid texture").stack);

            this._log.warn("[cgl_shader] invalid texture...", t);
            return;
        }

        this._textureStackUni.push(uniform);

        if (t.hasOwnProperty("tex"))
        {
            this._textureStackTexCgl.push(t);
            this._textureStackTex.push(null);
        }
        else
        {
            this._textureStackTexCgl.push(null);
            this._textureStackTex.push(t);
        }

        this._textureStackType.push(type);
    }

    /**
     * pop last texture
     */
    popTexture()
    {
        this._textureStackUni.pop();
        this._textureStackTex.pop();
        this._textureStackTexCgl.pop();
        this._textureStackType.pop();
    }

    /**
     * pop all textures
     */
    popTextures()
    {
        this._textureStackTex.length =
        this._textureStackTexCgl.length =
        this._textureStackType.length =
        this._textureStackUni.length = 0;
    }

    getMaterialId()
    {
        return this._materialId;
    }

    getInfo()
    {
        const info = {};
        info.name = this._name;
        // info.modules = JSON.parse(JSON.stringify(this._modules));
        // info.defines = JSON.parse(JSON.stringify(this._defines));
        info.defines = this.getDefines();
        info.hasErrors = this.hasErrors();

        return info;
    }

    getDefaultFragmentShader(r, g, b, a)
    {
        return getDefaultFragmentShader(r, g, b, a);
    }

    getDefaultVertexShader()
    {
        return getDefaultVertexShader();
    }
}

// --------------------------

CglShader.getDefaultVertexShader = getDefaultVertexShader;
CglShader.getDefaultFragmentShader = getDefaultFragmentShader;

CglShader.getErrorFragmentShader = function ()
{
    return ""
        + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "void main()"
        + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "{"
        + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "   float g=mod((gl_FragCoord.y+gl_FragCoord.x),50.0)/50.0;"
        + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "   g= step(0.1,g);"
        + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "   outColor = vec4( g+0.5, 0.0, 0.0, 1.0);"
        + _constants_js__WEBPACK_IMPORTED_MODULE_0__.nl + "}";
};

/**
 * @param {CglContext} cgl
 * @param {String} str
 * @param {number} type
 * @param {CglShader} cglShader
 * @returns {CglShader}
 */
CglShader.createShader = function (cgl, str, type, cglShader)
{
    if (cgl.aborted) return;

    const shader = cgl.gl.createShader(type);
    cgl.gl.shaderSource(shader, str);
    cgl.gl.compileShader(shader);

    if (!cgl.gl.getShaderParameter(shader, cgl.gl.COMPILE_STATUS))
    {
        cglShader.error = { "str": str, "infoLog": cgl.gl.getShaderInfoLog(shader) };

        if (CABLES.UI) gui.emitEvent("ShaderError", cglShader);

        if (!cglShader.error.infoLog)
        {
            cglShader._log.warn("empty shader info log", this._name);
            return;
        }
        cglShader.setSource(CglShader.getDefaultVertexShader(), CglShader.getErrorFragmentShader());
    }
    return shader;
};




/***/ }),

/***/ 960:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   y: () => (/* binding */ ShaderLibMods)
/* harmony export */ });
/* harmony import */ var _cgl_shader_uniform_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(923);
/* harmony import */ var _cgl_textureeffect_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(771);
/* harmony import */ var _cgl_texture_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(70);




/** @type {Object} */
const ShaderLibMods = {
    "CGL.BLENDMODES": function ()
    {
        this.name = "blendmodes";
        this.srcHeadFrag = _cgl_textureeffect_js__WEBPACK_IMPORTED_MODULE_0__/* .TextureEffect */ .p.getBlendCode();
    },

    "CGL.BLENDMODES3": function ()
    {
        this.name = "blendmodes3";
        this.srcHeadFrag = _cgl_textureeffect_js__WEBPACK_IMPORTED_MODULE_0__/* .TextureEffect */ .p.getBlendCode(3);
    },

    "CGL.LUMINANCE": function ()
    {
        this.name = "luminance";
        this.srcHeadFrag = "".endl()
            + "float cgl_luminance(vec3 c)".endl()
            + "{".endl()
            + "    return dot(vec3(0.2126,0.7152,0.0722),c);".endl()
            + "}".endl();
    },

    // quite good random numbers, but somehow don't work in ANGLE
    "CGL.RANDOM_OLD": function ()
    {
        this.name = "randomNumber";
        this.srcHeadFrag = "".endl()
            + "float cgl_random(vec2 co)".endl()
            + "{".endl()
            + "    return fract(sin(dot(co.xy ,vec2(12.9898,4.1414))) * 432758.5453);".endl()
            + "}".endl()
            + "vec3 cgl_random3(vec2 co)".endl()
            + "{".endl()
            + "    return vec3( cgl_random(co),cgl_random(co+0.5711),cgl_random(co+1.5711));".endl()
            + "}";
    },

    // low quality generative ranodm numbers
    "CGL.RANDOM_LOW": function ()
    {
        this.name = "randomNumber";
        this.srcHeadFrag = "".endl()
            + "float cgl_random(vec2 co)".endl()
            + "{".endl()
            + "    return fract(sin(dot(co.xy ,vec2(12.9898,4.1414))) * 358.5453);".endl()
            + "}".endl()
            + "vec3 cgl_random3(vec2 co)".endl()
            + "{".endl()
            + "    return vec3( cgl_random(co),cgl_random(co+0.5711),cgl_random(co+1.5711));".endl()
            + "}";
    },

    "CGL.RANDOM_TEX": function ()
    {
        this.name = "randomNumbertex";

        this.srcHeadFrag = "".endl()
            + "UNI sampler2D CGLRNDTEX;".endl()
            + "float cgl_random(vec2 co)".endl()
            + "{".endl()
            + "    return texture(CGLRNDTEX,co*5711.0).r;".endl()
            + "}".endl()
            + "vec3 cgl_random3(vec2 co)".endl()
            + "{".endl()
            + "    return texture(CGLRNDTEX,co*5711.0).rgb;".endl()
            + "}";

        this.initUniforms = function (shader)
        {
            return [new _cgl_shader_uniform_js__WEBPACK_IMPORTED_MODULE_1__/* .Uniform */ .n(shader, "t", "CGLRNDTEX", 7)];
        };

        this.onBind = function (cgl, shader)
        {
            _cgl_texture_js__WEBPACK_IMPORTED_MODULE_2__/* .Texture */ .g.getRandomTexture(cgl);
            cgl.setTexture(7, _cgl_texture_js__WEBPACK_IMPORTED_MODULE_2__/* .Texture */ .g.getRandomTexture(cgl).tex);
        };
    }

};


/***/ }),

/***/ 923:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   n: () => (/* binding */ Uniform)
/* harmony export */ });
/* harmony import */ var _cg_cg_uniform_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(475);




/**
 * Shader uniforms
 *
 * types:
 * <pre>
 * f    - float
 * 2f   - vec2
 * 3f   - vec3
 * 4f   - vec4
 * i    - integer
 * t    - texture
 * m4   - mat4, 4x4 float matrix
 * f[]  - array of floats
 * 2f[] - array of float vec2
 * 3f[] - array of float vec3
 * 4f[] - array of float vec4
 * </pre>
 *
 * @namespace external:CGL
 * @class
 * @param {CgShader} shader
 * @param {String} [type=f]
 * @param {String} name
 * @param {Number|Port} value  can be a Number,Matrix or Port
 * @example
 * // bind float uniform called myfloat and initialize with value 1.0
 * const unir=new CGL.Uniform(shader,'f','myfloat',1.0);
 * unir.setValue(1.0);
 *
 * // bind float uniform called myfloat and automatically set it to input port value
 * const myPort=op.inFloat("input");
 * const pv=new CGL.Uniform(shader,'f','myfloat',myPort);
 *
 */

// export const Uniform(__shader, __type, __name, _value, _port2, _port3, _port4, _structUniformName, _structName, _propertyName)

class Uniform extends _cg_cg_uniform_js__WEBPACK_IMPORTED_MODULE_0__/* .CgUniform */ .v
{
    constructor(__shader, __type, __name, _value, _port2, _port3, _port4, _structUniformName, _structName, _propertyName)
    {
        super(__shader, __type, __name, _value, _port2, _port3, _port4, _structUniformName, _structName, _propertyName);
        this._loc = -1;
        this._cgl = __shader._cgl;
    }

    get name()
    {
        return this._name;
    }

    copy(newShader)
    {
        const uni = new Uniform(newShader, this._type, this._name, this._value, this._port2, this._port3, this._port4, this._structUniformName, this._structName, this._propertyName);
        uni.shaderType = this.shaderType;
        return uni;
    }

    /**
     * returns type as glsl type string. e.g. 'f' returns 'float'
     * @function getGlslTypeString
     * @memberof Uniform
     * @instance
     * @return {string} type as string
     */
    getGlslTypeString()
    {
        return Uniform.glslTypeString(this._type);
    }

    _isValidLoc()
    {
        return this._loc != -1;// && this._loc != null;
    }

    resetLoc()
    {
        this._loc = -1;
        this.needsUpdate = true;
    }

    bindTextures() {}

    getLoc()
    {
        return this._loc;
    }

    updateFromPort4f()
    {
        this._value[0] = this._port.get();
        this._value[1] = this._port2.get();
        this._value[2] = this._port3.get();
        this._value[3] = this._port4.get();
        this.setValue(this._value);
    }

    updateFromPort3f()
    {
        this._value[0] = this._port.get();
        this._value[1] = this._port2.get();
        this._value[2] = this._port3.get();
        this.setValue(this._value);
    }

    updateFromPort2f()
    {
        this._value[0] = this._port.get();
        this._value[1] = this._port2.get();
        this.setValue(this._value);
    }

    updateFromPort()
    {
        this.setValue(this._port.get());
    }

    updateValueF()
    {
        if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
        else this.needsUpdate = false;

        this._shader.getCgl().gl.uniform1f(this._loc, this._value);
        this._cgl.profileData.profileUniformCount++;
    }

    setValueF(v)
    {
        if (v != this._value)
        {
            this.needsUpdate = true;
            this._value = v;
        }
    }

    updateValueI()
    {
        if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
        else this.needsUpdate = false;

        this._shader.getCgl().gl.uniform1i(this._loc, this._value);
        this._cgl.profileData.profileUniformCount++;
    }

    updateValue2I()
    {
        if (!this._value) return;

        if (!this._isValidLoc())
        {
            this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
            this._cgl.profileData.profileShaderGetUniform++;
            this._cgl.profileData.profileShaderGetUniformName = this._name;
        }

        this._shader.getCgl().gl.uniform2i(this._loc, this._value[0], this._value[1]);

        this.needsUpdate = false;
        this._cgl.profileData.profileUniformCount++;
    }

    updateValue3I()
    {
        if (!this._value) return;
        if (!this._isValidLoc())
        {
            this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
            this._cgl.profileData.profileShaderGetUniform++;
            this._cgl.profileData.profileShaderGetUniformName = this._name;
        }

        this._shader.getCgl().gl.uniform3i(this._loc, this._value[0], this._value[1], this._value[2]);
        this.needsUpdate = false;
        this._cgl.profileData.profileUniformCount++;
    }

    updateValue4I()
    {
        if (!this._isValidLoc())
        {
            this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
            this._cgl.profileData.profileShaderGetUniform++;
            this._cgl.profileData.profileShaderGetUniformName = this._name;
        }
        this._shader.getCgl().gl.uniform4i(this._loc, this._value[0], this._value[1], this._value[2], this._value[3]);
        this._cgl.profileData.profileUniformCount++;
    }

    setValueI(v)
    {
        if (v != this._value)
        {
            this.needsUpdate = true;
            this._value = v;
        }
    }

    setValue2I(v)
    {
        if (!v) return;
        if (!this._oldValue)
        {
            this._oldValue = [v[0] - 1, 1];
            this.needsUpdate = true;
        }
        else if (v[0] != this._oldValue[0] || v[1] != this._oldValue[1])
        {
            this._oldValue[0] = v[0];
            this._oldValue[1] = v[1];
            this.needsUpdate = true;
        }

        this._value = v;
    }

    setValue3I(v)
    {
        if (!v) return;
        if (!this._oldValue)
        {
            this._oldValue = [v[0] - 1, 1, 2];
            this.needsUpdate = true;
        }
        else if (v[0] != this._oldValue[0] || v[1] != this._oldValue[1] || v[2] != this._oldValue[2])
        {
            this._oldValue[0] = v[0];
            this._oldValue[1] = v[1];
            this._oldValue[2] = v[2];
            this.needsUpdate = true;
        }

        this._value = v;
    }

    setValue4I(v)
    {
        this.needsUpdate = true;
        this._value = v || vec4.create();
    }

    updateValueBool()
    {
        if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
        else this.needsUpdate = false;
        this._shader.getCgl().gl.uniform1i(this._loc, this._value ? 1 : 0);

        this._cgl.profileData.profileUniformCount++;
    }

    setValueBool(v)
    {
        if (v != this._value)
        {
            this.needsUpdate = true;
            this._value = v;
        }
    }

    setValueArray4F(v)
    {
        this.needsUpdate = true;
        this._value = v;
    }

    updateValueArray4F()
    {
        if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
        else this.needsUpdate = false;

        if (!this._value) return;
        this._shader.getCgl().gl.uniform4fv(this._loc, this._value);
        this._cgl.profileData.profileUniformCount++;
    }

    setValueArray3F(v)
    {
        this.needsUpdate = true;
        this._value = v;
    }

    updateValueArray3F()
    {
        if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
        else this.needsUpdate = false;

        if (!this._value) return;
        this._shader.getCgl().gl.uniform3fv(this._loc, this._value);
        this._cgl.profileData.profileUniformCount++;
    }

    setValueArray2F(v)
    {
        this.needsUpdate = true;
        this._value = v;
    }

    updateValueArray2F()
    {
        if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
        else this.needsUpdate = false;

        if (!this._value) return;
        this._shader.getCgl().gl.uniform2fv(this._loc, this._value);
        this._cgl.profileData.profileUniformCount++;
    }

    setValueArrayF(v)
    {
        this.needsUpdate = true;
        this._value = v;
    }

    updateValueArrayF()
    {
        if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
        else this.needsUpdate = false;

        if (!this._value) return;
        this._shader.getCgl().gl.uniform1fv(this._loc, this._value);
        this._cgl.profileData.profileUniformCount++;
    }

    setValueArrayT(v)
    {
        this.needsUpdate = true;
        this._value = v;
    }

    updateValue3F()
    {
        if (!this._value) return;
        if (!this._isValidLoc())
        {
            this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
            this._cgl.profileData.profileShaderGetUniform++;
            this._cgl.profileData.profileShaderGetUniformName = this._name;
        }

        this._shader.getCgl().gl.uniform3f(this._loc, this._value[0], this._value[1], this._value[2]);
        this.needsUpdate = false;
        this._cgl.profileData.profileUniformCount++;
    }

    setValue3F(v)
    {
        if (!v) return;
        if (!this._oldValue)
        {
            this._oldValue = [v[0] - 1, 1, 2];
            this.needsUpdate = true;
        }
        else if (v[0] != this._oldValue[0] || v[1] != this._oldValue[1] || v[2] != this._oldValue[2])
        {
            this._oldValue[0] = v[0];
            this._oldValue[1] = v[1];
            this._oldValue[2] = v[2];
            this.needsUpdate = true;
        }

        this._value = v;
    }

    updateValue2F()
    {
        if (!this._value) return;

        if (!this._isValidLoc())
        {
            this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
            this._cgl.profileData.profileShaderGetUniform++;
            this._cgl.profileData.profileShaderGetUniformName = this._name;
        }

        this._shader.getCgl().gl.uniform2f(this._loc, this._value[0], this._value[1]);
        this.needsUpdate = false;
        this._cgl.profileData.profileUniformCount++;
    }

    setValue2F(v)
    {
        if (!v) return;
        if (!this._oldValue)
        {
            this._oldValue = [v[0] - 1, 1];
            this.needsUpdate = true;
        }
        else if (v[0] != this._oldValue[0] || v[1] != this._oldValue[1])
        {
            this._oldValue[0] = v[0];
            this._oldValue[1] = v[1];
            this.needsUpdate = true;
        }
        this._value = v;
    }

    updateValue4F()
    {
        if (!this._isValidLoc())
        {
            this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
            this._cgl.profileData.profileShaderGetUniform++;
            this._cgl.profileData.profileShaderGetUniformName = this._name;
        }

        if (!this._value)
        {
            this._log.warn("no value for uniform", this._name, this);
            this._value = [0, 0, 0, 0];
        }

        this.needsUpdate = false;
        this._shader.getCgl().gl.uniform4f(this._loc, this._value[0], this._value[1], this._value[2], this._value[3]);
        this._cgl.profileData.profileUniformCount++;
    }

    setValue4F(v)
    {
        if (typeof this.value == "number") this.value = vec4.create(); // this should not be needed, but somehow it crashes with some shadermods

        if (!v) return;
        if (!this._oldValue)
        {
            this._oldValue = [v[0] - 1, 1, 2, 3];
            this.needsUpdate = true;
        }
        else if (v[0] != this._oldValue[0] || v[1] != this._oldValue[1] || v[2] != this._oldValue[2] || v[3] != this._oldValue[3])
        {
            this._oldValue[0] = v[0];
            this._oldValue[1] = v[1];
            this._oldValue[2] = v[2];
            this.needsUpdate = true;
        }

        this._value = v;
    }

    updateValueM4()
    {
        if (!this._isValidLoc())
        {
            this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
            this._cgl.profileData.profileShaderGetUniform++;
            this._cgl.profileData.profileShaderGetUniformName = this._name;
        }
        if (!this._value || this._value.length % 16 != 0) return console.log("this.name", this._name, this._value);

        this._shader.getCgl().gl.uniformMatrix4fv(this._loc, false, this._value);
        this._cgl.profileData.profileUniformCount++;
    }

    setValueM4(v)
    {
        this.needsUpdate = true;
        this._value = v || mat4.create();
    }

    updateValueArrayT()
    {
        if (!this._isValidLoc()) this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
        else this.needsUpdate = false;

        if (!this._value) return;
        this._shader.getCgl().gl.uniform1iv(this._loc, this._value);
        this._cgl.profileData.profileUniformCount++;
    }

    updateValueT()
    {
        if (!this._isValidLoc())
        {
            this._loc = this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(), this._name);
            this._cgl.profileData.profileShaderGetUniform++;
            this._cgl.profileData.profileShaderGetUniformName = this._name;
        }

        this._cgl.profileData.profileUniformCount++;
        this._shader.getCgl().gl.uniform1i(this._loc, this._value);
        this.needsUpdate = false;
    }

    setValueT(v)
    {
        this.needsUpdate = true;
        this._value = v;
    }
}

Uniform.glslTypeString = (t) =>
{
    if (t == "f") return "float";
    if (t == "b") return "bool";
    if (t == "i") return "int";
    if (t == "2i") return "ivec2";
    if (t == "2f") return "vec2";
    if (t == "3f") return "vec3";
    if (t == "4f") return "vec4";
    if (t == "m4") return "mat4";

    if (t == "t") return "sampler2D";
    if (t == "tc") return "samplerCube";

    if (t == "3f[]") return null; // ignore this for now...
    if (t == "m4[]") return null; // ignore this for now...
    if (t == "f[]") return null; // ignore this for now...

    console.warn("[CGL UNIFORM] unknown glsl type string ", t);
};

/**
 * @function setValue
 * @memberof Uniform
 * @instance
 * @param {Number|Array|Matrix|Texture} value
 */


/***/ }),

/***/ 273:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   S: () => (/* binding */ MESHES)
/* harmony export */ });
/* harmony import */ var _cg_index_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(331);
/* harmony import */ var _cgl_mesh_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(264);



const MESHES = {};

MESHES.getSimpleRect = function (cgl, name, size = 1.0)
{
    const geom = new _cg_index_js__WEBPACK_IMPORTED_MODULE_0__/* .Geometry */ .V(name);

    geom.vertices = [1.0 * size, 1.0 * size, 0.0, -1.0 * size, 1.0 * size, 0.0, 1.0 * size, -1.0 * size, 0.0, -1.0 * size, -1.0 * size, 0.0];
    geom.texCoords = [1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0];
    geom.verticesIndices = [0, 1, 2, 2, 1, 3];
    geom.vertexNormals = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0];

    return cgl.createMesh(geom);
};

MESHES.getSimpleCube = function (cgl, name)
{
    const geom = new _cg_index_js__WEBPACK_IMPORTED_MODULE_0__/* .Geometry */ .V(name);
    geom.vertices = [-1, -1, 1, 1, -1, 1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, -1, 1, -1, 1, 1, -1, 1, 1, 1, -1, 1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, 1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1, 1, -1];
    geom.setTexCoords([0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0,]);
    geom.verticesIndices = [0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23];
    geom.vertexNormals = new Float32Array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0, -1.0, 0.0, 0.0]);
    geom.tangents = new Float32Array([0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1]);
    geom.biTangents = new Float32Array([-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1]);

    return new _cgl_mesh_js__WEBPACK_IMPORTED_MODULE_1__/* .Mesh */ .e(cgl, geom);
};




/***/ }),

/***/ 308:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   G: () => (/* binding */ CglContext)
/* harmony export */ });
/* unused harmony export BLENDS */
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(849);
/* harmony import */ var cables__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(562);
/* harmony import */ var _constants_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(997);
/* harmony import */ var _cgl_shader_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(24);
/* harmony import */ var _cg_cg_context_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(628);
/* harmony import */ var _cgl_mesh_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(264);
/* harmony import */ var _cgl_texture_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(70);










const BLENDS = {
    "BLEND_NONE": 0,
    "BLEND_NORMAL": 1,
    "BLEND_ADD": 2,
    "BLEND_SUB": 3,
    "BLEND_MUL": 4,
};

/**
 * cables gl context/state manager
 * @class
 * @namespace external:CGL
 * @hideconstructor
 */
// const Context(_patch)
class CglContext extends _cg_cg_context_js__WEBPACK_IMPORTED_MODULE_0__/* .CgContext */ .A
{

    /**
     * @param {Patch} _patch
     */
    constructor(_patch)
    {
        super(_patch);

        this.gApi = _cg_cg_context_js__WEBPACK_IMPORTED_MODULE_0__/* .CgContext */ .A.API_WEBGL;
        this.aborted = false;

        /** @deprecated */
        this.pushMvMatrix = this.pushModelMatrix; // deprecated and wrong... still used??
        /** @deprecated */
        this.popMvMatrix = this.popmMatrix = this.popModelMatrix;// deprecated and wrong... still used??

        this._log = new cables_shared_client__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .A("cgl_context", { "onError": _patch.config.onError });

        this.glVersion = 0;
        this.glUseHalfFloatTex = false;
        this.clearCanvasTransparent = true;
        this.clearCanvasDepth = true;
        this.debugOneFrame = false;
        this.checkGlErrors = false; // true is slow // false should be default...
        this.maxTextureUnits = 0;
        this.maxVaryingVectors = 0;
        this.currentProgram = null;
        this._hadStackError = false;
        this.glSlowRenderer = false;
        this._isSafariCrap = false;

        this.temporaryTexture = null;

        /** @type {WebGL2RenderingContext} */
        this.gl = null;

        this._cursor = "auto";
        this._currentCursor = "";

        this._viewPortStack = [];
        this._glFrameBufferStack = [];
        this._frameBufferStack = [];
        this._shaderStack = [];
        this._stackDepthTest = [];
        this.mainloopOp = null;
        this._stackBlendMode = [];
        this._stackBlendModePremul = [];
        this._stackBlend = [];
        this._stackDepthFunc = [];
        this._stackCullFaceFacing = [];
        this._stackCullFace = [];
        this._stackDepthWrite = [];
        this._stackDepthTest = [];
        this._stackStencil = [];

        this._simpleShader = new _cgl_shader_js__WEBPACK_IMPORTED_MODULE_2__/* .Shader */ .M(this, "simpleshader");
        this._simpleShader.setModules(["MODULE_VERTEX_POSITION", "MODULE_COLOR", "MODULE_BEGIN_FRAG", "MODULE_VERTEX_MODELVIEW"]);
        this._simpleShader.setSource(_cgl_shader_js__WEBPACK_IMPORTED_MODULE_2__/* .Shader */ .M.getDefaultVertexShader(), _cgl_shader_js__WEBPACK_IMPORTED_MODULE_2__/* .Shader */ .M.getDefaultFragmentShader());

        this._currentShader = this._simpleShader;

        this._oldCanvasWidth = -1;
        this._oldCanvasHeight = -1;
        this._enabledExtensions = {};

        this.errorShader = null;
    }

    // set pixelDensity(p)
    // {
    //     this._pixelDensity = p;
    // }

    // get pixelDensity()
    // {
    //     return this._pixelDensity;
    // }

    get viewPort()
    {
        if (this._viewPortStack.length > 3)
        {
            const l = this._viewPortStack.length;

            return [
                this._viewPortStack[l - 4],
                this._viewPortStack[l - 3],
                this._viewPortStack[l - 2],
                this._viewPortStack[l - 1]
            ];
        }
        else
        {
            // workaround pre viewport stack times / or+and initial value...

            return this._viewPort;
        }
    }

    get mvMatrix() // deprecate
    {
        return this.mMatrix;
    }

    set mvMatrix(m) // deprecate
    {
        this.mMatrix = m;
    }

    /**
     * @param {HTMLCanvasElement} canv
     */
    _setCanvas(canv)
    {
        if (!canv) this._log.stack("_setCanvas undef");

        if (!this.patch.config.canvas) this.patch.config.canvas = {};
        if (!this.patch.config.canvas.hasOwnProperty("preserveDrawingBuffer")) this.patch.config.canvas.preserveDrawingBuffer = true;
        if (!this.patch.config.canvas.hasOwnProperty("premultipliedAlpha")) this.patch.config.canvas.premultipliedAlpha = false;
        if (!this.patch.config.canvas.hasOwnProperty("alpha")) this.patch.config.canvas.alpha = false;

        this.patch.config.canvas.stencil = true;

        if (this.patch.config.hasOwnProperty("clearCanvasColor")) this.clearCanvasTransparent = this.patch.config.clearCanvasColor;
        if (this.patch.config.hasOwnProperty("clearCanvasDepth")) this.clearCanvasDepth = this.patch.config.clearCanvasDepth;

        // safari stuff..........
        if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent) && (navigator.userAgent.match(/iPhone/i)))
        {
            this._isSafariCrap = true;
            this.glUseHalfFloatTex = true;
        }

        if (!this.patch.config.canvas.forceWebGl1) this.gl = canv.getContext("webgl2", this.patch.config.canvas);

        if (!this.gl || this.gl.isContextLost())
        {
            this.aborted = true;
            this._log.error("NO_WEBGL", "sorry, could not initialize WebGL. Please check if your Browser supports WebGL or try to restart your browser.");
            return;
        }

        if (this.gl.getParameter(this.gl.VERSION) != "WebGL 1.0")
        {
            this.glVersion = 2;
        }
        else
        {
            this.gl = canv.getContext("webgl", this.patch.config.canvas) || canv.getContext("experimental-webgl", this.patch.config.canvas);
            this.glVersion = 1;

            // safari
            // if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent) && (navigator.userAgent.match(/iPhone/i)))
            // {
            //     this.glUseHalfFloatTex = true;
            // }

            // ios
            // @ts-ignore
            if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream)
            {
                if (!this.patch.config.canvas.hasOwnProperty("powerPreference")) this.patch.config.canvas.powerPreference = "high-performance";
            }

            this.enableExtension("OES_standard_derivatives");
            // this.enableExtension("GL_OES_standard_derivatives");
            const instancingExt = this.enableExtension("ANGLE_instanced_arrays") || this.gl;
            if (instancingExt.vertexAttribDivisorANGLE)
            {
                this.gl.vertexAttribDivisor = instancingExt.vertexAttribDivisorANGLE.bind(instancingExt);
                this.gl.drawElementsInstanced = instancingExt.drawElementsInstancedANGLE.bind(instancingExt);
            }
        }

        const dbgRenderInfo = this.enableExtension("WEBGL_debug_renderer_info");
        if (dbgRenderInfo)
        {
            this.glRenderer = this.gl.getParameter(dbgRenderInfo.UNMASKED_RENDERER_WEBGL);
            if (this.glRenderer === "Google SwiftShader") this.glSlowRenderer = true;
        }

        this.canvas.addEventListener("webglcontextlost", (event) =>
        {
            if (this.aborted) return this._log.warn("[cgl_state] aborted context lost... can be ignored...");
            this._log.error("canvas lost...", event);
            this.emitEvent("webglcontextlost");
            this.aborted = true;
        });

        this.maxAnisotropic = 0;
        if (this.enableExtension("EXT_texture_filter_anisotropic"))
            this.maxAnisotropic = this.gl.getParameter(this.enableExtension("EXT_texture_filter_anisotropic").MAX_TEXTURE_MAX_ANISOTROPY_EXT);

        this.maxVaryingVectors = this.gl.getParameter(this.gl.MAX_VARYING_VECTORS);
        this.maxTextureUnits = this.gl.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS);
        this.maxTexSize = this.gl.getParameter(this.gl.MAX_TEXTURE_SIZE);
        this.maxUniformsFrag = this.gl.getParameter(this.gl.MAX_FRAGMENT_UNIFORM_VECTORS);
        this.maxUniformsVert = this.gl.getParameter(this.gl.MAX_VERTEX_UNIFORM_VECTORS);
        this.maxSamples = 0;
        if (this.gl.MAX_SAMPLES) this.maxSamples = this.gl.getParameter(this.gl.MAX_SAMPLES);

        if (this.glVersion == 1)
        {
            this.enableExtension("OES_standard_derivatives");
            const instancingExt = this.enableExtension("ANGLE_instanced_arrays") || this.gl;

            if (instancingExt.vertexAttribDivisorANGLE)
            {
                this.gl.vertexAttribDivisor = instancingExt.vertexAttribDivisorANGLE.bind(instancingExt);
                this.gl.drawElementsInstanced = instancingExt.drawElementsInstancedANGLE.bind(instancingExt);
            }
        }

        this.DEPTH_FUNCS = [
            this.gl.NEVER,
            this.gl.ALWAYS,
            this.gl.LESS,
            this.gl.LEQUAL,
            this.gl.GREATER,
            this.gl.GEQUAL,
            this.gl.EQUAL,
            this.gl.NOTEQUAL
        ];
        this.CULL_MODES = [
            null,
            this.gl.BACK,
            this.gl.FRONT,
            this.gl.FRONT_AND_BACK
        ];
    }

    getInfo()
    {
        return {
            "glVersion": this.glVersion,
            "glRenderer": this.glRenderer,
            "glUseHalfFloatTex": this.glUseHalfFloatTex,
            "maxVaryingVectors": this.maxVaryingVectors,
            "maxTextureUnits": this.maxTextureUnits,
            "maxTexSize": this.maxTexSize,
            "maxUniformsFrag": this.maxUniformsFrag,
            "maxUniformsVert": this.maxUniformsVert,
            "maxSamples": this.maxSamples
        };
    }

    /**
     * @function popViewPort
     * @memberof Context
     * @instance
     * @description pop viewPort stack
     */
    popViewPort()
    {
        this._viewPortStack.pop();
        this._viewPortStack.pop();
        this._viewPortStack.pop();
        this._viewPortStack.pop();

        if (this._viewPortStack.length == 0)
            this.setViewPort(0, 0, this.canvasWidth, this.canvasHeight);
        else
            this.setViewPort(this._viewPortStack[this._viewPort.length - 4], this._viewPortStack[this._viewPort.length - 3], this._viewPortStack[this._viewPort.length - 2], this._viewPortStack[this._viewPort.length - 1]);
    }

    /**
     * @function pushViewPort
     * @memberof Context
     * @instance
     * @description push a new viewport onto stack
     * @param {Number} x
     * @param {Number} y
     * @param {Number} w
     * @param {Number} h
     */

    pushViewPort(x, y, w, h)
    {
        this._viewPortStack.push(x, y, w, h);
        this.setViewPort(x, y, w, h);
    }

    // old
    getViewPort()
    {
        return this._viewPort;
    }

    // old
    resetViewPort()
    {
        this.gl.viewport(this._viewPort[0], this._viewPort[1], this._viewPort[2], this._viewPort[3]);
    }

    // old
    /**
     * @param {number} x
     * @param {number} y
     * @param {number} w
     * @param {number} h
     */
    setViewPort(x, y, w, h)
    {
        this._viewPort[0] = Math.round(x);
        this._viewPort[1] = Math.round(y);
        this._viewPort[2] = Math.round(w);
        this._viewPort[3] = Math.round(h);
        this.gl.viewport(this._viewPort[0], this._viewPort[1], this._viewPort[2], this._viewPort[3]);
    }

    /**
     * @param {function} cb
     * @param {boolean} doScreenshotClearAlpha
     * @param {string} mimeType
     * @param {number} quality
     */
    screenShot(cb, doScreenshotClearAlpha, mimeType, quality)
    {
        if (doScreenshotClearAlpha)
        {
            this.gl.clearColor(1, 1, 1, 1);
            this.gl.colorMask(false, false, false, true);
            this.gl.clear(this.gl.COLOR_BUFFER_BIT);
            this.gl.colorMask(true, true, true, true);
        }

        if (this.canvas && this.canvas.toBlob)
        {
            this.canvas.toBlob(
                (blob) =>
                {
                    if (cb) cb(blob);
                    else this._log.log("no screenshot callback...");
                }, mimeType, quality);
        }
    }

    endFrame()
    {
        if (this.patch.isEditorMode()) CABLES.GL_MARKER.drawMarkerLayer(this);

        this.setPreviousShader();

        if (this._vMatrixStack.length() > 0) this.logStackError("view matrix stack length !=0 at end of rendering...");
        if (this._mMatrixStack.length() > 0) this.logStackError("mvmatrix stack length !=0 at end of rendering...");
        if (this._pMatrixStack.length() > 0) this.logStackError("pmatrix stack length !=0 at end of rendering...");
        if (this._glFrameBufferStack.length > 0) this.logStackError("glFrameBuffer stack length !=0 at end of rendering...");
        if (this._stackDepthTest.length > 0) this.logStackError("depthtest stack length !=0 at end of rendering...");
        if (this._stackDepthWrite.length > 0) this.logStackError("depthwrite stack length !=0 at end of rendering...");
        if (this._stackDepthFunc.length > 0) this.logStackError("depthfunc stack length !=0 at end of rendering...");
        if (this._stackBlend.length > 0) this.logStackError("blend stack length !=0 at end of rendering...");
        if (this._stackBlendMode.length > 0) this.logStackError("blendMode stack length !=0 at end of rendering...");
        if (this._shaderStack.length > 0) this.logStackError("this._shaderStack length !=0 at end of rendering...");
        if (this._stackCullFace.length > 0) this.logStackError("this._stackCullFace length !=0 at end of rendering...");
        if (this._stackCullFaceFacing.length > 0) this.logStackError("this._stackCullFaceFacing length !=0 at end of rendering...");
        if (this._viewPortStack.length > 0) this.logStackError("viewport stack length !=0 at end of rendering...");

        this._frameStarted = false;

        if (this._oldCanvasWidth != this.canvasWidth || this._oldCanvasHeight != this.canvasHeight)
        {
            this._oldCanvasWidth = this.canvasWidth;
            this._oldCanvasHeight = this.canvasHeight;
            this.emitEvent(_cg_cg_context_js__WEBPACK_IMPORTED_MODULE_0__/* .CgContext */ .A.EVENT_RESIZE);
        }

        if (this._cursor != this._currentCursor)
        {
            this._currentCursor = this.canvas.style.cursor = this._cursor;
        }

        this.emitEvent("endframe");

        this.fpsCounter.endFrame();
    }

    logStackError(str)
    {
        if (!this._hadStackError)
        {
            this._hadStackError = true;
            this._log.warn("[" + this.canvas.id + "]: ", str);
        }
    }

    // shader stack
    getShader()
    {
        if (this._currentShader) if (!this.tempData || ((this.tempData.renderOffscreen === true) == this._currentShader.offScreenPass) === true) return this._currentShader;

        for (let i = this._shaderStack.length - 1; i >= 0; i--) if (this._shaderStack[i]) if (this.tempData.renderOffscreen == this._shaderStack[i].offScreenPass) return this._shaderStack[i];
    }

    getDefaultShader()
    {
        return this._simpleShader;
    }

    /**
     * @deprecated
     * @param {Shader} s
     */
    setShader(s)
    {
        this.pushShader(s);
    }

    /**
     * push a shader to the shader stack
     * @function pushShader
     * @memberof Context
     * @instance
     * @param {Shader} shader
     * @function
     */
    pushShader(shader)
    {
        if (this.tempData.forceShaderMods)
        {
            for (let i = 0; i < this.tempData.forceShaderMods.length; i++)
            {
                // if (!currentShader.forcedMod && currentShader != this.tempData.forceShaderMods[i])
                // {
                //     currentShader.forcedMod = this.tempData.forceShaderMods[i];
                shader = this.tempData.forceShaderMods[i].bind(shader, false);
                // }
                // return currentShader;
                // if (this.tempData.forceShaderMods[i].currentShader() && shader != this.tempData.forceShaderMods[i].currentShader().shader)
            }
        }

        this._shaderStack.push(shader);
        this._currentShader = shader;
    }

    popShader()
    {
        this.setPreviousShader();
    }

    /**
     * pop current used shader from shader stack
     * @function popShader
     * @memberof Context
     * @instance
     * @function
     */
    setPreviousShader()
    {
        if (this.tempData.forceShaderMods)
        {
            for (let i = 0; i < this.tempData.forceShaderMods.length; i++)
            {
                // const a =
                this.tempData.forceShaderMods[i].unbind(false);
                // if (a) return;
                // this.popShader();
            }
        }

        if (this._shaderStack.length === 0) throw new Error("Invalid shader stack pop!");
        this._shaderStack.pop();
        this._currentShader = this._shaderStack[this._shaderStack.length - 1];
    }

    /**
     * push a framebuffer to the framebuffer stack
     * @function pushGlFrameBuffer
     * @memberof Context
     * @instance
     * @param {Object} fb framebuffer
     * @function
     */
    pushGlFrameBuffer(fb)
    {
        this._glFrameBufferStack.push(fb);
    }

    /**
     * pop framebuffer stack
     * @function popGlFrameBuffer
     * @memberof Context
     * @instance
     * @returns {Object} current framebuffer or null
     */
    popGlFrameBuffer()
    {
        if (this._glFrameBufferStack.length == 0) return null;
        this._glFrameBufferStack.pop();
        return this._glFrameBufferStack[this._glFrameBufferStack.length - 1];
    }

    /**
     * get current framebuffer
     * @function getCurrentFrameBuffer
     * @memberof Context
     * @instance
     * @returns {Object} current framebuffer or null
     */
    getCurrentGlFrameBuffer()
    {
        if (this._glFrameBufferStack.length === 0) return null;
        return this._glFrameBufferStack[this._glFrameBufferStack.length - 1];
    }

    /**
     * push a framebuffer to the framebuffer stack
     * @function pushGlFrameBuffer
     * @memberof Context
     * @instance
     * @param {Framebuffer2} fb framebuffer
     */
    pushFrameBuffer(fb)
    {
        this._frameBufferStack.push(fb);
    }

    /**
     * pop framebuffer stack
     * @function popFrameBuffer
     * @memberof Context
     * @instance
     * @returns {Framebuffer2} current framebuffer or null
     */
    popFrameBuffer()
    {
        if (this._frameBufferStack.length == 0) return null;
        this._frameBufferStack.pop();
        return this._frameBufferStack[this._frameBufferStack.length - 1];
    }

    /**
     * get current framebuffer
     * @function getCurrentFrameBuffer
     * @memberof Context
     * @instance
     * @returns {Framebuffer2} current framebuffer or null
     */
    getCurrentFrameBuffer()
    {
        if (this._frameBufferStack.length === 0) return null;
        return this._frameBufferStack[this._frameBufferStack.length - 1];
    }

    renderStart(cgl, identTranslate, identTranslateView)
    {
        this.fpsCounter.startFrame();
        this.pushDepthTest(true);
        this.pushDepthWrite(true);
        this.pushDepthFunc(cgl.gl.LEQUAL);
        this.pushCullFaceFacing(cgl.gl.BACK);
        this.pushCullFace(false);

        // if (this.clearCanvasTransparent)
        // {
        //     cgl.gl.clearColor(0, 0, 0, 0);
        //     cgl.gl.clear(cgl.gl.COLOR_BUFFER_BIT);
        // }
        // if (this.clearCanvasDepth) cgl.gl.clear(cgl.gl.DEPTH_BUFFER_BIT);

        cgl.setViewPort(0, 0, cgl.canvasWidth, cgl.canvasHeight);

        this._startMatrixStacks(identTranslate, identTranslateView);

        cgl.pushBlendMode(_constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.BLEND_MODES.BLEND_NORMAL, false);

        for (let i = 0; i < this._textureslots.length; i++) this._textureslots[i] = null;

        this.pushShader(this._simpleShader);

        this._frameStarted = true;

        this._execOneTimeCallbacks();

        for (let i = 0; i < this._textureslots.length; i++)
        {
            this.gl.activeTexture(this.gl.TEXTURE0 + i);
            this.gl.bindTexture(this.gl.TEXTURE_2D, null);
            this._textureslots[i] = null;
        }

        this.emitEvent("beginFrame");
    }

    /**
     * @param {CglContext} cgl
     */
    renderEnd(cgl)
    {
        this._endMatrixStacks();

        this.popDepthTest();
        this.popDepthWrite();
        this.popDepthFunc();
        this.popCullFaceFacing();
        this.popCullFace();
        this.popBlend();
        this.popBlendMode();

        cgl.endFrame();

        this.emitEvent("endFrame");
    }

    /**
     * @param {number} slot
     */
    getTexture(slot)
    {
        return this._textureslots[slot];
    }

    hasFrameStarted()
    {
        return this._frameStarted;
    }

    /**
     * log warning to console if the rendering of one frame has not been started / handy to check for async problems
     * @function checkFrameStarted
     * @memberof Context
     * @param {string} string
     * @instance
     */
    checkFrameStarted(string)
    {
        if (!this._frameStarted)
        {
            this._log.warn("frame not started " + string);

            Error.stackTraceLimit = 25;
            cables__WEBPACK_IMPORTED_MODULE_4__.logStack();
            this.patch.printTriggerStack();
        }
    }

    /**
     * @param {number} slot
     * @param {WebGLTexture} t
     * @param {undefined} [type]
     */
    setTexture(slot, t, type)
    {
        this.checkFrameStarted("cgl setTexture");

        if (t === null) t = _cgl_texture_js__WEBPACK_IMPORTED_MODULE_5__/* .Texture */ .g.getEmptyTexture(this).tex;

        if (this._textureslots[slot] != t)
        {
            this.gl.activeTexture(this.gl.TEXTURE0 + slot);
            this.gl.bindTexture(type || this.gl.TEXTURE_2D, t);
            this._textureslots[slot] = t;
        }

        return true;
    }

    fullScreen()
    {
        if (this.canvas.requestFullscreen) this.canvas.requestFullscreen();
        else if (this.canvas.mozRequestFullScreen) this.canvas.mozRequestFullScreen();
        else if (this.canvas.webkitRequestFullscreen) this.canvas.webkitRequestFullscreen();
        else if (this.canvas.msRequestFullscreen) this.canvas.msRequestFullscreen();
    }

    /**
     * @param {string} [str]
     */
    printError(str)
    {
        if (!this.checkGlErrors) return;
        let found = false;
        let error = this.gl.getError();

        if (error != this.gl.NO_ERROR)
        {
            let errStr = "";
            if (error == this.gl.OUT_OF_MEMORY) errStr = "OUT_OF_MEMORY";
            if (error == this.gl.INVALID_ENUM) errStr = "INVALID_ENUM";
            if (error == this.gl.INVALID_OPERATION) errStr = "INVALID_OPERATION";
            if (error == this.gl.INVALID_FRAMEBUFFER_OPERATION) errStr = "INVALID_FRAMEBUFFER_OPERATION";
            if (error == this.gl.INVALID_VALUE) errStr = "INVALID_VALUE";
            if (error == this.gl.CONTEXT_LOST_WEBGL)
            {
                this.aborted = true;
                errStr = "CONTEXT_LOST_WEBGL";
            }
            if (error == this.gl.NO_ERROR) errStr = "NO_ERROR";

            found = true;

            this._log.warn("gl error [" + this.canvas.id + "]: ", str, error, errStr);

            if (this.canvas.id.includes("glGuiCanvas"))
                if (!this._loggedGlError)
                {
                    this.patch.printTriggerStack();
                    this._log.stack("glerror");
                    this._loggedGlError = true;
                }
        }
        error = this.gl.getError();

        return found;
    }

    _dispose()
    {
        this._simpleShader.dispose();
        this.gl = null;
    }

    // state depthtest

    /**
     * push depth testing enabled state
     * @function pushDepthTest
     * @param {Boolean} enabled
     * @memberof Context
     * @instance
     */

    pushDepthTest(enabled)
    {
        this._stackDepthTest.push(enabled);
        if (!enabled) this.gl.disable(this.gl.DEPTH_TEST);
        else this.gl.enable(this.gl.DEPTH_TEST);
    }

    /**
     * current state of depth testing
     * @function stateCullFace
     * @returns {Boolean} enabled
     * @memberof Context
     * @instance
     */
    stateDepthTest()
    {
        return this._stackDepthTest[this._stackDepthTest.length - 1];
    }

    /**
     * pop depth testing state
     * @function popCullFace
     * @memberof Context
     * @instance
     */
    popDepthTest()
    {
        this._stackDepthTest.pop();

        if (!this._stackDepthTest[this._stackDepthTest.length - 1]) this.gl.disable(this.gl.DEPTH_TEST);
        else this.gl.enable(this.gl.DEPTH_TEST);
    }

    // --------------------------------------
    // state depthwrite

    /**
     * push depth write enabled state
     * @function pushDepthTest
     * @param {Boolean} enabled
     * @memberof Context
     * @instance
     */
    pushDepthWrite(enabled)
    {
        enabled = enabled || false;
        this._stackDepthWrite.push(enabled);
        this.gl.depthMask(enabled);
    }

    /**
     * current state of depth writing
     * @function stateDepthWrite
     * @returns {Boolean} enabled
     * @memberof Context
     * @instance
     */
    stateDepthWrite()
    {
        return this._stackDepthWrite[this._stackDepthWrite.length - 1];
    }

    /**
     * pop depth writing state
     * @function popDepthWrite
     * @memberof Context
     * @instance
     */
    popDepthWrite()
    {
        this._stackDepthWrite.pop();
        this.gl.depthMask(this._stackDepthWrite[this._stackDepthWrite.length - 1] || false);
    }

    // --------------------------------------
    // state CullFace

    /**
     * push face culling face enabled state
     * @function pushCullFace
     * @param {Boolean} enabled
     * @memberof Context
     * @instance
     */
    pushCullFace(enabled)
    {
        this._stackCullFace.push(enabled);

        if (enabled) this.gl.enable(this.gl.CULL_FACE);
        else this.gl.disable(this.gl.CULL_FACE);
    }

    /**
     * current state of face culling
     * @function stateCullFace
     * @returns {Boolean} enabled
     * @memberof Context
     * @instance
     */
    stateCullFace()
    {
        return this._stackCullFace[this._stackCullFace.length - 1];
    }

    /**
     * pop face culling enabled state
     * @function popCullFace
     * @memberof Context
     * @instance
     */
    popCullFace()
    {
        this._stackCullFace.pop();

        if (this._stackCullFace[this._stackCullFace.length - 1]) this.gl.enable(this.gl.CULL_FACE);
        else this.gl.disable(this.gl.CULL_FACE);
    }

    // --------------------------------------
    // state CullFace Facing

    /**
     * push face culling face side
     * @function pushCullFaceFacing
     * @param {Number} face - cgl.gl.FRONT_AND_BACK, cgl.gl.BACK or cgl.gl.FRONT
     * @memberof Context
     * @instance
     */

    pushCullFaceFacing(face)
    {
        this._stackCullFaceFacing.push(face);
        this.gl.cullFace(this._stackCullFaceFacing[this._stackCullFaceFacing.length - 1]);
    }

    /**
     * current state of face culling side
     * @function stateCullFaceFacing
     * @returns {Boolean} enabled
     * @memberof Context
     * @instance
     */
    stateCullFaceFacing()
    {
        return this._stackCullFaceFacing[this._stackCullFaceFacing.length - 1];
    }

    /**
     * pop face culling face side
     * @function popCullFaceFacing
     * @memberof Context
     * @instance
     */
    popCullFaceFacing()
    {
        this._stackCullFaceFacing.pop();
        if (this._stackCullFaceFacing.length > 0) this.gl.cullFace(this._stackCullFaceFacing[this._stackCullFaceFacing.length - 1]);
    }

    // --------------------------------------
    // state depthfunc

    /**
     * enable / disable depth testing
     * like `gl.depthFunc(boolean);`
     * @function pushDepthFunc
     * @memberof Context
     * @instance
     * @param {Boolean} f depthtesting
     */
    pushDepthFunc(f)
    {
        this._stackDepthFunc.push(f);
        this.gl.depthFunc(f);
    }

    /**
     * current state of blend
     * @function stateDepthFunc
     * @memberof Context
     * @instance
     * @returns {Boolean} depth testing enabled/disabled
     */
    stateDepthFunc()
    {
        if (this._stackDepthFunc.length > 0) return this._stackDepthFunc[this._stackDepthFunc.length - 1];
        return false;
    }

    /**
     * pop depth testing and set the previous state
     * @function popDepthFunc
     * @memberof Context
     * @instance
     */
    popDepthFunc()
    {
        this._stackDepthFunc.pop();
        if (this._stackDepthFunc.length > 0) this.gl.depthFunc(this._stackDepthFunc[this._stackDepthFunc.length - 1]);
    }

    // --------------------------------------
    // state blending

    /**
     * enable / disable blend
     * like gl.enable(gl.BLEND); / gl.disable(gl.BLEND);
     * @function pushBlend
     * @memberof Context
     * @instance
     * @param {boolean} b blending
     */
    pushBlend(b)
    {
        this._stackBlend.push(b);
        if (!b) this.gl.disable(this.gl.BLEND);
        else this.gl.enable(this.gl.BLEND);
    }

    /**
     * pop blend state and set the previous state
     * @function popBlend
     * @memberof Context
     * @instance
     */
    popBlend()
    {
        this._stackBlend.pop();

        if (!this._stackBlend[this._stackBlend.length - 1]) this.gl.disable(this.gl.BLEND);
        else this.gl.enable(this.gl.BLEND);
    }

    /**
     * current state of blend
     * @function stateBlend
     * @returns {boolean} blending enabled/disabled
     * @memberof Context
     * @instance
     */
    stateBlend()
    {
        return this._stackBlend[this._stackBlend.length - 1];
    }

    /**
     * push and switch to predefined blendmode (CONSTANTS.BLEND_MODES.BLEND_NONE,CONSTANTS.BLEND_MODES.BLEND_NORMAL,CONSTANTS.BLEND_MODES.BLEND_ADD,CONSTANTS.BLEND_MODES.BLEND_SUB,CONSTANTS.BLEND_MODES.BLEND_MUL)
     * @function pushBlendMode
     * @memberof Context
     * @instance
     * @param {Number} blendMode
     * @param {Boolean} premul premultiplied mode
     */
    pushBlendMode(blendMode, premul)
    {
        this._stackBlendMode.push(blendMode);
        this._stackBlendModePremul.push(premul);

        const n = this._stackBlendMode.length - 1;

        this.pushBlend(this._stackBlendMode[n] !== _constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.BLEND_MODES.BLEND_NONE);
        this._setBlendMode(this._stackBlendMode[n], this._stackBlendModePremul[n]);
    }

    /**
     * pop predefined blendmode / switch back to previous blendmode
     * @function popBlendMode
     * @memberof Context
     * @instance
     */
    popBlendMode()
    {
        this._stackBlendMode.pop();
        this._stackBlendModePremul.pop();

        const n = this._stackBlendMode.length - 1;

        this.popBlend();

        if (n >= 0) this._setBlendMode(this._stackBlendMode[n], this._stackBlendModePremul[n]);
    }

    // --------------------------------------
    // state stencil

    /**
     * enable / disable stencil testing

    * @function pushStencil
    * @memberof Context
    * @instance
    * @param {Boolean} b enable
    */
    pushStencil(b)
    {
        this._stackStencil.push(b);
        if (!b) this.gl.disable(this.gl.STENCIL_TEST);
        else this.gl.enable(this.gl.STENCIL_TEST);
    }

    /**
     * pop stencil test state and set the previous state
     * @function popStencil
     * @memberof Context
     * @instance
     */
    popStencil()
    {
        this._stackStencil.pop();

        if (!this._stackStencil[this._stackStencil.length - 1]) this.gl.disable(this.gl.STENCIL_TEST);
        else this.gl.enable(this.gl.STENCIL_TEST);
    }

    // --------------------------------------

    glGetAttribLocation(prog, name)
    {
        const l = this.gl.getAttribLocation(prog, name);
        // if (l == -1)
        // {
        //     this._log.warn("get attr loc -1 ", name);
        // }
        return l;
    }

    /**
     * should an op now draw helpermeshes
     * @param {Op} op
     */
    shouldDrawHelpers(op)
    {
        if (this.tempData.shadowPass) return false;
        if (!op.patch.isEditorMode()) return false;
        return gui.shouldDrawOverlay;
    }

    _setBlendMode(blendMode, premul)
    {
        const gl = this.gl;

        if (blendMode == _constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.BLEND_MODES.BLEND_NONE)
        {
            // this.gl.disable(this.gl.BLEND);
        }
        else if (blendMode == _constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.BLEND_MODES.BLEND_ADD)
        {
            if (premul)
            {
                gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
                gl.blendFuncSeparate(gl.ONE, gl.ONE, gl.ONE, gl.ONE);
            }
            else
            {
                gl.blendEquation(gl.FUNC_ADD);
                gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
            }
        }
        else if (blendMode == _constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.BLEND_MODES.BLEND_SUB)
        {
            if (premul)
            {
                gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
                gl.blendFuncSeparate(gl.ZERO, gl.ZERO, gl.ONE_MINUS_SRC_COLOR, gl.ONE_MINUS_SRC_ALPHA);
            }
            else
            {
                gl.blendEquation(gl.FUNC_ADD);
                gl.blendFunc(gl.ZERO, gl.ONE_MINUS_SRC_COLOR);
            }
        }
        else if (blendMode == _constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.BLEND_MODES.BLEND_MUL)
        {
            if (premul)
            {
                gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
                gl.blendFuncSeparate(gl.ZERO, gl.SRC_COLOR, gl.ZERO, gl.SRC_ALPHA);
            }
            else
            {
                gl.blendEquation(gl.FUNC_ADD);
                gl.blendFunc(gl.ZERO, gl.SRC_COLOR);
            }
        }
        else if (blendMode == _constants_js__WEBPACK_IMPORTED_MODULE_3__/* .CONSTANTS */ .a.BLEND_MODES.BLEND_NORMAL)
        {
            if (premul)
            {
                gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
                gl.blendFuncSeparate(gl.ONE, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
            }
            else
            {
                gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
                gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
            }
        }
        else
        {
            this._log.log("setblendmode: unknown blendmode");
        }
    }

    /**
     * @param {Geometry} geom
     * @param {CglMeshOptions} options
     */
    createMesh(geom, options)
    {
        if (cables__WEBPACK_IMPORTED_MODULE_4__.isNumeric(options))options = { "glPrimitive": options }; // old constructor fallback...
        return new _cgl_mesh_js__WEBPACK_IMPORTED_MODULE_6__/* .Mesh */ .e(this, geom, options);
    }

    /**
     * set cursor
     * @function setCursor
     * @memberof Context
     * @instance
     * @param {String} str css cursor string
     */
    setCursor(str)
    {
        this._cursor = str;
    }

    /**
     * enable a webgl extension
     * @function enableExtension
     * @memberof Context
     * @instance
     * @param {String} name extension name
     * @returns {Object} extension object or null
     */
    enableExtension(name)
    {
        if (!this.gl) return null;

        if (this._enabledExtensions.hasOwnProperty(name))
            return this._enabledExtensions[name];

        const o = this.gl.getExtension(name);
        this._enabledExtensions[name] = o;

        if (!o) this._log.warn("[cgl_state] extension not available " + name);

        return o;
    }

    getErrorShader()
    {
        if (this.errorShader) return this.errorShader;

        this.errorShader = new _cgl_shader_js__WEBPACK_IMPORTED_MODULE_2__/* .Shader */ .M(this, "errormaterial");
        this.errorShader.setSource(_cgl_shader_js__WEBPACK_IMPORTED_MODULE_2__/* .Shader */ .M.getDefaultVertexShader(), _cgl_shader_js__WEBPACK_IMPORTED_MODULE_2__/* .Shader */ .M.getErrorFragmentShader());
        return this.errorShader;
    }

}


/***/ }),

/***/ 70:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   g: () => (/* binding */ Texture)
/* harmony export */ });
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(849);
/* harmony import */ var cables__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(562);
/* harmony import */ var _cg_cg_texture_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(356);





const DEFAULT_TEXTURE_SIZE = 8;

const log = new cables_shared_client__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A("cgl_texture");

/**
 * A Texture
 * @namespace external:CGL
 * @class
 * @param {CglContext} __cgl cgl
 * @param {Object} options
 * @hideconstructor
 * @example
 * // generate a 256x256 pixel texture of random colors
 * const size=256;
 * const data = new Uint8Array(size*size*4);
 *
 * for(var x=0;x<size*size*4;x++) data[ x*4+3]=255;
 *
 * const tex=new CGL.Texture(cgl);
 * tex.initFromData(data,size,size,CGL.Texture.FILTER_NEAREST,CGL.Texture.WRAP_REPEAT);
 */
class Texture extends _cg_cg_texture_js__WEBPACK_IMPORTED_MODULE_1__/* .CgTexture */ .U
{

    /**
     * @param {CglContext} __cgl
     */
    constructor(__cgl, options = {})
    {
        super(options);
        if (!__cgl) throw new Error("no cgl");

        this._cgl = __cgl;
        this._log = new cables_shared_client__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A("tex");
        this.tex = this._cgl.gl.createTexture();
        this.loading = false;
        this.flip = true;
        this.flipped = false;
        this.shadowMap = false;
        this.deleted = false;
        this.image = null;
        this.anisotropic = 0;
        this.filter = Texture.FILTER_NEAREST;
        this.wrap = Texture.WRAP_CLAMP_TO_EDGE;
        this.texTarget = this._cgl.gl.TEXTURE_2D;
        if (options && options.type) this.texTarget = options.type;
        this.textureType = Texture.TYPE_DEFAULT;
        this.unpackAlpha = true;
        this._fromData = true;

        this._glDataType = -1;
        this._glInternalFormat = -1;
        this._glDataFormat = -1;

        if (options)
        {
            if (options.isDepthTexture) this.textureType = Texture.TYPE_DEPTH;
            if (options.isFloatingPointTexture === true) this.textureType = Texture.TYPE_FLOAT;

            if ("textureType" in options) this.textureType = options.textureType;
            if ("filter" in options) this.filter = options.filter;
            if ("wrap" in options) this.wrap = options.wrap;
            if ("unpackAlpha" in options) this.unpackAlpha = options.unpackAlpha;
            if ("flip" in options) this.flip = options.flip;
            if ("shadowMap" in options) this.shadowMap = options.shadowMap;
            if ("anisotropic" in options) this.anisotropic = options.anisotropic;
        }
        else
        {
            options = {};
        }

        if (!options.pixelFormat && options.isFloatingPointTexture) this.pixelFormat = Texture.PFORMATSTR_RGBA32F;

        if (this.textureType == Texture.TYPE_DEPTH) this.pixelFormat = Texture.PFORMATSTR_DEPTH;

        this._cgl.profileData.profileTextureNew++;

        this.setFormat(Texture.setUpGlPixelFormat(this._cgl, this.pixelFormat));
        this._cgl.profileData.addHeavyEvent("texture created", this.name, options.width + "x" + options.height);

        this.setSize(options.width, options.height);
        this.getInfoOneLine();
    }

    isFloatingPoint()
    {
        return Texture.isPixelFormatFloat(this.pixelFormat);
    }

    /**
     * returns true if otherTexture has same options (width/height/filter/wrap etc)
     * @function compareSettings
     * @memberof Texture
     * @instance
     * @param {Texture} tex otherTexture
     * @returns {Boolean}
     */
    compareSettings(tex)
    {
    // if (!tex) { this._log.warn("compare: no tex"); return false; }
    // if (tex.width != this.width) this._log.warn("tex.width not equal", tex.width, this.width);
    // if (tex.height != this.height) this._log.warn("tex.height not equal", tex.height, this.height);
    // if (tex.filter != this.filter) this._log.warn("tex.filter not equal");
    // if (tex.wrap != this.wrap) this._log.warn("tex.wrap not equal");
    // if (tex.textureType != this.textureType) this._log.warn("tex.textureType not equal");
    // if (tex.unpackAlpha != this.unpackAlpha) this._log.warn("tex.unpackAlpha not equal");
    // if (tex.anisotropic != this.anisotropic) this._log.warn("tex.anisotropic not equal");
    // if (tex.shadowMap != this.shadowMap) this._log.warn("tex.shadowMap not equal");
    // if (tex.texTarget != this.texTarget) this._log.warn("tex.texTarget not equal");
    // if (tex.flip != this.flip) this._log.warn("tex.flip not equal");

        if (!tex) return false;
        return (
            tex.width == this.width &&
            tex.height == this.height &&
            tex.filter == this.filter &&
            tex.wrap == this.wrap &&
            tex.textureType == this.textureType &&
            tex.unpackAlpha == this.unpackAlpha &&
            tex.anisotropic == this.anisotropic &&
            tex.shadowMap == this.shadowMap &&
            tex.texTarget == this.texTarget &&
            tex.flip == this.flip
        );
    }

    /**
     * returns a new texture with the same settings (does not copy texture itself)
     * @function clone
     * @memberof Texture
     * @instance
     * @returns {Texture}
     */
    clone()
    {
        const newTex = new Texture(this._cgl, {
            "name": this.name,
            "filter": this.filter,
            "anisotropic": this.anisotropic,
            "wrap": this.wrap,
            "textureType": this.textureType,
            "pixelFormat": this.pixelFormat,
            "unpackAlpha": this.unpackAlpha,
            "flip": this.flip,
            "width": this.width,
            "height": this.height,
        });

        this._cgl.profileData.addHeavyEvent("texture created", this.name, this.width + "x" + this.height);

        if (!this.compareSettings(newTex))
        {
            this._log.error("Cloned texture settings do not compare!");
            this._log.error(this);
            this._log.error(newTex);
        }

        return newTex;
    }

    /**
     * @param {object} o
     */
    setFormat(o)
    {
        this.pixelFormat = o.pixelFormat;
        this._glDataFormat = o.glDataFormat;
        this._glInternalFormat = o.glInternalFormat;
        this._glDataType = o.glDataType;
    }

    /**
     * set pixel size of texture
     * @function setSize
     * @memberof Texture
     * @instance
     * @param {Number} w width
     * @param {Number} h height
     */
    setSize(w, h)
    {
        if (this._cgl.aborted) return;
        if (w != w || w <= 0 || !w) w = DEFAULT_TEXTURE_SIZE;
        if (h != h || h <= 0 || !h) h = DEFAULT_TEXTURE_SIZE;

        if (w > this._cgl.maxTexSize || h > this._cgl.maxTexSize) this._log.error("texture size too big! " + w + "x" + h + " / max: " + this._cgl.maxTexSize);

        w = Math.min(w, this._cgl.maxTexSize);
        h = Math.min(h, this._cgl.maxTexSize);

        w = Math.floor(w);
        h = Math.floor(h);
        if (this.width == w && this.height == h) return;

        w = this._cgl.checkTextureSize(w);
        h = this._cgl.checkTextureSize(h);

        this.width = w;
        this.height = h;
        this.deleted = false;

        this.setFormat(Texture.setUpGlPixelFormat(this._cgl, this.pixelFormat));

        this.shortInfoString = this.getInfoOneLine();// w + "x" + h + "";

        this._cgl.gl.bindTexture(this.texTarget, this.tex);
        this._cgl.profileData.profileTextureResize++;

        const uarr = null;

        this._cgl.gl.texImage2D(this.texTarget, 0, this._glInternalFormat, w, h, 0, this._glDataFormat, this._glDataType, uarr);

        this._setFilter();

        this.updateMipMap();

        this._cgl.gl.bindTexture(this.texTarget, null);
    }

    /**
     * @function initFromData
     * @memberof Texture
     * @instance
     * @description create texturem from rgb data
     * @param {Array<Number>} data rgb color array [r,g,b,a,r,g,b,a,...]
     * @param {Number} w width
     * @param {Number} h height
     * @param {Number} filter
     * @param {Number} wrap
     */
    initFromData(data, w, h, filter, wrap)
    {
        this.filter = filter;
        this.wrap = wrap;
        if (filter == undefined) this.filter = Texture.FILTER_LINEAR;
        if (wrap == undefined) this.wrap = Texture.WRAP_CLAMP_TO_EDGE;
        this.width = w;
        this.height = h;
        this._fromData = true;
        this.deleted = false;

        if (this.height > this._cgl.maxTexSize || this.width > this._cgl.maxTexSize)
        {
            const t = CGL.Texture.getTempTexture(this._cgl);
            this.width = t.width;
            this.height = t.height;
            this.tex = t.tex;
            this._log.warn("[cgl_texture] texture size too big!", this.width, this.height, this._cgl.maxTexSize);
            return;
        }

        if (this.flip) this._cgl.gl.pixelStorei(this._cgl.gl.UNPACK_FLIP_Y_WEBGL, this.flip);

        this._cgl.gl.bindTexture(this.texTarget, this.tex);

        this.setFormat(Texture.setUpGlPixelFormat(this._cgl, this.pixelFormat));

        this._cgl.gl.texImage2D(this.texTarget, 0, this._glInternalFormat, w, h, 0, this._glDataFormat, this._glDataType, data);

        this._setFilter();
        this.updateMipMap();

        if (this.flip) this._cgl.gl.pixelStorei(this._cgl.gl.UNPACK_FLIP_Y_WEBGL, false);
        this._cgl.gl.bindTexture(this.texTarget, null);
    }

    updateMipMap()
    {
        if ((this._cgl.glVersion == 2 || this.isPowerOfTwo()) && this.filter == Texture.FILTER_MIPMAP)
        {
            this._cgl.gl.generateMipmap(this.texTarget);
            this._cgl.profileData.profileGenMipMap++;
        }
    }

    /**
     * set texture data from an image/canvas object
     * @function initTexture
     * @memberof Texture
     * @instance
     * @param {Object} img image
     * @param {Number} filter
     */
    initTexture(img, filter = null)
    {
        this._cgl.printError("before initTexture");
        this._cgl.checkFrameStarted("texture inittexture");
        this._fromData = false;

        this._cgl.gl.pixelStorei(this._cgl.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.unpackAlpha);
        if (img.width || img.videoWidth) this.width = img.videoWidth || img.width;
        if (img.height || img.videoHeight) this.height = img.videoHeight || img.height;

        if (filter !== null) this.filter = filter; // todo: can we remove this filter param?

        if (img.height > this._cgl.maxTexSize || img.width > this._cgl.maxTexSize)
        {
            const t = CGL.Texture.getTempTexture(this._cgl);
            this.width = t.width;
            this.height = t.height;
            this.tex = t.tex;
            this._log.warn("[cgl_texture] texture size too big!", img.width, img.height, this._cgl.maxTexSize);
            return;
        }

        this._cgl.gl.bindTexture(this.texTarget, this.tex);

        this.deleted = false;
        this.flipped = !this.flip;
        if (this.flipped) this._cgl.gl.pixelStorei(this._cgl.gl.UNPACK_FLIP_Y_WEBGL, this.flipped);

        this.setFormat(Texture.setUpGlPixelFormat(this._cgl, this.pixelFormat));

        this._cgl.gl.texImage2D(this.texTarget, 0, this._glInternalFormat, this._glDataFormat, this._glDataType, img);

        this._setFilter();
        this.updateMipMap();

        this._cgl.gl.bindTexture(this.texTarget, null);
        this._cgl.gl.pixelStorei(this._cgl.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
        if (this.flipped) this._cgl.gl.pixelStorei(this._cgl.gl.UNPACK_FLIP_Y_WEBGL, false);

        this.getInfoOneLine();
        this._cgl.printError("initTexture");
    }

    /**
     * delete texture. use this when texture is no longer needed
     * @function delete
     * @memberof Texture
     * @instance
     */
    dispose()
    {
        this.delete();
    }

    delete()
    {
        if (this.loading)
        {
            // cant delete texture when still loading
            // setTimeout(this.delete.bind(this), 50);
            return;
        }

        this.deleted = true;
        this.width = 0;
        this.height = 0;
        this._cgl.profileData.profileTextureDelete++;
        this._cgl.gl.deleteTexture(this.tex);
        this.image = null;

        this.tex = null;
    }

    /**
     * @function isPowerOfTwo
     * @memberof Texture
     * @instance
     * @description return true if texture width and height are both power of two
     * @return {Boolean}
     */
    isPowerOfTwo()
    {
        return Texture.isPowerOfTwo(this.width) && Texture.isPowerOfTwo(this.height);
    }

    printInfo()
    {
        log.log(this.getInfo());
    }

    getInfoReadable()
    {
        const info = this.getInfo();
        let html = "";

        info.name = info.name.substr(0, info.name.indexOf("?rnd="));

        for (const i in info)
        {
            html += "* " + i + ":  **" + info[i] + "**\n";
        }

        return html;
    }

    getInfoOneLine()
    {
        let txt = "" + this.width + "x" + this.height;
        txt += " ";
        // if (this.textureType === CGL.Texture.TYPE_FLOAT) txt += " 32bit"; else txt += " 8bit";
        // if (this.textureType === CGL.Texture.TYPE_FLOAT) txt += " 32bit"; else txt += " 8bit";
        txt += this.pixelFormat;

        if (this.filter === Texture.FILTER_NEAREST) txt += " nearest";
        if (this.filter === Texture.FILTER_LINEAR) txt += " linear";
        if (this.filter === Texture.FILTER_MIPMAP) txt += " mipmap";

        if (this.wrap === Texture.WRAP_CLAMP_TO_EDGE) txt += " clamp";
        if (this.wrap === Texture.WRAP_REPEAT) txt += " repeat";
        if (this.wrap === Texture.WRAP_MIRRORED_REPEAT) txt += " repeatmir";

        this.shortInfoString = txt;

        return txt;
    }

    getInfoOneLineShort()
    {
        let txt = "" + this.width + "x" + this.height;
        // if (this.textureType === CGL.Texture.TYPE_FLOAT) txt += " 32bit"; else txt += " 8bit";
        txt += " ";
        txt += this.pixelFormat;

        this.shortInfoString = txt;

        return txt;
    }

    getInfo()
    {
        return Texture.getTexInfo(this);
    }

    _setFilter()
    {
        this._cgl.printError("before _setFilter");

        if (!this._fromData)
        {
            this._cgl.gl.pixelStorei(this._cgl.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, this.unpackAlpha);
        }

        if (this.shadowMap)
        {
            this._cgl.gl.texParameteri(this._cgl.gl.TEXTURE_2D, this._cgl.gl.TEXTURE_COMPARE_MODE, this._cgl.gl.COMPARE_REF_TO_TEXTURE);
            this._cgl.gl.texParameteri(this._cgl.gl.TEXTURE_2D, this._cgl.gl.TEXTURE_COMPARE_FUNC, this._cgl.gl.LEQUAL);
        }

        if (this.textureType == Texture.TYPE_FLOAT && this.filter == Texture.FILTER_MIPMAP)
        {
            this.filter = Texture.FILTER_LINEAR;
            this._log.stack("texture: HDR and mipmap filtering at the same time is not possible");
        }

        if (this._cgl.glVersion == 1 && !this.isPowerOfTwo())
        {
            this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_MAG_FILTER, this._cgl.gl.NEAREST);
            this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_MIN_FILTER, this._cgl.gl.NEAREST);

            this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_WRAP_S, this._cgl.gl.CLAMP_TO_EDGE);
            this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_WRAP_T, this._cgl.gl.CLAMP_TO_EDGE);

            this.filter = Texture.FILTER_NEAREST;
            this.wrap = Texture.WRAP_CLAMP_TO_EDGE;
        }
        else
        {
            if (this.wrap == Texture.WRAP_CLAMP_TO_EDGE)
            {
                this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_WRAP_S, this._cgl.gl.CLAMP_TO_EDGE);
                this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_WRAP_T, this._cgl.gl.CLAMP_TO_EDGE);
            }
            else if (this.wrap == Texture.WRAP_REPEAT)
            {
                this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_WRAP_S, this._cgl.gl.REPEAT);
                this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_WRAP_T, this._cgl.gl.REPEAT);
            }
            else if (this.wrap == Texture.WRAP_MIRRORED_REPEAT)
            {
                this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_WRAP_S, this._cgl.gl.MIRRORED_REPEAT);
                this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_WRAP_T, this._cgl.gl.MIRRORED_REPEAT);
            }

            if (this.filter == Texture.FILTER_NEAREST)
            {
                this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_MAG_FILTER, this._cgl.gl.NEAREST);
                this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_MIN_FILTER, this._cgl.gl.NEAREST);
            }
            else if (this.filter == Texture.FILTER_LINEAR)
            {
                this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_MIN_FILTER, this._cgl.gl.LINEAR);
                this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_MAG_FILTER, this._cgl.gl.LINEAR);
            }
            else if (this.filter == Texture.FILTER_MIPMAP)
            {
                this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_MAG_FILTER, this._cgl.gl.LINEAR);
                this._cgl.gl.texParameteri(this.texTarget, this._cgl.gl.TEXTURE_MIN_FILTER, this._cgl.gl.LINEAR_MIPMAP_LINEAR);
            }
            else
            {
                this._log.log("unknown texture filter!", this.filter);
                throw new Error("unknown texture filter!" + this.filter);
            }

            if (this.anisotropic)
            {
                const ext = this._cgl.enableExtension("EXT_texture_filter_anisotropic");

                if (this._cgl.maxAnisotropic)
                {
                    const aniso = Math.min(this._cgl.maxAnisotropic, this.anisotropic);
                    this._cgl.gl.texParameterf(this._cgl.gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY_EXT, aniso);
                }
            }
        }
        this.getInfoOneLine();
        this._cgl.printError("_setFilter");
    }
}

/**
 * @function load
 * @static
 * @memberof Texture
 * @description load an image from an url
 * @param {CglContext} cgl
 * @param {String} url
 * @param {Function} finishedCallback
 * @param {Object} settings
 * @return {Texture}
 */
Texture.load = function (cgl, url, finishedCallback, settings)
{
    if (!url) return finishedCallback({ "error": true });
    let loadingId = null;
    if (!cgl.patch.loading.existByName(url)) loadingId = cgl.patch.loading.start("cgl.texture", url);

    const texture = new Texture(cgl);
    texture.name = url;

    texture.image = new Image();
    texture.image.crossOrigin = "anonymous";
    texture.loading = true;

    if (settings && settings.hasOwnProperty("filter")) texture.filter = settings.filter;
    if (settings && settings.hasOwnProperty("flip")) texture.flip = settings.flip;
    if (settings && settings.hasOwnProperty("wrap")) texture.wrap = settings.wrap;
    if (settings && settings.hasOwnProperty("anisotropic")) texture.anisotropic = settings.anisotropic;
    if (settings && settings.hasOwnProperty("unpackAlpha")) texture.unpackAlpha = settings.unpackAlpha;
    if (settings && settings.hasOwnProperty("pixelFormat")) texture.pixelFormat = settings.pixelFormat;

    texture.image.onabort = texture.image.onerror = (e) =>
    {
        console.warn("[cgl.texture.load] error loading texture", url, e);
        texture.loading = false;
        if (loadingId) cgl.patch.loading.finished(loadingId);
        const error = { "error": true };
        if (finishedCallback) finishedCallback(error, texture);
    };

    texture.image.onload = function (e)
    {
        cgl.addNextFrameOnceCallback(() =>
        {
            texture.initTexture(texture.image);
            if (loadingId) cgl.patch.loading.finished(loadingId);
            texture.loading = false;

            if (finishedCallback) finishedCallback(null, texture);
        });
    };
    texture.image.src = url;

    return texture;
};

/**
 * @static
 * @function getTempTexture
 * @memberof Texture
 * @description returns the default temporary texture (grey diagonal stipes)
 // * @param {CglContext} cgl
 * @return {Texture}
 */
Texture.getTempTexture = function (cgl)
{
    if (!cgl) console.error("[getTempTexture] no cgl!");
    if (!cgl.tempTexture) cgl.tempTexture = Texture.getTemporaryTexture(cgl, 256, Texture.FILTER_LINEAR, Texture.REPEAT);
    return cgl.tempTexture;
};

/**
 * @static
 * @function getErrorTexture
 * @memberof Texture
 * @description returns the default temporary texture (grey diagonal stipes)
 * @param {CglContext} cgl
 * @return {Texture}
 */
Texture.getErrorTexture = function (cgl)
{
    if (!cgl) console.error("[getTempTexture] no cgl!");
    if (!cgl.errorTexture) cgl.errorTexture = Texture.getTemporaryTexture(cgl, 256, Texture.FILTER_LINEAR, Texture.REPEAT, 1, 0.2, 0.2);
    return cgl.errorTexture;
};

/**
 * @function getEmptyTexture
 * @memberof Texture
 * @instance
 * @param cgl
 * @param fp
 * @description returns a reference to a small empty (transparent) texture
 * @return {Texture}
 */
Texture.getEmptyTexture = function (cgl, fp)
{
    if (fp) return Texture.getEmptyTextureFloat(cgl);
    if (!cgl) console.error("[getEmptyTexture] no cgl!");
    if (cgl.tempTextureEmpty) return cgl.tempTextureEmpty;

    let size = 8;

    cgl.tempTextureEmpty = new Texture(cgl, { "name": "emptyTexture" });
    const data = Texture.getDefaultTextureData("empty", size);

    cgl.tempTextureEmpty.initFromData(data, size, size, Texture.FILTER_NEAREST, Texture.WRAP_REPEAT);

    return cgl.tempTextureEmpty;
};

/**
 * @function getEmptyTextureFloat
 * @memberof Texture
 * @instance
 * @param cgl
 * @description returns a reference to a small empty (transparent) 32bit texture
 * @return {Texture}
 */
Texture.getEmptyTextureFloat = function (cgl)
{
    if (!cgl) console.error("[getEmptyTextureFloat] no cgl!");
    if (cgl.tempTextureEmptyFloat) return cgl.tempTextureEmptyFloat;

    cgl.tempTextureEmptyFloat = new Texture(cgl, { "name": "emptyTexture", "isFloatingPointTexture": true });
    const data = new Float32Array(8 * 8 * 4).fill(1);
    for (let i = 0; i < 8 * 8 * 4; i += 4) data[i + 3] = 0;

    cgl.tempTextureEmptyFloat.initFromData(data, 8, 8, Texture.FILTER_NEAREST, Texture.WRAP_REPEAT);

    return cgl.tempTextureEmptyFloat;
};

/**
 * @function getRandomTexture
 * @memberof Texture
 * @static
 * @param cgl
 * @description returns a reference to a random texture
 * @return {Texture}
 */
Texture.getRandomTexture = function (cgl)
{
    if (!cgl) console.error("[getRandomTexture] no cgl!");
    if (cgl.randomTexture) return cgl.randomTexture;

    const size = 256;
    const data = Texture.getDefaultTextureData("randomUInt", size);

    cgl.randomTexture = new Texture(cgl);
    cgl.randomTexture.initFromData(data, size, size, Texture.FILTER_NEAREST, Texture.WRAP_REPEAT);

    return cgl.randomTexture;
};

/**
 * @function getRandomFloatTexture
 * @memberof Texture
 * @static
 * @param cgl
 * @description returns a reference to a texture containing random numbers between -1 and 1
 * @return {Texture}
 */
Texture.getRandomFloatTexture = function (cgl)
{
    if (!cgl) console.error("[getRandomTexture] no cgl!");
    if (cgl.getRandomFloatTexture) return cgl.getRandomFloatTexture;

    const size = 256;
    const data = Texture.getDefaultTextureData("randomFloat", size);

    cgl.getRandomFloatTexture = new Texture(cgl, { "isFloatingPointTexture": true });
    cgl.getRandomFloatTexture.initFromData(data, size, size, Texture.FILTER_NEAREST, Texture.WRAP_REPEAT);

    return cgl.getRandomFloatTexture;
};

/**
 * @function getBlackTexture
 * @memberof Texture
 * @static
 * @param {CglContext} cgl
 * @description returns a reference to a black texture
 * @return {Texture}
 */
Texture.getBlackTexture = function (cgl)
{
    if (cgl.blackTexture) return cgl.blackTexture;

    const size = 8;
    const data = Texture.getDefaultTextureData("color", size, { "r": 0, "g": 0, "b": 0 });

    cgl.blackTexture = new Texture(cgl);
    cgl.blackTexture.initFromData(data, size, size, Texture.FILTER_NEAREST, Texture.WRAP_REPEAT);

    return cgl.blackTexture;
};

/**
 * @function getEmptyCubemapTexture
 * @memberof Texture
 * @static
 * @param cgl
 * @description returns an empty cubemap texture with rgba = [0, 0, 0, 0]
 * @return {Texture}
 */
Texture.getEmptyCubemapTexture = function (cgl)
{
    const faces = [
        cgl.gl.TEXTURE_CUBE_MAP_POSITIVE_X,
        cgl.gl.TEXTURE_CUBE_MAP_NEGATIVE_X,
        cgl.gl.TEXTURE_CUBE_MAP_POSITIVE_Y,
        cgl.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,
        cgl.gl.TEXTURE_CUBE_MAP_POSITIVE_Z,
        cgl.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z
    ];

    const tex = cgl.gl.createTexture();
    const target = cgl.gl.TEXTURE_CUBE_MAP;
    const filter = Texture.FILTER_NEAREST;
    const wrap = Texture.WRAP_CLAMP_TO_EDGE;
    const width = 8;
    const height = 8;

    cgl.profileData.profileTextureNew++;

    cgl.gl.bindTexture(target, tex);
    cgl.profileData.profileTextureResize++;

    for (let i = 0; i < 6; i += 1)
    {
        const data = new Uint8Array(8 * 8 * 4);

        cgl.gl.texImage2D(faces[i], 0, cgl.gl.RGBA, 8, 8, 0, cgl.gl.RGBA, cgl.gl.UNSIGNED_BYTE, data);
        cgl.gl.texParameteri(target, cgl.gl.TEXTURE_MAG_FILTER, cgl.gl.NEAREST);
        cgl.gl.texParameteri(target, cgl.gl.TEXTURE_MIN_FILTER, cgl.gl.NEAREST);

        cgl.gl.texParameteri(target, cgl.gl.TEXTURE_WRAP_S, cgl.gl.CLAMP_TO_EDGE);
        cgl.gl.texParameteri(target, cgl.gl.TEXTURE_WRAP_T, cgl.gl.CLAMP_TO_EDGE);
    }

    cgl.gl.bindTexture(target, null);

    return {
        "id": cables__WEBPACK_IMPORTED_MODULE_2__.uuid(),
        "tex": tex,
        "cubemap": tex,
        "width": width,
        "height": height,
        "filter": filter,
        "wrap": wrap,
        "unpackAlpha": true,
        "flip": true,
        "_fromData": true,
        "name": "emptyCubemapTexture",
        "anisotropic": 0,
    };
};

Texture.getTempGradientTexture = function (cgl) // deprecated...
{
    if (!cgl) console.error("[getTempGradientTexture] no cgl!");
    return Texture.getTempTexture(cgl);
};

Texture.getTemporaryTexture = function (cgl, size, filter, wrap, r, g, b)
{
    const data = Texture.getDefaultTextureData("stripes", 256, { "r": r, "g": g, "b": b });
    const temptex = new Texture(cgl);
    temptex.initFromData(data, size, size, filter, wrap);
    return temptex;
};

/**
 * @static
 * @function createFromImage
 * @memberof Texture
 * @description create texturem from image data (e.g. image or canvas)
 * @param {CglContext} cgl
 * @param {Object} img image
 * @param {Object} options
 */
Texture.createFromImage = function (cgl, img, options)
{
    options = options || {};
    const texture = new Texture(cgl, options);
    texture.flip = false;
    texture.image = img;
    texture.width = img.videoWidth || img.width || 8;
    texture.height = img.videoHeight || img.height || 8;
    if (options.hasOwnProperty("wrap"))texture.wrap = options.wrap;

    texture.initTexture(img, options.filter);

    return texture;
};

// deprecated!
Texture.fromImage = function (cgl, img, filter, wrap)
{
    console.error("deprecated texture from image...");

    const texture = new Texture(cgl);
    texture.flip = false;
    if (filter) texture.filter = filter;
    if (wrap) texture.wrap = wrap;
    texture.image = img;
    texture.initTexture(img);
    return texture;
};

/**
 * @static
 * @function isPowerOfTwo
 * @memberof Texture
 * @description returns true if x is power of two
 * @param {Number} x
 * @return {Boolean}
 */
Texture.isPowerOfTwo = function (x)
{
    return x == 1 || x == 2 || x == 4 || x == 8 || x == 16 || x == 32 || x == 64 || x == 128 || x == 256 || x == 512 || x == 1024 || x == 2048 || x == 4096 || x == 8192 || x == 16384;
};

Texture.getTexInfo = function (tex)
{
    const obj = {};

    obj.name = tex.name;
    obj["power of two"] = tex.isPowerOfTwo();
    obj.size = tex.width + " x " + tex.height;

    let targetString = tex.texTarget;
    if (tex.texTarget == tex._cgl.gl.TEXTURE_2D) targetString = "TEXTURE_2D";
    obj.target = targetString;

    obj.unpackAlpha = tex.unpackAlpha;

    if (tex.cubemap)obj.cubemap = true;

    if (tex.textureType == Texture.TYPE_FLOAT) obj.textureType = "TYPE_FLOAT";
    if (tex.textureType == Texture.TYPE_HALF_FLOAT) obj.textureType = "TYPE_HALF_FLOAT";
    else if (tex.textureType == Texture.TYPE_DEPTH) obj.textureType = "TYPE_DEPTH";
    else if (tex.textureType == Texture.TYPE_DEFAULT) obj.textureType = "TYPE_DEFAULT";
    else obj.textureType = "UNKNOWN " + this.textureType;

    if (tex.wrap == Texture.WRAP_CLAMP_TO_EDGE) obj.wrap = "CLAMP_TO_EDGE";
    else if (tex.wrap == Texture.WRAP_REPEAT) obj.wrap = "WRAP_REPEAT";
    else if (tex.wrap == Texture.WRAP_MIRRORED_REPEAT) obj.wrap = "WRAP_MIRRORED_REPEAT";
    else obj.wrap = "UNKNOWN";

    if (tex.filter == Texture.FILTER_NEAREST) obj.filter = "FILTER_NEAREST";
    else if (tex.filter == Texture.FILTER_LINEAR) obj.filter = "FILTER_LINEAR";
    else if (tex.filter == Texture.FILTER_MIPMAP) obj.filter = "FILTER_MIPMAP";
    else obj.filter = "UNKNOWN";

    obj.pixelFormat = tex.pixelFormat || "unknown";

    return obj;
};

Texture.setUpGlPixelFormat = function (cgl, pixelFormatStr)
{
    const o = {};

    if (!pixelFormatStr)
    {
        cgl._log.error("no pixelformatstr!");
        cgl._log.log(new Error());
        pixelFormatStr = Texture.PFORMATSTR_RGBA8UB;
    }

    o.pixelFormatBase = pixelFormatStr;
    o.pixelFormat = pixelFormatStr;
    o.glDataType = cgl.gl.UNSIGNED_BYTE;
    o.glInternalFormat = cgl.gl.RGBA8;
    o.glDataFormat = cgl.gl.RGBA;

    let floatDatatype = cgl.gl.FLOAT;

    if (cgl.glUseHalfFloatTex)
    {
        if (pixelFormatStr == Texture.PFORMATSTR_RGBA32F) pixelFormatStr = Texture.PFORMATSTR_RGBA16F;
        if (pixelFormatStr == Texture.PFORMATSTR_RG32F) pixelFormatStr = Texture.PFORMATSTR_RG16F;
        if (pixelFormatStr == Texture.PFORMATSTR_R32F) pixelFormatStr = Texture.PFORMATSTR_R16F;
    }

    if (pixelFormatStr.includes("16bit"))
    {
        if (cgl.glVersion == 2)
        {
            // cgl.enableExtension("OES_texture_half_float");
            const hasExt = cgl.enableExtension("EXT_color_buffer_half_float");

            if (!hasExt)
            {
                console.warn("no 16bit extension, fallback to 32bit", pixelFormatStr);
                // fallback to 32 bit?
                if (pixelFormatStr == Texture.PFORMATSTR_RGBA16F) pixelFormatStr = Texture.PFORMATSTR_RGBA32F;
                if (pixelFormatStr == Texture.PFORMATSTR_RGB16F) pixelFormatStr = Texture.PFORMATSTR_RGB32F;
                if (pixelFormatStr == Texture.PFORMATSTR_RG16F) pixelFormatStr = Texture.PFORMATSTR_RG32F;
                if (pixelFormatStr == Texture.PFORMATSTR_R16F) pixelFormatStr = Texture.PFORMATSTR_R32F;
            }
            else
            {
                floatDatatype = cgl.gl.HALF_FLOAT;
            }
        }
    }

    if (cgl.glVersion == 1)
    {
        o.glInternalFormat = cgl.gl.RGBA;

        if (pixelFormatStr == Texture.PFORMATSTR_RGBA16F || pixelFormatStr == Texture.PFORMATSTR_RG16F || pixelFormatStr == Texture.PFORMATSTR_R16F)
        {
            const ext = cgl.enableExtension("OES_texture_half_float");
            if (!ext) throw new Error("no half float texture extension");

            floatDatatype = ext.HALF_FLOAT_OES;
        }
    }

    if (pixelFormatStr == Texture.PFORMATSTR_RGBA8UB)
    {
    }
    else if (pixelFormatStr == Texture.PFORMATSTR_RGB565)
    {
        o.glInternalFormat = cgl.gl.RGB565;
        o.glDataFormat = cgl.gl.RGB;
    }
    else if (pixelFormatStr == Texture.PFORMATSTR_R8UB)
    {
        o.glInternalFormat = cgl.gl.R8;
        o.glDataFormat = cgl.gl.RED;
    }
    else if (pixelFormatStr == Texture.PFORMATSTR_RG8UB)
    {
        o.glInternalFormat = cgl.gl.RG8;
        o.glDataFormat = cgl.gl.RG;
    }
    else if (pixelFormatStr == Texture.PFORMATSTR_RGB8UB)
    {
        o.glInternalFormat = cgl.gl.RGB8;
        o.glDataFormat = cgl.gl.RGB;
    }
    else if (pixelFormatStr == Texture.PFORMATSTR_SRGBA8)
    {
        o.glInternalFormat = cgl.gl.SRGB8_ALPHA8;
    }

    else if (pixelFormatStr == Texture.PFORMATSTR_R32F)
    {
        o.glInternalFormat = cgl.gl.R32F;
        o.glDataFormat = cgl.gl.RED;
        o.glDataType = floatDatatype;
    }
    else if (pixelFormatStr == Texture.PFORMATSTR_R16F)
    {
        o.glInternalFormat = cgl.gl.R16F;
        o.glDataType = floatDatatype;
        o.glDataFormat = cgl.gl.RED;
    }
    else if (pixelFormatStr == Texture.PFORMATSTR_RG16F)
    {
        o.glInternalFormat = cgl.gl.RG16F;
        o.glDataType = floatDatatype;
        o.glDataFormat = cgl.gl.RG;
    }
    else if (pixelFormatStr == Texture.PFORMATSTR_RGBA16F)
    {
        if (cgl.glVersion == 1) o.glInternalFormat = cgl.gl.RGBA;
        else o.glInternalFormat = cgl.gl.RGBA16F;
        o.glDataType = floatDatatype;
    }
    else if (pixelFormatStr == Texture.PFORMATSTR_R11FG11FB10F)
    {
        o.glInternalFormat = cgl.gl.R11F_G11F_B10F;
        o.glDataType = floatDatatype;
        o.glDataFormat = cgl.gl.RGB;
    }
    else if (pixelFormatStr == Texture.PFORMATSTR_RGBA32F)
    {
        if (cgl.glVersion == 1) o.glInternalFormat = cgl.gl.RGBA;
        else o.glInternalFormat = cgl.gl.RGBA32F;
        o.glDataType = floatDatatype;
    }
    else if (pixelFormatStr == Texture.PFORMATSTR_DEPTH)
    {
        if (cgl.glVersion == 1)
        {
            o.glInternalFormat = cgl.gl.DEPTH_COMPONENT;
            o.glDataType = cgl.gl.UNSIGNED_SHORT;
            o.glDataFormat = cgl.gl.DEPTH_COMPONENT;
        }
        else
        {
            o.glInternalFormat = cgl.gl.DEPTH_COMPONENT32F;
            o.glDataType = cgl.gl.FLOAT;
            o.glDataFormat = cgl.gl.DEPTH_COMPONENT;
        }
    }
    else
    {
        log.log("unknown pixelformat ", pixelFormatStr);
    }

    /// //////

    if (pixelFormatStr.includes("32bit") || pixelFormatStr == Texture.PFORMATSTR_R11FG11FB10F)
    {
        if (cgl.glVersion == 2) cgl.enableExtension("EXT_color_buffer_float");
        if (cgl.glVersion == 2) cgl.enableExtension("EXT_float_blend");

        cgl.enableExtension("OES_texture_float_linear"); // yes, i am sure, this is a webgl 1 and 2 ext
    }

    o.numColorChannels = Texture.getPixelFormatNumChannels(pixelFormatStr);

    if (!o.glDataType || !o.glInternalFormat || !o.glDataFormat) log.log("pixelformat wrong ?!", pixelFormatStr, o.glDataType, o.glInternalFormat, o.glDataFormat, this);

    return o;
};

Texture.getPixelFormatNumChannels =
    (pxlFrmtStr) =>
    {
        if (pxlFrmtStr.startsWith("RGBA")) return 4;
        if (pxlFrmtStr.startsWith("RGB")) return 3;
        if (pxlFrmtStr.startsWith("RG")) return 2;
        return 1;
    };

Texture.isPixelFormatFloat =
    (pxlFrmtStr) =>
    {
        return (pxlFrmtStr || "").includes("float");
    };

Texture.isPixelFormatHalfFloat =
    (pxlFrmtStr) =>
    {
        return (pxlFrmtStr || "").includes("float") && (pxlFrmtStr || "").includes("16bit");
    };


/***/ }),

/***/ 771:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   p: () => (/* binding */ TextureEffect)
/* harmony export */ });
/* harmony import */ var cables_shared_client__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(849);
/* harmony import */ var _cgl_texture_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(70);
/* harmony import */ var _cgl_simplerect_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(273);




class TextureEffect
{
    constructor(cgl, options)
    {
        this._cgl = cgl;
        this._log = new cables_shared_client__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A("cgl_TextureEffect");

        if (!cgl.TextureEffectMesh) this.createMesh();

        this._textureSource = null;
        this._options = options;
        this.name = options.name || "unknown";

        this.imgCompVer = 0;
        this.aspectRatio = 1;
        this._textureTarget = null; // new CGL.Texture(this._cgl,opts);
        this._frameBuf = this._cgl.gl.createFramebuffer();
        this._frameBuf2 = this._cgl.gl.createFramebuffer();
        this._renderbuffer = this._cgl.gl.createRenderbuffer();
        this._renderbuffer2 = this._cgl.gl.createRenderbuffer();
        this.switched = false;
        this.depth = false;
    }

    dispose()
    {
        if (this._renderbuffer) this._cgl.gl.deleteRenderbuffer(this._renderbuffer);
        if (this._frameBuf) this._cgl.gl.deleteFramebuffer(this._frameBuf);
        if (this._renderbuffer2) this._cgl.gl.deleteRenderbuffer(this._renderbuffer2);
        if (this._frameBuf2) this._cgl.gl.deleteFramebuffer(this._frameBuf2);
    }

    getWidth()
    {
        return this._textureSource.width;
    }

    getHeight()
    {
        return this._textureSource.height;
    }

    setSourceTexture(tex)
    {
        if (tex === null)
        {
            this._textureSource = new _cgl_texture_js__WEBPACK_IMPORTED_MODULE_1__/* .Texture */ .g(this._cgl);
            this._textureSource.setSize(16, 16);
        }
        else
        {
            this._textureSource = tex;
        }

        if (!this._textureSource.compareSettings(this._textureTarget))
        {
            if (this._textureTarget) this._textureTarget.delete();

            this._textureTarget = this._textureSource.clone();

            this._cgl.profileData.profileEffectBuffercreate++;

            this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._frameBuf);

            this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER, this._renderbuffer);

            // if(tex.textureType==CGL.Texture.TYPE_FLOAT) this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER,this._cgl.gl.RGBA32F, this._textureSource.width,this._textureSource.height);
            // else this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER,this._cgl.gl.RGBA8, this._textureSource.width,this._textureSource.height);

            if (this.depth) this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER, this._cgl.gl.DEPTH_COMPONENT16, this._textureSource.width, this._textureSource.height);
            this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.COLOR_ATTACHMENT0, this._cgl.gl.TEXTURE_2D, this._textureTarget.tex, 0);
            if (this.depth) this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.DEPTH_ATTACHMENT, this._cgl.gl.RENDERBUFFER, this._renderbuffer);

            // this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.COLOR_ATTACHMENT0, this._cgl.gl.TEXTURE_2D, this._textureTarget.tex, 0);

            this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D, null);
            this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER, null);
            this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, null);

            this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._frameBuf2);

            this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER, this._renderbuffer2);

            // if(tex.textureType==CGL.Texture.TYPE_FLOAT) this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER,this._cgl.gl.RGBA32F, this._textureSource.width,this._textureSource.height);
            // else this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER,this._cgl.gl.RGBA8, this._textureSource.width,this._textureSource.height);

            if (this.depth) this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER, this._cgl.gl.DEPTH_COMPONENT16, this._textureSource.width, this._textureSource.height);
            this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.COLOR_ATTACHMENT0, this._cgl.gl.TEXTURE_2D, this._textureSource.tex, 0);

            if (this.depth) this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.DEPTH_ATTACHMENT, this._cgl.gl.RENDERBUFFER, this._renderbuffer2);

            // this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.COLOR_ATTACHMENT0, this._cgl.gl.TEXTURE_2D, this._textureSource.tex, 0);

            this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D, null);
            this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER, null);
            this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, null);
        }

        this.aspectRatio = this._textureSource.width / this._textureSource.height;
    }

    continueEffect()
    {
        this._cgl.pushDepthTest(false);
        this._cgl.pushModelMatrix();
        this._cgl.pushPMatrix();
        // todo why two pushs?

        this._cgl.pushViewPort(0, 0, this.getCurrentTargetTexture().width, this.getCurrentTargetTexture().height);

        mat4.perspective(this._cgl.pMatrix, 45, this.getCurrentTargetTexture().width / this.getCurrentTargetTexture().height, 0.1, 1100.0); // todo: why?

        this._cgl.pushPMatrix();
        mat4.identity(this._cgl.pMatrix);

        this._cgl.pushViewMatrix();
        mat4.identity(this._cgl.vMatrix);

        this._cgl.pushModelMatrix();
        mat4.identity(this._cgl.mMatrix);
    }

    startEffect(bgTex)
    {
        if (!this._textureTarget)
        {
            this._log.warn("effect has no target");
            return;
        }

        this.switched = false;

        this.continueEffect();

        if (bgTex)
        {
            this._bgTex = bgTex;
        }
        this._countEffects = 0;
    }

    endEffect()
    {
        this._cgl.popDepthTest();
        this._cgl.popModelMatrix();

        this._cgl.popPMatrix();
        this._cgl.popModelMatrix();
        this._cgl.popViewMatrix();

        this._cgl.popPMatrix();
        this._cgl.popViewPort();
    }

    bind()
    {
        if (this._textureSource === null)
        {
            this._log.warn("no base texture set!");
            return;
        }

        if (!this.switched)
        {
            this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._frameBuf);
            this._cgl.pushGlFrameBuffer(this._frameBuf);
        }
        else
        {
            this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._frameBuf2);
            this._cgl.pushGlFrameBuffer(this._frameBuf2);
        }
    }

    finish()
    {
        if (this._textureSource === null)
        {
            this._log.warn("no base texture set!");
            return;
        }

        this._cgl.TextureEffectMesh.render(this._cgl.getShader());

        this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._cgl.popGlFrameBuffer());

        this._cgl.profileData.profileTextureEffect++;

        if (this._textureTarget.filter == _cgl_texture_js__WEBPACK_IMPORTED_MODULE_1__/* .Texture */ .g.FILTER_MIPMAP)
        {
            if (!this.switched)
            {
                this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D, this._textureTarget.tex);
                this._textureTarget.updateMipMap();
            }
            else
            {
                this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D, this._textureSource.tex);
                this._textureSource.updateMipMap();
            }

            this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D, null);
        }

        this.switched = !this.switched;
        this._countEffects++;
    }

    getCurrentTargetTexture()
    {
        if (this.switched) return this._textureSource;
        return this._textureTarget;
    }

    getCurrentSourceTexture()
    {
        if (this._countEffects == 0 && this._bgTex) return this._bgTex;

        if (this.switched) return this._textureTarget;
        return this._textureSource;
    }

    delete()
    {
        if (this._textureTarget) this._textureTarget.delete();
        if (this._textureSource) this._textureSource.delete();
        this._cgl.gl.deleteRenderbuffer(this._renderbuffer);
        this._cgl.gl.deleteFramebuffer(this._frameBuf);
    }

    createMesh()
    {
        this._cgl.TextureEffectMesh = _cgl_simplerect_js__WEBPACK_IMPORTED_MODULE_2__/* .MESHES */ .S.getSimpleRect(this._cgl, "texEffectRect");
    }

    // ---------------------------------------------------------------------------------
}

TextureEffect.checkOpNotInTextureEffect = function (op)
{
    if (!op.patch.cgl) return true;
    if (op.uiAttribs.error && !op.patch.cgl.currentTextureEffect)
    {
        op.setUiError("textureeffect", null);
        return true;
    }
    if (!op.patch.cgl.currentTextureEffect) return true;

    if (op.patch.cgl.currentTextureEffect && !op.uiAttribs.error)
    {
        op.setUiError("textureeffect", "This op can not be a child of a ImageCompose/texture effect! imagecompose should only have textureeffect childs.", 0);
        return false;
    }

    if (op.patch.cgl.currentTextureEffect) return false;
    return true;
};

TextureEffect.checkOpInEffect = function (op, minver)
{
    minver = minver || 0;

    if (op.patch.cgl.currentTextureEffect)
    {
        if (op.uiAttribs.uierrors && op.patch.cgl.currentTextureEffect.imgCompVer >= minver)
        {
            op.setUiError("texeffect", null);
            return true;
        }

        if (minver && op.patch.cgl.currentTextureEffect.imgCompVer < minver)
        {
            op.setUiError("texeffect", "This op must be a child of an ImageCompose op with version >=" + minver + " <span class=\"button-small\" onclick=\"gui.patchView.downGradeOp('" + op.id + "','" + op.name + "')\">Downgrade</span> to previous version", 1);
        }
    }

    if (op.patch.cgl.currentTextureEffect) return true;

    if (!op.patch.cgl.currentTextureEffect && (!op.uiAttribs.uierrors || op.uiAttribs.uierrors.length == 0))
    {
        op.setUiError("texeffect", "This op must be a child of an ImageCompose op! More infos <a href=\"https://cables.gl/docs/image_composition/image_composition.html\" target=\"_blank\">here</a>. ", 1);
        return false;
    }

    if (!op.patch.cgl.currentTextureEffect) return false;
    return true;
};

TextureEffect.getBlendCode = function (ver)
{
    let src = "".endl()
        + "vec3 _blend(vec3 base,vec3 blend)".endl()
        + "{".endl()
        + "   vec3 colNew=blend;".endl()
        + "   #ifdef BM_MULTIPLY".endl()
        + "       colNew=base*blend;".endl()
        + "   #endif".endl()
        + "   #ifdef BM_MULTIPLY_INV".endl()
        + "       colNew=base* vec3(1.0)-blend;".endl()
        + "   #endif".endl()
        + "   #ifdef BM_AVERAGE".endl()
        + "       colNew=((base + blend) / 2.0);".endl()
        + "   #endif".endl()
        + "   #ifdef BM_ADD".endl()
        + "       colNew=min(base + blend, vec3(1.0));".endl()
        + "   #endif".endl()
        + "   #ifdef BM_SUBTRACT_ONE".endl()
        + "       colNew=max(base + blend - vec3(1.0), vec3(0.0));".endl()
        + "   #endif".endl()

        + "   #ifdef BM_SUBTRACT".endl()
        + "       colNew=base - blend;".endl()
        + "   #endif".endl()

        + "   #ifdef BM_DIFFERENCE".endl()
        + "       colNew=abs(base - blend);".endl()
        + "   #endif".endl()
        + "   #ifdef BM_NEGATION".endl()
        + "       colNew=(vec3(1.0) - abs(vec3(1.0) - base - blend));".endl()
        + "   #endif".endl()
        + "   #ifdef BM_EXCLUSION".endl()
        + "       colNew=(base + blend - 2.0 * base * blend);".endl()
        + "   #endif".endl()
        + "   #ifdef BM_LIGHTEN".endl()
        + "       colNew=max(blend, base);".endl()
        + "   #endif".endl()
        + "   #ifdef BM_DARKEN".endl()
        + "       colNew=min(blend, base);".endl()
        + "   #endif".endl()
        + "   #ifdef BM_OVERLAY".endl()
        + "      #define BlendOverlayf(base, blend)  (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)))"
            // .endl()+'       #define BlendOverlay(base, blend)       Blend(base, blend, BlendOverlayf)'
            //    .endl()+'      colNew=Blend(base, blend, BlendOverlayf);'
            .endl()
        + "      colNew=vec3(BlendOverlayf(base.r, blend.r),BlendOverlayf(base.g, blend.g),BlendOverlayf(base.b, blend.b));".endl()
        + "   #endif".endl()
        + "   #ifdef BM_SCREEN".endl()
        + "      #define BlendScreenf(base, blend)       (1.0 - ((1.0 - base) * (1.0 - blend)))"
            // .endl()+'       #define BlendScreen(base, blend)        Blend(base, blend, BlendScreenf)'
            // .endl()+'      colNew=Blend(base, blend, BlendScreenf);'
            .endl()
        + "      colNew=vec3(BlendScreenf(base.r, blend.r),BlendScreenf(base.g, blend.g),BlendScreenf(base.b, blend.b));".endl()
        + "   #endif".endl()
        + "   #ifdef BM_SOFTLIGHT".endl()
        + "      #define BlendSoftLightf(base, blend)    ((blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend)))"
            // .endl()+'       #define BlendSoftLight(base, blend)     Blend(base, blend, BlendSoftLightf)'
            //    .endl()+'      colNew=Blend(base, blend, BlendSoftLightf);'
            .endl()
        + "      colNew=vec3(BlendSoftLightf(base.r, blend.r),BlendSoftLightf(base.g, blend.g),BlendSoftLightf(base.b, blend.b));".endl()
        + "   #endif".endl()
        + "   #ifdef BM_HARDLIGHT".endl()
        + "      #define BlendOverlayf(base, blend)  (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)))"
            // .endl()+'       #define BlendOverlay(base, blend)       Blend(base, blend, BlendOverlayf)'
            // .endl()+'      colNew=Blend(blend, base, BlendOverlayf);'
            .endl()
        + "      colNew=vec3(BlendOverlayf(base.r, blend.r),BlendOverlayf(base.g, blend.g),BlendOverlayf(base.b, blend.b));".endl()
        + "   #endif".endl()
        + "   #ifdef BM_COLORDODGE".endl()
        + "      #define BlendColorDodgef(base, blend)   ((blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0))"
            // .endl()+'      colNew=Blend(base, blend, BlendColorDodgef);'
            .endl()
        + "      colNew=vec3(BlendColorDodgef(base.r, blend.r),BlendColorDodgef(base.g, blend.g),BlendColorDodgef(base.b, blend.b));".endl()
        + "   #endif".endl()
        + "   #ifdef BM_COLORBURN".endl()
        + "      #define BlendColorBurnf(base, blend)    ((blend == 0.0) ? blend : max((1.0 - ((1.0 - base) / blend)), 0.0))"
            // .endl()+'      colNew=Blend(base, blend, BlendColorBurnf);'
            .endl()
        + "      colNew=vec3(BlendColorBurnf(base.r, blend.r),BlendColorBurnf(base.g, blend.g),BlendColorBurnf(base.b, blend.b));".endl()
        + "   #endif".endl()

        + "   return colNew;".endl()
        + "}".endl();

    if (!ver)
        src += "vec4 cgl_blend(vec4 oldColor,vec4 newColor,float amount)".endl()
                + "{".endl()
                    + "vec4 col=vec4( _blend(oldColor.rgb,newColor.rgb) ,1.0);".endl()
                    + "col=vec4( mix( col.rgb, oldColor.rgb ,1.0-oldColor.a*amount),1.0);".endl()
                    + "return col;".endl()
                + "}".endl();

    if (ver >= 3)
        src += "vec4 cgl_blendPixel(vec4 base,vec4 col,float amount)".endl() +
                "{".endl() +

                "#ifdef BM_MATH_ADD".endl() +
                "   return vec4(base.rgb+col.rgb*amount,1.0);".endl() +
                "#endif".endl() +

                "#ifdef BM_MATH_SUB".endl() +
                "   return vec4(base.rgb-col.rgb*amount,1.0);".endl() +
                "#endif".endl() +

                "#ifdef BM_MATH_MUL".endl() +
                "   return vec4(base.rgb*col.rgb*amount,1.0);".endl() +
                "#endif".endl() +

                "#ifdef BM_MATH_DIV".endl() +
                "   return vec4(base.rgb/col.rgb*amount,1.0);".endl() +
                "#endif".endl() +

                    "#ifndef BM_MATH".endl() +
                        "vec3 colNew=_blend(base.rgb,col.rgb);".endl() +

                        "float newA=clamp(base.a+(col.a*amount),0.,1.);".endl() +

                        "#ifdef BM_ALPHAMASKED".endl() +
                            "newA=base.a;".endl() +
                        "#endif".endl() +

                        "return vec4(".endl() +
                            "mix(colNew,base.rgb,1.0-(amount*col.a)),".endl() +
                            "newA);".endl() +

                    "#endif".endl() +
    "}".endl();

    return src;
};

TextureEffect.onChangeBlendSelect = function (shader, blendName, maskAlpha = false)
{
    blendName = String(blendName);
    shader.toggleDefine("BM_NORMAL", blendName == "normal");
    shader.toggleDefine("BM_MULTIPLY", blendName == "multiply");
    shader.toggleDefine("BM_MULTIPLY_INV", blendName == "multiply invert");
    shader.toggleDefine("BM_AVERAGE", blendName == "average");
    shader.toggleDefine("BM_ADD", blendName == "add");
    shader.toggleDefine("BM_SUBTRACT_ONE", blendName == "subtract one");
    shader.toggleDefine("BM_SUBTRACT", blendName == "subtract");
    shader.toggleDefine("BM_DIFFERENCE", blendName == "difference");
    shader.toggleDefine("BM_NEGATION", blendName == "negation");
    shader.toggleDefine("BM_EXCLUSION", blendName == "exclusion");
    shader.toggleDefine("BM_LIGHTEN", blendName == "lighten");
    shader.toggleDefine("BM_DARKEN", blendName == "darken");
    shader.toggleDefine("BM_OVERLAY", blendName == "overlay");
    shader.toggleDefine("BM_SCREEN", blendName == "screen");
    shader.toggleDefine("BM_SOFTLIGHT", blendName == "softlight");
    shader.toggleDefine("BM_HARDLIGHT", blendName == "hardlight");
    shader.toggleDefine("BM_COLORDODGE", blendName == "color dodge");
    shader.toggleDefine("BM_COLORBURN", blendName == "color burn");

    shader.toggleDefine("BM_MATH_ADD", blendName == "Math Add");
    shader.toggleDefine("BM_MATH_SUB", blendName == "Math Subtract");
    shader.toggleDefine("BM_MATH_MUL", blendName == "Math Multiply");
    shader.toggleDefine("BM_MATH_DIV", blendName == "Math Divide");

    shader.toggleDefine("BM_MATH", blendName.indexOf("Math ") == 0);

    shader.toggleDefine("BM_ALPHAMASKED", maskAlpha);
};

TextureEffect.AddBlendSelect = function (op, name, defaultMode)
{
    const p = op.inValueSelect(name || "Blend Mode", [
        "normal", "lighten", "darken", "multiply", "multiply invert", "average", "add", "subtract", "difference", "negation", "exclusion", "overlay", "screen", "color dodge", "color burn", "softlight", "hardlight", "subtract one",
        "Math Add",
        "Math Subtract",
        "Math Multiply",
        "Math Divide",

    ], defaultMode || "normal");
    return p;
};

TextureEffect.AddBlendAlphaMask = function (op, name, defaultMode)
{
    const p = op.inSwitch(name || "Alpha Mask", ["Off", "On"], defaultMode || "Off");
    return p;
};

TextureEffect.setupBlending = function (op, shader, blendPort, amountPort, alphaMaskPort)
{
    const onChange = () =>
    {
        let maskAlpha = false;
        if (alphaMaskPort) maskAlpha = alphaMaskPort.get() == "On";
        TextureEffect.onChangeBlendSelect(shader, blendPort.get(), maskAlpha);

        let str = blendPort.get();
        if (str == "normal") str = null;
        else if (str == "multiply") str = "mul";
        else if (str == "multiply invert") str = "mulinv";
        else if (str == "lighten") str = "light";
        else if (str == "darken") str = "darken";
        else if (str == "average") str = "avg";
        else if (str == "subtract one") str = "sub one";
        else if (str == "subtract") str = "sub";
        else if (str == "difference") str = "diff";
        else if (str == "negation") str = "neg";
        else if (str == "exclusion") str = "exc";
        else if (str == "overlay") str = "ovl";
        else if (str == "color dodge") str = "dodge";
        else if (str == "color burn") str = "burn";
        else if (str == "softlight") str = "soft";
        else if (str == "hardlight") str = "hard";
        else if (str == "Math Add") str = "+";
        else if (str == "Math Subtract") str = "-";
        else if (str == "Math Multiply") str = "*";
        else if (str == "Math Divide") str = "/";

        op.setUiAttrib({ "extendTitle": str });
    };
    op.setPortGroup("Blending", [blendPort, amountPort, alphaMaskPort]);

    let maskAlpha = false;

    blendPort.onChange = onChange;
    if (alphaMaskPort)
    {
        alphaMaskPort.onChange = onChange;
        maskAlpha = alphaMaskPort.get() == "On";
    }

    TextureEffect.onChangeBlendSelect(shader, blendPort.get(), maskAlpha);
};


/***/ }),

/***/ 997:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   a: () => (/* binding */ CONSTANTS),
/* harmony export */   nl: () => (/* binding */ nl)
/* harmony export */ });
const SHADER = {
    // default attributes
    "SHADERVAR_VERTEX_POSITION": "vPosition",
    "SHADERVAR_VERTEX_NUMBER": "attrVertIndex",
    "SHADERVAR_VERTEX_NORMAL": "attrVertNormal",
    "SHADERVAR_VERTEX_TEXCOORD": "attrTexCoord",
    "SHADERVAR_INSTANCE_MMATRIX": "instMat",
    "SHADERVAR_VERTEX_COLOR": "attrVertColor",

    "SHADERVAR_INSTANCE_INDEX": "instanceIndex",

    // default uniforms
    "SHADERVAR_UNI_PROJMAT": "projMatrix",
    "SHADERVAR_UNI_VIEWMAT": "viewMatrix",
    "SHADERVAR_UNI_MODELMAT": "modelMatrix",
    "SHADERVAR_UNI_NORMALMAT": "normalMatrix",
    "SHADERVAR_UNI_INVVIEWMAT": "inverseViewMatrix",
    "SHADERVAR_UNI_INVPROJMAT": "invProjMatrix",
    "SHADERVAR_UNI_MATERIALID": "materialId",
    "SHADERVAR_UNI_OBJECTID": "objectId",

    "SHADERVAR_UNI_VIEWPOS": "camPos",
};

const BLEND_MODES = {
    "BLEND_NONE": 0,
    "BLEND_NORMAL": 1,
    "BLEND_ADD": 2,
    "BLEND_SUB": 3,
    "BLEND_MUL": 4,
};

const RAD2DEG = 180.0 / Math.PI;
const DEG2RAD = Math.PI / 180.0;

const CONSTANTS = {
    "MATH": {
        "DEG2RAD": DEG2RAD,
        "RAD2DEG": RAD2DEG,
    },
    "SHADER": SHADER,
    "BLEND_MODES": BLEND_MODES,
};
const nl = "\n";// newline



/***/ }),

/***/ 772:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";

// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  Rq: () => (/* binding */ cgl_CGL)
});

// UNUSED EXPORTS: Framebuffer2, Geometry, Mesh, Shader, Texture, Uniform

// EXTERNAL MODULE: ./src/core/anim.js
var anim = __webpack_require__(344);
// EXTERNAL MODULE: ../shared/client/src/logger.js
var logger = __webpack_require__(849);
// EXTERNAL MODULE: ./src/corelibs/cgl/cgl_texture.js
var cgl_texture = __webpack_require__(70);
;// CONCATENATED MODULE: ./src/corelibs/cgl/cgl_framebuffer2.js




class Framebuffer2
{

    /**
     * @param {CglContext} cgl
     * @param {number} w
     * @param {number} h
     * @param {object} options
     */
    constructor(cgl, w, h, options)
    {
        this._log = new logger/* default */.A("cgl_framebuffer2");
        if (cgl.glVersion == 1) this._log.error("framebuffer2 used on webgl1");
        this.Framebuffer2DrawTargetsDefault = null;
        this.Framebuffer2BlittingFramebuffer = null;
        this.Framebuffer2FinalFramebuffer = null;
        this._cgl = cgl;

        this._cgl.printError("before framebuffer2 constructor");

        this._width = 0;
        this._height = 0;
        this.valid = true;

        this._depthRenderbuffer = null;
        this._frameBuffer = null;
        this._textureFrameBuffer = null;
        this._colorRenderbuffers = [];
        this._drawTargetArray = [];
        this._disposed = false;

        if (!this.Framebuffer2BlittingFramebuffer) this.Framebuffer2BlittingFramebuffer = cgl.gl.createFramebuffer();
        if (!this.Framebuffer2FinalFramebuffer) this.Framebuffer2FinalFramebuffer = cgl.gl.createFramebuffer();

        if (!this.Framebuffer2DrawTargetsDefault) this.Framebuffer2DrawTargetsDefault = [cgl.gl.COLOR_ATTACHMENT0];

        this._options = options || {
            "isFloatingPointTexture": false,
        };

        this.name = this._options.name || "unknown";

        this._cgl.profileData.addHeavyEvent("framebuffer create", this.name);

        if (!this._options.hasOwnProperty("numRenderBuffers")) this._options.numRenderBuffers = 1;
        if (!this._options.hasOwnProperty("depth")) this._options.depth = true;
        if (!this._options.hasOwnProperty("clear")) this._options.clear = true;
        if (!this._options.hasOwnProperty("multisampling"))
        {
            this._options.multisampling = false;
            this._options.multisamplingSamples = 0;
        }

        if (this._options.multisamplingSamples)
        {
            if (this._cgl.glSlowRenderer) this._options.multisamplingSamples = 0;
            if (!this._cgl.gl.MAX_SAMPLES) this._options.multisamplingSamples = 0;
            else this._options.multisamplingSamples = Math.min(this._cgl.maxSamples, this._options.multisamplingSamples);
        }

        if (!this._options.hasOwnProperty("filter")) this._options.filter = cgl_texture/* Texture */.g.FILTER_LINEAR;
        if (!this._options.hasOwnProperty("wrap")) this._options.wrap = cgl_texture/* Texture */.g.WRAP_REPEAT;

        this._numRenderBuffers = this._options.numRenderBuffers;
        this._colorTextures = [];

        this.clearColors = [];
        for (let i = 0; i < this._numRenderBuffers; i++) this.clearColors.push([0, 0, 0, 1]);

        if (!options.pixelFormat)
        {
            if (options.isFloatingPointTexture) this._options.pixelFormat = cgl_texture/* Texture */.g.PFORMATSTR_RGBA32F;
            else this._options.pixelFormat = cgl_texture/* Texture */.g.PFORMATSTR_RGBA8UB;
        }

        for (let i = 0; i < this._numRenderBuffers; i++)
        {
            this._colorTextures[i] = new cgl_texture/* Texture */.g(cgl, {
                "name": "fb2 " + this.name + " " + i,
                "isFloatingPointTexture": this._options.isFloatingPointTexture,
                "anisotropic": this._options.anisotropic || 0,
                "pixelFormat": this._options.pixelFormat,
                "filter": this._options.filter,
                "wrap": this._options.wrap,
            });
        }

        let fil = cgl_texture/* Texture */.g.FILTER_NEAREST;
        if (this._options.shadowMap) fil = cgl_texture/* Texture */.g.FILTER_LINEAR;

        const defaultTexSize = 512;

        if (this._options.depth)
        {
            this._textureDepth = new cgl_texture/* Texture */.g(cgl,
                {
                    "name": "fb2 depth " + this.name,
                    "isDepthTexture": true,
                    "filter": fil,
                    "shadowMap": this._options.shadowMap || false,
                    "width": w || defaultTexSize,
                    "height": h || defaultTexSize,
                });
        }

        if (cgl.aborted) return;

        this.setSize(w || defaultTexSize, h || defaultTexSize);

        this._cgl.printError("framebuffer2 constructor");
    }

    getWidth()
    {
        return this._width;
    }

    getHeight()
    {
        return this._height;
    }

    getGlFrameBuffer()
    {
        return this._frameBuffer;
    }

    getDepthRenderBuffer()
    {
        return this._depthRenderbuffer;
    }

    getTextureColor()
    {
        return this._colorTextures[0];
    }

    getTextureColorNum(i)
    {
        return this._colorTextures[i];
    }

    getTextureDepth()
    {
        return this._textureDepth;
    }

    setFilter(f)
    {
        for (let i = 0; i < this._numRenderBuffers; i++)
        {
            this._colorTextures[i].filter = f;
            this._colorTextures[i].setSize(this._width, this._height);
        }
    }

    delete()
    {
        this.dispose();
    }

    dispose()
    {
        this._disposed = true;
        let i = 0;
        for (i = 0; i < this._numRenderBuffers; i++) this._colorTextures[i].delete();
        // this._texture.delete();
        if (this._textureDepth) this._textureDepth.delete();
        for (i = 0; i < this._numRenderBuffers; i++) this._cgl.gl.deleteRenderbuffer(this._colorRenderbuffers[i]);
        this._cgl.gl.deleteRenderbuffer(this._depthRenderbuffer);
        this._cgl.gl.deleteFramebuffer(this._frameBuffer);
        this._cgl.gl.deleteFramebuffer(this._textureFrameBuffer);
    }

    /**
     * @param {number} w
     * @param {number} h
     */
    setSize(w, h)
    {
        if (this._disposed) return this._log.warn("disposed framebuffer setsize...");
        this._cgl.profileData.addHeavyEvent("framebuffer resize", this.name);

        let i = 0;

        this._width = this._cgl.checkTextureSize(w);
        this._height = this._cgl.checkTextureSize(h);

        this._cgl.profileData.profileFrameBuffercreate++;

        if (this._frameBuffer)
        {
            for (i = 0; i < this._numRenderBuffers; i++) this._cgl.gl.deleteRenderbuffer(this._colorRenderbuffers[i]);
            // this._cgl.gl.deleteRenderbuffer(this._colorRenderbuffer);
            this._cgl.gl.deleteRenderbuffer(this._depthRenderbuffer);
            this._cgl.gl.deleteFramebuffer(this._frameBuffer);
            this._cgl.gl.deleteFramebuffer(this._textureFrameBuffer);
        }

        this._frameBuffer = this._cgl.gl.createFramebuffer();
        this._textureFrameBuffer = this._cgl.gl.createFramebuffer();

        const depth = this._options.depth;

        for (i = 0; i < this._numRenderBuffers; i++)
        {
            this._colorTextures[i].setSize(this._width, this._height);
        }

        for (i = 0; i < this._numRenderBuffers; i++)
        {
            const renderBuffer = this._cgl.gl.createRenderbuffer();

            // color renderbuffer

            this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._frameBuffer);
            this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER, renderBuffer);

            const info = cgl_texture/* Texture */.g.setUpGlPixelFormat(this._cgl, this._options.pixelFormat);
            let internFormat = info.glInternalFormat;

            // if (this._options.isFloatingPointTexture)
            // {
            if (CGL.Texture.isPixelFormatHalfFloat(info.pixelFormat))
            {
                if (!this._cgl.enableExtension("OES_texture_float_linear"))
                {
                    this._options.filter = cgl_texture/* Texture */.g.FILTER_NEAREST;
                    this.setFilter(this._options.filter);
                }
            }
            else if (CGL.Texture.isPixelFormatFloat(info.pixelFormat))
            {
                if (!this._cgl.enableExtension("OES_texture_float_linear"))
                {
                    this._log.warn("no linear pixelformat,using nearest");
                    this._options.filter = cgl_texture/* Texture */.g.FILTER_NEAREST;
                    this.setFilter(this._options.filter);
                }
            }
            // else if (info.pixelFormat == Texture.PFORMATSTR_RGBA32F || info.pixelFormat == Texture.PFORMATSTR_R11FG11FB10F
            // else if (info.pixelFormat == Texture.PFORMATSTR_RGBA32F || info.pixelFormat == Texture.PFORMATSTR_R11FG11FB10F
            // else if (info.pixelFormat == Texture.PFORMATSTR_RG16F)
            // {
            //     const extcb = this._cgl.enableExtension("EXT_color_buffer_float");

            //     if (!this._cgl.enableExtension("OES_texture_float_linear"))
            //     {
            //         console.log("no linear pixelformat,switching to nearest");
            //         this._options.filter = Texture.FILTER_NEAREST;
            //         this.setFilter(this._options.filter);
            //     }
            // }
            // }

            if (this._options.multisampling && this._options.multisamplingSamples)
            {
                this._cgl.gl.renderbufferStorageMultisample(this._cgl.gl.RENDERBUFFER, this._options.multisamplingSamples, internFormat, this._width, this._height);
            }
            else
            {
                this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER, internFormat, this._width, this._height);
            }

            this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.COLOR_ATTACHMENT0 + i, this._cgl.gl.RENDERBUFFER, renderBuffer);
            this._colorRenderbuffers[i] = renderBuffer;
        }

        // this._cgl.gl.bindFramebuffer(this._cgl.gl.DRAW_FRAMEBUFFER, this._textureFrameBuffer);
        this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._textureFrameBuffer);

        for (i = 0; i < this._numRenderBuffers; i++)
        {
            this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.COLOR_ATTACHMENT0 + i, this._cgl.gl.TEXTURE_2D, this._colorTextures[i].tex, 0);
        }

        if (this._options.depth)
        {
            this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.DEPTH_ATTACHMENT, this._cgl.gl.TEXTURE_2D, this._textureDepth.tex, 0);
        }

        // depth renderbuffer

        this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._frameBuffer);

        let depthType = this._cgl.gl.DEPTH_COMPONENT32F;

        if (this._cgl.glSlowRenderer) depthType = this._cgl.gl.DEPTH_COMPONENT16;
        if (depth)
        {
            this._textureDepth.setSize(this._width, this._height);
            this._depthRenderbuffer = this._cgl.gl.createRenderbuffer();

            this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER, this._depthRenderbuffer);
            if (this._options.isFloatingPointTexture)
            {
                if (this._options.multisampling) this._cgl.gl.renderbufferStorageMultisample(this._cgl.gl.RENDERBUFFER, this._options.multisamplingSamples, depthType, this._width, this._height);
                else this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER, depthType, this._width, this._height);
            }
            else if (this._options.multisampling)
            {
                this._cgl.gl.renderbufferStorageMultisample(this._cgl.gl.RENDERBUFFER, this._options.multisamplingSamples, depthType, this._width, this._height);
            // this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER,depthType, this._width, this._height);
            }
            else
            {
                this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER, depthType, this._width, this._height);
            }

            this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.DEPTH_ATTACHMENT, this._cgl.gl.RENDERBUFFER, this._depthRenderbuffer);
        }

        // this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, null);
        // this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._textureFrameBuffer);

        this._drawTargetArray.length = 0;
        for (i = 0; i < this._numRenderBuffers; i++) this._drawTargetArray.push(this._cgl.gl.COLOR_ATTACHMENT0 + i);

        // this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, null);

        if (!this._cgl.gl.isFramebuffer(this._textureFrameBuffer)) this._log.warn("invalid framebuffer");// throw new Error("Invalid framebuffer");
        const status = this._cgl.gl.checkFramebufferStatus(this._cgl.gl.FRAMEBUFFER);

        if (status != this._cgl.gl.FRAMEBUFFER_COMPLETE)
        {
            this._log.error("framebuffer incomplete: " + this.name, this);
            this._log.log("options", this._options);
            this._log.log("options pixelformat", this._options.pixelFormat);

            switch (status)
            {
            case this._cgl.gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
                this._log.warn("FRAMEBUFFER_INCOMPLETE_ATTACHMENT...", this);
                throw new Error("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
            case this._cgl.gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
                this._log.warn("FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
                throw new Error("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
            case this._cgl.gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
                this._log.warn("FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
                throw new Error("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
            case this._cgl.gl.FRAMEBUFFER_UNSUPPORTED:
                this._log.warn("FRAMEBUFFER_UNSUPPORTED");
                throw new Error("Incomplete framebuffer: FRAMEBUFFER_UNSUPPORTED");
            default:
                this.valid = false;
                this._log.error("incomplete framebuffer", status, this._frameBuffer);
                this._cgl.printError();

                this._frameBuffer = null;
                // debugger;
                throw new Error("Incomplete framebuffer: " + status);

        // throw("Incomplete framebuffer: " + status);
            }
        }

        this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, null);
        this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER, null);

    // this._cgl.printError("fb setsize");
    }

    renderStart()
    {
        if (this._disposed) return this._log.warn("disposed framebuffer renderStart...");
        this._cgl.checkFrameStarted("fb2 renderstart");
        this._cgl.pushModelMatrix(); // needed ??

        this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._frameBuffer);
        this._cgl.pushGlFrameBuffer(this._frameBuffer);
        this._cgl.pushFrameBuffer(this);

        this._cgl.pushPMatrix();
        this._cgl.pushViewPort(0, 0, this._width, this._height);

        this._cgl.gl.drawBuffers(this._drawTargetArray);

        if (this._options.clear)
        {
            this._cgl.gl.clearColor(0, 0, 0, 0);
            this._cgl.gl.clear(this._cgl.gl.COLOR_BUFFER_BIT | this._cgl.gl.DEPTH_BUFFER_BIT);
        }
    }

    clear()
    {
        if (this._numRenderBuffers <= 1)
        {
            this._cgl.gl.bindFramebuffer(this._cgl.gl.READ_FRAMEBUFFER, this._frameBuffer);
            this._cgl.gl.bindFramebuffer(this._cgl.gl.DRAW_FRAMEBUFFER, this._textureFrameBuffer);
        }
        else this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._frameBuffer);

        this._cgl.gl.drawBuffers(this._drawTargetArray);

        for (let i = 0; i < this._numRenderBuffers; i++)
        {
            this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.COLOR_ATTACHMENT0 + i, this._cgl.gl.TEXTURE_2D, this._colorTextures[i].tex, 0);
            this._cgl.gl.clearBufferfv(this._cgl.gl.COLOR, i, this.clearColors[i]);
        }
        this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, null);
    }

    renderEnd()
    {
        if (this._disposed) return this._log.warn("disposed framebuffer renderEnd...");
        this._cgl.popPMatrix();

        this._cgl.profileData.profileFramebuffer++;

        if (this._numRenderBuffers <= 1)
        {
            this._cgl.gl.bindFramebuffer(this._cgl.gl.READ_FRAMEBUFFER, this._frameBuffer);
            this._cgl.gl.bindFramebuffer(this._cgl.gl.DRAW_FRAMEBUFFER, this._textureFrameBuffer);

            this._cgl.gl.clearBufferfv(this._cgl.gl.COLOR, 0, [0.0, 0.0, 0.0, 1.0]);
            this._cgl.gl.blitFramebuffer(0, 0, this._width, this._height, 0, 0, this._width, this._height, this._cgl.gl.COLOR_BUFFER_BIT | this._cgl.gl.DEPTH_BUFFER_BIT, this._cgl.gl.NEAREST);
        }
        else
        {
            this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this.Framebuffer2BlittingFramebuffer);
            this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.DEPTH_ATTACHMENT, this._cgl.gl.RENDERBUFFER, this._depthRenderbuffer);

            this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this.Framebuffer2FinalFramebuffer);
            this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.DEPTH_ATTACHMENT, this._cgl.gl.TEXTURE_2D, this._textureDepth.tex, 0);

            for (let i = 0; i < this._numRenderBuffers; i++)
            {
                this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this.Framebuffer2BlittingFramebuffer);
                this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.COLOR_ATTACHMENT0, this._cgl.gl.RENDERBUFFER, this._colorRenderbuffers[i]);

                this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this.Framebuffer2FinalFramebuffer);
                this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER, this._cgl.gl.COLOR_ATTACHMENT0, this._cgl.gl.TEXTURE_2D, this._colorTextures[i].tex, 0);

                this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, null);

                this._cgl.gl.bindFramebuffer(this._cgl.gl.READ_FRAMEBUFFER, this.Framebuffer2BlittingFramebuffer);
                this._cgl.gl.bindFramebuffer(this._cgl.gl.DRAW_FRAMEBUFFER, this.Framebuffer2FinalFramebuffer);

                // this._cgl.gl.clearBufferfv(this._cgl.gl.COLOR, i, [0.0, 0.0, 0.0, 1.0]);

                let flags = this._cgl.gl.COLOR_BUFFER_BIT;
                if (i == 0) flags |= this._cgl.gl.DEPTH_BUFFER_BIT;

                this._cgl.gl.blitFramebuffer(0, 0, this._width, this._height, 0, 0, this._width, this._height, flags, this._cgl.gl.NEAREST);
            }
        }

        this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER, this._cgl.popGlFrameBuffer());
        this._cgl.popFrameBuffer();

        this._cgl.popModelMatrix();
        this._cgl.popViewPort();

        if (this._colorTextures[0].filter == cgl_texture/* Texture */.g.FILTER_MIPMAP)
        {
            for (let i = 0; i < this._numRenderBuffers; i++)
            {
                this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D, this._colorTextures[i].tex);
                this._colorTextures[i].updateMipMap();
                this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D, null);
            }
        }
    }
}

;// CONCATENATED MODULE: ./src/corelibs/cgl/cgl_marker.js
/** @type {function}
 * @deprecated
*/
const Marker = function (_cgl) // deprecated...
{
    this.draw = function (cgl, _size, depthTest) {};
};

/** @type {function}
 * @deprecated
*/
const WirePoint = function (cgl) // deprecated...
{
    this.render = function (_cgl, _size) {};
};

/** @type {function}
 * @deprecated
*/
const WireCube = function (cgl) // deprecated...
{
    this.render = function (_cgl, sizeX, sizeY, sizeZ) {};
};

// EXTERNAL MODULE: ./src/corelibs/cgl/cgl_mesh.js
var cgl_mesh = __webpack_require__(264);
// EXTERNAL MODULE: ./src/corelibs/cgl/cgl_shader_uniform.js
var cgl_shader_uniform = __webpack_require__(923);
// EXTERNAL MODULE: ./src/corelibs/cgl/cgl_shader_lib.js
var cgl_shader_lib = __webpack_require__(960);
;// CONCATENATED MODULE: ./src/corelibs/cgl/cgl_unicolorshader.js


class UniColorShader
{
    constructor(_cgl)
    {
        this.shader = new CGL.Shader(_cgl, "markermaterial");

        const frag = ""
            .endl() + "void main()"
            .endl() + "{"
            .endl() + "    outColor = vec4(color.rgb,1.0);"
            .endl() + "}";

        const vert = ""
            .endl() + "IN vec3 vPosition;"
            .endl() + "UNI mat4 projMatrix;"
            .endl() + "UNI mat4 mvMatrix;"

            .endl() + "void main()"
            .endl() + "{"
            .endl() + "   gl_Position = projMatrix * mvMatrix * vec4(vPosition,1.0);"
            .endl() + "}";

        this.shader.setSource(vert, frag);
        this.coloruni = this.shader.addUniformFrag("4f", "color", [1, 0.777, 1, 1]);
    }

    setColor(r, g, b, a)
    {
        this.coloruni.set(r, g, b, a);
    }
}

// EXTERNAL MODULE: ./src/corelibs/cgl/cgl_shader.js
var cgl_shader = __webpack_require__(24);
// EXTERNAL MODULE: ./src/corelibs/cgl/cgl_simplerect.js
var cgl_simplerect = __webpack_require__(273);
;// CONCATENATED MODULE: ./src/corelibs/cgl/cgl_utils.js
/**
 * @namespace CGL
 */

/**
 * multiply to get radians from degree, e.g. `360 * CGL.DEG2RAD`
 * @const {Number}
 * @memberof CGL
 * @static
 */
const DEG2RAD = Math.PI / 180.0;

/**
 * to get degrees from radians, e.g. `3.14 * CGL.RAD2DEG`
 * @const {number}
 * @memberof CGL
 */
const RAD2DEG = 180.0 / Math.PI;

const onLoadingAssetsFinished = null; // deprecated / remove later

/**
 * get normalized mouse wheel delta (including browser specific adjustment)
 * @function getWheelDelta
 * @static
 * @memberof CGL
 * @param {MouseEvent} event
 * @return {Number} normalized delta
 */
const isWindows = window.navigator.userAgent.includes("Windows");
const getWheelDelta_ = function (event)
{
    let normalized;
    if (event.wheelDelta)
    {
        // chrome
        normalized = (event.wheelDelta % 120) - 0 == -0 ? event.wheelDelta / 120 : event.wheelDelta / 30;
        normalized *= -1.5;
        if (isWindows) normalized *= 2;
    }
    else
    {
        // firefox
        let d = event.deltaY;
        if (event.shiftKey) d = event.deltaX;
        const rawAmmount = d || event.detail;
        normalized = -(rawAmmount % 3 ? rawAmmount * 10 : rawAmmount / 3);
        normalized *= -3;
    }

    if (normalized > 20) normalized = 20;
    if (normalized < -20) normalized = -20;

    return normalized;
};

const getWheelSpeed = getWheelDelta_;
const getWheelDelta = getWheelDelta_;

// EXTERNAL MODULE: ./src/corelibs/cgl/cgl_textureeffect.js
var cgl_textureeffect = __webpack_require__(771);
// EXTERNAL MODULE: ./src/corelibs/cgl/constants.js
var constants = __webpack_require__(997);
// EXTERNAL MODULE: ./src/corelibs/cgl/cgl_profiledata.js
var cgl_profiledata = __webpack_require__(460);
// EXTERNAL MODULE: ./src/corelibs/cg/cg_geom.js
var cg_geom = __webpack_require__(331);
// EXTERNAL MODULE: ./src/corelibs/cg/cg_boundingbox.js
var cg_boundingbox = __webpack_require__(982);
// EXTERNAL MODULE: ./src/corelibs/cg/cg_matrixstack.js
var cg_matrixstack = __webpack_require__(868);
// EXTERNAL MODULE: ./src/corelibs/cgl/cgl_state.js
var cgl_state = __webpack_require__(308);
;// CONCATENATED MODULE: ./src/corelibs/cgl/index.js

















const cgl_CGL = {
    "Framebuffer2": Framebuffer2,
    "Geometry": cg_geom/* Geometry */.V,
    "BoundingBox": cg_boundingbox/* BoundingBox */.I,
    "Marker": Marker,
    "WirePoint": WirePoint,
    "WireCube": WireCube,
    "MatrixStack": cg_matrixstack/* MatrixStack */.u,
    "Mesh": cgl_mesh/* Mesh */.e,
    "MESH": cgl_mesh/* MESH */.C,
    "ShaderLibMods": cgl_shader_lib/* ShaderLibMods */.y,
    "Shader": cgl_shader/* Shader */.M,
    "Uniform": cgl_shader_uniform/* Uniform */.n,
    "MESHES": cgl_simplerect/* MESHES */.S,
    "getWheelSpeed": getWheelSpeed,
    "getWheelDelta": getWheelDelta,
    "Context": cgl_state/* CglContext */.G,
    "Texture": cgl_texture/* Texture */.g,
    "TextureEffect": cgl_textureeffect/* TextureEffect */.p,
    "onLoadingAssetsFinished": onLoadingAssetsFinished,
    "ProfileData": cgl_profiledata/* ProfileData */.E,
    "UniColorShader": UniColorShader,
    ...constants/* CONSTANTS */.a.BLEND_MODES,
    ...constants/* CONSTANTS */.a.SHADER,
    ...constants/* CONSTANTS */.a.MATH,
    ...constants/* CONSTANTS */.a.BLEND_MODES,
};

window.CABLES = window.CABLES || {};
window.CABLES.CGL = window.CABLES.CGL || cgl_CGL;
window.CGL = window.CGL || cgl_CGL;

/**
 * @param {number} time
 * @param {quat} q
 * @param {Anim} animx
 * @param {Anim} animy
 * @param {Anim} animz
 * @param {Anim} animw
 */
anim/* Anim */.k.slerpQuaternion = function (time, q, animx, animy, animz, animw)
{
    if (!anim/* Anim */.k.slerpQuaternion.q1)
    {
        anim/* Anim */.k.slerpQuaternion.q1 = quat.create();
        anim/* Anim */.k.slerpQuaternion.q2 = quat.create();
    }

    const i1 = animx.getKeyIndex(time);
    let i2 = i1 + 1;
    if (i2 >= animx.keys.length) i2 = animx.keys.length - 1;

    if (i1 == i2)
    {
        quat.set(q, animx.keys[i1].value, animy.keys[i1].value, animz.keys[i1].value, animw.keys[i1].value);
    }
    else
    {
        const key1Time = animx.keys[i1].time;
        const key2Time = animx.keys[i2].time;
        const perc = (time - key1Time) / (key2Time - key1Time);

        quat.set(anim/* Anim */.k.slerpQuaternion.q1, animx.keys[i1].value, animy.keys[i1].value, animz.keys[i1].value, animw.keys[i1].value);

        quat.set(anim/* Anim */.k.slerpQuaternion.q2, animx.keys[i2].value, animy.keys[i2].value, animz.keys[i2].value, animw.keys[i2].value);

        quat.slerp(q, anim/* Anim */.k.slerpQuaternion.q1, anim/* Anim */.k.slerpQuaternion.q2, perc);
    }
    return q;
};




/***/ }),

/***/ 626:
/***/ ((__unused_webpack___webpack_module__, __unused_webpack___webpack_exports__, __webpack_require__) => {

"use strict";

// UNUSED EXPORTS: CGP

// EXTERNAL MODULE: ../shared/client/src/logger.js
var logger = __webpack_require__(849);
// EXTERNAL MODULE: ./src/corelibs/cg/cg_context.js
var cg_context = __webpack_require__(628);
// EXTERNAL MODULE: ./src/corelibs/cg/cg_texture.js
var cg_texture = __webpack_require__(356);
// EXTERNAL MODULE: ./node_modules/gl-matrix/esm/mat4.js
var mat4 = __webpack_require__(684);
// EXTERNAL MODULE: ./src/core/timer.js
var timer = __webpack_require__(920);
// EXTERNAL MODULE: ./src/corelibs/cg/cg_uniform.js
var cg_uniform = __webpack_require__(475);
;// CONCATENATED MODULE: ./src/corelibs/cgp/cgp_uniform.js




class CgpUniform extends cg_uniform/* CgUniform */.v
{

    /** @type {CgpContext} */
    #cgp = null;

    /** @type {GPUBuffer} */
    gpuBuffer = null;

    gpuBufferChanged = false;

    /**
     * Description
     * @param {CgpShader} __shader
     * @param {string} __type
     * @param {string} __name
     * @param {any} _value
     * @param {any} _port2
     * @param {any} _port3
     * @param {any} _port4
     */
    constructor(__shader, __type, __name, _value, _port2, _port3, _port4)
    {
        super(__shader, __type, __name, _value, _port2, _port3, _port4);
        this.#cgp = __shader._cgp;

        if (!_value || (_value.get && !_value.get()))
        {
            // if (this.getType() == "m4") this._value = mat4.create();
            if (this.getType() == "t")
            {
                this._value = this.#cgp.getEmptyTexture();
            }
            // else if (this.getType() == "2f") this._value = [0, 0];
            // else if (this.getType() == "4f") this._value = [0, 1, 0, 1];
            // else if (this.getType() == "3f") this._value = [0, 1, 0];
        }

    }

    getInfo()
    {
        return { "name": this.name, "type": this.type, "value": this.getValue() };
    }

    updateValueF() { }

    updateValueArrayF() {}

    setValueArrayF(v)
    {
        this.needsUpdate = true;
        this._value = v;
    }

    setValueF(v)
    {
        this.needsUpdate = true;
        this._value = v;
    }

    updateValue2F() { }

    setValue2F(v)
    {
        this.needsUpdate = true;
        this._value = v;
    }

    updateValue3F() { }

    setValue3F(v)
    {
        this.needsUpdate = true;
        this._value = v;
    }

    updateValue4F() { }

    setValue4F(v)
    {
        if (v[0] == undefined)
        {
            this._log.stack("uniform value undefined");
            console.error("uniform value undefined");
        }
        this.needsUpdate = true;
        this._value = v;
    }

    setValueT(v)
    {
        // if (this._value != v)
        //     this._shader.needsPipelineUpdate = "texture changed"; // todo really needed ? change binding instead?

        this.needsUpdate = true;
        this._value = v;
    }

    updateValueM4(v) {}

    setValueM4(v)
    {
        this.needsUpdate = true;
        this._value = v;
    }

    setValueAny(v)
    {
        this.needsUpdate = true;
        this._value = v;
    }

    updateValueAny() {}

    updateValueT() {}

    /**
     * @param {GPUBuffer} b
     */
    setGpuBuffer(b)
    {
        this.gpuBufferChanged = true;
        this.gpuBuffer = b;
    }

    copyToBuffer(buff, pos = 0)
    {
        if (this._type == "f")
        {
            buff[pos] = this._value;
        }
        else if (this._type == "t")
        {
        }
        else if (this._type == "4f")
        {
            buff[pos] = this._value[0];
            buff[pos + 1] = this._value[1];
            buff[pos + 2] = this._value[2];
            buff[pos + 3] = this._value[3];
        }
        else if (this._type == "2f")
        {
            buff[pos] = this._value[0];
            buff[pos + 1] = this._value[1];
        }
        else if (this._type == "3f")
        {
            buff[pos] = this._value[0];
            buff[pos + 1] = this._value[1];
            buff[pos + 2] = this._value[2];
        }
        else if (this._type == "f[]")
        {
            for (let i = 0; i < this._value.length; i++)
                buff[pos + i] = this._value[i];
        }
        else if (this._type == "m4")
        {
            for (let i = 0; i < 16; i++)
                buff[pos + i] = this._value[i];
        }
        else
        {
            this._log.warn("uniform copy to buffer unknown", this._type);
        }
    }

    getWgslTypeStr()
    {
        if (this._type == "m4") return "mat4x4f";
        if (this._type == "4f") return "vec4f";
        if (this._type == "3f") return "vec3f";
        if (this._type == "2f") return "vec2f";
        if (this._type == "f") return "f32";
        if (this._type == "f[]") return "array<vec4f>";
        if (this._type == "i") return "int";
        if (this._type == "sampler") return "sampler";
        if (this._type == "t") return "texture_2d<f32>";
        this._log.warn("unknown type getWgslTypeStr", this._type);
        return "???";
    }

    getSizeBytes()
    {
        const bytesPerFloat = 4;
        const bytesPerInt = 4;
        if (this._type == "t") return 4;
        if (this._type == "sampler") return 4;
        if (this._type == "f") return 1 * bytesPerFloat;
        if (this._type == "2f") return 2 * bytesPerFloat;
        if (this._type == "3f") return 3 * bytesPerFloat;
        if (this._type == "4f") return 4 * bytesPerFloat;
        if (this._type == "f[]") return this._value.length * bytesPerFloat;
        if (this._type == "m4") return 4 * 4 * bytesPerFloat;
        if (this._type == "i") return 1 * bytesPerInt;
        if (this._type == "2i") return 2 * bytesPerInt;

        this._log.warn("unknown type getSizeBytes", this._type);
        return 4;
    }

    /**
     * @param {CgpShader} shader
     */
    copy(shader)
    {
        const uni = new CgpUniform(shader, this._type, this._name, this._value, this._port2, this._port3, this._port4);
        uni.shaderType = this.shaderType;

        // console.log(this._name, this._value, uni._value);

        return uni;
    }

}

;// CONCATENATED MODULE: ./src/corelibs/cg/preproc.js
/**
 * @param {string} str
 * @param {object} vars
 */
function preproc(str, vars)
{
    if (!str)
    {
        console.warn("shader preproc no shader code given");
    }
    str = str || "";
    const lines = str.split("\n");
    const outLines = [];
    let stack = [];

    for (let i = 0; i < lines.length; i++)
    {
        let line = lines[i].trim();
        let parts = line.split(" ");

        if (line.startsWith("#ifdef "))
        {
            const s = vars[parts[1]];
            stack.push({ "state": s });
            continue;
        }
        if (line.startsWith("#ifndef "))
        {
            const s = vars[parts[1]];
            stack.push({ "state": !s });
            continue;
        }
        if (line.startsWith("#endif"))
        {
            stack.pop();
            continue;
        }
        const state = stack[stack.length - 1];

        if (line.startsWith("#else"))
        {
            state.state = !state.state;
            continue;
        }

        if (!state || state.state)
        {
            outLines.push(lines[i]);
        }
    }

    return outLines.join("\n");
}

// EXTERNAL MODULE: ./src/corelibs/cg/cg_shader.js
var cg_shader = __webpack_require__(694);
;// CONCATENATED MODULE: ./src/corelibs/cgp/binding/bindgroup.js




class BindGroup
{

    /** @type {Array<GPUBindGroup>} */
    #gpuBindGroups = [];

    /** @type {Array<Binding>} */
    #bindings = [];

    name = "";

    needsPipelineUpdate = false;

    bla = 1;

    /** @type {CgpContext} */
    #cgp;

    /**
     * @param {CgpContext} cgp
     * @param {string} name
     */
    constructor(cgp, name)
    {
        this.#cgp = cgp;
        this.name = name;
    }

    /**
     * @returns {GPUBindGroup}
     */
    // get gpuBindgroup()
    // {
    //     if (!this.#gpuBindGroup)
    //     {
    //         this.create();
    //     }
    //     // console.log(this.#gpuBindGroup);
    //     return this.#gpuBindGroup;
    // }

    /**
     * @param {Binding} b
     * @returns {boolean}
     */
    hasBinding(b)
    {
        return this.#bindings.includes(b);
    }

    /**
     * @param {string} n
     * @returns {Binding}
     */
    getBindingByName(n)
    {

        for (let i = 0; i < this.#bindings.length; i++)
        {
            if (this.#bindings[i].name == n) return this.#bindings[i];
        }
    }

    /**
     * @param {Binding} b
     */
    removeBinding(b)
    {
        const idx = this.#bindings.indexOf(b);
        this.#bindings.splice(idx, 1);
    }

    /**
     * @param {Binding} b
     * @returns {Binding}
     */
    addBinding(b)
    {
        const oldBinding = this.getBindingByName(b.name);
        if (oldBinding) this.removeBinding(oldBinding);
        b.needsRebuildBindgroup = true;
        b.bindNum = this.#bindings.length;
        this.#bindings.push(b);

        return b;
    }

    // /**
    //  * @param {CgpShader} shader
    //  */
    // bind(shader)
    // {
    //     shader.setBindgroup(this);
    // }

    /**
     * @param {CgpShader} [shader]
     */
    getLayoutEntries(shader)
    {
        const arr = [];
        for (let i = 0; i < this.#bindings.length; i++)
        {
            arr.push(this.#bindings[i].getLayoutEntry(shader));
        }

        if (arr.length == 0)
        {
            // console.log("nooooooooooooooooooooooo");
        }
        return arr;
    }

    /**
     * @returns {Array<GPUBindGroupEntry>}
     * @param {number} inst
     */
    getEntries(inst)
    {
        const arr = [];
        for (let i = 0; i < this.#bindings.length; i++)
        {
            arr.push(this.#bindings[i].getBindgroupEntry(inst));
        }

        if (arr.length == 0)
        {
            // console.log("nooooooooooooooooooooooo");
        }
        return arr;
    }

    /**
     * @param {CgpShader} [shader]
     */
    getLayout(shader)
    {
        // console.log(this.getLayoutEntries(shader));

        /** @type {GPUBindGroupLayout} */
        const bindGroupLayout = this.#cgp.device.createBindGroupLayout(
            {
                "label": "bindgrouplayout " + this.name,
                "entries": this.getLayoutEntries(shader),
            });

        return bindGroupLayout;
    }

    /**
     * @param {number} inst
     */
    create(inst)
    {

        /** @type {GPUBindGroupDescriptor} */
        const bg = {
            "label": " " + this.name + " i" + inst,
            "layout": this.getLayout(),
            "entries": this.getEntries(inst)
        };

        this.#cgp.profileData.count("bindgroup created", this.name);

        // if (bindingGroupEntries.length != this.bindingGroupLayoutEntries.length)
        // {
        //     this.#log.error("bindingGroupEntries.length!= this.bindingGroupLayoutEntries.length", bindingGroupEntries.length, this.bindingGroupLayoutEntries.length);
        //     this.#rebuildNumBindingGroups = true;
        //     this.#isValid = false;
        //     return;
        // }

        try
        {
            this.#gpuBindGroups[inst] = this.#cgp.device.createBindGroup(bg);
            this.needsRebuildBindgroup = true;

        }
        catch (e)
        {
            console.log(bg);
            console.error(e);
        }

        this.updateValues(inst);
    }

    /**
     * @param {number} inst
     */
    updateValues(inst)
    {
        for (let i = 0; i < this.#bindings.length; i++)
        {
            this.#bindings[i].updateValues(inst);
        }
    }

    /**
     * @param {number} inst
     * @param {GPURenderPassEncoder|GPUComputePassEncoder} passEnc
     */
    bind(inst = 0, passEnc = null, idx = 0)
    {
        for (let i = 0; i < this.#bindings.length; i++)
            if (this.#bindings[i].needsRebuildBindgroup)
            {
                // console.log("rebuild bg");
                this.create(inst);
                this.#bindings[i].needsRebuildBindgroup = false;
                this.#gpuBindGroups = [];
                // todo: dispose
            }

        if (!this.#gpuBindGroups[inst]) this.create(inst);
        (passEnc || this.#cgp.passEncoder).setBindGroup(idx, this.#gpuBindGroups[inst]);
    }

    /**
     * @param {CgpShader} shader
     * @param {number} idx
     */
    getShaderHeaderCode(shader, idx)
    {
        const srcs = { "vertex": "", "fragment": "", "compute": "" };

        this.#cgp.profileData.count("bindgroup shadercode", this.name);
        for (let i = 0; i < this.#bindings.length; i++)
        {
            const bind = this.#bindings[i];
            let src = "";
            src += bind.getShaderHeaderCode(shader, idx);
            if (bind.stage & GPUShaderStage.VERTEX)srcs.vertex += src;
            else if (bind.stage === GPUShaderStage.FRAGMENT)srcs.fragment += src;
            else if (bind.stage & GPUShaderStage.COMPUTE)srcs.compute += src;
        }

        return srcs;
    }

    /**
     * @param {CgpShader} shader
     */
    copy(shader)
    {
        const newBg = new BindGroup(this.#cgp, this.name);
        for (let i = 0; i < this.#bindings.length; i++)
        {
            newBg.addBinding(this.#bindings[i].copy(shader));
        }
        return newBg;
    }

    setBindingNums()
    {

        for (let i = 0; i < this.#bindings.length; i++)
        {
            this.#bindings[i].setBindNum(i);
        }
    }

    getInfo()
    {
        const o = { "name": this.name, "bindings": [] };
        for (let i = 0; i < this.#bindings.length; i++)
        {
            o.bindings.push(this.#bindings[i].getInfo());
        }
        return o;
    }
}

// EXTERNAL MODULE: ./src/core/utils.js + 1 modules
var utils = __webpack_require__(562);
// EXTERNAL MODULE: ./src/corelibs/cgl/constants.js
var constants = __webpack_require__(997);
;// CONCATENATED MODULE: ./src/corelibs/cgp/binding/binding.js






class Binding
{
    id = utils.simpleId();
    name = "";
    bindNum = 0;
    stage = GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT;
    define = "";
    log = new logger/* default */.A("binding");
    needsRebuildBindgroup = false;

    /** @type {CgpContext} */
    cgp = null;

    /**
     * Description
     * @param {CgpContext} cgp
     * @param {string} name
     * @param {object} options
     */
    constructor(cgp, name, options)
    {
        this.cgp = cgp;
        this.name = name;
        if (!name) this.log.error("no binding name given");
        this.options = options || {};
        if (options.hasOwnProperty("stage")) this.stage = options.stage;
    }

    /**
     * @param {number} _inst
     */
    getResource(_inst)
    {
        // overwrite
        return null;
    }

    /**
     * @param {number} i
     */
    setBindNum(i)
    {
        if (this.bindNum != i) this.needsRebuildBindgroup = true;
        this.bindNum = i;
    }

    /**
     * @returns {GPUBindGroupLayoutEntry}
     * @param {CgpShader} _shader
     */
    getLayoutEntry(_shader)
    {
        this.log.warn("unknown binding type?", this);
        return null;
    }

    /**
     * @returns {GPUBindGroupEntry}
     * @param {number} inst
     */
    getBindgroupEntry(inst)
    {
        let label = "layout " + this.name + " [" + this.constructor.name;
        label += "]";

        return {
            "binding": this.bindNum,
            "resource": this.getResource(inst)
        };
    }

    /** @param {CgpShader} _shader */
    isActiveByDefine(_shader)
    {
        if (!this.define) return true;
        // if (this.define && !shader.hasDefine(this.define)) return false;
        return true;
    }

    /** @param {number} _inst */
    updateValues(_inst)
    {
        // overwrite
    }

    /**
     * @param {CgpShader} _shader
     * @param {number} _bindGroupNum
     * @returns {String}
     */
    getShaderHeaderCode(_shader, _bindGroupNum)
    {
        return "//getShaderHeaderCode function not emplemented " + constants.nl;
    }

    /**
     * @param {CgpShader} _shader
     * @returns {Binding}
     */
    copy(_shader)
    {
        // implenented in inheriting classes
        return null;
    }

    getInfo()
    {
        const o = { "name": this.name, "id": this.id, "class": this.constructor.name };
        return o;
    }
}

// EXTERNAL MODULE: ../shared/client/src/eventtarget.js + 2 modules
var eventtarget = __webpack_require__(125);
;// CONCATENATED MODULE: ./src/corelibs/cgp/cgp_gpubuffer.js




/** @typedef GPUBufferOptions
 * @property {number} [length]
 * @property {GPUBufferDescriptor} [buffCfg]
*/

class CgpGguBuffer extends eventtarget/* default */.A
{
    #name = "unknown";

    /** @type {CgpContext} */
    #cgp = null;

    /** @type {GPUBuffer} */
    #gpuBuffer = null;

    /** @type {GPUBufferDescriptor} */
    buffCfg = null;

    #length = 0;
    id = utils.shortId();
    floatArr = null;
    needsUpdate = true;
    #log;

    // static BINDINGTYPE_STORAGE = "storage";
    // static BINDINGTYPE_UNIFORM = "uniform";
    // static BINDINGTYPE_READONLY_STORAGE = "read-only-storage";

    /**
     * Description
     * @param {CgpContext} cgp
     * @param {String} name
     * @param {Array} data=null
     * @param {GPUBufferOptions} options={}
     */
    constructor(cgp, name, data = null, options = {})
    {
        super();
        this.#log = new logger/* default */.A("cgpGpubuffer");
        if (!cgp.supported) return;

        this.#name = name;
        // this.setData([0, 0, 0, 0]);

        this.buffCfg = options.buffCfg || {};
        if (data) this.setData(data);
        if (options.length) this.setLength(options.length);

        this.buffCfg.usage = this.buffCfg.usage || (GPUBufferUsage.COPY_DST | GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_SRC);
        this.updateGpuBuffer(cgp);
    }

    /**
     * @param {Array} arr
     */
    setData(arr)
    {
        this.floatArr = new Float32Array(arr);
        this.setLength(this.floatArr.length);

        this.needsUpdate = true;
    }

    /**
     * @param {number} s
     */
    setLength(s)
    {
        this.#length = s;
        if (!this.floatArr || s != this.floatArr.length)
        {
            this.floatArr = new Float32Array(this.#length);
            this.needsUpdate = true;
        }
    }

    /**
     * @param {number} flag
     */
    hasUsage(flag)
    {
        return (this.buffCfg.usage & flag) === flag;
    }

    /** @param {CgpContext} cgp */
    updateGpuBuffer(cgp = null)
    {
        if (cgp) this.#cgp = cgp;
        if (!this.#cgp || !this.#cgp.device)
        {
            this.#log.warn("no cgp...", this.#name, this.#cgp);
            return;
        }

        this.#cgp.pushErrorScope("updateGpuBuffer");
        if (!this.#gpuBuffer || this.buffCfg.mappedAtCreation)
        {
            this.buffCfg = /** @type {GPUBufferDescriptor} */(this.buffCfg || {});
            this.buffCfg.label = "gpuBuffer-" + this.#name;
            if (!this.buffCfg.hasOwnProperty("size") && this.floatArr) this.buffCfg.size = this.floatArr.length * 4;

            this.#gpuBuffer = this.#cgp.device.createBuffer(this.buffCfg);
        }

        if (this.floatArr)
        {
            if (this.buffCfg.mappedAtCreation)
            {
                new Float32Array(this.#gpuBuffer.getMappedRange()).set(this.floatArr);
                this.#gpuBuffer.unmap();

            }
            else

                this.#cgp.device.queue.writeBuffer(
                    this.#gpuBuffer,
                    0,
                    this.floatArr.buffer,
                    this.floatArr.byteOffset,
                    this.floatArr.byteLength
                );
        }

        this.#cgp.popErrorScope();

        this.needsUpdate = false;
    }

    get name()
    {
        return this.#name;
    }

    /** @returns {GPUBuffer} */
    get gpuBuffer()
    {
        if (!this.#gpuBuffer || this.needsUpdate) this.updateGpuBuffer();

        return this.#gpuBuffer;
    }

    get length()
    {
        return this.#length;
    }

    getSizeBytes()
    {
        return this.floatArr.length * 4;
    }

    dispose()
    {
        // setTimeout(() =>
        // {
        //     if (this._gpuBuffer) this._gpuBuffer.destroy();
        // }, 100);
    }
}

;// CONCATENATED MODULE: ./src/corelibs/cgp/binding/binding_uniform.js






/** @extends Binding */
class BindingUniform extends Binding
{

    /** @type {Array<CgpUniform>} */
    #uniforms = [];

    /** @type {Array<CgpGguBuffer>} */
    cgpBuffer = [];

    /**
     * Description
     * @param {CgpContext} cgp
     * @param {string} name
     * @param {object} options
     */
    constructor(cgp, name, options)
    {
        super(cgp, name, options);

        console.log("new binding uniform", this.id);
    }

    /**
     * @param {CgpShader} shader
     * @returns {Binding}
     */
    copy(shader)
    {
        const b = new BindingUniform(this.cgp, this.name, this.options);
        console.log("copybinuni", this.id, b.id);
        b.stage = this.stage;

        for (let i = 0; i < this.#uniforms.length; i++)
        {
            let foundWorldUni = false;
            for (let j = 0; j < shader.worldUniforms.length; j++)
            {
                if (shader.worldUniforms[j].getName() == this.#uniforms[i].getName())
                {
                    b.addUniform(shader.worldUniforms[j]);
                    foundWorldUni = true;
                }
            }
            if (!foundWorldUni) b.addUniform(this.#uniforms[i]);
        }

        return b;
    }

    /**
     * @param {CgpUniform} u
     */
    addUniform(u)
    {
        this.#uniforms.push(u);
        this.needsRebuildBindgroup = true;
        console.log(this.#uniforms, this);
        return u;
    }

    /**
     * @returns {GPUBindingResource}
     * @param {number} inst
     */
    getResource(inst)
    {
        this.updateBuffer(inst);
        return {
            "buffer": this.cgpBuffer[inst].gpuBuffer,
        };
    }

    getSizeBytes()
    {
        let size = 0;
        for (let i = 0; i < this.#uniforms.length; i++)
            size += this.#uniforms[i].getSizeBytes();

        return size;
    }

    /**
     * @param {string} name
     */
    getUniform(name)
    {
        for (let i = 0; i < this.#uniforms.length; i++)
        {
            if (this.#uniforms[i].name == name) return this.#uniforms[i];
        }
        return null;
    }

    /**
     * @param {string} name
     */
    removeUniformByName(name)
    {
        for (let i = 0; i < this.#uniforms.length; i++)
            if (this.#uniforms[i].name == name)
            {
                this.needsRebuildBindgroup = true;
                return this.#uniforms.splice(i, 1);
            }
    }

    /**
     * @param {number} inst
     */
    createBuffer(inst)
    {
        let buffCfg = {
            "label": this.name,
            "size": this.getSizeBytes(),
            "usage": GPUBufferUsage.COPY_DST | GPUBufferUsage.UNIFORM
        };

        this.cgpBuffer[inst] = new CgpGguBuffer(this.cgp, this.name + " buff", null, { "buffCfg": buffCfg });
    }

    pipelineUpdated()
    {
        this.needsRebuildBindgroup = false;
    }

    needsPipeUpdate()
    {
        return this.needsRebuildBindgroup;
    }

    /**
     * @param {number} inst
     */
    updateBuffer(inst)
    {
        let info = { "name": this.#uniforms.length + " uniforms", "stage ": CgpShader.getStageString(this.stage), "uniforms": [] };

        let s = this.getSizeBytes() / 4;
        info.s = this.getSizeBytes();
        if (s == 16)s = 16;
        if (!this.cgpBuffer[inst])
        {
            this.createBuffer(inst);
            // console.log("no cpubuff? ", s, this.#uniforms);
            // return;
        }
        this.cgpBuffer[inst].setLength(s);

        let off = 0;
        for (let i = 0; i < this.#uniforms.length; i++)
        {
            this.#uniforms[i].copyToBuffer(this.cgpBuffer[inst].floatArr, off);

            if (this.#uniforms[i].gpuBufferChanged)
                console.log("un changed", this.cgpBuffer[inst].floatArr);

            info.uniforms.push(this.#uniforms[i].getInfo());

            off += this.#uniforms[i].getSizeBytes() / 4;
        }
        if (this.cgp.branchProfiler) this.cgp.branchProfiler.push("binding update buff", CgpShader.getStageString(this.stage), { "info": info });

        this.cgpBuffer[inst].updateGpuBuffer();

        if (this.cgp.branchProfiler) this.cgp.branchProfiler.pop();
    }

    /**
     * @param {CgpShader} shader
     * @param {number} bindGroupNum
     */
    getShaderHeaderCode(shader, bindGroupNum)
    {
        this.cgp.profileData.count("shadercode uni", this.name);
        let str = "";
        let typeStr = "";
        let name = this.name;

        str += "//   [binding_uniform] - \"" + this.name + "\" " + this.id + " uniforms:" + this.#uniforms.length + "\n";

        if (!this.isActiveByDefine(shader))
        {
            str += "// " + typeStr + " " + this.name + ": excluded because define " + this.define + "\n";
            return str;
        }

        if (this.#uniforms.length > 1)
        {
            typeStr = "strct_" + name;

            str += "struct " + typeStr + "\n";
            str += "{\n";
            // if (this.#uniforms.length == 0) str += "placehoder:1.";
            // else
            for (let i = 0; i < this.#uniforms.length; i++)
            {
                str += "    " + this.#uniforms[i].name + ": " + this.#uniforms[i].getWgslTypeStr();
                if (i != this.#uniforms.length - 1)str += ",";
                str += "\n";
            }
            str += "};\n";

        }
        else if (this.#uniforms.length == 1)
        {
            typeStr = this.#uniforms[0].getWgslTypeStr();
            name = this.#uniforms[0].name;
        }
        else if (this.#uniforms.length == 0)
        {
            return str;
            // typeStr = "float";
            // name = "placeholder";
        }

        // console.log("shadercode uniforms", this.#uniforms[0].name);
        str += "@group(" + bindGroupNum + ") ";
        str += "@binding(" + this.bindNum + ") ";

        str += "var<uniform> ";
        str += name + ": " + typeStr + ";\n";

        // console.log(str);
        return str + "\n";
    }

    /** @returns {GPUBindGroupLayoutEntry} */
    getLayoutEntry()
    {
        return {
            "visibility": this.stage,
            "binding": this.bindNum,
            "minBindingSize": this.getSizeBytes(),
            "hasDynamicOffset": 0,
            "buffer": {}
        };
    }

    /**
     * @param {number} inst
     */
    updateValues(inst)
    {
        for (let i = 0; i < this.#uniforms.length; i++)
        {
            // if (this.#uniforms[i].needsUpdate)
        }
        return this.updateBuffer(inst);

    }

    getInfo()
    {
        const o = { "name": this.name, "id": this.id, "stage": this.stage, "class": this.constructor.name, "uniforms": [] };

        for (let i = 0; i < this.#uniforms.length; i++)
        {
            o.uniforms.push(this.#uniforms[i].getInfo());
        }
        return o;
    }
}

;// CONCATENATED MODULE: ./src/corelibs/cgp/binding/binding_sampler.js



/** @extends Binding */
class BindingSampler extends Binding
{

    /** @type {GPUSamplerDescriptor} */
    smplDesc = {
        "addressModeU": "mirror-repeat",
        "addressModeV": "mirror-repeat",
        "magFilter": "linear",
        "minFilter": "linear",
        "mipmapFilter": "linear",
    };

    /** @type {GPUSampler} */
    sampler = null;

    constructor(cgp, name, options)
    {
        super(cgp, name, options);
        this.sampler = this.cgp.device.createSampler(this.smplDesc);

    }

    copy()
    {
        const b = new BindingSampler(this.cgp, this.name, this.options);
        return b;
    }

    getResource()
    {
        return this.sampler;
    }

    /** @returns {GPUBindGroupLayoutEntry} */
    getLayoutEntry()
    {
        return {
            "visibility": this.stage,
            "binding": this.bindNum,
            "sampler": {}
        };
    }

    /**
     * @param {CgpShader} shader
     * @param {number} bindGroupNum
     */
    getShaderHeaderCode(shader, bindGroupNum)
    {
        let str = "@group(" + bindGroupNum + ") @binding(" + this.bindNum + ") ";
        str += "var " + this.name + ": sampler;".endl();
        return str;
    }
}

;// CONCATENATED MODULE: ./src/corelibs/cgp/binding/binding_texture.js





/** @extends {Binding} */
class BindingTexture extends Binding
{

    /** @type {GPUSampler} */
    sampler = null;
    uniform = null;

    /**
     * @param {CgpContext} cgp
     * @param {string} name
     * @param {object} options
     */
    constructor(cgp, name, options)
    {
        super(cgp, name, options);

        /** @type {CgpUniform} */
        this.uniform = options.uniform;

        if (this.uniform.port)
        {
            this.uniform.port.on("change", () =>
            {
                this.needsRebuildBindgroup = true;
            });
        }

        console.log(this.uniform);
    }

    copy()
    {
        const b = new BindingTexture(this.cgp, this.name, this.options);
        return b;
    }

    getResource()
    {
        if (this.uniform.getValue() && this.uniform.getValue().gpuTexture) return this.uniform.getValue().gpuTexture.createView();
        else return this.cgp.getDefaultTexture().createView();
    }

    /** @returns {GPUBindGroupLayoutEntry} */
    getLayoutEntry()
    {
        return {
            "visibility": this.stage,
            "binding": this.bindNum,
            "texture": {}
        };
    }

    /**
     * @param {CgpShader} _shader
     * @param {number} bindGroupNum
     */
    getShaderHeaderCode(_shader, bindGroupNum)
    {
        let str = "@group(" + bindGroupNum + ") @binding(" + this.bindNum + ") ";
        str += "var " + this.name + ": " + this.uniform.getWgslTypeStr() + ";\n";
        return str;
    }
}

;// CONCATENATED MODULE: ./src/corelibs/cgp/cgp_shader.js













/** @typedef CgpShaderOptions
 * @property {Boolean} [compute]
 * @property {String} [entryPoint]
 */

class CgpShader extends cg_shader/* CgShader */.U
{

    #lastCompileReason = "first";

    /** @type {CgpUniform} */
    uniModelMatrix;

    /** @type {CgpUniform} */
    uniViewMatrix;

    /** @type {CgpUniform} */
    uniProjMatrix;

    /**
     * @type {GPUCompilationInfo}
     */
    compilationInfo;

    /**
     * @param {CgpContext} _cgp
     * @param {String} _name
     * @param {CgpShaderOptions} options={}
     */
    constructor(_cgp, _name, options = {})
    {
        super();
        if (!_cgp) throw new Error("shader constructed without cgp " + _name);
        this._log = new logger/* default */.A("cgp_shader");
        this._cgp = _cgp;
        this._name = _name;
        this.options = options;
        this.options.compute = this.options.compute || false;

        if (!_name) this._log.stack("no shader name given");
        this._name = _name || "unknown";
        this.gpuShaderModule = null;
        this.frameUsageCounter = 0;
        this.lastFrameUsageCounter = -2;
        this.frameUsageFrame = -1;

        this._bindingIndexCount = 0;
        this.compileCount = 0;
        this.worldUniforms = [];

        this.defaultBindGroup = new BindGroup(_cgp, this._name);
        this.modsBindGroup = new BindGroup(_cgp, this._name);

        /** @type {Array<BindGroup>} */
        this.bindGroups = [this.defaultBindGroup, this.modsBindGroup];

        if (!this.options.compute)
        {
            // this.bindingWorld = new BindingUniform(_cgp, "world", { "stage": GPUShaderStage.VERTEX });
            // this.defaultBindGroup.addBinding(this.bindingWorld);

            this.defaultUniBindingVert = new BindingUniform(_cgp, "uniVert", { "stage": GPUShaderStage.VERTEX });
            this.defaultBindGroup.addBinding(this.defaultUniBindingVert);

            this.defaultUniBindingFrag = new BindingUniform(_cgp, "uniFrag", { "stage": GPUShaderStage.FRAGMENT });
            this.defaultBindGroup.addBinding(this.defaultUniBindingFrag);
        }
        else
        {
            this.defaultUniBindingCompute = new BindingUniform(_cgp, "uniCompute", { "stage": GPUShaderStage.COMPUTE });
            this.defaultBindGroup.addBinding(this.defaultUniBindingCompute);
        }

        if (!this.options.compute)
        {
            this.uniModelMatrix = this.addUniform(new CgpUniform(this, "m4", "modelMatrix"), GPUShaderStage.VERTEX);
            this.uniViewMatrix = this.addUniform(new CgpUniform(this, "m4", "viewMatrix"), GPUShaderStage.VERTEX);
            this.uniProjMatrix = this.addUniform(new CgpUniform(this, "m4", "projMatrix"), GPUShaderStage.VERTEX);
            this.uniNormalMatrix = this.addUniform(new CgpUniform(this, "m4", "normalMatrix"), GPUShaderStage.VERTEX);
            this.uniModelViewMatrix = this.addUniform(new CgpUniform(this, "m4", "modelViewMatrix"), GPUShaderStage.VERTEX);
            this._tempNormalMatrix = mat4.create();
            this._tempModelViewMatrix = mat4.create();
            this.worldUniforms.push(this.uniModelMatrix, this.uniViewMatrix, this.uniProjMatrix, this.uniNormalMatrix, this.uniModelViewMatrix);
        }

        this._src = "";

        this._cgp.on("deviceChange", () =>
        {
            this.gpuShaderModule = null;
            this.setWhyCompile("device changed");
        });
    }

    reInit()
    {

    }

    /** @returns {boolean} */
    isValid()
    {
        return this._isValid;
    }

    getName()
    {
        return this._name;
    }

    incFrameUsageCount()
    {
        if (this.frameUsageFrame != this._cgp.frame)
        {
            this.lastFrameUsageCounter = this.frameUsageCounter;
            this.frameUsageCounter = 0;
        }
        else this.frameUsageCounter++;
        this.frameUsageFrame = this._cgp.frame;

        return this.frameUsageCounter;
    }

    getNewBindingGroupIndex()
    {
        return ++this._bindingIndexCount;
    }

    /**
     * @param {String} src
     */
    setSource(src)
    {
        this._src = src;
        this.setWhyCompile("Source changed");
    }

    /**
     * @param {import("../cg/cg_shader.js").ShaderModule} mod
     * @param {string} src
     */
    _replaceModPrefixes(mod, src)
    {
        return src.replace(/MOD_/g, mod.prefix);
    }

    /**
     * @param {String} vs
     * @param {{}} defs
     */
    _replaceMods(vs, defs)
    {
        let srcHeadVert = "";
        for (let i = 0; i < this._moduleNames.length; i++)
        {
            let srcVert = "";

            for (let j = 0; j < this._modules.length; j++)
            {
                const mod = this._modules[j];
                if (mod.name == this._moduleNames[i])
                {
                    srcHeadVert += constants.nl + constants.nl + "//---- MOD: group:" + mod.group + ": idx:" + j + " - prfx:" + mod.prefix + " - " + mod.title + " ------" + constants.nl;

                    srcVert += constants.nl + constants.nl + "//---- MOD: " + mod.title + " / " + mod.priority + " ------" + constants.nl;

                    if (mod.attributes)
                        for (let k = 0; k < mod.attributes.length; k++)
                        {
                            const r = this._getAttrSrc(mod.attributes[k], false);
                            if (r.srcHeadVert)srcHeadVert += r.srcHeadVert;
                            if (r.srcVert)srcVert += r.srcVert;
                        }

                    srcHeadVert += mod.srcHead || "";
                    srcVert += mod.srcBody || "";

                    srcHeadVert += constants.nl + "//---- end mod ------" + constants.nl;

                    srcVert += constants.nl + "//---- end mod ------" + constants.nl;

                    srcVert = this._replaceModPrefixes(mod, srcVert);
                    srcHeadVert = this._replaceModPrefixes(mod, srcHeadVert);

                }
            }

            srcVert = preproc(srcVert, defs);
            vs = vs.replace("{{" + this._moduleNames[i] + "}}", srcVert);
        }

        srcHeadVert = preproc(srcHeadVert, defs);
        vs = vs.replace("{{MODULES_HEAD}}", srcHeadVert);
        return vs;
    }

    /**
     * @param {string} src
     */
    _replaceVertexOutputs(src = "")
    {
        const strVertOut = "{{VERTEX_OUTPUT";
        const posVertOut = src.indexOf(strVertOut);
        if (posVertOut > -1)
        {
            try
            {
                let str = src.substring(posVertOut + strVertOut.length, posVertOut + 100);
                let endPos = str.indexOf("}}");
                let startNum = parseInt(str.substring(0, endPos));

                for (let j = 0; j < this._modules.length; j++)
                {
                    if (!this._modules[j].outputs) continue;
                    let outs = this._modules[j].outputs;
                    let l = 0;
                    while (outs.indexOf("@location(" + l + ")") > -1)
                    {
                        outs = outs.replaceAll("@location(" + l + ")", "@location(" + (l + startNum) + ")");
                    }
                    outs = this._replaceModPrefixes(this._modules[j], outs);
                    src = src.replaceAll(strVertOut + " " + startNum + "}}", outs);
                }

            }
            catch (e)
            {
                console.log(e);
            }
        }
        return src;
    }

    getDefines()
    {
        return this._defines;
    }

    getProcessedSource()
    {
        const defs = {};
        for (let i = 0; i < this._defines.length; i++)
            defs[this._defines[i][0]] = this._defines[i][1] || true;

        let src = "";
        src += preproc(this._src, defs);

        let strDefs = "";
        for (let i = 0; i < this._defines.length; i++)
            strDefs += "// #define " + this._defines[i] + "\n";

        let bindingsHeadVert = "";
        let bindingsHeadFrag = "";
        let bindingsHeadCompute = "";

        for (let i = 0; i < this.bindGroups.length; i++)
        {
            const src = this.bindGroups[i].getShaderHeaderCode(this, i);
            bindingsHeadFrag += src.fragment || "";
            bindingsHeadVert += src.vertex || "";
            bindingsHeadCompute += src.compute || "";
        }

        if (this.options.compute)
            src = bindingsHeadCompute + "\n\n////////////////\n\n" + src;
        else
            src = bindingsHeadFrag + "\n\n////////////////\n\n" + bindingsHeadVert + "\n\n////////////////\n\n" + src;

        src = this._replaceMods(src, defs);

        src = this._replaceVertexOutputs(src);

        const strVertOut = "{{VERTEX_OUTPUT";
        const posVertOut = src.indexOf(strVertOut);
        if (posVertOut > -1)
        {
            try
            {
                let str = src.substring(posVertOut + strVertOut.length, posVertOut + 100);
                let endPos = str.indexOf("}}");
                let startNum = parseInt(str.substring(0, endPos));
                let locCode = "@location(" + (startNum) + ") pos:vec4f, // generated";

                src = src.replaceAll(strVertOut + " " + startNum + "}}", locCode);
            }
            catch (e)
            {
                console.log(e);
            }
        }
        src = strDefs + "\n" + src;

        let srcHead = "//" + constants.nl + "// ";
        if (this.options.compute)srcHead += "Compute ";
        else srcHead += "Render ";

        srcHead += "Shader: " + this._name + " - " + this.id + constants.nl;
        srcHead += "//" + constants.nl;

        return srcHead + src;
    }

    compile()
    {
        this._isValid = true;
        this._cgp.pushErrorScope("cgp_shader " + this._name);

        if (this._cgp.branchProfiler) this._cgp.branchProfiler.push("shadercompile", this._name, { "info": this.getInfo() });

        this._cgp.profileData.count("shader compile", this._name);
        this.gpuShaderModule = this._cgp.device.createShaderModule({ "code": this.getProcessedSource(), "label": this._name });

        this.gpuShaderModule.getCompilationInfo().then((compInfo) =>
        {
            this.compilationInfo = compInfo;
            if (compInfo.messages.length > 0)
            {
                let hasErrors = false;
                for (const msg of compInfo.messages)
                {
                    switch (msg.type)
                    {
                    case "error":
                        console.error("Shader " + msg.type + " at line " + msg.lineNum + ":" + msg.linePos + " :" + msg.message);
                        hasErrors = true;
                    case "warning":
                        console.warn("Shader " + msg.type + " at line " + msg.lineNum + ":" + msg.linePos + " :" + msg.message);
                        break;
                    case "info":
                        console.info("Shader " + msg.type + " at line " + msg.lineNum + ":" + msg.linePos + " :" + msg.message);
                        break;
                    }
                }
                if (hasErrors)
                {
                    console.log("has errrrrrrrrrr");
                    CABLES.UI.showShaderErrorCgp(this, compInfo, this.getProcessedSource());
                }

            }
        });

        this._cgp.popErrorScope(this.error.bind(this));

        this.#lastCompileReason = this._compileReason;

        this.lastCompile = (0,timer/* now */.tB)();
        // console.log("#lastCompileReason", this.#lastCompileReason);

        this.emitEvent("compiled", this._compileReason);
        this._needsRecompile = false;
        this._compileReason = "none";
        this.compileCount++;

        if (this._cgp.branchProfiler) this._cgp.branchProfiler.pop();
    }

    error(e)
    {
        this._isValid = false;
    }

    bind(passEnc = null)
    {

        this.incFrameUsageCount();
        if (!this.options.compute)
        {
            this.uniModelMatrix.setValue(this._cgp.mMatrix);
            this.uniViewMatrix.setValue(this._cgp.vMatrix);
            this.uniProjMatrix.setValue(this._cgp.pMatrix);

            // mat4.invert(this._tempNormalMatrix, this._cgp.mMatrix);
            // mat4.transpose(this._tempNormalMatrix, this._tempNormalMatrix);
            mat4.mul(this._tempModelViewMatrix, this._cgp.vMatrix, this._cgp.mMatrix);
            this.uniModelViewMatrix.setValue(this._tempModelViewMatrix);

            mat4.copy(this._tempNormalMatrix, this._cgp.mMatrix);
            mat4.invert(this._tempNormalMatrix, this._tempNormalMatrix);
            mat4.transpose(this._tempNormalMatrix, this._tempNormalMatrix);

            // cpu billboarding?
            // this._tempModelViewMatrix[0 * 4 + 0] = 1.0;
            // this._tempModelViewMatrix[0 * 4 + 1] = 0.0;
            // this._tempModelViewMatrix[0 * 4 + 2] = 0.0;

            // // #ifndef BILLBOARDING_CYLINDRIC
            // this._tempModelViewMatrix[1 * 4 + 0] = 0.0;
            // this._tempModelViewMatrix[1 * 4 + 1] = 1.0;
            // this._tempModelViewMatrix[1 * 4 + 2] = 0.0;
            // // #endif

            // this._tempModelViewMatrix[2 * 4 + 0] = 0.0;
            // this._tempModelViewMatrix[2 * 4 + 1] = 0.0;
            // this._tempModelViewMatrix[2 * 4 + 2] = 1.0;

            this.uniNormalMatrix.setValue(this._tempNormalMatrix);
        }

        for (let i = 0; i < this.bindGroups.length; i++)
        {
            this.bindGroups[i].updateValues(this.frameUsageCounter);
            this.bindGroups[i].bind(this.frameUsageCounter, passEnc, i);
        }
        if (this._needsRecompile) this.compile();
    }

    /**
     * @param {number} stage
     * @returns {BindingUniform}
     */
    getDefaultUniBinding(stage)
    {
        let binding = this.defaultUniBindingFrag;
        if (stage == GPUShaderStage.VERTEX) binding = this.defaultUniBindingVert;
        if (this.options.compute && stage == GPUShaderStage.COMPUTE) binding = this.defaultUniBindingCompute;
        return binding;
    }

    pipelineUpdated()
    {

        if (this.defaultUniBindingFrag) this.defaultUniBindingFrag.pipelineUpdated();
        if (this.defaultUniBindingVert) this.defaultUniBindingVert.pipelineUpdated();
        if (this.defaultUniBindingCompute) this.defaultUniBindingCompute.pipelineUpdated();
    }

    bindingsNeedPipeUpdate()
    {
        return (
            (this.defaultUniBindingFrag && this.defaultUniBindingFrag.needsPipeUpdate()) ||
            (this.defaultUniBindingVert && this.defaultUniBindingVert.needsPipeUpdate()) ||
            (this.defaultUniBindingCompute && this.defaultUniBindingCompute.needsPipeUpdate())
        );
    }

    /**
     * @param {String} name
     * @param {number} stage
     */
    hasUniformInStage(name, stage)
    {
        let binding = this.getDefaultUniBinding(stage);

        // console.log("bindingget uni", stage, binding, CgpShader.getStageString(stage));
        if (!binding) return false;
        return !!binding.getUniform(name);
    }

    /**
     * @param {String} name
     */
    hasUniform(name)
    {
        return this.hasUniformInStage(name, GPUShaderStage.FRAGMENT) || this.hasUniformInStage(name, GPUShaderStage.VERTEX) || this.hasUniformInStage(name, GPUShaderStage.COMPUTE);
    }

    /**
     * @param {CgpUniform} u
     * @param {number} stage
     * @returns {CgpUniform}
     */
    addUniform(u, stage)
    {
        const binding = this.getDefaultUniBinding(stage);
        if (u.type == "t") this.defaultBindGroup.addBinding(new BindingTexture(this._cgp, u.name, { "uniform": u }));
        else if (u.type == "sampler") this.defaultBindGroup.addBinding(new BindingSampler(this._cgp, u.name, { "uniform": u }));
        else
        {
            binding.addUniform(u);
        }

        this.needsPipelineUpdate = "add uniform";
        console.log("adduni2", this._name, u.name, this.id, binding, CgpShader.getStageString(stage));
        console.log("code", binding.getShaderHeaderCode(this, 0));

        // if (!this.defaultBindGroup.hasBinding(binding)) this.defaultBindGroup.addBinding(binding);
        return u;
    }

    removeUniformByName(name)
    {
        const binding = this.getDefaultUniBinding(stage);
        binding.removeUniformByName(name);

    }

    /**
     * copy current shader
     * @returns newShader
     */
    copy()
    {
        this.bind();
        const shader = new CgpShader(this._cgp, this._name + " copy", this.options);
        console.log("copyyyyyy", this.id, shader.id);
        shader.setSource(this._src);

        shader._modules = JSON.parse(JSON.stringify(this._modules));
        shader._defines = JSON.parse(JSON.stringify(this._defines));

        shader._moduleNames = this._moduleNames;

        shader.bindGroups = [];
        for (let i = 0; i < this.bindGroups.length; i++)
        {
            const bg = this.bindGroups[i].copy(shader);
            shader.bindGroups.push(bg);

            if (this.bindGroups[i] == this.defaultBindGroup) shader.defaultBindGroup = bg;
            // if (this.bindGroups[i] == this.modsBindGroup) shader.modsBindGroup = bg;
            bg.setBindingNums();
        }

        shader.setWhyCompile("copy");
        shader.compile();
        return shader;
    }

    dispose()
    {

    }

    /**
     * @param {number} stage
     */
    static getStageString(stage)
    {
        if (stage == GPUShaderStage.FRAGMENT) return "frag";
        if (stage == GPUShaderStage.VERTEX) return "vertex";
        if (stage == (GPUShaderStage.FRAGMENT | GPUShaderStage.VERTEX)) return "frag+vertex";
        if (stage == (GPUShaderStage.FRAGMENT | GPUShaderStage.VERTEX | GPUShaderStage.COMPUTE)) return "frag+vertex+comp";
        if (stage == GPUShaderStage.COMPUTE) return "compute";

        return "unknown" + stage;
    }

    getInfo()
    {
        const o = {
            "class": this.constructor.name,
            "id": this.id,
            "name": this._name,
            "needsPipelineUpdate": this.needsPipelineUpdate,
            "frameUsageCounter": this.lastFrameUsageCounter,
            "lastCompileReason": this.#lastCompileReason,
            "compileCount": this.compileCount,
            "defines": this._defines,
            "isCompute": this.options.compute,
            "modules": [],
            "bindgroups": []
        };

        for (let i = 0; i < this.bindGroups.length; i++)
        {
            o.bindgroups.push(this.bindGroups[i].getInfo());
        }

        for (let i = 0; i < this._modules.length; i++)
        {
            o.modules.push(this._modules[i].title + " " + this._modules[i].name + " " + this._modules[i].group);
            // console.log(this._modules[i]);
        }

        return o;
    }

    copyUniformValues(orig)
    {

    }
}

;// CONCATENATED MODULE: ./src/corelibs/cgp/cgp_texture.js




class Texture extends cg_texture/* CgTexture */.U
{
    #log = new logger/* default */.A("cgp_texture");

    /** @type {CgpContext} */
    #cgp = null;

    /** @type {GPUTexture} */
    gpuTexture = null;

    /** @type {GPUTextureDescriptor} */
    gpuTextureDescriptor = null;
    name = "unknown";
    width = 8;
    height = 8;
    textureType = "???";

    samplerDesc = {};

    /**
    * @param {CgpContext} _cgp
    * @param {Object} options={}
    */
    constructor(_cgp, options = {})
    {
        super(options);
        options = options || {};

        this.#cgp = _cgp;
        if (!this.#cgp) throw new Error("no cgp");

        if (options.name) this.name = options.name;
        if (options.height && options.width) this.setSize(options.width, options.height);

        this.#cgp.on("deviceChange", () =>
        {
        });
        this.samplerDesc = {
            "addressModeU": options.wrap || options.addressModeU || "clamp-to-edge",
            "addressModeV": options.wrap || options.addressModeV || "clamp-to-edge",
            "magFilter": options.magFilter || options.filter || "linear",
            "minFilter": options.minFilter || options.filter || "linear",
        };

    }

    /**
     * @param {Number} w
     * @param {Number} h
     */
    setSize(w, h)
    {
        this.width = w;
        this.height = h;
    }

    /**
     * set texture data from an image/canvas object
     * @function initTexture
     * @memberof Texture
     * @instance
     * @param {Object} img image
     * @param {Number} filter
     */
    initTexture(img, filter)
    {
        this.width = img.width;
        this.height = img.height;

        const textureType = "rgba8unorm";

        this.#cgp.pushErrorScope("inittexture", { "logger": this.#log });

        this.gpuTextureDescriptor = {

            "size": { "width": img.width, "height": img.height },
            "format": textureType,
            // "sampleCount": 4,
            "usage": GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT
        };

        this.gpuTexture = this.#cgp.device.createTexture(this.gpuTextureDescriptor);
        this.#cgp.device.queue.copyExternalImageToTexture({ "source": img }, { "texture": this.gpuTexture }, this.gpuTextureDescriptor.size);

        this.#cgp.popErrorScope();

        return this.gpuTexture;
    }

    dispose()
    {
        console.log("todo dispose");
    }

    getInfo()
    {
        const obj = {};

        obj.name = this.name || "???";
        obj.size = this.width + " x " + this.height;

        obj.textureType = this.textureType;

        return obj;
    }

    createView()
    {
        if (!this.gpuTexture)
        {
            console.log("no gputexture...");
            return null;
        }
        return this.gpuTexture.createView();
    }

    getSampler()
    {
        // "clamp-to-edge"
        // "repeat"
        // "mirror-repeat"

        return this.samplerDesc;
    }

    /**
     * @function initFromData
     * @memberof Texture
     * @instance
     * @description create texturem from rgb data
     * @param {ArrayBuffer} data rgb color array [r,g,b,a,r,g,b,a,...]
     * @param {Number} w width
     * @param {Number} h height
     * @param {Number} filter
     * @param {Number} wrap
     */
    initFromData(data, w, h, filter, wrap)
    {
        if (!w || !h) this.#log.error("texture size is 0");
        this.width = w;
        this.height = h;
        this.gpuTexture = this.#cgp.device.createTexture(
            {
                "size": [w, h],
                "format": "rgba8unorm",
                "usage": GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.RENDER_ATTACHMENT,
            });

        this.#cgp.device.queue.writeTexture(
            { "texture": this.gpuTexture },
            data,
            { "bytesPerRow": w * 4 },
            { "width": w, "height": h });
    }

    /**
     * @param {any} v
     */
    setWrap(v)
    {
        this.samplerDesc.addressModeU = this.samplerDesc.addressModeV = v;
    }

    /**
     * @param {any} v
     */
    setFilter(v)
    {
        this.samplerDesc.minFilter = this.samplerDesc.magFilter = v;
    }
}

/**
 * @function load
 * @static
 * @memberof Texture
 * @description load an image from an url
 * @param {CgpContext} cgp
 * @param {String} url
 * @param {Function} onFinished
 * @param {Object} settings
 */
Texture.load = function (cgp, url, onFinished, settings)
{
    fetch(url).then((response) =>
    {
        const texture = new Texture(cgp, { "name": url });

        response.blob().then((blob) =>
        {
            createImageBitmap(blob).then((imgBitmap) =>
            {
                texture.initTexture(imgBitmap);
                if (onFinished)onFinished(texture);
                else console.log("Texture.load no onFinished callback");
            }).catch((err) =>
            {
                if (onFinished)onFinished(cgp.getErrorTexture());
            });
        });
    });
};

;// CONCATENATED MODULE: ./src/corelibs/cgp/cgp_pipeline.js
/// <reference types="@webgpu/types" />




class Pipeline
{
    static TYPE_RENDER = 0;
    static TYPE_COMPUTE = 1;

    #log = new logger/* default */.A("pipeline");
    name = "";

    /** @type {CgpContext} */
    #cgp = null;
    #isValid = true;

    /** @type {string} */
    presentationFormat = null;

    /** @type {GPURenderPipelineDescriptor} */
    #pipeCfg = null;

    /** @type {GPUBindGroupLayout} */
    bindGroupLayout = null;

    /** @type {Array<string>} */
    #shaderListeners = [];
    #type = -1;
    lastRebuildReason = "first";
    rebuildCount = 0;
    profile = false;

    /** @type {Array<GPUBindGroupLayoutEntry>} */
    bindingGroupLayoutEntries = [];

    /**
     * Description
     * @param {CgpContext} _cgp
     * @param {String} name
     * @param {Number} type
     */
    constructor(_cgp, name, type = 0)
    {
        if (!_cgp) throw new Error("Pipeline constructed without cgp " + name);
        this.name = name;
        this.#cgp = _cgp;
        this.#type = type;

        // this.#cgp.on("deviceChange", () =>
        // {
        //     this.#renderPipeline = null;
        // });
    }

    get passEncoder()
    {
        return this.#cgp.passEncoder;
    }

    get log()
    {
        return this.#log;
    }

    get cgp()
    {
        return this.#cgp;
    }

    get isValid() { return this.#isValid; }

    /**
     * @param {String} name
     */
    setName(name)
    {
        this.name = name;
    }

    // setShaderListener(oldShader, newShader)
    // {
    //     for (let i = 0; i < this.#shaderListeners.length; i++) oldShader.off(this.#shaderListeners[i]);
    //     this.#shaderListeners = [];
    //     this.#shaderListeners.push(
    //         newShader.on("compiled", (/** @type {string} */ reason) =>
    //         {
    //             this.needsRebuildReason = "shader compiled: " + reason || "???";
    //         }));
    // }

    getInfo()
    {
        const info = {
            "class": this.constructor.name,
            "name": this.name,
            "rebuildReason": this.lastRebuildReason,
            "rebuildCount": this.rebuildCount,
            // "numBindgroups": this.#bindingInstances.length,
            "bindingGroupLayoutEntries": this.bindingGroupLayoutEntries,
        };

        if (this.#type == Pipeline.TYPE_COMPUTE)info.type = "COMPUTE";
        if (this.#type == Pipeline.TYPE_RENDER)info.type = "RENDER";

        return info;
    }

    pushDebug()
    {
        this.#cgp.currentPipeDebug =
        {
            "name": this.name,
            "rebuildreason": this.lastRebuildReason,
            "rebuildCount": this.rebuildCount,
            "cfg": this.#pipeCfg,
            "bindingGroupLayoutEntries": this.bindingGroupLayoutEntries
        };
    }

    /**
     * @param {CgpShader} shader
     */
    _bindUniforms(shader)
    {
        shader.bind();
    }

    dispose()
    {
        // todo...
    }

}

;// CONCATENATED MODULE: ./src/corelibs/cgp/cgp_renderpipeline.js
/// <reference types="@webgpu/types" />





class RenderPipeline extends Pipeline
{
    static DEPTH_COMPARE_FUNCS_STRINGS = ["never", "less", "equal", "lessequal", "greater", "notequal", "greaterequal", "always"];

    #isValid = true;

    /** @type {string} */
    presentationFormat = null;

    /** @type {GPURenderPipelineDescriptor} */
    #pipeCfg = null;

    /** @type {GPURenderPipeline} */
    #renderPipeline = null;

    /** @type {GPUBindGroupLayout} */
    bindGroupLayout = null;

    /** @type {GPURenderPassEncoder} */
    #passEncoder;

    // #shaderListeners = [];
    #old = {};
    #type = RenderPipeline.TYPE_RENDER;
    lastRebuildReason = "first";
    #rebuildNumBindingGroups = false;
    #compileCount = -1;

    /**
     * Description
     * @param {CgpContext} _cgp
     * @param {String} name
     */
    constructor(_cgp, name)
    {
        super(_cgp, name, Pipeline.TYPE_RENDER);
    }

    /**
     * @param {CgpShader} shader
     * @param {CgpMesh} mesh
     */
    setPipeline(shader, mesh = null)
    {
        if (this.#type == RenderPipeline.TYPE_RENDER)
        {
            if (!mesh)
            {
                this.log.log("pipeline unknown mesh");
                return;
            }
        }
        if (!shader)
        {
            this.log.log("pipeline unknown shader");
            return;
        }

        if (this.cgp.branchProfiler) this.cgp.branchProfiler.push("setPipeline", this.name, { "info": this.getInfo(), "shader": shader.getInfo() });

        let needsRebuildReason = "";
        if (!this.#renderPipeline) needsRebuildReason = "no renderpipeline";
        if (!this.#pipeCfg)needsRebuildReason = "no pipecfg";
        if (this.#old.mesh != mesh)needsRebuildReason = "no mesh";
        if (this.#old.shader != shader)
        {
            // this.setShaderListener(this.#old.shader, shader);
            needsRebuildReason = "shader changed";
        }

        if (shader.needsPipelineUpdate)
        {
            needsRebuildReason = "shader needs update: " + shader.needsPipelineUpdate;
            shader.needsPipelineUpdate = "";
        }

        if (this.#type == RenderPipeline.TYPE_RENDER && mesh.needsPipelineUpdate)
        {
            needsRebuildReason = "mesh needs update";
            mesh.needsPipelineUpdate = false;
        }

        if (this.bindingGroupLayoutEntries.length != shader.defaultBindGroup.getLayoutEntries(shader).length)
        {
            needsRebuildReason = "num bindgroup layouts wrong...";
        }

        if (shader.bindingsNeedPipeUpdate())
        {
            console.log("binding needs uptate");
            needsRebuildReason = "bindings needs update";
            this.needsRebuildBindgroup = true;
        }

        // if (this.#rebuildNumBindingGroups)
        // {
        //     needsRebuildReason = "num bindgroups wrong...";
        // }

        if (this.#pipeCfg)
        {
            this.#pipeCfg =/** @type {GPURenderPipelineDescriptor} */ (this.#pipeCfg || {});
            if (this.#pipeCfg.depthStencil.depthWriteEnabled != this.cgp.stateDepthWrite())
                needsRebuildReason = "depth changed";

            if (this.#pipeCfg.fragment.targets[0].blend != this.cgp.stateBlend())
            {
                needsRebuildReason = "blend changed";
                this.#pipeCfg.fragment.targets[0].blend = this.cgp.stateBlend();
            }

            if (this.#pipeCfg.depthStencil.depthCompare != this.cgp.getDepthCompare())
                needsRebuildReason = "depth compare changed";

            if (this.#pipeCfg.primitive.cullMode != this.cgp.stateCullFaceFacing())
                needsRebuildReason = "cullmode change";

            if (this.#pipeCfg.multisample.count != this.cgp.stateMultisampling())
                needsRebuildReason = "multisample change";

        }
        if (this.#compileCount != shader.compileCount)
        {
            needsRebuildReason = "shader compiled " + shader.compileCount;
        }

        this.pushDebug();

        if (needsRebuildReason != "")
        {
            this.cgp.profileData.addHeavyEvent("pipeline created", this.name, needsRebuildReason);
            this.lastRebuildReason = needsRebuildReason;
            this.rebuildCount++;
            this.cgp.pushErrorScope("createPipeline", { "logger": this.log });

            this.#rebuildNumBindingGroups = false;

            this.#pipeCfg = this.getPipelineObject(shader);

            this.#old.device = this.cgp.device;
            this.#old.shader = shader;
            this.#old.mesh = mesh;
            this.#isValid = true;
            this.#compileCount = shader.compileCount;
            shader.pipelineUpdated();

            try
            {

                this.#renderPipeline = this.cgp.device.createRenderPipeline(this.#pipeCfg);

            }
            catch (e)
            {

                console.error("pipe error catch...", e.message, this.#pipeCfg);
                this.#isValid = false;
            }

            this.cgp.popErrorScope(
                () =>
                {
                    console.log("this.#pipeCfg", this.#pipeCfg);
                });
        }

        if (this.#renderPipeline && this.#isValid)
        {
            this.cgp.pushErrorScope("setpipeline", { "logger": this.log });

            let passEnc = this.cgp.passEncoder;

            // if (this.#type != RenderPipeline.TYPE_RENDER) passEnc = this.#passEncoder;

            if (this.cgp.branchProfiler) this.cgp.branchProfiler.push("pipe updateUniforms", this.name, { "shader": shader.getInfo() });

            /// ///////////////////

            shader.bind();
            passEnc.setPipeline(this.#renderPipeline);

            if (this.cgp.branchProfiler) this.cgp.branchProfiler.pop();

            this.cgp.popErrorScope();
        }
        if (this.cgp.branchProfiler) this.cgp.branchProfiler.pop();

    }

    /**
     * @param {CgpShader} shader
     * @returns {GPURenderPipelineDescriptor}
     */
    getPipelineObject(shader)
    {

        this.bindingGroupLayoutEntries = [];
        this.bindingGroupLayoutEntries = shader.defaultBindGroup.getLayoutEntries(shader);

        const bindGroupLayouts = [shader.defaultBindGroup.getLayout(shader)];

        /** @type {GPUPipelineLayout} */
        const pipelineLayout = this.cgp.device.createPipelineLayout({
            "label": "pipe layout " + this.name,
            "bindGroupLayouts": bindGroupLayouts
        });

        /** @type {Array<GPUVertexBufferLayout>} */
        let buffers = [
            // position
            {
                "arrayStride": 3 * 4, // 3 floats, 4 bytes each
                "attributes": [
                    { "shaderLocation": 0, "offset": 0, "format": "float32x3" },
                ],
            },
            // texcoords
            {
                "arrayStride": 2 * 4, // 2 floats, 4 bytes each
                "attributes": [
                    { "shaderLocation": 2, "offset": 0, "format": "float32x2", },
                ],
            },
            // normals
            {
                "arrayStride": 3 * 4, // 3 floats, 4 bytes each
                "attributes": [
                    { "shaderLocation": 1, "offset": 0, "format": "float32x3" },
                ],
            }];

        /** @type {GPURenderPipelineDescriptor} */
        let pipeCfg = {
            "label": this.name,
            "layout": pipelineLayout,

            "primitive": {
                "topology": "triangle-list",
                "cullMode": this.cgp.stateCullFaceFacing(), // back/none/front
            // "point-list",
            // "line-list",
            // "line-strip",
            // "triangle-list",
            // "triangle-strip"
            },
            "multisample": {
                "count": this.cgp.stateMultisampling(),
                "alphaToCoverageEnabled": false // Enable if using alpha testing
            },
            "depthStencil": {
                "depthWriteEnabled": this.cgp.stateDepthWrite(),
                "depthCompare": this.cgp.getDepthCompare(),
                "format": "depth24plus",

            },
            "vertex":
            {
                "module": shader.gpuShaderModule,
                "entryPoint": "myVSMain",
                "buffers": buffers
            },
            "fragment":
            {
                "module": shader.gpuShaderModule,
                "entryPoint": "myFSMain",
                "targets": [
                    {
                        "format": this.cgp.presentationFormat,
                        "blend": this.cgp.stateBlend()
                    },
                ],
            }
        };
        return pipeCfg;
    }

    dispose()
    {
        // todo...
    }

}

// EXTERNAL MODULE: ./src/corelibs/cg/cg_mesh.js
var cg_mesh = __webpack_require__(434);
;// CONCATENATED MODULE: ./src/corelibs/cgp/cgp_mesh.js





class CgpMesh extends cg_mesh/* CgMesh */.w
{
    #log = new logger/* default */.A("cgl_mesh");
    needsPipelineUpdate = false;

    /**
     * @param {any} _cgp
     * @param {any} __geom
     */
    constructor(_cgp, __geom)
    {
        super();

        this.cgp = _cgp;
        this._geom = null;
        this.numIndex = 0;
        this.instances = 1;

        this._pipe = new RenderPipeline(this.cgp, "pipe mesh " + __geom.name);
        this._numNonIndexed = 0;
        this._positionBuffer = null;

        this._attributes = [];

        if (__geom) this.setGeom(__geom);
    }

    /**
     * @param {GPUDevice} device
     * @param {any} data
     * @param {any} usage
     */
    _createBuffer(device, data, usage)
    {
        let bo = {
            "size": data.byteLength,
            "usage": usage,
            "mappedAtCreation": true,
        };
        const buffer = device.createBuffer(bo);
        const dst = new data.constructor(buffer.getMappedRange());
        dst.set(data);
        buffer.unmap();
        return buffer;
    }

    /**
     * @function setGeom
     * @memberof Mesh
     * @instance
     * @description set geometry for mesh
     * @param {Geometry} geom geometry
     */
    setGeom(geom)
    {
        this.needsPipelineUpdate = true;
        this._geom = geom;
        this._disposeAttributes();

        this._positionBuffer = this._createBuffer(this.cgp.device, new Float32Array(geom.vertices), GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST);

        let vi = geom.verticesIndices;
        if (!geom.isIndexed()) vi = Array.from(Array(geom.vertices.length / 3).keys());
        this._numIndices = vi.length;
        this._indicesBuffer = this._createBuffer(this.cgp.device, new Uint32Array(vi), GPUBufferUsage.INDEX | GPUBufferUsage.COPY_DST);

        if (geom.texCoords && geom.texCoords.length) this.setAttribute("texCoords", geom.texCoords, 2);
        if (geom.vertexNormals && geom.vertexNormals.length) this.setAttribute("normals", geom.vertexNormals, 3);

        this.setAttribute("normals", geom.vertexNormals, 3);
    }

    _disposeAttributes()
    {
        this.needsPipelineUpdate = true;
        for (let i = 0; i < this._attributes.length; i++) this._attributes[i].buffer.destroy();
        this._attributes.length = 0;
    }

    dispose()
    {
        this._disposeAttributes();
    }

    /**
     * @function setAttribute
     * @description update attribute
     * @memberof Mesh
     * @instance
     * @param {String} name attribute name
     * @param {Array} array data
     * @param {Number} itemSize
     * @param {Object} options
     */
    setAttribute(name, array, itemSize, options = {})
    {
        if (!array)
        {
            this.#log.error("mesh addAttribute - no array given! " + name);
            throw new Error();
        }

        let instanced = false;
        if (options.instanced) instanced = options.instanced;

        const buffer = this._createBuffer(this.cgp.device, new Float32Array(array), GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST);

        const attr = {
            "buffer": buffer,
            "name": name,
            "instanced": instanced,
        };
        this._attributes.push(attr);

        return attr;
    }

    /**
     * @param {CgpShader} shader
     */
    render(shader)
    {
        if (!this._positionBuffer) return;
        if (this.instances <= 0) return;

        if (this.cgp.branchProfiler) this.cgp.branchProfiler.push("mesh.render()", "geom " + this._geom.name);

        shader = shader || this.cgp.getShader();
        if (shader)shader.bind();

        if (!shader || !shader.isValid)
        {
            // this.status = "shader invalid";
            return;
        }

        this._pipe.setName("mesh.render " + this._geom.name + " " + shader.getName() + " " + shader.id);
        this._pipe.setPipeline(shader, this);

        if (this._pipe.isValid)
        {
            if (this.cgp.branchProfiler) this.cgp.branchProfiler.push("mesh.render().draw", "geom " + this._geom.name, {
                "geom": this._geom.getInfo(),
                "shader": shader.getInfo(),
                "numAttributes": this._attributes.length
            });

            this.cgp.passEncoder.setVertexBuffer(0, this._positionBuffer);
            for (let i = 0; i < this._attributes.length; i++)
                this.cgp.passEncoder.setVertexBuffer(i + 1, this._attributes[i].buffer);

            this.cgp.passEncoder.setIndexBuffer(this._indicesBuffer, "uint32");

            this.cgp.profileData.count("draw mesh", this._name);
            if (this._numNonIndexed)
                this.cgp.passEncoder.draw(this._numIndices, this.instances);
            else
                this.cgp.passEncoder.drawIndexed(this._numIndices, this.instances);

            if (this.cgp.branchProfiler) this.cgp.branchProfiler.pop();
        }
        else
        {
            if (this.cgp.branchProfiler)
            {
                this.cgp.branchProfiler.push("mesh invalid pipeline ", "geom " + this._geom.name);
                this.cgp.branchProfiler.pop();
            }
        }

        if (this.cgp.branchProfiler) this.cgp.branchProfiler.pop();

        // if (shader)shader.unbind();
    }
}

;// CONCATENATED MODULE: ./src/corelibs/cgp/cgp_state.js









// https://github.com/greggman/webgpu-utils
// https://developer.chrome.com/blog/from-webgl-to-webgpu/
// https://gpuweb.github.io/gpuweb/explainer/

// eslint-disable-next-line no-restricted-syntax
const defaultShaderSrcVert = `
struct MyVSInput
{
    @location(0) position: vec3<f32>,
    @location(1) normal: vec3<f32>,
    @location(2) texcoord: vec2<f32>,
};

struct MyVSOutput
{
    @builtin(position) position: vec4<f32>,
    @location(0) normal: vec3<f32>,
    @location(1) texcoord: vec2<f32>,
};

@vertex
fn myVSMain(v: MyVSInput) -> MyVSOutput
{
    var vsOut: MyVSOutput;
    var pos =vec4<f32>(v.position, 1.0);

    var mvMatrix=uniVert.viewMatrix * uniVert.modelMatrix;
    vsOut.position = uniVert.projMatrix * mvMatrix * pos;

    vsOut.normal = v.normal;
    vsOut.texcoord = v.texcoord;
    return vsOut;
}

@fragment
fn myFSMain(v: MyVSOutput) -> @location(0) vec4<f32>
{
    return vec4<f32>(.5,.5,.5,1.0);
}
`;

/**
 * cables webgpu context/state manager
 * @class
 * @namespace external:CGP
 * @hideconstructor
 */
class CgpContext extends cg_context/* CgContext */.A
{

    branchProfiler = null;

    /**
     * @param {Patch} _patch
     */
    constructor(_patch)
    {
        super(_patch);
        this.patch = _patch;

        this.lastErrorMsg = "";

        this._log = new logger/* default */.A("WebGpuContext");
        this.gApi = cg_context/* CgContext */.A.API_WEBGPU;
        this._viewport = [0, 0, 256, 256];
        this._shaderStack = [];
        this._simpleShader = null;
        this.frame = 0;
        this.catchErrors = true;

        this._stackCullFaceFacing = [];
        this._stackDepthTest = [];
        this._stackCullFace = [];
        this._stackDepthFunc = [];
        this._stackDepthWrite = [];
        this._stackErrorScope = [];
        this._stackBlend = [];
        this._stackErrorScopeLogs = [];
        this._stackMultisampling = [];

        this.currentPipeDebug = null;
        this.canvasAttachments = [];

        /** @type {GPUDevice} */
        this.device = null;

        /** @type {GPURenderPassEncoder} */
        this.passEncoder = null;

        this._defaultBlend = {
            "color": {
                "operation": "add",
                "srcFactor": "one",
                "dstFactor": "zero",
            },
            "alpha": {
                "operation": "add",
                "srcFactor": "one",
                "dstFactor": "zero",
            },
        };

        this.DEPTH_FUNCS = [
            "never",
            "always",
            "less",
            "less-equal",
            "greater",
            "greater-equal",
            "equal",
            "not-equal"
        ];

        this.CULL_MODES = [
            "none",
            "back",
            "front",
            "none" // both does not exist in webgpu
        ];

        /** @type {GPUTextureFormat} */
        this.presentationFormat = "bgra8unorm";
    }

    get supported()
    {
        return !!navigator.gpu;
    }

    /// ////////////////////

    /**
     * Description
     * @param {any} cgp
     * @param {any} identTranslate
     * @param {any} identTranslateView
     * @returns {any}
     */
    renderStart(cgp, identTranslate, identTranslateView)
    {

        this.frame++;
        this.pushErrorScope("cgpstate internal", { "scope": "internal" });
        this.pushErrorScope("cgpstate out-of-memory", { "scope": "out-of-memory" });

        if (!this._simpleShader)
        {
            this._simpleShader = new CgpShader(this, "simple default shader");
            this._simpleShader.setSource(defaultShaderSrcVert);

            this._simpleShader.addUniform(new CgpUniform(this._simpleShader, "4f", "color", [1, 1, 0, 1]), GPUShaderStage.FRAGMENT);
        }

        this.fpsCounter.startFrame();

        this._startMatrixStacks(identTranslate, identTranslateView);
        this.setViewPort(0, 0, this.canvasWidth, this.canvasHeight);

        this.pushShader(this._simpleShader);
        this.pushDepthTest(true);
        this.pushDepthWrite(true);
        this.pushDepthFunc("less-equal");

        this.pushBlend(this._defaultBlend);

        this._execOneTimeCallbacks();

        this.emitEvent("beginFrame");
    }

    renderEnd()
    {
        this._endMatrixStacks();

        this.popShader();
        this.popDepthFunc();
        this.popDepthWrite();
        this.popDepthTest();

        this.popErrorScope();
        this.popErrorScope();

        if (this._stackErrorScope.length > 0)console.log("error scope stack length invalid...");
        this._stackErrorScope.length = 0;

        this.emitEvent("endFrame");
        this.fpsCounter.endFrame();
    }

    /**
     * @param {number} x
     * @param {number} [y]
     * @param {undefined} [w]
     * @param {undefined} [h]
     */
    setViewPort(x, y, w, h)
    {
        this._viewport = [x, y, w, h];
    }

    /**
     * @function getViewPort
     * @memberof Context
     * @instance
     * @description get current gl viewport
     * @returns {Array} array [x,y,w,h]
     */
    getViewPort()
    {
        return this._viewPort;
    }

    /**
     * @param {Geometry} geom
     * @param {any} glPrimitive
     * @returns {CgpMesh}
     */
    createMesh(geom, glPrimitive)
    {
        return new CgpMesh(this, geom);
    }

    /**
     * @function popViewPort
     * @memberof Context
     * @instance
     * @description pop viewPort stack
     */
    popViewPort()
    {
        this._viewPortStack.pop();

        if (this._viewPortStack.length == 0)
            this._viewPort = [0, 0, this.canvasWidth, this.canvasHeight];
        else
            this.setViewPort(this._viewPortStack[this._viewPort.length - 1]);
    }

    /**
     * @function pushViewPort
     * @memberof Context
     * @instance
     * @description push a new viewport onto stack
     * @param {Number} x
     * @param {Number} y
     * @param {Number} w
     * @param {Number} h
     */

    pushViewPort(x, y, w, h)
    {
        this._viewPortStack.push([x, y, w, h]);
        this._viewPort = [x, y, w, h];
    }

    /**
     * push a shader to the shader stack
     * @function pushShader
     * @memberof Context
     * @instance
     * @param {Object} shader
     * @function
    */
    pushShader(shader)
    {
        this._shaderStack.push(shader);
        // currentShader = shader;
    }

    /**
     * pop current used shader from shader stack
     * @function popShader
     * @memberof Context
     * @instance
     * @function
     */
    popShader()
    {
        if (this._shaderStack.length === 0) throw new Error("Invalid shader stack pop!");
        this._shaderStack.pop();
        // currentShader = this._shaderStack[this._shaderStack.length - 1];
    }

    getShader()
    {
        return this._shaderStack[this._shaderStack.length - 1];
    }

    /**
     * @param {GPUDevice} device
     */
    setDevice(device)
    {
        this.device = device;

        if (this._emptyTexture) this._emptyTexture = this._emptyTexture.dispose();
        if (this._defaultTexture) this._defaultTexture = this._defaultTexture.dispose();
        if (this._errorTexture) this._errorTexture = this._errorTexture.dispose();

        this.emitEvent("deviceChange");
    }

    /**
     * @typedef ErrorScopeOptions
     * @property {Logger} [logger]
     * @property {GPUErrorFilter} [scope]
    */

    /**
     * @param {String} name
     * @param {ErrorScopeOptions} options
     */
    pushErrorScope(name, options = { })
    {
        if (this.catchErrors)
        {
            this._stackErrorScope.push(name);
            this._stackErrorScopeLogs.push(options.logger || null);
            this.device.pushErrorScope(options.scope || "validation");
        }
    }

    /**
     * @param {Function} [cb]
     */
    popErrorScope(cb)
    {
        if (this.catchErrors)
        {
            const name = this._stackErrorScope.pop();
            const logger = this._stackErrorScopeLogs.pop();
            this.device.popErrorScope().then((error) =>
            {
                if (error)
                {
                    if (this.lastErrorMsg == error.message)
                    {
                        // this._log.warn("last error once more...");
                    }
                    else
                    {
                        (logger || this._log).error(error.constructor.name, "in ERROR SCOPE:", name);
                        (logger || this._log).error(error.message);
                    }
                    this.lastErrorMsg = error.message;

                    if (cb)cb(error);
                }
            });
        }
    }

    /**
     * push depth testing enabled state
     * @function pushDepthTest
     * @param {Boolean} b enabled
     * @memberof Context
     * @instance
     */
    pushDepthTest(b)
    {
        this._stackDepthTest.push(b);
    }

    getDepthCompare()
    {
        let depthComp = this.stateDepthFunc();
        if (!this.stateDepthTest())depthComp = "always";
        return depthComp;
    }

    /**
     * current state of depth testing
     * @function stateDepthTest
     * @returns {Boolean} enabled
     * @memberof Context
     * @instance
     */
    stateDepthTest()
    {
        return this._stackDepthTest[this._stackDepthTest.length - 1];
    }

    /**
     * pop depth testing state
     * @function popDepthTest
     * @memberof Context
     * @instance
     */
    popDepthTest()
    {
        this._stackDepthTest.pop();
    }

    // --------------------------------------
    // state depthwrite

    /**
     * push depth write enabled state
     * @function pushDepthWrite
     * @param {Boolean} b enabled
     * @memberof Context
     * @instance
     */
    pushDepthWrite(b)
    {
        b = b || false;
        this._stackDepthWrite.push(b);
    }

    /**
     * current state of depth writing
     * @returns {Boolean} enabled
     * @memberof Context
     * @instance
     */
    stateDepthWrite()
    {
        return this._stackDepthWrite[this._stackDepthWrite.length - 1];
    }

    /**
     * pop depth writing state
     * @memberof Context
     * @instance
     */
    popDepthWrite()
    {
        this._stackDepthWrite.pop();
    }

    // --------------------------------------
    // state depthfunc

    /**
     * @function pushDepthFunc
     * @memberof Context
     * @instance
     * @param {GPUCompareFunction} depthFunc depth compare func
     */
    pushDepthFunc(depthFunc)
    {
        this._stackDepthFunc.push(depthFunc);
    }

    /**
     * @function stateDepthFunc
     * @memberof Context
     * @instance
     * @returns {GPUCompareFunction}
     */
    stateDepthFunc()
    {
        if (this._stackDepthFunc.length > 0) return this._stackDepthFunc[this._stackDepthFunc.length - 1];
        return "less";
    }

    /**
     * pop depth compare func
     * @function popDepthFunc
     * @memberof Context
     * @instance
     */
    popDepthFunc()
    {
        this._stackDepthFunc.pop();
    }

    // --------------------------------------
    // state CullFace

    /**
     * push face culling face enabled state
     * @function pushCullFace
     * @param {Boolean} b enabled
     * @memberof Context
     * @instance
     */
    pushCullFace(b)
    {
        this._stackCullFace.push(b);
    }

    // --------------------------------------
    // state multisambling
    /**
     * @returns {number}
     */
    stateMultisampling()
    {
        return this._stackMultisampling[this._stackMultisampling.length - 1];
    }

    /**
     * @param {number} samples
     */
    pushMultisampling(samples)
    {
        this._stackMultisampling.push(samples);
    }

    popMultisampling()
    {
        this._stackMultisampling.pop();
    }

    // --------------------------------------
    // state CullFace Facing

    /**
     * push face culling face side
     * @param {string} b
     * @instance
     */
    pushCullFaceFacing(b)
    {
        this._stackCullFaceFacing.push(b);
    }

    /**
     * current state of face culling side
     * @returns {string}
     */
    stateCullFaceFacing()
    {
        return this._stackCullFaceFacing[this._stackCullFaceFacing.length - 1];
    }

    /**
     * pop face culling face side
     * @function popCullFaceFacing
     * @memberof Context
     * @instance
     */
    popCullFaceFacing()
    {
        this._stackCullFaceFacing.pop();
    }

    pushBlend(b)
    {
        this._stackBlend.push(b);
    }

    popBlend()
    {
        this._stackBlend.pop();
    }

    /**
     * @returns {GPUBlendComponent}
     */
    stateBlend()
    {
        return this._stackBlend[this._stackBlend.length - 1];
    }

    getEmptyTexture()
    {
        if (this._emptyTexture) return this._emptyTexture;
        const size = 8;
        this._emptyTexture = new Texture(this, {});
        this._emptyTexture.initFromData(cg_texture/* CgTexture */.U.getDefaultTextureData("empty", size), size, size);
        return this._emptyTexture;
    }

    getErrorTexture()
    {
        // if (this._errorTexture) return this._errorTexture;
        const size = 256;
        this._errorTexture = new Texture(this, {});
        this._errorTexture.initFromData(cg_texture/* CgTexture */.U.getDefaultTextureData("stripes", size, { "r": 1, "g": 0, "b": 0 }), size, size);
        return this._errorTexture;
    }

    getDefaultTexture()
    {
        if (this._defaultTexture) return this._defaultTexture;
        const size = 256;
        this._defaultTexture = new Texture(this, {});
        this._defaultTexture.initFromData(cg_texture/* CgTexture */.U.getDefaultTextureData("stripes", size), size, size);
        return this._defaultTexture;
    }

    /**
     * @param {function} cb
     * @param {boolean} _doScreenshotClearAlpha
     * @param {string} mimeType
     * @param {number} quality
     */
    screenShot(cb, _doScreenshotClearAlpha, mimeType, quality)
    {
        if (this.canvas && this.canvas.toBlob)
        {
            this.canvas.toBlob((blob) =>
            {
                if (cb) cb(blob);
                else this._log.log("no screenshot callback...");
            }, mimeType, quality);
        }

    }

}

// EXTERNAL MODULE: ./src/corelibs/cgl/cgl_simplerect.js
var cgl_simplerect = __webpack_require__(273);
;// CONCATENATED MODULE: ./src/corelibs/cgp/cgp_canvasattachment.js


class WebGpuCanvasAttachment
{

    /** @type {HTMLCanvasElement} */
    #canvas = null;

    /** @type {CgpContext} */
    #cgp = null;

    /** @type {GPUCanvasContext} */
    #ctx = null;

    /**
     * @param {CgpContext} cgp
     */
    constructor(cgp)
    {
        this.#cgp = cgp;
        this.#canvas = document.createElement("canvas");
        this.#canvas.id = "webgpucanvasOut";
        this.#canvas.style.width = 128 + "px";
        this.#canvas.style.height = 128 + "px";
    }

    get canvas()
    {
        return this.#canvas;
    }

    /**
     * @param {function} cb
     */
    render(cb)
    {

        const canvas = this.#cgp.canvas;
        if (this.#canvas.width != canvas.width || this.#canvas.height != canvas.height)
        {
            this.#canvas.style.width = canvas.width + "px";
            this.#canvas.style.height = canvas.height + "px";
            this.#canvas.width = canvas.width;
            this.#canvas.height = canvas.height;
        }

        if (!this.#ctx)
        {
            this.#ctx = this.#canvas.getContext("webgpu");

            if (!this.#ctx)
                return console.log("no context", this.#canvas, this.#ctx);
            this.#ctx.configure({
                "device": this.#cgp.device,
                "format": this.#cgp.presentationFormat
            });

        }

        // const cgp = this.#cgp;
        // cgp.canvasInfo.depthTextureView = this.#ctx.createView();

        this.#cgp.renderPassDescriptor = {
            "label": "preview renderpass",
            "colorAttachments": [
                {
                    "view": this.#ctx.getCurrentTexture().createView(),
                    "loadOp": "clear",
                    "storeOp": "store",
                },

            ],
            "depthStencilAttachment": {
                "view": this.#cgp.canvasInfo.depthTextureView,
                "depthClearValue": 1,
                "depthLoadOp": "clear",
                "depthStoreOp": "store",
            },
        };

        // make a render pass encoder to encode render specific commands
        this.#cgp.passEncoder = this.#cgp.commandEncoder.beginRenderPass(this.#cgp.renderPassDescriptor);
        this.#cgp.textureView = this.#ctx.getCurrentTexture().createView();
        this.#cgp.renderStart();

        cb();

        this.#cgp.tempPrevCanvas = this.#canvas;

        this.#cgp.renderEnd();
        this.#cgp.passEncoder.end();

    }

}

;// CONCATENATED MODULE: ./src/corelibs/cgp/binding/binding_storagebuffer.js





/** @extends Binding */
class BindingStorage extends Binding
{

    /** @type {CgpGguBuffer} */
    cgpbuffer = null;
    bindingType = "read-only-storage";

    /**
     * Description
     * @param {CgpContext} cgp
     * @param {string} name
     * @param {object} options
     */
    constructor(cgp, name, options)
    {
        super(cgp, name, options);
        this.cgpbuffer = options.cgpBuffer || new CgpGguBuffer(cgp, "temp", [0, 0, 0, 0]);
    }

    copy()
    {
        const b = new BindingStorage(this.cgp, this.name, this.options);
        return b;
    }

    /**
     * @returns {GPUBindingResource}
     * @param {number} _inst
     */
    getResource(_inst)
    {
        return {
            "buffer": this.cgpbuffer.gpuBuffer,
        };
    }

    /**
     * @returns {GPUBindGroupLayoutEntry}
     * @param {CgpShader} [_shader]
     */
    getLayoutEntry(_shader = null)
    {

        /** @type {GPUBufferBindingType} */
        let access = "read-only-storage";

        if (this.stage & GPUShaderStage.COMPUTE)
            if (this.cgpbuffer.hasUsage(GPUBufferUsage.COPY_SRC) && this.cgpbuffer.hasUsage(GPUBufferUsage.COPY_DST)) access = "storage";
        // else if (this.cgpbuffer.hasUsage(GPUBufferUsage.COPY_DST)) access = "write-only-storage";

        return {
            "visibility": this.stage,
            "binding": this.bindNum,
            // "minBindingSize": this.getSizeBytes(),
            // "hasDynamicOffset": 0,
            "buffer": {
                "type": access
            } };
    }

    /**
     * @param {CgpShader} _shader
     * @param {number} bindGroupNum
     */
    getShaderHeaderCode(_shader, bindGroupNum)
    {
        this.cgp.profileData.count("shadercode storage", this.name);
        let str = "";

        let access = "read";

        if (this.stage & GPUShaderStage.COMPUTE)
            if (this.cgpbuffer.hasUsage(GPUBufferUsage.COPY_SRC) && this.cgpbuffer.hasUsage(GPUBufferUsage.COPY_DST)) access = "read_write";
            else if (this.cgpbuffer.hasUsage(GPUBufferUsage.COPY_DST)) access = "write";

        str += "@group(" + bindGroupNum + ") ";
        str += "@binding(" + this.bindNum + ") ";

        str += "var<storage," + access + "> ";
        let typeStr = "array<f32>";
        str += this.name + ": " + typeStr + ";\n";

        return str + "\n";
    }
}

;// CONCATENATED MODULE: ./src/corelibs/cgp/cgp_computepipeline.js
/// <reference types="@webgpu/types" />





class ComputePipeline extends Pipeline
{

    #isValid = true;

    /** @type {string} */
    presentationFormat = null;

    /** @type {GPUComputePipelineDescriptor} */
    #pipeCfg = null;

    /** @type {GPUComputePipeline} */
    #computePipeline = null;

    /** @type {GPUBindGroupLayout} */
    bindGroupLayout = null;

    /** @type {GPUComputePassEncoder} */
    #computePassEncoder;

    #shaderListeners = [];
    #old = {};
    #errorCount = 0;
    lastRebuildReason = "first";
    rebuildCount = 0;
    profile = false;
    #rebuildNumBindingGroups = false;

    /**
     * Description
     * @param {CgpContext} _cgp
     * @param {String} name
     */
    constructor(_cgp, name)
    {
        super(_cgp, name, Pipeline.TYPE_COMPUTE);
    }

    /**
     * @param {CgpShader} shader
     * @param {CgpMesh} mesh
     */
    setPipeline(shader, mesh = null)
    {
        if (!shader)
        {
            this.log.log("pipeline unknown shader");
            return;
        }

        let needsRebuildReason = "";
        if (!this.#pipeCfg)needsRebuildReason = "no pipecfg";
        if (this.#old.mesh != mesh)needsRebuildReason = "no mesh";
        if (this.#old.shader != shader)
        {
            needsRebuildReason = "shader changed";
        }

        if (shader.needsPipelineUpdate)
        {
            needsRebuildReason = "shader needs update: " + shader.needsPipelineUpdate;
            shader.needsPipelineUpdate = "";
        }

        if (this.#rebuildNumBindingGroups)
        {
            needsRebuildReason = "num bindgroups wrong...";
        }

        this.pushDebug();

        if (needsRebuildReason != "")
        {
            this.cgp.profileData.count("pipeline created", this.name);

            this.lastRebuildReason = needsRebuildReason;
            this.rebuildCount++;
            // console.log("needsRebuildReason");
            this.cgp.pushErrorScope("createPipeline", { "logger": this.log });

            this.#rebuildNumBindingGroups = false;

            this.#pipeCfg = this.getPipelineObject(shader);
            console.log(this.#pipeCfg);

            this.#old.device = this.cgp.device;
            this.#old.shader = shader;
            this.#old.mesh = mesh;
            this.#isValid = true;
            console.log(this.#pipeCfg);
            try
            {
                this.#computePipeline = this.cgp.device.createComputePipeline(this.#pipeCfg);
            }
            catch (e)
            {
                console.error("pipe error catch...", e.message, this.#pipeCfg);
                this.#isValid = false;
            }

            this.cgp.popErrorScope(
                () =>
                {
                    console.log("this.#pipeCfg", this.#pipeCfg);
                });
        }

        if (this.cgp.branchProfiler) this.cgp.branchProfiler.pop();

    }

    /**
     * @param {CgpShader} shader
     * @returns {GPUComputePipelineDescriptor}
     */
    getPipelineObject(shader)
    {

        /** @type {Array<GPUBindGroupLayoutEntry>} */
        this.bindingGroupLayoutEntries = [];
        this.bindingGroupLayoutEntries = shader.defaultBindGroup.getLayoutEntries(shader);

        const bindGroupLayouts = [shader.defaultBindGroup.getLayout(shader)];

        /** @type {GPUPipelineLayout} */
        const pipelineLayout = this.cgp.device.createPipelineLayout({
            "label": "pipe layout " + this.name,
            "bindGroupLayouts": bindGroupLayouts
        });

        /** @type {GPUComputePipelineDescriptor} */
        let pipeCfg = {
            "label": this.name,
            "layout": pipelineLayout,
            "compute":
            {
                "module": shader.gpuShaderModule,
                "entryPoint": shader.options.entryPoint || "main"
            }
        };
        console.log("pipecft", pipeCfg, bindGroupLayouts);

        return pipeCfg;
    }

    /**
     * @param {CgpShader} shader
     * @param {Array} workGroups
     */
    compute(shader, workGroups = [8, 8])
    {
        if (!shader.gpuShaderModule) shader.compile();

        /** @type {GPUCommandEncoder} */
        const commandEncoder = this.cgp.device.createCommandEncoder();

        this.#computePassEncoder = commandEncoder.beginComputePass({ "label": "computepass " + shader.getName() });

        // if (!this.#computePipeline)
        this.setPipeline(shader);

        if (!this.#computePipeline)
        {
            this.log.warn("no render pipe");
            return;
        }

        this.#computePassEncoder.setPipeline(this.#computePipeline);
        shader.bind(this.#computePassEncoder);

        if (workGroups.length == 1) this.#computePassEncoder.dispatchWorkgroups(workGroups[0] || 8);
        else if (workGroups.length == 2) this.#computePassEncoder.dispatchWorkgroups(workGroups[0] || 8, workGroups[1] || 8);
        else if (workGroups.length == 3) this.#computePassEncoder.dispatchWorkgroups(workGroups[0] || 8, workGroups[1] || 8, workGroups[2] || 8);
        else console.log("workgroups length wrong,,,");

        this.#computePassEncoder.end();

        this.cgp.profileData.count("compute pipe", this.name);
        // console.log("llllllll", shader.defaultBindGroup.getLayout());
        const gpuCommands = commandEncoder.finish();
        this.cgp.device.queue.submit([gpuCommands]);
        this.pushDebug();
        // const entry = shader.bindingsVert[i].getBindingGroupEntry(shader.bindingCounter);
        // this._passEncoder = commandEncoder.beginComputePass();
        // this._passEncoder.setPipeline(computePipeline);
        // this.#passEncoder.setBindGroup(0, shader.defaultBindGroupshader.defaultBindGroup;
        // outBuff.setRef(gpuBuff);

    }

    dispose()
    {
        // todo...
    }

}

;// CONCATENATED MODULE: ./src/corelibs/cgp/cgp_shadermodifier.js





/**
 * @typedef UniformDescrip
 * @property {string} name
 * @property {string} type
 * @property {number} stage
 * @property {any} v1
 * @property {any} v2
 * @property {any} v3
 * @property {any} v4
 */

class ShaderModifier
{
    onBind = null;

    /**
     * @param {CgpContext} cgl
     * @param {string} name
     * @param {object} options
     */
    constructor(cgl, name, options)
    {

        /** @type {CgpContext} */
        this._cgl = cgl;
        this._name = name;
        this._origShaders = {};

        /** @type {Array<UniformDescrip>} */
        this._uniforms = [];
        this._structUniforms = [];
        this._definesToggled = {};
        this._defines = {};
        this._mods = [];
        this._textures = [];

        /** @type {object} */
        this._boundShader = null;
        this._changedDefines = true;
        this._changedUniforms = true;
        this._modulesChanged = false;
        this.needsTexturePush = false;

        /** @type {CgpShader} */
        this._lastShader = null;
        this._attributes = [];
        if (options && options.opId) this.opId = options.opId;

    }

    /**
     * @param {CgpShader} curShader
     * @param {boolean} pushShader
     */
    bind(curShader, pushShader = true)
    {
        const shader = curShader || this._cgl.getShader();
        if (!shader) return;

        this._boundShader = this._origShaders[shader.id];
        let missingMod = false;

        if (this._boundShader && this._lastShader != this._boundShader.shader) // shader changed since last bind
        {
            if (!this._boundShader.shader.hasModule(this._mods[0].id)) missingMod = true;
        }

        if (missingMod) console.warn("copy because  (missingMod)");
        if (!this._boundShader) console.warn("copy because  (!this._boundShader)");
        else if (shader.lastCompile != this._boundShader.lastCompile) console.warn("copy because  shader.lastCompile");
        if (this._modulesChanged) console.warn("copy because  this._modulesChanged");
        if (shader._needsRecompile) console.warn("copy because  shader._needsRecompile ", shader._compileReason);

        if (missingMod || !this._boundShader || shader.lastCompile != this._boundShader.lastCompile || this._modulesChanged || shader._needsRecompile)
        {
            if (this._boundShader) this._boundShader.shader.dispose();
            if (shader._needsRecompile) shader.compile();
            this.needsTexturePush = true;

            this._boundShader = this._origShaders[shader.id] =
            {
                "lastCompile": shader.lastCompile,
                "orig": shader,
                "shader": shader.copy()
            };

            console.log("mod shaderrrrrrrrrrr", shader.getName(), this._boundShader.shader.getName());

            this._addModulesToShader(this._boundShader.shader);
            this._updateDefinesShader(this._boundShader.shader);
            this._updateUniformsShader(this._boundShader.shader);
        }

        this._boundShader.wireframe = shader.wireframe;
        if (this._changedDefines) this._updateDefines();
        if (this._changedUniforms) this._updateUniforms();

        if (pushShader)
        {
            this._cgl.pushShader(this._boundShader.shader);
            // console.log(this._boundShader.shader.id);
        }

        // this._boundShader.shader.copyUniformValues(this._boundShader.orig);

        if (this.needsTexturePush)
        {
            for (let j = 0; j < this._textures.length; j++)
            {
                const uniformName = this._textures[j][0];
                const tex = this._textures[j][1];
                const texType = this._textures[j][2];

                if (this._getUniform(uniformName))
                {
                    const name = this.getPrefixedName(uniformName);
                    const uni = this._boundShader.shader.getUniform(name);

                    if (uni) this._boundShader.shader.pushTexture(uni, tex, texType);
                }
            }

            this.needsTexturePush = false;
            this._textures.length = 0;
        }

        this._modulesChanged = false;

        this._boundShader.shader.fromMod = this;

        if (this.onBind) this.onBind(this._boundShader.shader);

        return this._boundShader.shader;
    }

    /**
     * @param {boolean} popShader
     */
    unbind(popShader = true)
    {
        if (this._boundShader)
            if (popShader) this._cgl.popShader();

        this._boundShader = null;
    }

    /**
     * @param {CgpShader} shader
     */
    _addModulesToShader(shader)
    {
        let firstMod;

        if (this._mods.length > 1) firstMod = this._mods[0];

        for (let i = 0; i < this._mods.length; i++) shader.addModule(this._mods[i], firstMod);
    }

    /**
     * @param {import("../cg/cg_shader.js").ShaderModule} mod
     */
    _removeModulesFromShader(mod)
    {
        for (const j in this._origShaders) this._origShaders[j].shader.removeModule(mod);
    }

    /**
     * @param {import("../cg/cg_shader.js").ShaderModule} mod
     */
    addModule(mod)
    {
        this._mods.push(mod);
        this._modulesChanged = true;
    }

    /**
     * @param {string} title
     */
    removeModule(title)
    {
        const indicesToRemove = [];

        let found = false;
        for (let i = 0; i < this._mods.length; i++)
        {
            if (this._mods[i].title == title)
            {
                found = true;
                this._removeModulesFromShader(this._mods[i]);
                indicesToRemove.push(i);
            }
        }

        // * go in reverse order so the indices of the mods stay the same
        for (let j = indicesToRemove.length - 1; j >= 0; j -= 1)
            this._mods.splice(indicesToRemove[j], 1);

        this._modulesChanged = true;
    }

    /**
     * @param {CgpShader} shader
     */
    _updateUniformsShader(shader)
    {
        for (let i = 0; i < this._uniforms.length; i++)
        {
            const uni = this._uniforms[i];
            const name = this.getPrefixedName(uni.name);

            if (!shader.hasUniform(name))
            {
                console.log("shadermod uni ", name, shader.id, uni.stage);
                const u = new CgpUniform(shader, uni.type, name, uni.v1, uni.v2, uni.v3, uni.v4);

                console.log(uni);
                shader.addUniform(u, uni.stage);
            }
        }
    }

    _updateUniforms()
    {
        for (const j in this._origShaders)
            this._updateUniformsShader(this._origShaders[j].shader);

        this._changedUniforms = false;
    }

    /**
     * @param {CgShader} shader
     * @param {string} uniformName
     * @param {number} value
     */
    _setUniformValue(shader, uniformName, value)
    {
        const uniform = shader.getUniform(uniformName);

        if (uniform) uniform.setValue(value);
    }

    /**
     * @param {string} name
     * @param {number} value
     */
    setUniformValue(name, value)
    {
        const uni = this._getUniform(name);
        if (!uni) return;

        const defineName = this.getPrefixedName(name);

        for (const j in this._origShaders)
        {
            this._setUniformValue(this._origShaders[j].shader, defineName, value);
        }
    }

    /**
     * @param {string} name
     */
    hasUniform(name)
    {
        return !!this._getUniform(name);
    }

    /**
     * @param {string} name
     */
    _getUniform(name)
    {
        for (let i = 0; i < this._uniforms.length; i++)
        {
            if (this._uniforms[i].name == name) return this._uniforms[i];
        }
        return null;
    }

    /**
     * @param {number} stage
     * @param {string} name
     * @param {string} type
     * @param {any} valOrPort
     * @param {any} v2
     * @param {any} v3
     * @param {any} v4
     */
    addUniform(stage, type, name, valOrPort, v2, v3, v4)
    {
        if (!this._getUniform(name))
        {
            this._uniforms.push(
                {
                    "name": name,
                    "stage": stage,
                    "type": type,
                    "v1": valOrPort,
                    "v2": v2,
                    "v3": v3,
                    "v4": v4,
                });
            this._changedUniforms = true;
        }
    }

    // addUniformFrag(type, name, valOrPort, v2, v3, v4)
    // {
    //     this.addUniform(type, name, valOrPort, v2, v3, v4, null, null, null, "frag");
    //     this._changedUniforms = true;
    // }

    // addUniformVert(type, name, valOrPort, v2, v3, v4)
    // {
    //     this.addUniform(type, name, valOrPort, v2, v3, v4, null, null, null, "vert");
    //     this._changedUniforms = true;
    // }

    // addUniformBoth(type, name, valOrPort, v2, v3, v4)
    // {
    //     this.addUniform(type, name, valOrPort, v2, v3, v4, null, null, null, "both");
    //     this._changedUniforms = true;
    // }

    // addUniformStruct(structName, uniformName, members, shaderType)
    // {
    //     for (let i = 0; i < members.length; i += 1)
    //     {
    //         const member = members[i];
    //         if ((member.type === "2i" || member.type === "i" || member.type === "3i") && shaderType === "both")
    //             console.error("Adding an integer struct member to both shaders can potentially error. Please use different structs for each shader. Error occured in struct:", structName, " with member:", member.name, " of type:", member.type, ".");

    //         if (!this._getUniform(uniformName + "." + member.name))
    //         {
    //             this.addUniform(
    //                 member.type,
    //                 uniformName + "." + member.name,
    //                 member.v1,
    //                 member.v2,
    //                 member.v3,
    //                 member.v4,
    //                 uniformName,
    //                 structName,
    //                 member.name,
    //                 shaderType
    //             );
    //         }
    //     }
    //     if (!this._getStructUniform(uniformName))
    //     {
    //         this._structUniforms.push({
    //             "structName": structName,
    //             "uniformName": uniformName,
    //             "members": members,
    //             "shaderType": shaderType,
    //         });
    //     }
    // }

    // addUniformStructVert(structName, uniformName, members)
    // {
    //     this.addUniformStruct(structName, uniformName, members, "vert");
    // }

    // addUniformStructFrag(structName, uniformName, members)
    // {
    //     this.addUniformStruct(structName, uniformName, members, "frag");
    // }

    // addUniformStructBoth(structName, uniformName, members)
    // {
    //     this.addUniformStruct(structName, uniformName, members, "both");
    // }

    addAttribute(attr)
    {
        for (let i = 0; i < this._attributes.length; i++)
        {
            if (this._attributes[i].name == attr.name && this._attributes[i].nameFrag == attr.nameFrag) return;
        }
        this._attributes.push(attr);
    }

    pushTexture(uniformName, tex, texType)
    {
        if (!tex) throw (new Error("no texture given to texturestack"));

        this._textures.push([uniformName, tex, texType]);
        this.needsTexturePush = true;
    }

    /**
     * @param {string} name
     * @param {CgShader} shader
     */
    _removeUniformFromShader(name, shader)
    {
        if (shader.hasUniform(name)) shader.removeUniform(name);
    }

    /**
     * @param {string} name
     */
    removeUniform(name)
    {
        if (this._getUniform(name))
        {
            for (let j = this._uniforms.length - 1; j >= 0; j -= 1)
            {
                const nameToRemove = name;

                if (this._uniforms[j].name == name)
                {
                    for (const k in this._origShaders)
                    {
                        this._removeUniformFromShader(
                            this.getPrefixedName(nameToRemove),
                            this._origShaders[k].shader
                        );
                    }

                    this._uniforms.splice(j, 1);
                }
            }
            this._changedUniforms = true;
        }
    }

    /**
     * @param {string} name
     */
    getPrefixedName(name)
    {
        const prefix = this._mods[0].group;
        if (prefix === undefined)
        {
            return;
        }
        if (name.startsWith("MOD_"))
        {
            name = name.substr("MOD_".length);
            name = "mod" + prefix + "_" + name;
        }
        return name;
    }

    /**
     * @param {CgpShader} shader
     */
    _updateDefinesShader(shader)
    {
        for (const i in this._defines)
        {
            const name = this.getPrefixedName(i);
            if (this._defines[i] !== null && this._defines[i] !== undefined) shader.define(name, this._defines[i]);
            else shader.removeDefine(name);
        }

        for (const i in this._definesToggled)
        {
            const name = this.getPrefixedName(i);
            shader.toggleDefine(name, this._definesToggled[i]);
        }
    }

    _updateDefines()
    {
        for (const j in this._origShaders) this._updateDefinesShader(this._origShaders[j].shader);

        this._changedDefines = false;
    }

    /**
     * @param {string | number} what
     * @param {boolean} value
     */
    define(what, value)
    {
        if (value === undefined)value = true;
        this._defines[what] = value;
        this._changedDefines = true;
    }

    /**
     * @param {string} name
     */
    removeDefine(name)
    {
        this._defines[name] = null;
        this._changedDefines = true;
    }

    /**
     * @param {string} name
     */
    hasDefine(name)
    {
        if (this._defines[name] !== null && this._defines[name] !== undefined) return true;
        return false;
    }

    /**
     * @param {string} name
     * @param {any} b
     */
    toggleDefine(name, b)
    {
        this._changedDefines = true;
        this._definesToggled[name] = b;
    }

    currentShader()
    {
        if (!this._boundShader) return null;
        return this._boundShader.shader;
    }

    dispose()
    {

    }
}



;// CONCATENATED MODULE: ./src/corelibs/cgp/index.js
















const CGP = {
    "Context": CgpContext,
    "Shader": CgpShader,
    "Mesh": CgpMesh,
    "Texture": Texture,
    "Uniform": CgpUniform,
    "MESHES": cgl_simplerect/* MESHES */.S,
    "GPUBuffer": CgpGguBuffer
};

window.CABLES = window.CABLES || {};
window.CABLES.CGP = window.CABLES.CGP || CGP;
window.CGP = window.CGP || CGP;

window.CGP.WebGpuCanvasAttachment = WebGpuCanvasAttachment;
window.CGP.RenderPipeline = RenderPipeline;
window.CGP.ComputePipeline = ComputePipeline;
window.CGP.ShaderModifier = ShaderModifier;

window.CGP.BindingStorage = BindingStorage;
window.CGP.BindingUniform = BindingUniform;
window.CGP.BindingTexture = BindingTexture;
window.CGP.BindingSampler = BindingSampler;




/***/ }),

/***/ 564:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* unused harmony exports WebAudio, WEBAUDIO */
/* harmony import */ var cables__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(440);
/** @namespace WEBAUDIO */



/**
 * Part of the Web Audio API, the AudioBuffer interface represents a short audio asset residing in memory.
 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioBuffer}
 */

/**
 * Part of the Web Audio API, the AudioNode interface is a generic interface for representing an audio processing module.
 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioNode}
 */

/**
 * The AudioContext interface represents an audio-processing graph built from audio modules linked together
 * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/AudioContext}
 */

class WebAudio
{

    constructor()
    {
        this.toneJsInitialized = false;
    }

    /**
     * Checks if a global audio context has been created and creates
     * it if necessary. This audio context can be used for native Web Audio as well as Tone.js ops.
     * Associates the audio context with Tone.js if it is being used
     * @param {Op} op - The operator which needs the Audio Context
     */
    createAudioContext(op)
    {
        window.AudioContext = window.AudioContext || window.webkitAudioContext;
        if (window.AudioContext)
        {
            if (!window.audioContext)
            {
                window.audioContext = new AudioContext();
            }
            // check if tone.js lib is being used
            if (window.Tone && !this.toneJsInitialized)
            {
                // set current audio context in tone.js, and discard potentially audio context created by tone
                if (Tone.setContext) Tone.setContext(window.audioContext, true);
                this.toneJsInitialized = true;
            }
        }
        else
        {
            if (op.patch.config.onError)op.logError("NO_WEBAUDIO", "Web Audio is not supported in this browser.");
            return;
        }
        return window.audioContext;
    }

    /**
     * Returns the audio context.
     * Before `createAudioContext` must have been called at least once.
     * It most cases you should use `createAudioContext`, which just returns the audio context
     * when it has been created already.
     */
    _getAudioContext()
    {
        return window.audioContext;
    }

    /**
     * Creates an audio in port for the op with name `portName`
     * When disconnected it will disconnect the previous connected audio node
     * from the op's audio node.
     * @param {Op} op - The operator to create the audio port in
     * @param {string} portName - The name of the port
     * @param {AudioNode} audioNode - The audionode incoming connections should connect to
     * @param {number} [inputChannelIndex=0] - If the audio node has multiple inputs, this is the index of the input channel to connect to
     * @returns {Port|undefined} - The newly created audio in port or `undefined` if there was an error
     */
    createAudioInPort(op, portName, audioNode, inputChannelIndex)
    {
        if (!op || !portName || !audioNode)
        {
            const msg = "ERROR: createAudioInPort needs three parameters, op, portName and audioNode";
            op.log(msg);
            throw new Error(msg);
            // return;
        }
        if (!inputChannelIndex)
        {
            inputChannelIndex = 0;
        }
        op.webAudio = op.webAudio || {};
        op.webAudio.audioInPorts = op.webAudio.audioInPorts || [];
        const port = op.inObject(portName);
        port.webAudio = {};
        port.webAudio.previousAudioInNode = null;
        port.webAudio.audioNode = audioNode;

        op.webAudio.audioInPorts[portName] = port;

        port.onChange = function ()
        {
            const audioInNode = port.get();
            // when port disconnected, disconnect audio nodes
            if (!audioInNode)
            {
                if (port.webAudio.previousAudioInNode)
                {
                    try
                    {
                        if (port.webAudio.previousAudioInNode.disconnect) port.webAudio.previousAudioInNode.disconnect(port.webAudio.audioNode, 0, inputChannelIndex);
                        op.setUiError("audioCtx", null);
                    }
                    catch (e)
                    {
                        try
                        {
                            port.webAudio.previousAudioInNode.disconnect(port.webAudio.audioNode);
                        }
                        catch (er)
                        {
                            op.log(
                                "Disconnecting audio node with in/out port index, as well as without in/out-port-index did not work ",
                                e,
                            );
                            if (e.printStackTrace)
                            {
                                e.printStackTrace();
                            }
                            throw e;
                        }
                    }
                }
            }
            else
            {
                try
                {
                    if (audioInNode.connect)
                    {
                        audioInNode.connect(port.webAudio.audioNode, 0, inputChannelIndex);
                        op.setUiError("audioCtx", null);
                    }
                    else op.setUiError("audioCtx", "The passed input is not an audio context. Please make sure you connect an audio context to the input.", 2);
                }
                catch (e)
                {
                    op.log("Error: Failed to connect web audio node!", e);
                    op.log("port.webAudio.audioNode", port.webAudio.audioNode);
                    op.log("audioInNode: ", audioInNode);
                    op.log("inputChannelIndex:", inputChannelIndex);
                    op.log("audioInNode.connect: ", audioInNode.connect);
                    throw e;
                }
            }
            port.webAudio.previousAudioInNode = audioInNode;
        };
        // TODO: Maybe add subtype to audio-node-object?
        return port;
    }

    /**
     * Creates an audio out port which takes care of (dis-)connecting on it’s own
     * @param {Op} op - The op to create an audio out port for
     * @param {string} portName - The name of the port to be created
     * @param {AudioNode} audioNode - The audio node to link to the port
     * @returns {(CABLES.Port|undefined)} - The newly created audio out port or `undefined` if there was an error
     */
    createAudioOutPort(op, portName, audioNode)
    {
        if (!op || !portName || !audioNode)
        {
            const msg = "ERROR: createAudioOutPort needs three parameters, op, portName and audioNode";
            op.log(msg);
            throw new Error(msg);
        }

        const port = op.outObject(portName);
        // TODO: Maybe add subtype to audio-node-object?
        port.set(audioNode);
        return port;
    }

    /**
     * Creates an audio param in port for the op with name portName.
     * The port accepts other audio nodes as signals as well as values (numbers)
     * When the port is disconnected it will disconnect the previous connected audio node
     * from the op's audio node and restore the number value set before.
     *
     * @deprecated
     * @param {Op} op - The operator to create an audio param input port for
     * @param {string} portName - The name of the port to create
     * @param audioNode
     * @param options
     * @param defaultValue
     * @returns {(CABLES.Port|undefined)} - The newly created port, which takes care of (dis-)connecting on its own, or `undefined` if there was an error
     */
    createAudioParamInPort(op, portName, audioNode, options, defaultValue)
    {
        if (!op || !portName || !audioNode)
        {
            op.log("ERROR: createAudioParamInPort needs three parameters, op, portName and audioNode");
            if (op && op.name) op.log("opname: ", op.name);
            op.log("portName", portName);
            op.log("audioNode: ", audioNode);
            return;
        }
        op.webAudio = op.webAudio || {};
        op.webAudio.audioInPorts = op.webAudio.audioInPorts || [];
        // var port = op.inObject(portName);
        const port = op.inDynamic(
            portName,
            [cables__WEBPACK_IMPORTED_MODULE_0__/* .CONSTANTS */ .a.OP.OP_PORT_TYPE_VALUE, cables__WEBPACK_IMPORTED_MODULE_0__/* .CONSTANTS */ .a.OP.OP_PORT_TYPE_OBJECT],
            options,
            defaultValue,
        );
        port.webAudio = {};
        port.webAudio.previousAudioInNode = null;
        port.webAudio.audioNode = audioNode;

        op.webAudio.audioInPorts[portName] = port;

        port.onChange = () =>
        {
            const audioInNode = port.get();
            const node = port.webAudio.audioNode;
            const audioCtx = this._getAudioContext();

            if (audioInNode != undefined)
            {
                if (typeof audioInNode === "object" && audioInNode.connect)
                {
                    try
                    {
                        audioInNode.connect(node);
                    }
                    catch (e)
                    {
                        op.log("Could not connect audio node: ", e);
                        if (e.printStackTrace)
                        {
                            e.printStackTrace();
                        }
                        throw e;
                    }
                    port.webAudio.previousAudioInNode = audioInNode;
                }
                else
                {
                    // tone.js audio param
                    if (node._param && node._param.minValue && node._param.maxValue)
                    {
                        if (audioInNode >= node._param.minValue && audioInNode <= node._param.maxValue)
                        {
                            try
                            {
                                if (node.setValueAtTime)
                                {
                                    node.setValueAtTime(audioInNode, audioCtx.currentTime);
                                }
                                else
                                {
                                    node.value = audioInNode;
                                }
                            }
                            catch (e)
                            {
                                op.log("Possible AudioParam problem with tone.js op: ", e);
                                if (e.printStackTrace)
                                {
                                    e.printStackTrace();
                                }
                                throw e;
                            }
                        }
                        else
                        {
                            op.log("Warning: The value for an audio parameter is out of range!");
                        }
                    } // native Web Audio param
                    else if (node.minValue && node.maxValue)
                    {
                        if (audioInNode >= node.minValue && audioInNode <= node.maxValue)
                        {
                            try
                            {
                                if (node.setValueAtTime)
                                {
                                    node.setValueAtTime(audioInNode, audioCtx.currentTime);
                                }
                                else
                                {
                                    node.value = audioInNode;
                                }
                            }
                            catch (e)
                            {
                                op.log(
                                    "AudioParam has minValue / maxValue defined, and value is in range, but setting the value failed! ",
                                    e,
                                );
                                if (e.printStackTrace)
                                {
                                    e.printStackTrace();
                                }
                                throw e;
                            }
                        }
                        else
                        {
                            op.log("Warning: The value for an audio parameter is out of range!");
                        }
                    } // no min-max values, try anyway
                    else
                    {
                        try
                        {
                            if (node.setValueAtTime)
                            {
                                node.setValueAtTime(audioInNode, audioCtx.currentTime);
                            }
                            else
                            {
                                node.value = audioInNode;
                            }
                        }
                        catch (e)
                        {
                            op.log("Possible AudioParam problem (without minValue / maxValue): ", e);
                            if (e.printStackTrace)
                            {
                                e.printStackTrace();
                            }
                            throw e;
                        }
                    }

                    if (port.webAudio.previousAudioInNode && port.webAudio.previousAudioInNode.disconnect)
                    {
                        try
                        {
                            port.webAudio.previousAudioInNode.disconnect(node);
                        }
                        catch (e)
                        {
                            op.log("Could not disconnect previous audio node: ", e);
                            throw e;
                        }
                        port.webAudio.previousAudioInNode = undefined;
                    }
                }
            }
            else
            {
                // disconnected
                if (port.webAudio.previousAudioInNode)
                {
                }
            }
        };
        return port;
    }

    /**
     * Loads an audio file and updates the loading indicators when cables is run in the editor.
     * @param {Patch} patch - The cables patch, when called from inside an op this is `op.patch`
     * @param {string} url - The url of the audio file to load
     * @param {function} onFinished - The callback to be called when the loading is finished, passes the AudioBuffer
     * @param {function} onError - The callback when there was an error loading the file, the rror message is passed
     * @param loadingTask
     * @see {@link https://developer.mozilla.org/de/docs/Web/API/AudioContext/decodeAudioData}
     */
    loadAudioFile(patch, url, onFinished, onError, loadingTask)
    {
        const audioContext = this.createAudioContext();

        if (!audioContext) onError(new Error("No Audiocontext"));

        let loadingId = null;
        if (loadingTask || loadingTask === undefined)
        {
            loadingId = patch.loading.start("audio", url);
            if (patch.isEditorMode()) gui.jobs().start({ "id": "loadaudio" + loadingId, "title": " loading audio (" + url + ")" });
        }
        const request = new XMLHttpRequest();

        if (!url) return;

        request.open("GET", url, true);
        request.responseType = "arraybuffer";

        request.onload = function ()
        {
            patch.loading.finished(loadingId);
            if (patch.isEditorMode()) gui.jobs().finish("loadaudio" + loadingId);

            audioContext.decodeAudioData(request.response, onFinished, onError).catch((e) =>
            {
                onError(e);
            });
        };
        request.send();
    }

    /**
     * Checks if the passed time is a valid time to be used in any of the Tone.js ops.
     * @deprecated
     * @param {(string|number)} t - The time to check
     * @returns {boolean} - True if time is valid, false if not
     */
    isValidToneTime(t)
    {
        try
        {
            const time = new Tone.Time(t);
        }
        catch (e)
        {
            return false;
        }
        return true;
    }

    /**
     * Checks if the passed note is a valid note to be used with Tone.js
     * @deprecated
     * @param {string} note - The note to be checked, e.g. `"C4"`
     * @returns {boolean} - True if the note is a valid note, false otherwise
     */
    isValidToneNote(note)
    {
        try
        {
            Tone.Frequency(note);
        }
        catch (e)
        {
            return false;
        }
        return true;
    }
}

const WEBAUDIO = new WebAudio();

window.CABLES = window.CABLES || {};
window.CABLES.WEBAUDIO = WEBAUDIO;




/***/ }),

/***/ 125:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";

// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  A: () => (/* binding */ Events)
});

;// CONCATENATED MODULE: ../shared/client/src/eventlistener.js
class EventListener
{

    /**
     * @param {Object} emitter
     * @param {string} id
     * @param {string} eventName
     * @param {Function} cb
     */
    constructor(emitter, id, eventName, cb)
    {
        this.targetObj = emitter;
        this.id = id;
        this.eventName = eventName;
        this.cb = cb;
    }

    remove()
    {
        this.targetObj.off(this.id);
    }
}

;// CONCATENATED MODULE: ../shared/client/src/helper.js
/**
 * Shared helper methods for cables uis
 */
class Helper
{
    constructor()
    {
        this._simpleIdCounter = 0;
    }

    /**
     * generate a random v4 uuid
     *
     * @return {string}
     */
    uuid()
    {
        let d = new Date().getTime();
        return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) =>
        {
            const r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c === "x" ? r : (r & 0x3) | 0x8).toString(16);
        });
    }

    /**
     * checks value for !isNan and isFinite
     *
     * @param {string} n
     * @return {boolean}
     */
    isNumeric(n)
    {
        const nn = parseFloat(n);
        return !isNaN(nn) && isFinite(nn);
    }

    /**
     * generate a simple ID using an internal counter
     *
     * @return {Number} new id
     * @static
     */
    simpleId()
    {
        this._simpleIdCounter++;
        return this._simpleIdCounter;
    }

    pathLookup(obj, path)
    {
        const parts = path.split(".");
        if (parts.length == 1)
        {
            return obj[parts[0]];
        }
        return this.pathLookup(obj[parts[0]], parts.slice(1).join("."));
    }

}
/* harmony default export */ const helper = (new Helper());

// EXTERNAL MODULE: ../shared/client/src/logger.js
var logger = __webpack_require__(849);
;// CONCATENATED MODULE: ../shared/client/src/eventtarget.js




/**
 * add eventlistener functionality to classes
 */
class Events
{
    #eventLog = new logger/* default */.A("eventtarget");

    /** @type {Object<string,EventListener>} */
    #listeners = {};
    #logEvents = false;
    #logName = "";
    #eventCallbacks = {};
    #countErrorUnknowns = 0;
    eventsPaused = false;

    constructor()
    {
    }

    /**
     * @callback whatever
     * @param {...any} param
     */

    /**
     * add event listener
     * @param {string} eventName event name
     * @param {whatever} cb callback
     * @param {string} idPrefix prefix for id, default empty
     * @return {EventListener} eventlistener
     */
    on(eventName, cb, idPrefix = "")
    {
        const newId = (idPrefix || "") + helper.simpleId();

        const event = new EventListener(this, newId, eventName, cb);

        if (!this.#eventCallbacks[eventName]) this.#eventCallbacks[eventName] = [event];
        else this.#eventCallbacks[eventName].push(event);

        this.#listeners[event.id] = event;

        return event;
    }

    removeAllEventListeners()
    {
        for (const i in this.#listeners)
        {
            this.off(this.#listeners[i]);
        }
    }

    /**
     *
     * @param {string} which
     * @param {whatever} cb
     */
    addEventListener(which, cb, idPrefix = "")
    {
        return this.on(which, cb, idPrefix);
    }

    /**
     * check event listener registration
     * @param {string|EventListener} id event id
     * @param {whatever} cb callback - deprecated
     * @return {boolean}
     */
    hasEventListener(id, cb = null)
    {
        if (id && !cb)
        {
            if (typeof id == "string") // check by id
                return !!this.#listeners[id];
            else
                return !!this.#listeners[id.id];

        }
        else
        {
            this.#eventLog.warn("old eventtarget function haseventlistener!");
            if (id && cb)
            {
                if (this.#eventCallbacks[id])
                {
                    const idx = this.#eventCallbacks[id].indexOf(cb);
                    return idx !== -1;
                }
            }
        }
    }

    /**
     * check event listener by name
     * @param {string } eventName event name
     * @return {boolean}
     */
    hasListenerForEventName(eventName)
    {
        return this.#eventCallbacks[eventName] && this.#eventCallbacks[eventName].length > 0;
    }

    /** @deprecated */
    removeEventListener(id)
    {
        return this.off(id);
    }

    /**
     * remove event listener registration
     * @param {EventListener} listenerParam
     */
    off(listenerParam)
    {
        if (listenerParam === null || listenerParam === undefined)
        {
            this.#eventLog.warn("removeEventListener id null", listenerParam);
            return;
        }

        let id = listenerParam; // old off was using id strings directly, now uses eventlistener class
        // @ts-ignore
        if (listenerParam.eventName) id = listenerParam.id;

        if (typeof id != "string")
        {
            console.log("old function signature: removeEventListener! use listener id");
            return;
        }

        const event = this.#listeners[id];
        if (!event)
        {
            if (this.#countErrorUnknowns == 20) this.#eventLog.warn("stopped reporting unknown events");
            if (this.#countErrorUnknowns < 20) this.#eventLog.warn("could not find event...", id);
            this.#countErrorUnknowns++;
            return;
        }

        let removeCount = 0;

        let found = true;
        while (found)
        {
            found = false;
            let index = -1;
            for (let i = 0; i < this.#eventCallbacks[event.eventName].length; i++)
            {
                if (this.#eventCallbacks[event.eventName][i].id.indexOf(id) === 0) // this._eventCallbacks[event.eventName][i].id == which ||
                {
                    found = true;
                    index = i;
                }
            }

            if (index !== -1)
            {
                this.#eventCallbacks[event.eventName].splice(index, 1);
                delete this.#listeners[id];
                removeCount++;
            }
        }

        if (removeCount == 0)console.log("no events removed", event.eventName, id);

        return;
    }

    /**
     * enable/disable logging of events for the class
     *
     * @param {boolean} enabled
     * @param {string} logName
     */
    logEvents(enabled, logName)
    {
        this.#logEvents = enabled;
        this.#logName = logName;
    }

    /**
     * emit event
     *
     * @param {string} which event name
     * @param {*} param1
     * @param {*} param2
     * @param {*} param3
     * @param {*} param4
     * @param {*} param5
     * @param {*} param6
     */
    emitEvent(which, param1 = null, param2 = null, param3 = null, param4 = null, param5 = null, param6 = null, param7 = null, param8 = null)
    {
        if (this.eventsPaused) return;
        if (this.#logEvents) this.#eventLog.log("[event] ", this.#logName, which, this.#eventCallbacks);

        if (this.#eventCallbacks[which])
        {
            for (let i = 0; i < this.#eventCallbacks[which].length; i++)
            {
                if (this.#eventCallbacks[which][i])
                {
                    this.#eventCallbacks[which][i].cb(param1, param2, param3, param4, param5, param6, param7, param8);
                }
            }
        }
        else
        {
            if (this.#logEvents) this.#eventLog.log("[event] has no event callback", which, this.#eventCallbacks);
        }
    }
}


/***/ }),

/***/ 849:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   A: () => (/* binding */ Logger)
/* harmony export */ });
/* eslint-disable no-console */
class Logger
{

    /**
     * @param {any} initiator
     * @param {Object} options
     */
    constructor(initiator, options)
    {
        this.initiator = initiator;
        this._options = options;
    }

    /**
     * @param {string} t
     */
    stack(t)
    {
        console.info("[" + this.initiator + "] ", t);
        console.log((new Error()).stack);
    }

    /**
     * @param {string} t
     */
    groupCollapsed(t)
    {
        if ((CABLES.UI && CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 0 }, ...arguments)) || !CABLES.logSilent) console.log("[" + this.initiator + "]", ...arguments);

        console.groupCollapsed("[" + this.initiator + "] " + t);
    }

    /**
     * @param {any[][]} t
     */
    table(t)
    {
        console.table(t);
    }

    groupEnd()
    {
        console.groupEnd();
    }

    error()
    {
        if ((CABLES.UI && CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 2 }, ...arguments)) || !CABLES.UI)
        {
            console.error("[" + this.initiator + "]", ...arguments);
        }

        if (this._options && this._options.onError)
        {
            this._options.onError(this.initiator, ...arguments);
            // console.log("emitevent onerror...");
            // CABLES.patch.emitEvent("onError", this.initiator, ...arguments);
            // CABLES.logErrorConsole("[" + this.initiator + "]", ...arguments);
        }
    }

    errorGui()
    {
        if (CABLES.UI) CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 2 }, ...arguments);
    }

    warn()
    {
        if ((CABLES.UI && CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 1 }, ...arguments)) || !CABLES.logSilent)
            console.warn("[" + this.initiator + "]", ...arguments);
    }

    verbose()
    {
        if ((CABLES.UI && CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 0 }, ...arguments)) || !CABLES.logSilent)
            console.log("[" + this.initiator + "]", ...arguments);
    }

    info()
    {
        if ((CABLES.UI && CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 0 }, ...arguments)) || !CABLES.logSilent)
            console.info("[" + this.initiator + "]", ...arguments);
    }

    log()
    {
        if ((CABLES.UI && CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 0 }, ...arguments)) || !CABLES.logSilent)
            console.log("[" + this.initiator + "]", ...arguments);
    }

    logGui()
    {
        if (CABLES.UI) CABLES.UI.logFilter.filterLog({ "initiator": this.initiator, "level": 0 }, ...arguments);
    }

    userInteraction(text)
    {
        // this.log({ "initiator": "userinteraction", "text": text });
    }
}


/***/ })

/******/ 	});
/************************************************************************/
/******/ 	// The module cache
/******/ 	var __webpack_module_cache__ = {};
/******/ 	
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/ 		// Check if module is in cache
/******/ 		var cachedModule = __webpack_module_cache__[moduleId];
/******/ 		if (cachedModule !== undefined) {
/******/ 			return cachedModule.exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = __webpack_module_cache__[moduleId] = {
/******/ 			// no module.id needed
/******/ 			// no module.loaded needed
/******/ 			exports: {}
/******/ 		};
/******/ 	
/******/ 		// Execute the module function
/******/ 		__webpack_modules__[moduleId](module, module.exports, __webpack_require__);
/******/ 	
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/ 	
/************************************************************************/
/******/ 	/* webpack/runtime/define property getters */
/******/ 	(() => {
/******/ 		// define getter functions for harmony exports
/******/ 		__webpack_require__.d = (exports, definition) => {
/******/ 			for(var key in definition) {
/******/ 				if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ 					Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ 				}
/******/ 			}
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
/******/ 	(() => {
/******/ 		__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/make namespace object */
/******/ 	(() => {
/******/ 		// define __esModule on exports
/******/ 		__webpack_require__.r = (exports) => {
/******/ 			if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ 				Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ 			}
/******/ 			Object.defineProperty(exports, '__esModule', { value: true });
/******/ 		};
/******/ 	})();
/******/ 	
/************************************************************************/
/******/ 	
/******/ 	// startup
/******/ 	// Load entry module and return exports
/******/ 	__webpack_require__(748);
/******/ 	// This entry module is referenced by other modules so it can't be inlined
/******/ 	__webpack_require__(772);
/******/ 	__webpack_require__(626);
/******/ 	__webpack_require__(564);
/******/ 	var __webpack_exports__ = __webpack_require__(606);
/******/ 	var __webpack_export_target__ = (CABLES = typeof CABLES === "undefined" ? {} : CABLES);
/******/ 	for(var i in __webpack_exports__) __webpack_export_target__[i] = __webpack_exports__[i];
/******/ 	if(__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, "__esModule", { value: true });
/******/ 	
/******/ })()
;


var CABLES = CABLES || {}; CABLES.build = {"timestamp":1751991309701,"created":"2025-07-08T16:15:09.701Z","git":{"branch":"master","commit":"5ac55484344fd962b81b053230809aa18281d23f","date":"1751875203","message":"sidebar colorpicker opacity cables-gl/cables/issues/7458"}};
//# sourceMappingURL=cables.js.map
if(!CABLES.exportedPatches)CABLES.exportedPatches={};CABLES.exportedPatches["8RrHYT"]={_id:"689f9eacea8d7fccebd9f752",ops:[{id:"af901d4d-5f75-440d-a1c5-2a48cd0cd138",uiAttribs:{},portsOut:[{name:"trigger 0",links:[{portIn:"render",portOut:"trigger 0",objIn:"zqas4xdnv",objOut:"af901d4d-5f75-440d-a1c5-2a48cd0cd138"}]},{name:"trigger 15",links:[{portIn:"exe",portOut:"trigger 15",objIn:"905a80d2-7bc6-4764-8786-f8cb286d93bb",objOut:"af901d4d-5f75-440d-a1c5-2a48cd0cd138"}]}],objName:"Ops.Trigger.Sequence"},{id:"d0397aad-d1da-4296-aa59-0e0472293fe8",uiAttribs:{},portsOut:[{name:"Passthrough",value:5}],objName:"Ops.Ui.VizNumberBar"},{id:"e7135b5f-5ae1-4811-8e2e-4394d59811f3",uiAttribs:{},portsIn:[{name:"current",anim:{keys:[{t:.06666666666666667,v:"0",e:1},{t:4,v:1,e:1},{t:16.166666666666668,v:2,e:1},{t:28.033333333333335,v:3,e:0}],loop:0,tlActive:true}},{name:"overwriteTime",value:0},{name:"ignoreInSubPatch",value:0}],portsOut:[{name:"currentKeyTime",value:-.06666666666666667},{name:"Current",value:5},{name:"trigger 0",links:[{portIn:"render",portOut:"trigger 0",objIn:"3ara7lixk",objOut:"e7135b5f-5ae1-4811-8e2e-4394d59811f3"}]},{name:"trigger 1",links:[{portIn:"Input_0",portOut:"trigger 1",objIn:"8l238z8l0",objOut:"e7135b5f-5ae1-4811-8e2e-4394d59811f3"}]},{name:"trigger 2",links:[{portIn:"Input_0",portOut:"trigger 2",objIn:"squ7m4tnn",objOut:"e7135b5f-5ae1-4811-8e2e-4394d59811f3"}]},{name:"trigger 3",links:[{portIn:"Input_0",portOut:"trigger 3",objIn:"2zebln2pu",objOut:"e7135b5f-5ae1-4811-8e2e-4394d59811f3"}]},{name:"trigger 4",links:[{portIn:"Input_0",portOut:"trigger 4",objIn:"xg3kpufdb",objOut:"e7135b5f-5ae1-4811-8e2e-4394d59811f3"}]},{name:"trigger 5",links:[{portIn:"Input_0",portOut:"trigger 5",objIn:"cp19h46pj",objOut:"e7135b5f-5ae1-4811-8e2e-4394d59811f3"}]}],objName:"Ops.Trigger.TimedSequence"},{id:"794b4b97-6b53-4aeb-b7c5-820532b32395",uiAttribs:{},portsIn:[{name:"Variable",value:"beatFloat"}],portsOut:[{name:"Value",links:[{portIn:"beat",portOut:"Value",objIn:"rdyyxbqhv",objOut:"794b4b97-6b53-4aeb-b7c5-820532b32395"}]}],objName:"Ops.Vars.VarGetNumber_v2"},{id:"24933c75-84e5-44e6-85e7-960d9d74b388",uiAttribs:{},portsIn:[{name:"Variable",value:"currentScene"}],objName:"Ops.Vars.VarSetNumber_v2"},{id:"6d6e7c34-07f4-48e9-a1a2-154246b7caec",uiAttribs:{},portsIn:[{name:"Scale index",value:1},{name:"Scale",value:"Fit"},{name:"Flip Y",value:0},{name:"Flip X",value:0}],objName:"Ops.Gl.Meshes.FullscreenRectangle"},{id:"26pqnrgsl",uiAttribs:{},portsIn:[{name:"FPS Limit",value:0},{name:"Reduce FPS not focussed",value:0},{name:"Reduce FPS loading",value:0},{name:"Clear",value:1},{name:"ClearAlpha",value:1},{name:"Fullscreen Button",value:0},{name:"Active",value:1},{name:"Hires Displays",value:0},{name:"Pixel Unit index",value:0},{name:"Pixel Unit",value:"Display"}],portsOut:[{name:"trigger",links:[{portIn:"Trigger",portOut:"trigger",objIn:"ftljvq63b",objOut:"26pqnrgsl"}]},{name:"width",value:902},{name:"height",value:508}],objName:"Ops.Gl.MainLoop"},{id:"q2viw7oos",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"URL",value:"assets/jarig.ogg",display:"file"},{name:"Create Loading Task",value:1}],portsOut:[{name:"Audio Buffer",links:[{portIn:"Audio Buffer",portOut:"Audio Buffer",objIn:"o88idj6yn",objOut:"q2viw7oos"}]},{name:"Finished Loading",links:[{portIn:"bool 1",portOut:"Finished Loading",objIn:"2e13ca45-b93e-452e-81c3-8eba7502d89e",objOut:"q2viw7oos"}]},{name:"Sample Rate",value:48e3},{name:"Length",value:4263114},{name:"Duration",links:[{portIn:"number1",portOut:"Duration",objIn:"er6frbx13",objOut:"q2viw7oos"}]},{name:"Number of Channels",value:2},{name:"isLoading",value:false}],objName:"Ops.WebAudio.AudioBuffer_v2"},{id:"o88idj6yn",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Loop",value:0},{name:"Playback Rate",value:1},{name:"Detune",value:0}],portsOut:[{name:"Audio Out",links:[{portIn:"Audio In",portOut:"Audio Out",objIn:"naikeap0f",objOut:"o88idj6yn"}]},{name:"Is Playing",value:false},{name:"Loading",value:false}],objName:"Ops.WebAudio.AudioBufferPlayer_v2"},{id:"naikeap0f",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Show Audio Suspended Button",value:0}],portsOut:[{name:"Current Volume",value:1},{name:"Number Of Channels",value:2},{name:"Context State",value:"running"}],objName:"Ops.WebAudio.Output_v2"},{id:"zuqq5tu35",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsIn:[{name:"Play Timeline",value:0}],portsOut:[{name:"Next",links:[{portIn:"Trigger",portOut:"Next",objIn:"m6sjox2xg",objOut:"zuqq5tu35"}]},{name:"Finished Initial Loading",links:[{portIn:"boolean",portOut:"Finished Initial Loading",objIn:"7cb6901a-7932-40b5-b238-3359873e0e37",objOut:"zuqq5tu35"}]},{name:"Loading",value:0},{name:"Progress",links:[{portIn:"number1",portOut:"Progress",objIn:"jijn22dli",objOut:"zuqq5tu35"}]},{name:"Trigger Loading Finished ",links:[{portIn:"Trigger",portOut:"Trigger Loading Finished ",objIn:"3joq8dsxn",objOut:"zuqq5tu35"}]}],objName:"Ops.Cables.LoadingStatus_v2"},{id:"jijn22dli",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsOut:[{name:"result",links:[{portIn:"number1",portOut:"result",objIn:"2ubbsvup2",objOut:"jijn22dli"}]}],objName:"Ops.Math.Sum"},{id:"2ubbsvup2",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsIn:[{name:"number2",value:2}],portsOut:[{name:"result",links:[{portIn:"number1",portOut:"result",objIn:"b591b734-03ad-4b5b-968e-190fbdac13fb",objOut:"2ubbsvup2"},{portIn:"out2 Total Load Progress result",portOut:"result",objIn:"6yjm5kuye",objOut:"2ubbsvup2"}]}],objName:"Ops.Math.Divide"},{id:"ablytx3pz",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsIn:[{name:"Times",value:[0,3.2666666666666666,16.2,29,67.4,86.6,86.61666666666666]},{name:"Manual Timestamps",value:0},{name:"Record Events",value:0},{name:"ReRender on Resize",value:0}],portsOut:[{name:"Next",links:[{portIn:"out0 Ops.Sequence exe",portOut:"Next",objIn:"6yjm5kuye",objOut:"ablytx3pz"}]},{name:"Prerendered Frame",links:[{portIn:"exe",portOut:"Prerendered Frame",objIn:"pwq65p8ax",objOut:"ablytx3pz"},{portIn:"out1 Ops.Boolean.IfTrueThen_v2 else",portOut:"Prerendered Frame",objIn:"6yjm5kuye",objOut:"ablytx3pz"},{portIn:"Play",portOut:"Prerendered Frame",objIn:"474d9904-e3f0-4352-8997-fee337f00759",objOut:"ablytx3pz"}]},{name:"Progress",links:[{portIn:"number2",portOut:"Progress",objIn:"jijn22dli",objOut:"ablytx3pz"}]},{name:"Num Events",value:7}],objName:"Ops.TimeLine.DemoPrerender"},{id:"ihcr5lvd4",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsOut:[{name:"Play/Stop",links:[{portIn:"Start / Stop",portOut:"Play/Stop",objIn:"o88idj6yn",objOut:"ihcr5lvd4"}]},{name:"time",links:[{portIn:"Offset",portOut:"time",objIn:"o88idj6yn",objOut:"ihcr5lvd4"}]}],objName:"Ops.TimeLine.TimeLineControls"},{id:"pwq65p8ax",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsOut:[{name:"then",links:[{portIn:"Set Cursor",portOut:"then",objIn:"1pul1v2g3",objOut:"pwq65p8ax"}]}],objName:"Ops.Boolean.IfTrueThen_v2"},{id:"3do3wyq18",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsOut:[{name:"Result",links:[{portIn:"boolean",portOut:"Result",objIn:"pwq65p8ax",objOut:"3do3wyq18"}]}],objName:"Ops.Boolean.Not"},{id:"nq1s2gu0o",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsOut:[{name:"UI",links:[{portIn:"Boolean",portOut:"UI",objIn:"3do3wyq18",objOut:"nq1s2gu0o"}]},{name:"Overlay Mode",value:0},{name:"Remote Viewer",value:0},{name:"Is Standalone",value:0},{name:"Canvas Mode",value:0},{name:"Patch Field Visible",value:0}],objName:"Ops.Cables.UIMode"},{id:"eamhm2gmo",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsIn:[{name:"Active",value:1},{name:"relative",value:0},{name:"normalize",value:0},{name:"flip y",value:1},{name:"Area index",value:0},{name:"Area",value:"Canvas"},{name:"right click prevent default",value:1},{name:"Touch support",value:1},{name:"smooth",value:0},{name:"smoothSpeed",value:20},{name:"multiply",value:1}],portsOut:[{name:"x",value:315},{name:"y",value:1},{name:"button down",value:0},{name:"click right",links:[{portIn:"trigger",portOut:"click right",objIn:"2zcv74khx",objOut:"eamhm2gmo"}]},{name:"mouseOver",value:0},{name:"button",value:0}],objName:"Ops.Devices.Mouse.Mouse_v2"},{id:"2zcv74khx",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsIn:[{name:"Default",value:0}],portsOut:[{name:"result",links:[{portIn:"Value",portOut:"result",objIn:"na2a9rh24",objOut:"2zcv74khx"},{portIn:"Value",portOut:"result",objIn:"d4b08f4b-6fb8-4492-b48a-90dfb505012c",objOut:"2zcv74khx"},{portIn:"bool 1",portOut:"result",objIn:"80c514d0-5c5a-4e6a-8864-2f716ff04045",objOut:"2zcv74khx"}]}],objName:"Ops.Boolean.ToggleBool"},{id:"03ohwrxwu",uiAttribs:{},portsOut:[{name:"trigger 8",links:[{portIn:"in0 Ops.Patch.PlayButton Next",portOut:"trigger 8",objIn:"bfm5kfuuw",objOut:"03ohwrxwu"}]},{name:"trigger 14",links:[{portIn:"Execute",portOut:"trigger 14",objIn:"3a913fff-b464-4489-a317-f57aa425bb82",objOut:"03ohwrxwu"}]}],objName:"Ops.Trigger.Sequence"},{id:"eyxnv2tsm",uiAttribs:{},portsIn:[{name:"Named Trigger",value:"overlay"}],objName:"Ops.Trigger.TriggerSend"},{id:"r8iwybz9e",uiAttribs:{},portsOut:[{name:"trigger",links:[{portIn:"Trigger",portOut:"trigger",objIn:"eyxnv2tsm",objOut:"r8iwybz9e"}]}],objName:"Ops.Gl.ClearDepth"},{id:"m27bcavsl",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsOut:[{name:"create port",value:0}],objName:"Ops.Ui.PatchInput"},{id:"ynyb036ok",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsIn:[{name:"create port",value:0}],objName:"Ops.Ui.PatchOutput"},{id:"8yvc83q4w",uiAttribs:{},storage:{subPatchVer:1},portsIn:[{name:"create port",value:0},{name:"dataStr",value:0},{name:"patchId",value:"83f2e9c1-d9c2-43b1-9159-572dd649f463"}],portsOut:[{name:"create port out",value:0}],objName:"Ops.Ui.SubPatch"},{id:"m7mvm9uy8",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsIn:[{name:"Variable",value:"mute"}],objName:"Ops.Vars.VarSetNumber_v2"},{id:"r34oj3erg",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Variable",value:"mute"}],portsOut:[{name:"Value",links:[{portIn:"Mute",portOut:"Value",objIn:"naikeap0f",objOut:"r34oj3erg"}]}],objName:"Ops.Vars.VarGetNumber_v2"},{id:"aefr8susr",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsOut:[{name:"create port",value:0},{name:"in0 Ops.Patch.PlayButton Next",links:[{portIn:"exe",portOut:"in0 Ops.Patch.PlayButton Next",objIn:"zuqq5tu35",objOut:"aefr8susr"}]},{name:"in1 Ops.Patch.PlayButton Clicked",value:0}],objName:"Ops.Ui.PatchInput"},{id:"6yjm5kuye",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsIn:[{name:"create port",value:0},{name:"out0 Ops.Sequence exe",title:"Render Demo"},{name:"out1 Ops.Boolean.IfTrueThen_v2 else",title:"Render Progress"},{name:"out2 Total Load Progress result",title:"Progress"}],objName:"Ops.Ui.PatchOutput"},{id:"bfm5kfuuw",uiAttribs:{},storage:{subPatchVer:1},portsIn:[{name:"create port",value:0},{name:"dataStr",value:'{"ports":[{"name":"in0 Ops.Patch.PlayButton Next","type":1},{"name":"in1 Ops.Patch.PlayButton Clicked","type":0}],"portsOut":[{"name":"out0 Ops.Sequence exe","type":1,"title":"Render Demo"},{"name":"out1 Ops.Boolean.IfTrueThen_v2 else","type":1,"title":"Render Progress"},{"name":"out2 Total Load Progress result","type":0,"title":"Progress"}]}'},{name:"patchId",value:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"}],portsOut:[{name:"create port out",value:0},{name:"out0 Ops.Sequence exe",title:"Render Demo",links:[{portIn:"exe",portOut:"out0 Ops.Sequence exe",objIn:"af901d4d-5f75-440d-a1c5-2a48cd0cd138",objOut:"bfm5kfuuw"}]},{name:"out1 Ops.Boolean.IfTrueThen_v2 else",title:"Render Progress",links:[{portIn:"in0 Ops.Trigger.Sequence trigger 15",portOut:"out1 Ops.Boolean.IfTrueThen_v2 else",objIn:"5bl9o5nqo",objOut:"bfm5kfuuw"}]},{name:"out2 Total Load Progress result",title:"Progress",links:[{portIn:"in1 Total Load Progress result",portOut:"out2 Total Load Progress result",objIn:"5bl9o5nqo",objOut:"bfm5kfuuw"}]}],objName:"Ops.Ui.SubPatch"},{id:"qgp9c1mz0",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsOut:[{name:"create port",value:0},{name:"in0 Ops.WebAudio.Output_v2 Volume",links:[{portIn:"Volume",portOut:"in0 Ops.WebAudio.Output_v2 Volume",objIn:"naikeap0f",objOut:"qgp9c1mz0"}]},{name:"in1 Ops.WebAudio.Output_v2 Volume",value:0}],objName:"Ops.Ui.PatchInput"},{id:"xdc0xlfky",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"create port",value:0}],objName:"Ops.Ui.PatchOutput"},{id:"yyqvaav8e",uiAttribs:{},storage:{subPatchVer:1},portsIn:[{name:"create port",value:0},{name:"dataStr",value:'{"ports":[{"name":"in0 Ops.WebAudio.Output_v2 Volume","type":0},{"name":"in1 Ops.WebAudio.Output_v2 Volume","type":0}],"portsOut":[]}'},{name:"patchId",value:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"}],portsOut:[{name:"create port out",value:0}],objName:"Ops.Ui.SubPatch"},{id:"na2a9rh24",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsIn:[{name:"Variable",value:"overlay_show"}],objName:"Ops.Vars.VarSetNumber_v2"},{id:"h7dynfe9m",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsIn:[{name:"Variable",value:"overlay_show"}],portsOut:[{name:"Value",links:[{portIn:"Visible",portOut:"Value",objIn:"u1kk8qixh",objOut:"h7dynfe9m"}]}],objName:"Ops.Vars.VarGetNumber_v2"},{id:"er6frbx13",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"number2",value:2}],portsOut:[{name:"result",links:[{portIn:"number2",portOut:"result",objIn:"6xnjdtsmy",objOut:"er6frbx13"},{portIn:"Value",portOut:"result",objIn:"2sashovh4",objOut:"er6frbx13"}]}],objName:"Ops.Math.Sum"},{id:"6xnjdtsmy",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsOut:[{name:"result",links:[{portIn:"bool 2",portOut:"result",objIn:"2e13ca45-b93e-452e-81c3-8eba7502d89e",objOut:"6xnjdtsmy"}]}],objName:"Ops.Math.Compare.GreaterThan"},{id:"fvht61sdu",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsOut:[{name:"Next",links:[{portIn:"Close",portOut:"Next",objIn:"knrpbhyn0",objOut:"fvht61sdu"}]}],objName:"Ops.Boolean.TriggerChangedTrue"},{id:"2sashovh4",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Variable",value:"demo_length"}],objName:"Ops.Vars.VarSetNumber_v2"},{id:"my3lkvypy",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsOut:[{name:"time",links:[{portIn:"number1",portOut:"time",objIn:"6xnjdtsmy",objOut:"my3lkvypy"},{portIn:"number1",portOut:"time",objIn:"jixpaazz1",objOut:"my3lkvypy"}]}],objName:"Ops.TimeLine.TimeLineTime"},{id:"5hnd0wu0a",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsIn:[{name:"Variable",value:"demo_length"}],portsOut:[{name:"Value",links:[{portIn:"Length",portOut:"Value",objIn:"u1kk8qixh",objOut:"5hnd0wu0a"}]}],objName:"Ops.Vars.VarGetNumber_v2"},{id:"agbyk5hu6",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsOut:[{name:"time",links:[{portIn:"Current",portOut:"time",objIn:"u1kk8qixh",objOut:"agbyk5hu6"}]}],objName:"Ops.TimeLine.TimeLineTime"},{id:"mfh9exohr",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsOut:[{name:"Next",links:[{portIn:"Trigger",portOut:"Next",objIn:"uu19igkn6",objOut:"mfh9exohr"}]}],objName:"Ops.TimeLine.TimeLinePlay"},{id:"njas42ku3",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsIn:[{name:"number2",value:2}],portsOut:[{name:"result",links:[{portIn:"Time",portOut:"result",objIn:"vyembu1d1",objOut:"njas42ku3"}]}],objName:"Ops.Math.Subtract"},{id:"l0j6c3tp1",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsIn:[{name:"number2",value:2}],portsOut:[{name:"result",links:[{portIn:"Time",portOut:"result",objIn:"vqdkpfo29",objOut:"l0j6c3tp1"}]}],objName:"Ops.Math.Sum"},{id:"vyembu1d1",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},objName:"Ops.TimeLine.TimeLineSetTime"},{id:"vqdkpfo29",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},objName:"Ops.TimeLine.TimeLineSetTime"},{id:"sh4j6xati",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},objName:"Ops.TimeLine.TimeLineRewind"},{id:"3kqpy5r9t",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsOut:[{name:"Next",links:[{portIn:"Play",portOut:"Next",objIn:"mfh9exohr",objOut:"3kqpy5r9t"}]}],objName:"Ops.TimeLine.TimeLineSetTime"},{id:"zd7hbvfzi",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},objName:"Ops.TimeLine.TimeLineSetTime"},{id:"2qjs5z4qn",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsOut:[{name:"Play/Stop",links:[{portIn:"Is Playing",portOut:"Play/Stop",objIn:"u1kk8qixh",objOut:"2qjs5z4qn"}]},{name:"time",value:.033399999999906865}],objName:"Ops.TimeLine.TimeLineControls"},{id:"u1kk8qixh",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsIn:[{name:"Clamp",value:1},{name:"Show Time",value:1},{name:"Show Skip Buttons",value:1}],portsOut:[{name:"Play clicked",links:[{portIn:"Update",portOut:"Play clicked",objIn:"3kqpy5r9t",objOut:"u1kk8qixh"}]},{name:"Pause clicked",links:[{portIn:"Pause",portOut:"Pause clicked",objIn:"mfh9exohr",objOut:"u1kk8qixh"}]},{name:"Rewind clicked",links:[{portIn:"exe",portOut:"Rewind clicked",objIn:"sh4j6xati",objOut:"u1kk8qixh"}]},{name:"Skip Back clicked",links:[{portIn:"Update",portOut:"Skip Back clicked",objIn:"vyembu1d1",objOut:"u1kk8qixh"}]},{name:"Skip Forward clicked",links:[{portIn:"Update",portOut:"Skip Forward clicked",objIn:"vqdkpfo29",objOut:"u1kk8qixh"}]},{name:"Dragged",links:[{portIn:"Update",portOut:"Dragged",objIn:"zd7hbvfzi",objOut:"u1kk8qixh"}]},{name:"Current Value",links:[{portIn:"Time",portOut:"Current Value",objIn:"zd7hbvfzi",objOut:"u1kk8qixh"},{portIn:"Time",portOut:"Current Value",objIn:"3kqpy5r9t",objOut:"u1kk8qixh"},{portIn:"number1",portOut:"Current Value",objIn:"l0j6c3tp1",objOut:"u1kk8qixh"},{portIn:"number1",portOut:"Current Value",objIn:"njas42ku3",objOut:"u1kk8qixh"}]},{name:"Dragging",value:0}],objName:"Ops.Html.Utils.PlayerControlPanel_v2"},{id:"jixpaazz1",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"number2",value:60}],portsOut:[{name:"result",links:[{portIn:"number1",portOut:"result",objIn:"s3r515jtc",objOut:"jixpaazz1"}]}],objName:"Ops.Math.Divide"},{id:"s3r515jtc",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsOut:[{name:"result",links:[{portIn:"number1",portOut:"result",objIn:"zpzcqsgyi",objOut:"s3r515jtc"}]}],objName:"Ops.Math.Multiply"},{id:"3h420ckfj",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Variable",value:"bpmConst"}],portsOut:[{name:"Value",links:[{portIn:"number2",portOut:"Value",objIn:"s3r515jtc",objOut:"3h420ckfj"}]}],objName:"Ops.Vars.VarGetNumber_v2"},{id:"0iaiewkmt",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Variable",value:"beatFloat"}],objName:"Ops.Vars.VarSetNumber_v2"},{id:"uu19igkn6",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsIn:[{name:"Named Trigger",value:"play"}],objName:"Ops.Trigger.TriggerSend"},{id:"ftljvq63b",uiAttribs:{},portsIn:[{name:"Active",value:1},{name:"Force index",value:1},{name:"Force",value:"Aspect Ratio"},{name:"Center In Parent",value:1},{name:"Scale to fit Parent",value:0},{name:"Set Width",value:300},{name:"Set Height",value:200},{name:"Aspect Ratio index",value:3},{name:"Aspect Ratio",value:"16:9"},{name:"Ratio",value:1.7777777777777777},{name:"Fill Parent index",value:0},{name:"Fill Parent",value:"Auto"}],portsOut:[{name:"Next",links:[{portIn:"exe 3",portOut:"Next",objIn:"03ohwrxwu",objOut:"ftljvq63b"}]},{name:"Width",value:902},{name:"Height",value:508},{name:"Margin Left",value:0},{name:"Margin Top",value:.5}],objName:"Ops.Gl.ForceCanvasSize"},{id:"3joq8dsxn",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsIn:[{name:"Named Trigger",value:"Loading finished"}],objName:"Ops.Trigger.TriggerSend"},{id:"1pul1v2g3",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsIn:[{name:"cursor index",value:16},{name:"cursor",value:"none"}],objName:"Ops.Html.Cursor"},{id:"knrpbhyn0",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},objName:"Ops.Html.WindowClose"},{id:"nmqotuz7l",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Named Trigger",value:"overlay"}],portsOut:[{name:"Triggered",links:[{portIn:"render",portOut:"Triggered",objIn:"d4hj66x4w",objOut:"nmqotuz7l"}]}],objName:"Ops.Trigger.TriggerReceive"},{id:"m3hc1rlhs",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Draw",value:1,title:"Render mesh"},{name:"innerRadius",value:0},{name:"segments",value:40},{name:"percent",value:1},{name:"steps",value:0},{name:"invertSteps",value:0},{name:"mapping index",value:0},{name:"mapping",value:"flat"},{name:"Spline",value:0}],portsOut:[{name:"trigger",links:[{portIn:"Render",portOut:"trigger",objIn:"llq1b20hg",objOut:"m3hc1rlhs"}]}],objName:"Ops.Graphics.Meshes.Circle_v2"},{id:"c5vszjasc",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsOut:[{name:"Result",links:[{portIn:"number2",portOut:"Result",objIn:"6d6k78l6d",objOut:"c5vszjasc"},{portIn:"Number",portOut:"Result",objIn:"3tlfvt24e",objOut:"c5vszjasc"}]}],objName:"Ops.Math.Fract"},{id:"6d6k78l6d",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"number1",value:1}],portsOut:[{name:"result",links:[{portIn:"radius",portOut:"result",objIn:"m3hc1rlhs",objOut:"6d6k78l6d"}]}],objName:"Ops.Math.Subtract"},{id:"d4hj66x4w",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"posX",value:1.79},{name:"posY",value:-.94},{name:"posZ",value:0},{name:"scale",value:.11},{name:"rotX",value:0},{name:"rotY",value:0},{name:"rotZ",value:0}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"m3hc1rlhs",objOut:"d4hj66x4w"}]}],objName:"Ops.Graphics.Transform"},{id:"6zllzz3o6",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"number2",value:4}],portsOut:[{name:"result",links:[{portIn:"number1",portOut:"result",objIn:"6etswqe3n",objOut:"6zllzz3o6"},{portIn:"number1",portOut:"result",objIn:"uc64ovx3x",objOut:"6zllzz3o6"}]}],objName:"Ops.Math.Divide"},{id:"6etswqe3n",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"number2",value:8}],portsOut:[{name:"result",links:[{portIn:"Integer",portOut:"result",objIn:"31512e8eb",objOut:"6etswqe3n"}]}],objName:"Ops.Math.Divide"},{id:"uc64ovx3x",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"number2",value:8},{name:"pingpong",value:0}],portsOut:[{name:"result",links:[{portIn:"Integer",portOut:"result",objIn:"tdm4z3xq8",objOut:"uc64ovx3x"}]}],objName:"Ops.Math.Modulo"},{id:"7m3qjzwa4",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"number2",value:4},{name:"pingpong",value:0}],portsOut:[{name:"result",links:[{portIn:"Integer",portOut:"result",objIn:"jivkr4o57",objOut:"7m3qjzwa4"}]}],objName:"Ops.Math.Modulo"},{id:"jivkr4o57",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsOut:[{name:"Number out",links:[{portIn:"number1",portOut:"Number out",objIn:"v89c2in6m",objOut:"jivkr4o57"}]}],objName:"Ops.Number.Integer"},{id:"tdm4z3xq8",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsOut:[{name:"Number out",links:[{portIn:"number1",portOut:"Number out",objIn:"zgzhtisw0",objOut:"tdm4z3xq8"}]}],objName:"Ops.Number.Integer"},{id:"31512e8eb",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsOut:[{name:"Number out",links:[{portIn:"number1",portOut:"Number out",objIn:"n2ju3j8gk",objOut:"31512e8eb"}]}],objName:"Ops.Number.Integer"},{id:"zpzcqsgyi",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"number2",value:8.44}],portsOut:[{name:"result",links:[{portIn:"Value",portOut:"result",objIn:"0iaiewkmt",objOut:"zpzcqsgyi"}]}],objName:"Ops.Math.Subtract"},{id:"2n3lmq5rw",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Format",value:"$a.$b.$c"},{name:"String E",value:""},{name:"String F",value:""}],portsOut:[{name:"Result",links:[{portIn:"Text",portOut:"Result",objIn:"llq1b20hg",objOut:"2n3lmq5rw"}]}],objName:"Ops.String.StringCompose_v3"},{id:"10bagkejc",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Decimal Places",value:4}],portsOut:[{name:"Result",links:[{portIn:"String A",portOut:"Result",objIn:"2n3lmq5rw",objOut:"10bagkejc"}]}],objName:"Ops.String.NumberToString_v2"},{id:"3hfs17gpn",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Decimal Places",value:4}],portsOut:[{name:"Result",links:[{portIn:"String B",portOut:"Result",objIn:"2n3lmq5rw",objOut:"3hfs17gpn"}]}],objName:"Ops.String.NumberToString_v2"},{id:"ukicdmj5q",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Decimal Places",value:4}],portsOut:[{name:"Result",links:[{portIn:"String C",portOut:"Result",objIn:"2n3lmq5rw",objOut:"ukicdmj5q"}]}],objName:"Ops.String.NumberToString_v2"},{id:"3tlfvt24e",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Decimal Places",value:4}],portsOut:[{name:"Result",links:[{portIn:"String D",portOut:"Result",objIn:"2n3lmq5rw",objOut:"3tlfvt24e"}]}],objName:"Ops.String.NumberToString_v2"},{id:"v89c2in6m",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"number2",value:1}],portsOut:[{name:"result",links:[{portIn:"Number",portOut:"result",objIn:"ukicdmj5q",objOut:"v89c2in6m"}]}],objName:"Ops.Math.Sum"},{id:"zgzhtisw0",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"number2",value:1}],portsOut:[{name:"result",links:[{portIn:"Number",portOut:"result",objIn:"3hfs17gpn",objOut:"zgzhtisw0"}]}],objName:"Ops.Math.Sum"},{id:"n2ju3j8gk",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"number2",value:1}],portsOut:[{name:"result",links:[{portIn:"Number",portOut:"result",objIn:"10bagkejc",objOut:"n2ju3j8gk"}]}],objName:"Ops.Math.Sum"},{id:"llq1b20hg",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Scale Text",value:1},{name:"Scale",value:1,title:"Line Scale"},{name:"Font",value:"Arial"},{name:"align index",value:1},{name:"align",value:"center"},{name:"vertical align index",value:1},{name:"vertical align",value:"Middle"},{name:"Line Height",value:1},{name:"Letter Spacing",value:0},{name:"filter index",value:2},{name:"filter",value:"mipmap"},{name:"Anisotropic index",value:0},{name:"Anisotropic",value:0},{name:"r",value:1},{name:"g",value:1},{name:"b",value:1},{name:"a",value:1}],portsOut:[{name:"Total Lines",value:1},{name:"Width",value:.7943289620535716},{name:"Font Available",value:0}],objName:"Ops.Gl.Meshes.TextMesh_v2"},{id:"s8rx8uc8y",uiAttribs:{},portsIn:[{name:"Variable",value:"overlay_show"}],portsOut:[{name:"Value",links:[{portIn:"Pass Through",portOut:"Value",objIn:"3a913fff-b464-4489-a317-f57aa425bb82",objOut:"s8rx8uc8y"}]}],objName:"Ops.Vars.VarGetNumber_v2"},{id:"dddfa5d5-d9e2-4032-b433-6e54355aa764",uiAttribs:{},portsIn:[{name:"Opacity",value:1},{name:"Default Minimized",value:0},{name:"Minimized Opacity",value:.5},{name:"Show undo button",value:0},{name:"Show Minimize",value:0},{name:"Title",value:""},{name:"Side",value:1},{name:"Default CSS",value:1}],portsOut:[{name:"childs",title:"Children",links:[{portIn:"link",portOut:"childs",objIn:"a41b0fe1-6605-49ca-b128-29eff42918b2",objOut:"dddfa5d5-d9e2-4032-b433-6e54355aa764"}]},{name:"Opfened",value:false,title:"Opened"}],objName:"Ops.Sidebar.Sidebar"},{id:"defd8f06-8106-4965-ba9f-5112422cd7ab",uiAttribs:{},portsIn:[{name:"Variable",value:"overlay_show"}],portsOut:[{name:"Value",links:[{portIn:"Visible",portOut:"Value",objIn:"dddfa5d5-d9e2-4032-b433-6e54355aa764",objOut:"defd8f06-8106-4965-ba9f-5112422cd7ab"}]}],objName:"Ops.Vars.VarGetNumber_v2"},{id:"a41b0fe1-6605-49ca-b128-29eff42918b2",uiAttribs:{},portsIn:[{name:"Text",value:"Volume"},{name:"Min",value:0},{name:"Max",value:1},{name:"Step",value:1e-5},{name:"Suffix",value:""},{name:"Grey Out",value:0},{name:"Visible",value:1},{name:"Input",value:1},{name:"Default",value:1}],portsOut:[{name:"Result",links:[{portIn:"in0 Ops.WebAudio.Output_v2 Volume",portOut:"Result",objIn:"yyqvaav8e",objOut:"a41b0fe1-6605-49ca-b128-29eff42918b2"}]}],objName:"Ops.Sidebar.Slider_v3"},{id:"41wxrzq2b",uiAttribs:{},portsIn:[{name:"file",value:"assets/adrip1.ttf",display:"file"},{name:"family",value:"adrip"},{name:"Active",value:1}],portsOut:[{name:"Loaded",value:1}],objName:"Ops.Html.FontFile_v2"},{id:"fzxzsjgbg",uiAttribs:{},portsIn:[{name:"Fragment Code",value:'// yoinked from\n// https://github.com/libretro/slang-shaders/blob/master/pal/shaders/pal-singlepass.slang\n// ported into a CustomShader and added some more parameters\n\n/*\n    pal-singlepass.slang\n\n    svo\'s PAL single pass shader, ported to libretro\n    ------------------------------------------------\n    "Software composite video modulation/demodulation experiments\n\n    The idea is to reproduce in GLSL shaders realistic composite-like\n    artifacting by applying PAL modulation and demodulation.\n    \n    Digital texture, passed through the model of an analog channel,\n    should suffer same effects as its analog counterpart and exhibit properties,\n    such as dot crawl and colour bleeding, that may be desirable for faithful\n    reproduction of look and feel of old computer games."\n    \n    https://github.com/svofski/CRT\n\n    Copyright (c) 2016, Viacheslav Slavinsky\n    All rights reserved.\n\n    Redistribution and use in source and binary forms, with or without\n    modification, are permitted provided that the following conditions are met:\n\n    1. Redistributions of source code must retain the above copyright notice, \n    this list of conditions and the following disclaimer.\n\n    2. Redistributions in binary form must reproduce the above copyright notice, \n    this list of conditions and the following disclaimer in the documentation\n    and/or other materials provided with the distribution.\n\n    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" \n    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n    ARE DISCLAIMED.\n    IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY\n    DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n    (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND\n    ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n    THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\nUNI sampler2D tex;\nUNI vec2 SourceSize;\nUNI float FrameCount;\nUNI float PHASE_NOISE;\nUNI float FIR_GAIN;\nUNI float FIR_INVGAIN;\nUNI float PIXEL_WOBBLE;\nUNI float LUMA_STRIPING;\nIN vec2 texCoord;\n{{MODULES_HEAD}}\n\n\n\n/* Subcarrier frequency */\n#define FSC          4433618.75\n\n/* Line frequency */\n#define FLINE        15625.0\n\n#define VISIBLELINES 312.0\n\n#define PI           3.14159265358\n\n#define RGB_to_YIQ  mat3x3( 0.299,    0.595716,  0.211456,\\\n                            0.587,   -0.274453, -0.522591,\\\n                            0.114,   -0.321263,  0.311135)\n\n#define YIQ_to_RGB  mat3x3( 1.0   ,   1.0,       1.0,\\\n                            0.9563,  -0.2721,   -1.1070,\\\n                            0.6210,  -0.6474,    1.7046)\n\n#define RGB_to_YUV  mat3x3( 0.299,   -0.14713,   0.615,\\\n                            0.587,   -0.28886,  -0.514991,\\\n                            0.114,    0.436,    -0.10001)\n\n#define YUV_to_RGB  mat3x3( 1.0,      1.0,       1.0,\\\n                            0.0,     -0.39465,   2.03211,\\\n                            1.13983, -0.58060,   0.0)\n                            \n#define fetch(ofs,center,invx) texture(tex, vec2(float(ofs) * (invx) + center.x, 1.-center.y))\n\n#define FIRTAPS 20\nfloat FIR[FIRTAPS] = float[FIRTAPS] (\n   -0.008030271,\n    0.003107906,\n    0.016841352,\n    0.032545161,\n    0.049360136,\n    0.066256720,\n    0.082120150,\n    0.095848433,\n    0.106453014,\n    0.113151423,\n    0.115441842,\n    0.113151423,\n    0.106453014,\n    0.095848433,\n    0.082120150,\n    0.066256720,\n    0.049360136,\n    0.032545161,\n    0.016841352,\n    0.003107906\n);\n\n/* subcarrier counts per scan line = FSC/FLINE = 283.7516 */\n/* We save the reciprocal of this only to optimize it */\nfloat counts_per_scanline_reciprocal = 1.0 / (FSC/FLINE);\n\nfloat width_ratio;\nfloat height_ratio;\nfloat altv;\nfloat invx;\n\n/* http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ */\nfloat rand(vec2 co)\n{\n    float a  = 12.9898;\n    float b  = 78.233;\n    float c  = 43758.5453;\n    float dt = dot(co.xy, vec2(a, b));\n    float sn = mod(dt,3.14);\n\n    return fract(sin(sn) * c);\n}\n\nfloat modulated(vec2 xy, float sinwt, float coswt) \n{\n    vec3 rgb = fetch(0, xy, invx).xyz;\n    vec3 yuv = RGB_to_YUV * rgb;\n\n    return clamp(yuv.x + LUMA_STRIPING * (yuv.y * sinwt + yuv.z * coswt), 0.0, 1.0);    \n}\n\nvec2 modem_uv(vec2 xy, float ofs) {\n    float t  = (xy.x + ofs * invx) * SourceSize.x;\n    float wt = t * 2. * PI / width_ratio;\n\n    float sinwt = sin(wt);\n    float coswt = cos(wt + altv);\n\n    vec3 rgb = fetch(ofs, xy, invx).xyz;\n    vec3 yuv = RGB_to_YUV * rgb;\n    float signal = clamp(yuv.x + yuv.y * sinwt + yuv.z * coswt, 0.0, 1.0);\n    \n    if (PHASE_NOISE != 0.0)\n    {\n        /* .yy is horizontal noise, .xx looks bad, .xy is classic noise */\n        vec2 seed = xy.yy * FrameCount;\n        wt        = wt + PHASE_NOISE * (rand(seed) - 0.5);\n        sinwt     = sin(wt);\n        coswt     = cos(wt + altv);\n    }\n\n    return vec2(signal * sinwt, signal * coswt);\n}\n\n\nvoid main()\n{\n    vec2 xy      = texCoord;\n    // LJ: Flip Y\n    xy.y=1.-xy.y;\n    width_ratio  = SourceSize.x * (counts_per_scanline_reciprocal);\n    height_ratio = SourceSize.y / VISIBLELINES;\n    altv         = PIXEL_WOBBLE * mod(floor(xy.y * VISIBLELINES + 0.5), 2.0) * PI;\n    invx         = 0.25 * (counts_per_scanline_reciprocal); // equals 4 samples per Fsc period\n   \n    // lowpass U/V at baseband\n    vec2 filtered = vec2(0.0, 0.0);\n    for (int i = 0; i < FIRTAPS; i++) {\n        vec2 uv   = modem_uv(xy, float(i - FIRTAPS/2));\n        filtered += FIR_GAIN * uv * FIR[i];\n    }\n\n    float t  = xy.x * SourceSize.x;\n    float wt = t * 2. * PI / width_ratio;\n\n    float sinwt = sin(wt);\n    float coswt = cos(wt + altv);\n\n    float luma = modulated(xy, sinwt, coswt) - FIR_INVGAIN * (filtered.x * sinwt + filtered.y * coswt);\n    vec3 yuv_result = vec3(luma, filtered.x, filtered.y);\n\n    outColor = vec4(YUV_to_RGB * yuv_result, 1.0);\n}\n'},{name:"Vertex Code",value:"{{MODULES_HEAD}}\nIN vec3 vPosition;\nIN vec2 attrTexCoord;\nIN vec3 attrVertNormal;\nIN vec3 attrTangent,attrBiTangent;\n\nIN float attrVertIndex;\n\nOUT vec2 texCoord;\nOUT vec3 norm;\nUNI mat4 projMatrix;\nUNI mat4 viewMatrix;\nUNI mat4 modelMatrix;\n\nvoid main()\n{\n    texCoord=attrTexCoord;\n    norm=attrVertNormal;\n    vec4 pos=vec4(vPosition,  1.0);\n    vec3 tangent=attrTangent;\n    vec3 bitangent=attrBiTangent;\n    mat4 mMatrix=modelMatrix;\n    {{MODULE_VERTEX_POSITION}}\n    gl_Position = projMatrix * (viewMatrix*mMatrix) * pos;\n}\n"},{name:"Use As Material",value:0},{name:"FIR_INVGAIN",value:0},{name:"PIXEL_WOBBLE",value:0},{name:"LUMA_STRIPING",value:0}],portsOut:[{name:"trigger",links:[{portIn:"Render",portOut:"trigger",objIn:"7e135f9a-8846-4ef4-b7e0-f731176f014a",objOut:"fzxzsjgbg"}]},{name:"Shader",links:[{portIn:"Shader",portOut:"Shader",objIn:"7e135f9a-8846-4ef4-b7e0-f731176f014a",objOut:"fzxzsjgbg"}]},{name:"Has Errors",value:false}],objName:"Ops.Gl.Shader.CustomShader_v2"},{id:"7e135f9a-8846-4ef4-b7e0-f731176f014a",uiAttribs:{},portsIn:[{name:"Use Viewport Size",value:1},{name:"Width",value:688},{name:"Height",value:387},{name:"filter index",value:0},{name:"filter",value:"nearest"},{name:"Anisotropic index",value:0},{name:"Anisotropic",value:"0"},{name:"wrap index",value:0},{name:"wrap",value:"clamp to edge"},{name:"Floating Point",value:0},{name:"Num Textures index",value:0},{name:"Num Textures",value:"1"}],portsOut:[{name:"Next",links:[{portIn:"Render",portOut:"Next",objIn:"45da5689-5936-474d-9e7e-8df21bff2f4d",objOut:"7e135f9a-8846-4ef4-b7e0-f731176f014a"}]},{name:"Texture",links:[{portIn:"Base Texture",portOut:"Texture",objIn:"45da5689-5936-474d-9e7e-8df21bff2f4d",objOut:"7e135f9a-8846-4ef4-b7e0-f731176f014a"},{portIn:"Image",portOut:"Texture",objIn:"ba0cc518-ac6e-4d3e-bb37-1cbd47ccd125",objOut:"7e135f9a-8846-4ef4-b7e0-f731176f014a"}]}],objName:"Ops.Gl.Shader.ShaderToTexture"},{id:"ea2dc725-010a-4e33-91cb-dae80da41e06",uiAttribs:{},portsOut:[{name:"Name",value:"fb2 render2texture zqas4xdnv 0"},{name:"PixelFormat",value:"RGBA 8bit ubyte"},{name:"Width",links:[{portIn:"SourceSize X",portOut:"Width",objIn:"fzxzsjgbg",objOut:"ea2dc725-010a-4e33-91cb-dae80da41e06"},{portIn:"number1",portOut:"Width",objIn:"f81d3j0gg",objOut:"ea2dc725-010a-4e33-91cb-dae80da41e06"}]},{name:"Height",links:[{portIn:"SourceSize Y",portOut:"Height",objIn:"fzxzsjgbg",objOut:"ea2dc725-010a-4e33-91cb-dae80da41e06"},{portIn:"number1",portOut:"Height",objIn:"1lw2ctx0d",objOut:"ea2dc725-010a-4e33-91cb-dae80da41e06"}]},{name:"Ratio",value:1.778012684989429},{name:"Filter",value:"1 linear"},{name:"Wrap",value:"0 repeat"},{name:"Flipped",value:0},{name:"HDR",value:0,title:"Float"},{name:"Is Empty Default Texture",value:0},{name:"Is Default Texture",value:0},{name:"Is Cubemap",value:0},{name:"Id",value:"b6f99319-0b5d-47ce-ac74-d96c3d50de83"}],objName:"Ops.Gl.Textures.TextureInfo"},{id:"45da5689-5936-474d-9e7e-8df21bff2f4d",uiAttribs:{},portsIn:[{name:"Size index",value:2},{name:"Size",value:"Manual"},{name:"Filter index",value:1},{name:"Filter",value:"linear"},{name:"Wrap index",value:0},{name:"Wrap",value:"clamp to edge"},{name:"Anisotropic index",value:0},{name:"Anisotropic",value:"0"},{name:"Pixel Format index",value:4},{name:"Pixel Format",value:"RGBA 8bit ubyte"},{name:"Clear",value:1},{name:"R",value:0},{name:"G",value:0},{name:"B",value:0},{name:"A",value:0}],portsOut:[{name:"Next",links:[{portIn:"render",portOut:"Next",objIn:"8ae92143-f1d3-48f1-9431-34be60c202ae",objOut:"45da5689-5936-474d-9e7e-8df21bff2f4d"}]},{name:"texture_out",links:[{portIn:"Image",portOut:"texture_out",objIn:"f6d7bd77-081f-4cfa-a409-242243a13a25",objOut:"45da5689-5936-474d-9e7e-8df21bff2f4d"}]},{name:"Aspect Ratio",value:1.7763713080168777},{name:"Texture Width",value:421},{name:"Texture Height",value:237}],objName:"Ops.Gl.ImageCompose.ImageCompose_v4"},{id:"dd75fc21-5009-4275-953b-14d4ac9bca5f",uiAttribs:{},portsIn:[{name:"Speed",value:60},{name:"Play",value:1},{name:"Sync to timeline",value:0}],portsOut:[{name:"Time",links:[{portIn:"FrameCount",portOut:"Time",objIn:"fzxzsjgbg",objOut:"dd75fc21-5009-4275-953b-14d4ac9bca5f"}]}],objName:"Ops.Anim.Timer_v2"},{id:"8ae92143-f1d3-48f1-9431-34be60c202ae",uiAttribs:{},portsIn:[{name:"amount",value:3.92},{name:"direction index",value:0},{name:"direction",value:"both"},{name:"Fast",value:1}],objName:"Ops.Gl.ImageCompose.Blur"},{id:"da7da2f2-f5c4-40b7-b1dc-84a7e4090412",uiAttribs:{},portsIn:[{name:"Size index",value:0},{name:"Size",value:"Auto"},{name:"Width",value:640},{name:"Height",value:480},{name:"Filter index",value:1},{name:"Filter",value:"linear"},{name:"Wrap index",value:0},{name:"Wrap",value:"clamp to edge"},{name:"Anisotropic index",value:0},{name:"Anisotropic",value:"0"},{name:"Pixel Format index",value:4},{name:"Pixel Format",value:"RGBA 8bit ubyte"},{name:"Clear",value:1},{name:"R",value:0},{name:"G",value:0},{name:"B",value:0},{name:"A",value:0}],portsOut:[{name:"Next",links:[{portIn:"render",portOut:"Next",objIn:"ba0cc518-ac6e-4d3e-bb37-1cbd47ccd125",objOut:"da7da2f2-f5c4-40b7-b1dc-84a7e4090412"}]},{name:"texture_out",links:[{portIn:"Texture",portOut:"texture_out",objIn:"6d6e7c34-07f4-48e9-a1a2-154246b7caec",objOut:"da7da2f2-f5c4-40b7-b1dc-84a7e4090412"}]},{name:"Aspect Ratio",value:1.7755905511811023},{name:"Texture Width",value:902},{name:"Texture Height",value:508}],objName:"Ops.Gl.ImageCompose.ImageCompose_v4"},{id:"f6d7bd77-081f-4cfa-a409-242243a13a25",uiAttribs:{},portsIn:[{name:"blendMode index",value:12},{name:"blendMode",value:"screen"},{name:"Premultiplied",value:0},{name:"Alpha Mask",value:0},{name:"removeAlphaSrc",value:0},{name:"Mask Src index",value:1},{name:"Mask Src",value:"luminance"},{name:"Invert alpha channel",value:0},{name:"Aspect Ratio",value:0},{name:"Stretch Axis index",value:0},{name:"Stretch Axis",value:"X"},{name:"Position",value:0},{name:"Crop",value:0},{name:"flip x",value:0},{name:"flip y",value:0},{name:"Transform",value:0},{name:"Scale X",value:1},{name:"Scale Y",value:1},{name:"Position X",value:0},{name:"Position Y",value:0},{name:"Rotation",value:0},{name:"Clip Repeat",value:0}],objName:"Ops.Gl.ImageCompose.DrawImage_v3"},{id:"ac8213a8-2999-4809-9cad-55b371e58556",uiAttribs:{},portsIn:[{name:"Default index",value:0},{name:"Default",value:"Empty"}],portsOut:[{name:"Result",links:[{portIn:"tex",portOut:"Result",objIn:"fzxzsjgbg",objOut:"ac8213a8-2999-4809-9cad-55b371e58556"},{portIn:"Texture",portOut:"Result",objIn:"ea2dc725-010a-4e33-91cb-dae80da41e06",objOut:"ac8213a8-2999-4809-9cad-55b371e58556"},{portIn:"Base Texture",portOut:"Result",objIn:"45da5689-5936-474d-9e7e-8df21bff2f4d",objOut:"ac8213a8-2999-4809-9cad-55b371e58556"},{portIn:"Base Texture",portOut:"Result",objIn:"da7da2f2-f5c4-40b7-b1dc-84a7e4090412",objOut:"ac8213a8-2999-4809-9cad-55b371e58556"}]}],objName:"Ops.Gl.ValidTexture"},{id:"ba0cc518-ac6e-4d3e-bb37-1cbd47ccd125",uiAttribs:{},portsIn:[{name:"blendMode index",value:0},{name:"blendMode",value:"normal"},{name:"Premultiplied",value:0},{name:"Alpha Mask",value:0},{name:"removeAlphaSrc",value:0},{name:"Mask Src index",value:1},{name:"Mask Src",value:"luminance"},{name:"Invert alpha channel",value:0},{name:"Aspect Ratio",value:0},{name:"Stretch Axis index",value:0},{name:"Stretch Axis",value:"X"},{name:"Position",value:0},{name:"Crop",value:0},{name:"flip x",value:0},{name:"flip y",value:0},{name:"Transform",value:0},{name:"Scale X",value:1},{name:"Scale Y",value:1},{name:"Position X",value:0},{name:"Position Y",value:0},{name:"Rotation",value:0},{name:"Clip Repeat",value:0}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"f6d7bd77-081f-4cfa-a409-242243a13a25",objOut:"ba0cc518-ac6e-4d3e-bb37-1cbd47ccd125"}]}],objName:"Ops.Gl.ImageCompose.DrawImage_v3"},{id:"8f80aa7b-0406-45f2-9f39-2de77bcfd270",uiAttribs:{},portsIn:[{name:"Bypass2",value:0},{name:"PAL Phase Noise2",value:4.04},{name:"PAL Gain2",value:.54},{name:"PAL Amount2",value:1},{name:"Bloom Amount2",value:.7}],portsOut:[{name:"PAL Phase Noise",links:[{portIn:"PHASE_NOISE",portOut:"PAL Phase Noise",objIn:"fzxzsjgbg",objOut:"8f80aa7b-0406-45f2-9f39-2de77bcfd270"}]},{name:"PAL Gain",links:[{portIn:"FIR_GAIN",portOut:"PAL Gain",objIn:"fzxzsjgbg",objOut:"8f80aa7b-0406-45f2-9f39-2de77bcfd270"}]},{name:"PAL Amount",links:[{portIn:"amount",portOut:"PAL Amount",objIn:"ba0cc518-ac6e-4d3e-bb37-1cbd47ccd125",objOut:"8f80aa7b-0406-45f2-9f39-2de77bcfd270"}]},{name:"Bloom Amount",links:[{portIn:"amount",portOut:"Bloom Amount",objIn:"f6d7bd77-081f-4cfa-a409-242243a13a25",objOut:"8f80aa7b-0406-45f2-9f39-2de77bcfd270"}]},{name:"Settings string",value:"[0.2, 2.42, 1, 0.7],"}],objName:"Ops.Patch.P8RrHYT.PostProcDirector"},{id:"3da01564-dff2-4a8e-b68c-b2f2c5f94ded",uiAttribs:{},portsIn:[{name:"number2",value:8}],portsOut:[{name:"result",value:144.64875}],objName:"Ops.Math.Subtract"},{id:"905a80d2-7bc6-4764-8786-f8cb286d93bb",uiAttribs:{},portsOut:[{name:"trigger 0",links:[{portIn:"render",portOut:"trigger 0",objIn:"fzxzsjgbg",objOut:"905a80d2-7bc6-4764-8786-f8cb286d93bb"}]},{name:"trigger 6",links:[{portIn:"Render",portOut:"trigger 6",objIn:"da7da2f2-f5c4-40b7-b1dc-84a7e4090412",objOut:"905a80d2-7bc6-4764-8786-f8cb286d93bb"}]},{name:"trigger 15",links:[{portIn:"render",portOut:"trigger 15",objIn:"6d6e7c34-07f4-48e9-a1a2-154246b7caec",objOut:"905a80d2-7bc6-4764-8786-f8cb286d93bb"}]}],objName:"Ops.Trigger.Sequence"},{id:"cb4f1fdf-19b7-49eb-a160-4d4b5c6e2002",uiAttribs:{},portsIn:[{name:"Variable",value:"currentScene"}],portsOut:[{name:"Value",links:[{portIn:"scene",portOut:"Value",objIn:"8f80aa7b-0406-45f2-9f39-2de77bcfd270",objOut:"cb4f1fdf-19b7-49eb-a160-4d4b5c6e2002"}]}],objName:"Ops.Vars.VarGetNumber_v2"},{id:"dat4vbti6",uiAttribs:{},portsIn:[{name:"number2",value:16}],portsOut:[{name:"result",value:136.64875}],objName:"Ops.Math.Subtract"},{id:"a78006f6-95f9-4cdb-8546-d6deceec322c",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},objName:"Ops.TimeLine.TimeLineRewind"},{id:"b591b734-03ad-4b5b-968e-190fbdac13fb",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsIn:[{name:"number2",value:1}],portsOut:[{name:"result",links:[{portIn:"Boolean",portOut:"result",objIn:"cd89f2ba-aae8-4c4c-936b-e49468de5258",objOut:"b591b734-03ad-4b5b-968e-190fbdac13fb"}]}],objName:"Ops.Math.Compare.Equals"},{id:"cd89f2ba-aae8-4c4c-936b-e49468de5258",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsOut:[{name:"Result",links:[{portIn:"Value",portOut:"Result",objIn:"m7mvm9uy8",objOut:"cd89f2ba-aae8-4c4c-936b-e49468de5258"}]}],objName:"Ops.Boolean.Not"},{id:"m6sjox2xg",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsIn:[{name:"Only if Audio Suspended",value:1},{name:"Style Outer",value:"width:100px;\nheight:100px;\nleft:50%;\ntop:50%;\nborder-radius:100%;\nposition:absolute;\ncursor:pointer;\nopacity:0.7;\ntransform:translate(-50%,-50%);\nz-index:999999;\nbackground-color:#333;\nborder:5px solid #333;"},{name:"Style Inner",value:"\nborder-style:solid;\nborder-color:transparent transparent transparent #ccc;\nbox-sizing:border-box;\nwidth:50px;\nheight:50px;\nmargin-top:25px;\nmargin-left:36px;\nborder-width:25px 0px 25px 40px;\npointer-events:none;\n"},{name:"Active",value:1}],portsOut:[{name:"Next",links:[{portIn:"exe",portOut:"Next",objIn:"7cb6901a-7932-40b5-b238-3359873e0e37",objOut:"m6sjox2xg"}]},{name:"Not Clicked",links:[{portIn:"out1 Ops.Boolean.IfTrueThen_v2 else",portOut:"Not Clicked",objIn:"6yjm5kuye",objOut:"m6sjox2xg"}]},{name:"Audiocontext State",value:"running"},{name:"Clicked",value:1}],objName:"Ops.Html.Utils.PlayButton"},{id:"7cb6901a-7932-40b5-b238-3359873e0e37",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},portsOut:[{name:"then",links:[{portIn:"Render",portOut:"then",objIn:"ablytx3pz",objOut:"7cb6901a-7932-40b5-b238-3359873e0e37"}]},{name:"else",links:[{portIn:"out1 Ops.Boolean.IfTrueThen_v2 else",portOut:"else",objIn:"6yjm5kuye",objOut:"7cb6901a-7932-40b5-b238-3359873e0e37"}]}],objName:"Ops.Boolean.IfTrueThen_v2"},{id:"jpj1qg2kq",uiAttribs:{subPatch:"2fd4cff1-4d26-4ad5-9b13-ec870a859e68"},portsIn:[{name:"posX",value:1.5},{name:"posY",value:0},{name:"posZ",value:0},{name:"scale",value:1},{name:"rotX",value:0},{name:"rotY",value:0},{name:"rotZ",value:180}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"3j0tuq4u9",objOut:"jpj1qg2kq"}]}],objName:"Ops.Graphics.Transform"},{id:"mffh3xjtu",uiAttribs:{subPatch:"2fd4cff1-4d26-4ad5-9b13-ec870a859e68"},portsIn:[{name:"Enable depth testing",value:0},{name:"Depth Test Method index",value:3},{name:"Depth Test Method",value:"less or equal"},{name:"Write to depth buffer",value:0}],portsOut:[{name:"Next",links:[{portIn:"render",portOut:"Next",objIn:"38ybff26c",objOut:"mffh3xjtu"}]}],objName:"Ops.Graphics.DepthTest"},{id:"3j0tuq4u9",uiAttribs:{subPatch:"2fd4cff1-4d26-4ad5-9b13-ec870a859e68"},portsIn:[{name:"r",value:0},{name:"g",value:0},{name:"b",value:0},{name:"a",value:1}],portsOut:[{name:"trigger",links:[{portIn:"Render",portOut:"trigger",objIn:"mffh3xjtu",objOut:"3j0tuq4u9"}]}],objName:"Ops.Gl.ClearColor"},{id:"38ybff26c",uiAttribs:{subPatch:"2fd4cff1-4d26-4ad5-9b13-ec870a859e68"},portsIn:[{name:"r",value:1},{name:"g",value:.8},{name:"b",value:.19999999999999996},{name:"a",value:1},{name:"colorizeTexture",value:0},{name:"Alpha Mask Source index",value:0},{name:"Alpha Mask Source",value:"Luminance"},{name:"Opacity TexCoords Transform",value:0},{name:"Discard Transparent Pixels",value:0},{name:"diffuseRepeatX",value:1},{name:"diffuseRepeatY",value:1},{name:"Tex Offset X",value:0},{name:"Tex Offset Y",value:0},{name:"billboard",value:0}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"hx8xmz1gn",objOut:"38ybff26c"}]}],objName:"Ops.Gl.Shader.BasicMaterial_v2"},{id:"7aufark68",uiAttribs:{subPatch:"2fd4cff1-4d26-4ad5-9b13-ec870a859e68"},portsIn:[{name:"r",value:.12941176470588237},{name:"g",value:.11764705882352941},{name:"b",value:.12941176470588237},{name:"a",value:1},{name:"colorizeTexture",value:0},{name:"Alpha Mask Source index",value:0},{name:"Alpha Mask Source",value:"Luminance"},{name:"Opacity TexCoords Transform",value:0},{name:"Discard Transparent Pixels",value:0},{name:"diffuseRepeatX",value:1},{name:"diffuseRepeatY",value:1},{name:"Tex Offset X",value:0},{name:"Tex Offset Y",value:0},{name:"billboard",value:0}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"spl74v9y9",objOut:"7aufark68"}]}],objName:"Ops.Gl.Shader.BasicMaterial_v2"},{id:"hx8xmz1gn",uiAttribs:{subPatch:"2fd4cff1-4d26-4ad5-9b13-ec870a859e68"},portsIn:[{name:"width",value:3},{name:"height",value:.05},{name:"pivot x index",value:0},{name:"pivot x",value:"left"},{name:"pivot y index",value:1},{name:"pivot y",value:"center"},{name:"num columns",value:1},{name:"num rows",value:1},{name:"axis index",value:0},{name:"axis",value:"xy"},{name:"Active",value:1}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"7aufark68",objOut:"hx8xmz1gn"}]}],objName:"Ops.Graphics.Meshes.Rectangle"},{id:"uchw05q9b",uiAttribs:{subPatch:"2fd4cff1-4d26-4ad5-9b13-ec870a859e68"},portsIn:[{name:"width",value:3},{name:"height",value:.0501},{name:"pivot x index",value:0},{name:"pivot x",value:"left"},{name:"pivot y index",value:1},{name:"pivot y",value:"center"},{name:"num columns",value:1},{name:"num rows",value:1},{name:"axis index",value:0},{name:"axis",value:"xy"},{name:"Active",value:1}],objName:"Ops.Graphics.Meshes.Rectangle"},{id:"spl74v9y9",uiAttribs:{subPatch:"2fd4cff1-4d26-4ad5-9b13-ec870a859e68"},portsIn:[{name:"y",value:1},{name:"z",value:1}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"uchw05q9b",objOut:"spl74v9y9"}]}],objName:"Ops.Extension.Deprecated.ScaleXYZ"},{id:"jm6ab63p3",uiAttribs:{subPatch:"2fd4cff1-4d26-4ad5-9b13-ec870a859e68"},portsOut:[{name:"Result",links:[{portIn:"x",portOut:"Result",objIn:"spl74v9y9",objOut:"jm6ab63p3"}]}],objName:"Ops.Math.OneMinus"},{id:"ab8z1gczf",uiAttribs:{subPatch:"2fd4cff1-4d26-4ad5-9b13-ec870a859e68"},portsIn:[{name:"Gradient",value:'{"keys":[{"pos":0,"r":1,"g":0.8,"b":0.196078431372549},{"pos":0.088,"r":1,"g":0.8,"b":0.196078431372549},{"pos":0.41,"r":1,"g":0.9296874969692553,"b":0.723437488079071},{"pos":0.982,"r":1,"g":0.8,"b":0.196078431372549},{"pos":1,"r":1,"g":0.8,"b":0.196078431372549}]}'},{name:"Direction index",value:2},{name:"Direction",value:"Y"},{name:"Smoothstep",value:0},{name:"Step",value:0},{name:"Flip",value:0},{name:"sRGB",value:0},{name:"Oklab",value:0},{name:"Size",value:256},{name:"filter index",value:1},{name:"filter",value:"linear"},{name:"wrap index",value:0},{name:"wrap",value:"clamp to edge"},{name:"Dither",value:0},{name:"Gradient Array",value:0}],portsOut:[{name:"Texture",links:[{portIn:"texture",portOut:"Texture",objIn:"38ybff26c",objOut:"ab8z1gczf"}]}],objName:"Ops.Gl.GradientTexture"},{id:"vdl1k6zw5",uiAttribs:{subPatch:"2fd4cff1-4d26-4ad5-9b13-ec870a859e68"},portsOut:[{name:"create port",value:0},{name:"in0 Ops.Trigger.Sequence trigger 15",links:[{portIn:"render",portOut:"in0 Ops.Trigger.Sequence trigger 15",objIn:"jpj1qg2kq",objOut:"vdl1k6zw5"}]},{name:"in1 Total Load Progress result",links:[{portIn:"Value",portOut:"in1 Total Load Progress result",objIn:"jm6ab63p3",objOut:"vdl1k6zw5"}]}],objName:"Ops.Ui.PatchInput"},{id:"y4oy948lb",uiAttribs:{subPatch:"2fd4cff1-4d26-4ad5-9b13-ec870a859e68"},portsIn:[{name:"create port",value:0}],objName:"Ops.Ui.PatchOutput"},{id:"5bl9o5nqo",uiAttribs:{},storage:{subPatchVer:1},portsIn:[{name:"create port",value:0},{name:"dataStr",value:'{"ports":[{"name":"in0 Ops.Trigger.Sequence trigger 15","type":1},{"name":"in1 Total Load Progress result","type":0}],"portsOut":[]}'},{name:"patchId",value:"2fd4cff1-4d26-4ad5-9b13-ec870a859e68"}],portsOut:[{name:"create port out",value:0}],objName:"Ops.Ui.SubPatch"},{id:"474d9904-e3f0-4352-8997-fee337f00759",uiAttribs:{subPatch:"b1f3a112-3a3f-486a-9aa3-a0c6bfb362ae"},objName:"Ops.TimeLine.TimeLinePlay"},{id:"d4b08f4b-6fb8-4492-b48a-90dfb505012c",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsOut:[{name:"Next",links:[{portIn:"Update",portOut:"Next",objIn:"d718b2e1-75db-42df-a48c-c989cc5773cb",objOut:"d4b08f4b-6fb8-4492-b48a-90dfb505012c"}]}],objName:"Ops.Boolean.TriggerChangedTrue"},{id:"d718b2e1-75db-42df-a48c-c989cc5773cb",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsIn:[{name:"CSS Cursors index",value:0},{name:"CSS Cursors",value:"auto"},{name:"Set Parent Element",value:1}],objName:"Ops.Html.Cursor_v2"},{id:"48c7104d-99f3-442e-9f14-d99fb5fe55c2",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsOut:[{name:"Next",links:[{portIn:"Update",portOut:"Next",objIn:"992b2bbb-d9fa-459f-bdcd-f9e896f2a0cd",objOut:"48c7104d-99f3-442e-9f14-d99fb5fe55c2"}]}],objName:"Ops.Boolean.TriggerChangedFalse"},{id:"7d6a53d3-d8ae-41d1-b4b6-5eddf3c704f6",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsOut:[{name:"UI",links:[{portIn:"bool 2",portOut:"UI",objIn:"80c514d0-5c5a-4e6a-8864-2f716ff04045",objOut:"7d6a53d3-d8ae-41d1-b4b6-5eddf3c704f6"}]},{name:"Overlay Mode",value:0},{name:"Remote Viewer",value:0},{name:"Is Standalone",value:0},{name:"Canvas Mode",value:0},{name:"Patch Field Visible",value:0}],objName:"Ops.Cables.UIMode"},{id:"80c514d0-5c5a-4e6a-8864-2f716ff04045",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsIn:[{name:"bool 3",value:0},{name:"bool 4",value:0},{name:"bool 5",value:0},{name:"bool 6",value:0},{name:"bool 7",value:0},{name:"bool 8",value:0},{name:"bool 9",value:0},{name:"bool 10",value:0}],portsOut:[{name:"result",links:[{portIn:"Value",portOut:"result",objIn:"48c7104d-99f3-442e-9f14-d99fb5fe55c2",objOut:"80c514d0-5c5a-4e6a-8864-2f716ff04045"}]}],objName:"Ops.Boolean.Or"},{id:"992b2bbb-d9fa-459f-bdcd-f9e896f2a0cd",uiAttribs:{subPatch:"83f2e9c1-d9c2-43b1-9159-572dd649f463"},portsIn:[{name:"CSS Cursors index",value:17},{name:"CSS Cursors",value:"none"},{name:"Set Parent Element",value:1}],objName:"Ops.Html.Cursor_v2"},{id:"2e13ca45-b93e-452e-81c3-8eba7502d89e",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsOut:[{name:"result",links:[{portIn:"Value",portOut:"result",objIn:"fvht61sdu",objOut:"2e13ca45-b93e-452e-81c3-8eba7502d89e"}]}],objName:"Ops.Boolean.And"},{id:"7512b8eb-cab9-46a6-9866-c1e9776806cc",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Title",value:"Beat visualiser"}],objName:"Ops.Ui.Area"},{id:"792776cc-daa1-4066-b64e-296f6e070e11",uiAttribs:{subPatch:"51f7e2b3-4da4-4997-a462-97bfda5eed7a"},portsIn:[{name:"Variable",value:"beatFloat"}],portsOut:[{name:"Value",links:[{portIn:"Value",portOut:"Value",objIn:"c5vszjasc",objOut:"792776cc-daa1-4066-b64e-296f6e070e11"},{portIn:"number1",portOut:"Value",objIn:"6zllzz3o6",objOut:"792776cc-daa1-4066-b64e-296f6e070e11"},{portIn:"number1",portOut:"Value",objIn:"7m3qjzwa4",objOut:"792776cc-daa1-4066-b64e-296f6e070e11"}]}],objName:"Ops.Vars.VarGetNumber_v2"},{id:"3a913fff-b464-4489-a317-f57aa425bb82",uiAttribs:{},portsOut:[{name:"Trigger out",links:[{portIn:"render",portOut:"Trigger out",objIn:"r8iwybz9e",objOut:"3a913fff-b464-4489-a317-f57aa425bb82"}]}],objName:"Ops.Trigger.GateTrigger"},{id:"i9v4brnw0",uiAttribs:{},portsIn:[{name:"Scale Text",value:1},{name:"Scale",value:1,title:"Line Scale"},{name:"Font",value:"adrip"},{name:"align index",value:1},{name:"align",value:"center"},{name:"vertical align index",value:1},{name:"vertical align",value:"Middle"},{name:"Line Height",value:1},{name:"Letter Spacing",value:0},{name:"filter index",value:2},{name:"filter",value:"mipmap"},{name:"Anisotropic index",value:0},{name:"Anisotropic",value:0},{name:"r",value:1},{name:"g",value:1},{name:"b",value:1},{name:"a",value:1}],portsOut:[{name:"Total Lines",value:1},{name:"Width",value:3.895714196876061},{name:"Font Available",value:1}],objName:"Ops.Gl.Meshes.TextMesh_v2"},{id:"zqas4xdnv",uiAttribs:{},portsIn:[{name:"Size index",value:0},{name:"Size",value:"Canvas"},{name:"texture width",value:902},{name:"texture height",value:508},{name:"Auto Aspect",value:1},{name:"filter index",value:1},{name:"filter",value:"linear"},{name:"Wrap index",value:1},{name:"Wrap",value:"Repeat"},{name:"MSAA index",value:0},{name:"MSAA",value:"none"},{name:"Pixel Format index",value:4},{name:"Pixel Format",value:"RGBA 8bit ubyte"},{name:"Depth",value:1},{name:"Clear",value:1}],portsOut:[{name:"trigger",links:[{portIn:"exe",portOut:"trigger",objIn:"e7135b5f-5ae1-4811-8e2e-4394d59811f3",objOut:"zqas4xdnv"}]},{name:"texture",links:[{portIn:"Texture",portOut:"texture",objIn:"ac8213a8-2999-4809-9cad-55b371e58556",objOut:"zqas4xdnv"}]}],objName:"Ops.Gl.RenderToTexture_v3"},{id:"b9utaq1tt",uiAttribs:{},portsIn:[{name:"value",value:"ja\nja\nrig\nrig\n\n\n\n\non\nze\nlie\nve\nwurst\nge\ntrank\nis\nja\nja\nrig\nrig\n\n\nhij\nis\nja\nja\nrig\nrig\n\n\n\n\nja\nja\nrig\nrig\n\n\n\n\non\nze\nlie\nve\nwurst\nge\ntrank\nis\nja\nja\nrig\nrig\n\n\nhij\nis\nja\nja\nrig\nrig\n\n\n\n\nja\nja\nrig\nrig\n\n\nwurst\nis\nja\nja\nrig\nrig\n\n\no\nwat\nis\nis\nhet\nvan\ndaag\ntoch\neen\nfeest\nfeest\nfeest\nfeest!\nfeest!!\nfeest!!!\nfeest!!!!!\n!!!!!!!!!!!!!!!!!!!!!!!!\n!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"},{name:"Syntax index",value:0},{name:"Syntax",value:"text"}],portsOut:[{name:"Result",links:[{portIn:"text",portOut:"Result",objIn:"wg9l2g62q",objOut:"b9utaq1tt"}]}],objName:"Ops.String.StringEditor"},{id:"wg9l2g62q",uiAttribs:{},portsIn:[{name:"separator",value:","},{name:"Numbers",value:0},{name:"Trim",value:1},{name:"Split Lines",value:1}],portsOut:[{name:"array",links:[{portIn:"Array",portOut:"array",objIn:"2hrunbyal",objOut:"wg9l2g62q"}]},{name:"length",value:96}],objName:"Ops.Array.StringToArray_v2"},{id:"m3k6e7p01",uiAttribs:{},portsIn:[{name:"number2",value:2}],portsOut:[{name:"result",links:[{portIn:"Number",portOut:"result",objIn:"rek31r3c4",objOut:"m3k6e7p01"}]}],objName:"Ops.Math.Multiply"},{id:"2hrunbyal",uiAttribs:{},portsOut:[{name:"Result",links:[{portIn:"Text",portOut:"Result",objIn:"i9v4brnw0",objOut:"2hrunbyal"}]},{name:"Found",value:0}],objName:"Ops.Array.ArrayGetString_v2"},{id:"rek31r3c4",uiAttribs:{},portsOut:[{name:"Result",links:[{portIn:"Index",portOut:"Result",objIn:"2hrunbyal",objOut:"rek31r3c4"}]}],objName:"Ops.Math.Floor"},{id:"wh9c9j1jy",uiAttribs:{},portsIn:[{name:"file",value:"assets/6508cc5d93e3c2ac8a7fd9e1_BAHNSCHRIFT.otf",display:"file"},{name:"family",value:"Bahnschrift"},{name:"Active",value:1}],portsOut:[{name:"Loaded",value:1}],objName:"Ops.Html.FontFile_v2"},{id:"kls82saha",uiAttribs:{},portsIn:[{name:"Size index",value:0},{name:"Size",value:"Auto"},{name:"Width",value:640},{name:"Height",value:480},{name:"Filter index",value:1},{name:"Filter",value:"linear"},{name:"Wrap index",value:1},{name:"Wrap",value:"repeat"},{name:"Anisotropic index",value:0},{name:"Anisotropic",value:"0"},{name:"Pixel Format index",value:4},{name:"Pixel Format",value:"RGBA 8bit ubyte"},{name:"Clear",value:1},{name:"R",value:0},{name:"G",value:0},{name:"B",value:0},{name:"A",value:0}],portsOut:[{name:"Next",links:[{portIn:"render",portOut:"Next",objIn:"utx7ypeuu",objOut:"kls82saha"}]},{name:"texture_out",links:[{portIn:"Texture",portOut:"texture_out",objIn:"xivl77z3w",objOut:"kls82saha"}]},{name:"Aspect Ratio",value:1.7777777777777777},{name:"Texture Width",value:1920},{name:"Texture Height",value:1080}],objName:"Ops.Gl.ImageCompose.ImageCompose_v4"},{id:"utx7ypeuu",uiAttribs:{},portsIn:[{name:"Blend Mode index",value:0},{name:"Blend Mode",value:"normal"},{name:"Alpha Mask index",value:0},{name:"Alpha Mask",value:"Off"},{name:"Amount",value:.595},{name:"Width",value:26.29},{name:"Height",value:20},{name:"Aspect",value:1},{name:"Mul",value:.41},{name:"X",value:1.61},{name:"Y",value:0},{name:"Greyscale",value:1},{name:"Offset Multiply",value:1},{name:"Offset X index",value:0},{name:"Offset X",value:"None"},{name:"Offset Y index",value:0},{name:"Offset Y",value:"None"},{name:"Offset Time index",value:1},{name:"Offset Time",value:"R"}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"lnj7m0zr0",objOut:"utx7ypeuu"}]}],objName:"Ops.Gl.ImageCompose.Plasma_v2"},{id:"xivl77z3w",uiAttribs:{},portsIn:[{name:"Scale index",value:1},{name:"Scale",value:"Fit"},{name:"Flip Y",value:0},{name:"Flip X",value:0}],objName:"Ops.Gl.Meshes.FullscreenRectangle_v2"},{id:"lnj7m0zr0",uiAttribs:{},portsIn:[{name:"Blend Mode index",value:12},{name:"Blend Mode",value:"screen"},{name:"Amount",value:1},{name:"Alpha Mask index",value:0},{name:"Alpha Mask",value:"Off"},{name:"r",value:1},{name:"g",value:1},{name:"b",value:1},{name:"scale",value:2.83},{name:"scrollX",value:9},{name:"scrollY",value:0},{name:"repeat",value:1},{name:"aspect",value:1},{name:"Layer 1",value:1},{name:"Layer 2",value:1},{name:"Layer 3",value:1},{name:"Layer 4",value:1},{name:"Tileable",value:0}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"x9gwga0s2",objOut:"lnj7m0zr0"}]}],objName:"Ops.Gl.ImageCompose.Noise.FBMNoise_v2"},{id:"zcvgr0ald",uiAttribs:{},portsIn:[{name:"Speed",value:1.82},{name:"Play",value:1},{name:"Sync to timeline",value:0}],portsOut:[{name:"Time",links:[{portIn:"Time",portOut:"Time",objIn:"utx7ypeuu",objOut:"zcvgr0ald"}]}],objName:"Ops.Anim.Timer_v2"},{id:"uwf67tejn",uiAttribs:{},portsIn:[{name:"Speed",value:15.59},{name:"Play",value:1},{name:"Sync to timeline",value:0}],portsOut:[{name:"Time",links:[{portIn:"anim",portOut:"Time",objIn:"lnj7m0zr0",objOut:"uwf67tejn"}]}],objName:"Ops.Anim.Timer_v2"},{id:"hgzusj1cb",uiAttribs:{},portsOut:[{name:"Palette Array out",links:[{portIn:"Input Array",portOut:"Palette Array out",objIn:"wfrui3sfk",objOut:"hgzusj1cb"}]}],objName:"Ops.Array.PaletteLibrary"},{id:"x9gwga0s2",uiAttribs:{},portsIn:[{name:"Blend Mode index",value:0},{name:"Blend Mode",value:"normal"},{name:"Amount",value:1},{name:"Method index",value:0},{name:"Method",value:"Luminance"},{name:"Min",value:0},{name:"Max",value:1},{name:"Position",value:.5}],objName:"Ops.Gl.ImageCompose.ColorMap_v2"},{id:"wfrui3sfk",uiAttribs:{},portsIn:[{name:"Chunk Size",value:5},{name:"Circular",value:0}],portsOut:[{name:"Output Array",links:[{portIn:"Palette array",portOut:"Output Array",objIn:"lv0azebpf",objOut:"wfrui3sfk"}]},{name:"Array length",value:5}],objName:"Ops.Array.ArrayChunk"},{id:"lv0azebpf",uiAttribs:{},portsIn:[{name:"Smooth",value:1}],portsOut:[{name:"Texture",links:[{portIn:"Gradient",portOut:"Texture",objIn:"x9gwga0s2",objOut:"lv0azebpf"}]}],objName:"Ops.Gl.Textures.PaletteTexture"},{id:"o0fd97apq",uiAttribs:{},portsIn:[{name:"number2",value:5}],portsOut:[{name:"result",links:[{portIn:"Begin Index",portOut:"result",objIn:"wfrui3sfk",objOut:"o0fd97apq"}]}],objName:"Ops.Math.Multiply"},{id:"ojbfeoptb",uiAttribs:{},portsIn:[{name:"File",value:"assets/hetewurstactie.png",display:"file"},{name:"Filter index",value:2},{name:"Filter",value:"mipmap"},{name:"Wrap index",value:0},{name:"Wrap",value:"repeat"},{name:"Anisotropic index",value:0},{name:"Anisotropic",value:"0"},{name:"Data Format index",value:2},{name:"Data Format",value:"RGB"},{name:"Flip",value:0},{name:"Pre Multiplied Alpha",value:0},{name:"Active",value:1},{name:"Save Memory",value:1},{name:"Add Cachebuster",value:0}],portsOut:[{name:"Texture",links:[{portIn:"textureOpacity",portOut:"Texture",objIn:"cm3lmlika",objOut:"ojbfeoptb"}]},{name:"Width",value:1024},{name:"Height",value:1024},{name:"Aspect Ratio",links:[{portIn:"width",portOut:"Aspect Ratio",objIn:"ch16fzbms",objOut:"ojbfeoptb"}]},{name:"Loaded",value:1},{name:"Loading",value:0}],objName:"Ops.Gl.Texture_v2"},{id:"ch16fzbms",uiAttribs:{},portsIn:[{name:"render",title:"Trigger"},{name:"Render Mesh",value:1,title:"Render"},{name:"height",value:1},{name:"pivot x index",value:1},{name:"pivot x",value:"center"},{name:"pivot y index",value:1},{name:"pivot y",value:"center"},{name:"axis index",value:0},{name:"axis",value:"xy"},{name:"Flip TexCoord X",value:0},{name:"Flip TexCoord Y",value:1},{name:"num columns",value:1},{name:"num rows",value:1}],objName:"Ops.Graphics.Meshes.Rectangle_v4"},{id:"cm3lmlika",uiAttribs:{},portsIn:[{name:"r",value:.5333333333333333},{name:"g",value:.16777777574500258},{name:"b",value:.15222222010294598},{name:"a",value:.9933333333333333},{name:"colorizeTexture",value:0},{name:"Vertex Colors",value:0},{name:"Alpha Mask Source index",value:0},{name:"Alpha Mask Source",value:"Luminance"},{name:"Opacity TexCoords Transform",value:0},{name:"Discard Transparent Pixels",value:0},{name:"diffuseRepeatX",value:1},{name:"diffuseRepeatY",value:1},{name:"Tex Offset X",value:0},{name:"Tex Offset Y",value:0},{name:"Crop TexCoords",value:0},{name:"billboard",value:0}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"ch16fzbms",objOut:"cm3lmlika"}]}],objName:"Ops.Gl.Shader.BasicMaterial_v3"},{id:"8a6n39fdq",uiAttribs:{},portsIn:[{name:"posX",value:1.13},{name:"posY",value:-.28},{name:"posZ",value:0},{name:"scale",value:1.55},{name:"rotX",value:-8.44},{name:"rotY",value:0},{name:"rotZ",value:0}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"cm3lmlika",objOut:"8a6n39fdq"}]}],objName:"Ops.Graphics.Transform"},{id:"pl23173mi",uiAttribs:{},portsIn:[{name:"Font File",value:"assets/6405eae4c02b746bc7994096_Hubot-Sans-ExtraBoldSemi.otf",display:"file"}],portsOut:[{name:"Opentype Font",links:[{portIn:"Opentype Font",portOut:"Opentype Font",objIn:"3k463v8fa",objOut:"pl23173mi"}]}],objName:"Ops.Extension.OpenType.OpentypeFont"},{id:"3k463v8fa",uiAttribs:{},portsIn:[{name:"Text",value:"40"},{name:"Letter Spacing",value:0}],portsOut:[{name:"Path String",links:[{portIn:"SVG Path",portOut:"Path String",objIn:"i7ugm78ea",objOut:"3k463v8fa"}]}],objName:"Ops.Extension.OpenType.OpentypeToSvgPath"},{id:"wszdmnnjl",uiAttribs:{},portsIn:[{name:"Height",value:10},{name:"Smooth",value:1},{name:"Walls",value:1},{name:"Top",value:1},{name:"Bottom",value:1}],portsOut:[{name:"Result Geometry",links:[{portIn:"Geometry",portOut:"Result Geometry",objIn:"ns3xgljcz",objOut:"wszdmnnjl"}]}],objName:"Ops.Graphics.Geometry.GeometryExtrude"},{id:"i7ugm78ea",uiAttribs:{},portsIn:[{name:"Bezier Stepsize",value:1},{name:"Rescale",value:0}],portsOut:[{name:"Geometry",links:[{portIn:"Geometry",portOut:"Geometry",objIn:"wszdmnnjl",objOut:"i7ugm78ea"}]}],objName:"Ops.Graphics.Geometry.SvgPathToGeometry_v2"},{id:"tkzfiopwn",uiAttribs:{},portsIn:[{name:"Update All",value:1},{name:"Update Face Indices",value:0},{name:"Update Vertices",value:0},{name:"Update Texcoords",value:0},{name:"Vertex Numbers",value:1}],objName:"Ops.Gl.RenderGeometry"},{id:"2ldgdum04",uiAttribs:{},portsIn:[{name:"posX",value:6.67},{name:"posY",value:3.1},{name:"posZ",value:-15.84},{name:"scale",value:.17},{name:"rotX",value:21.91},{name:"rotZ",value:0}],portsOut:[{name:"trigger",links:[{portIn:"Render",portOut:"trigger",objIn:"omkalkhzy",objOut:"2ldgdum04"}]}],objName:"Ops.Graphics.Transform"},{id:"omkalkhzy",uiAttribs:{},portsIn:[{name:"r",value:1},{name:"g",value:1},{name:"b",value:1},{name:"Opacity",value:1},{name:"AO Intensity",value:1},{name:"Normal Map Intensity",value:1},{name:"Repeat X",value:1},{name:"Repeat Y",value:1},{name:"Offset X",value:0},{name:"Offset Y",value:0},{name:"Double Sided",value:0},{name:"Screen Space Normals",value:0},{name:"Calc normal tangents",value:1},{name:"Opacity TexCoords Transform",value:0},{name:"Discard Transparent Pixels",value:0},{name:"Alpha Mask Source index",value:0},{name:"Alpha Mask Source",value:"Luminance"}],portsOut:[{name:"Next",links:[{portIn:"render",portOut:"Next",objIn:"tkzfiopwn",objOut:"omkalkhzy"}]}],objName:"Ops.Gl.Shader.MatCapMaterial_v3"},{id:"9gn69c5cy",uiAttribs:{},portsIn:[{name:"File",value:"assets/lib_matcaps_test_steel.jpg",display:"file"},{name:"Filter index",value:2},{name:"Filter",value:"mipmap"},{name:"Wrap index",value:2},{name:"Wrap",value:"clamp to edge"},{name:"Anisotropic index",value:0},{name:"Anisotropic",value:0},{name:"Data Format index",value:3},{name:"Data Format",value:"RGBA"},{name:"Flip",value:0},{name:"Pre Multiplied Alpha",value:0},{name:"Active",value:1},{name:"Save Memory",value:1},{name:"Add Cachebuster",value:0}],portsOut:[{name:"Texture",links:[{portIn:"MatCap",portOut:"Texture",objIn:"omkalkhzy",objOut:"9gn69c5cy"}]},{name:"Width",value:512},{name:"Height",value:512},{name:"Aspect Ratio",value:1},{name:"Loaded",value:1},{name:"Loading",value:0}],objName:"Ops.Gl.Texture_v2"},{id:"ns3xgljcz",uiAttribs:{},portsIn:[{name:"X index",value:1},{name:"X",value:"Center"},{name:"Y index",value:1},{name:"Y",value:"Center"},{name:"Z index",value:1},{name:"Z",value:"Center"}],portsOut:[{name:"Result",links:[{portIn:"Geometry",portOut:"Result",objIn:"tkzfiopwn",objOut:"ns3xgljcz"}]}],objName:"Ops.Graphics.Geometry.AlignGeometry"},{id:"le5ws96uu",uiAttribs:{},portsIn:[{name:"Enable depth testing",value:1},{name:"Depth Test Method index",value:3},{name:"Depth Test Method",value:"less or equal"},{name:"Write to depth buffer",value:0}],portsOut:[{name:"Next",links:[{portIn:"Input_0",portOut:"Next",objIn:"fskt2orb0",objOut:"le5ws96uu"}]}],objName:"Ops.Graphics.DepthTest"},{id:"zq18ymucf",uiAttribs:{},portsIn:[{name:"Speed",value:62.37},{name:"Play",value:1},{name:"Sync to timeline",value:0}],portsOut:[{name:"Time",links:[{portIn:"rotY",portOut:"Time",objIn:"2ldgdum04",objOut:"zq18ymucf"}]}],objName:"Ops.Anim.Timer_v2"},{id:"zsp3j0qt1",uiAttribs:{},portsIn:[{name:"File",value:"assets/wurstanim.png",display:"file"},{name:"Filter index",value:0},{name:"Filter",value:"nearest"},{name:"Wrap index",value:0},{name:"Wrap",value:"repeat"},{name:"Anisotropic index",value:0},{name:"Anisotropic",value:"0"},{name:"Data Format index",value:3},{name:"Data Format",value:"RGBA"},{name:"Flip",value:0},{name:"Pre Multiplied Alpha",value:0},{name:"Active",value:1},{name:"Save Memory",value:1},{name:"Add Cachebuster",value:0}],portsOut:[{name:"Texture",links:[{portIn:"texture",portOut:"Texture",objIn:"mjof3dys1",objOut:"zsp3j0qt1"}]},{name:"Width",value:1024},{name:"Height",value:1024},{name:"Aspect Ratio",value:1},{name:"Loaded",value:1},{name:"Loading",value:0}],objName:"Ops.Gl.Texture_v2"},{id:"maxzm1qxo",uiAttribs:{},portsIn:[{name:"render",title:"Trigger"},{name:"Render Mesh",value:1,title:"Render"},{name:"width",value:.4},{name:"height",value:1},{name:"pivot x index",value:1},{name:"pivot x",value:"center"},{name:"pivot y index",value:1},{name:"pivot y",value:"center"},{name:"axis index",value:0},{name:"axis",value:"xy"},{name:"Flip TexCoord X",value:0},{name:"Flip TexCoord Y",value:1},{name:"num columns",value:1},{name:"num rows",value:1}],objName:"Ops.Graphics.Meshes.Rectangle_v4"},{id:"mjof3dys1",uiAttribs:{},portsIn:[{name:"r",value:1},{name:"g",value:1},{name:"b",value:1},{name:"a",value:1},{name:"colorizeTexture",value:0},{name:"Vertex Colors",value:0},{name:"Alpha Mask Source index",value:0},{name:"Alpha Mask Source",value:"Luminance"},{name:"Opacity TexCoords Transform",value:0},{name:"Discard Transparent Pixels",value:0},{name:"diffuseRepeatX",value:.4},{name:"diffuseRepeatY",value:1},{name:"Tex Offset Y",value:0},{name:"Crop TexCoords",value:0},{name:"billboard",value:0}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"maxzm1qxo",objOut:"mjof3dys1"}]}],objName:"Ops.Gl.Shader.BasicMaterial_v3"},{id:"mm7n5b7pp",uiAttribs:{},portsIn:[{name:"posX",value:-.46},{name:"posY",value:.17},{name:"posZ",value:0},{name:"scale",value:3},{name:"rotX",value:0},{name:"rotY",value:0},{name:"rotZ",value:0}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"mjof3dys1",objOut:"mm7n5b7pp"}]}],objName:"Ops.Graphics.Transform"},{id:"ynfrhkx1b",uiAttribs:{},portsIn:[{name:"File",value:"assets/wurstanim.png",display:"file"},{name:"Filter index",value:2},{name:"Filter",value:"mipmap"},{name:"Wrap index",value:0},{name:"Wrap",value:"repeat"},{name:"Anisotropic index",value:0},{name:"Anisotropic",value:"0"},{name:"Data Format index",value:3},{name:"Data Format",value:"RGBA"},{name:"Flip",value:0},{name:"Pre Multiplied Alpha",value:0},{name:"Active",value:1},{name:"Save Memory",value:1},{name:"Add Cachebuster",value:0}],portsOut:[{name:"Width",value:1024},{name:"Height",value:1024},{name:"Aspect Ratio",value:1},{name:"Loaded",value:1},{name:"Loading",value:0}],objName:"Ops.Gl.Texture_v2"},{id:"ub39dfhaz",uiAttribs:{},portsIn:[{name:"number2",value:2},{name:"pingpong",value:0}],portsOut:[{name:"result",links:[{portIn:"Number",portOut:"result",objIn:"1oahxrl6h",objOut:"ub39dfhaz"}]}],objName:"Ops.Math.Modulo"},{id:"ej1eswa09",uiAttribs:{},portsIn:[{name:"Variable",value:"beatFloat"}],portsOut:[{name:"Value",links:[{portIn:"number1",portOut:"Value",objIn:"ub39dfhaz",objOut:"ej1eswa09"}]}],objName:"Ops.Vars.VarGetNumber_v2"},{id:"1oahxrl6h",uiAttribs:{},portsOut:[{name:"Result",links:[{portIn:"number1",portOut:"Result",objIn:"ufqden3dy",objOut:"1oahxrl6h"}]}],objName:"Ops.Math.Floor"},{id:"ufqden3dy",uiAttribs:{},portsIn:[{name:"number2",value:.53}],portsOut:[{name:"result",links:[{portIn:"Tex Offset X",portOut:"result",objIn:"mjof3dys1",objOut:"ufqden3dy"}]}],objName:"Ops.Math.Multiply"},{id:"avwd3x720",uiAttribs:{},portsIn:[{name:"Value",value:150},{name:"Variable",value:"bpmConst"}],objName:"Ops.Vars.VarSetNumber_v2"},{id:"rdyyxbqhv",uiAttribs:{},portsOut:[{name:"scene",links:[{portIn:"Value",portOut:"scene",objIn:"24933c75-84e5-44e6-85e7-960d9d74b388",objOut:"rdyyxbqhv"},{portIn:"Number",portOut:"scene",objIn:"d0397aad-d1da-4296-aa59-0e0472293fe8",objOut:"rdyyxbqhv"},{portIn:"current",portOut:"scene",objIn:"e7135b5f-5ae1-4811-8e2e-4394d59811f3",objOut:"rdyyxbqhv"}]},{name:"scene beat",links:[{portIn:"number1",portOut:"scene beat",objIn:"3da01564-dff2-4a8e-b68c-b2f2c5f94ded",objOut:"rdyyxbqhv"},{portIn:"number1",portOut:"scene beat",objIn:"dat4vbti6",objOut:"rdyyxbqhv"},{portIn:"number1",portOut:"scene beat",objIn:"m3k6e7p01",objOut:"rdyyxbqhv"}]}],objName:"Ops.Patch.P8RrHYT.SceneSwitcher"},{id:"6f7y5e24h",uiAttribs:{},portsIn:[{name:"File",value:"assets/intro.png",display:"file"},{name:"Filter index",value:2},{name:"Filter",value:"mipmap"},{name:"Wrap index",value:0},{name:"Wrap",value:"repeat"},{name:"Anisotropic index",value:0},{name:"Anisotropic",value:"0"},{name:"Data Format index",value:2},{name:"Data Format",value:"RGB"},{name:"Flip",value:0},{name:"Pre Multiplied Alpha",value:0},{name:"Active",value:1},{name:"Save Memory",value:1},{name:"Add Cachebuster",value:0}],portsOut:[{name:"Texture",links:[{portIn:"textureOpacity",portOut:"Texture",objIn:"d2funex7v",objOut:"6f7y5e24h"}]},{name:"Width",value:512},{name:"Height",value:128},{name:"Aspect Ratio",links:[{portIn:"width",portOut:"Aspect Ratio",objIn:"mmaur99j5",objOut:"6f7y5e24h"}]},{name:"Loaded",value:1},{name:"Loading",value:0}],objName:"Ops.Gl.Texture_v2"},{id:"mmaur99j5",uiAttribs:{},portsIn:[{name:"render",title:"Trigger"},{name:"Render Mesh",value:1,title:"Render"},{name:"height",value:1},{name:"pivot x index",value:1},{name:"pivot x",value:"center"},{name:"pivot y index",value:1},{name:"pivot y",value:"center"},{name:"axis index",value:0},{name:"axis",value:"xy"},{name:"Flip TexCoord X",value:0},{name:"Flip TexCoord Y",value:1},{name:"num columns",value:1},{name:"num rows",value:1}],objName:"Ops.Graphics.Meshes.Rectangle_v4"},{id:"d2funex7v",uiAttribs:{},portsIn:[{name:"r",value:1},{name:"g",value:1},{name:"b",value:1},{name:"a",value:1},{name:"colorizeTexture",value:0},{name:"Vertex Colors",value:0},{name:"Alpha Mask Source index",value:0},{name:"Alpha Mask Source",value:"Luminance"},{name:"Opacity TexCoords Transform",value:0},{name:"Discard Transparent Pixels",value:0},{name:"diffuseRepeatX",value:1},{name:"diffuseRepeatY",value:1},{name:"Tex Offset X",value:0},{name:"Tex Offset Y",value:0},{name:"Crop TexCoords",value:0},{name:"billboard",value:0}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"mmaur99j5",objOut:"d2funex7v"}]}],objName:"Ops.Gl.Shader.BasicMaterial_v3"},{id:"3ara7lixk",uiAttribs:{},portsIn:[{name:"posX",value:0},{name:"posY",value:0},{name:"posZ",value:0},{name:"rotX",value:0},{name:"rotY",value:0}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"d2funex7v",objOut:"3ara7lixk"}]}],objName:"Ops.Graphics.Transform"},{id:"shhrtutmo",uiAttribs:{},portsIn:[{name:"Variable",value:"beatFloat"}],portsOut:[{name:"Value",links:[{portIn:"value",portOut:"Value",objIn:"n25qbkqur",objOut:"shhrtutmo"},{portIn:"value",portOut:"Value",objIn:"yck4tzfxx",objOut:"shhrtutmo"}]}],objName:"Ops.Vars.VarGetNumber_v2"},{id:"ymygwbov5",uiAttribs:{},portsIn:[{name:"number2",value:3.76},{name:"pingpong",value:0}],portsOut:[{name:"result",links:[{portIn:"Base",portOut:"result",objIn:"9turnddpo",objOut:"ymygwbov5"}]}],objName:"Ops.Math.Modulo"},{id:"n25qbkqur",uiAttribs:{},portsIn:[{name:"Maximum",value:0}],portsOut:[{name:"result",links:[{portIn:"number1",portOut:"result",objIn:"ymygwbov5",objOut:"n25qbkqur"}]}],objName:"Ops.Math.Max"},{id:"e7t1xt2jc",uiAttribs:{},portsIn:[{name:"number2",value:.95}],portsOut:[{name:"result",links:[{portIn:"scale",portOut:"result",objIn:"3ara7lixk",objOut:"e7t1xt2jc"}]}],objName:"Ops.Math.Sum"},{id:"9turnddpo",uiAttribs:{},portsIn:[{name:"Exponent",value:2}],portsOut:[{name:"Result",links:[{portIn:"number1",portOut:"Result",objIn:"e7t1xt2jc",objOut:"9turnddpo"}]}],objName:"Ops.Math.Pow"},{id:"yck4tzfxx",uiAttribs:{},portsIn:[{name:"old min",value:30},{name:"old max",value:32},{name:"new min",value:0},{name:"new max",value:360},{name:"Easing index",value:0},{name:"Easing",value:"Linear"},{name:"Clamp",value:1}],portsOut:[{name:"result",links:[{portIn:"rotZ",portOut:"result",objIn:"3ara7lixk",objOut:"yck4tzfxx"}]}],objName:"Ops.Math.MapRange"},{id:"hlngj83j3",uiAttribs:{},portsIn:[{name:"Variable",value:"beatFloat"}],portsOut:[{name:"Value",links:[{portIn:"A",portOut:"Value",objIn:"i0bcm1md7",objOut:"hlngj83j3"},{portIn:"A",portOut:"Value",objIn:"3hoo4cn0d",objOut:"hlngj83j3"},{portIn:"A",portOut:"Value",objIn:"spr4dx46p",objOut:"hlngj83j3"},{portIn:"A",portOut:"Value",objIn:"da67bgpf6",objOut:"hlngj83j3"}]}],objName:"Ops.Vars.VarGetNumber_v2"},{id:"tps0eu9yo",uiAttribs:{},portsIn:[{name:"Value 0",value:263},{name:"Value 1",value:263},{name:"Value 2",value:302},{name:"Value 3",value:28},{name:"Value 4",value:323.8},{name:"Value 5",value:263},{name:"Value 6",value:263},{name:"Value 7",value:0},{name:"Value 8",value:0},{name:"Value 9",value:0},{name:"Value 10",value:0},{name:"Value 11",value:0},{name:"Value 12",value:0},{name:"Value 13",value:0},{name:"Value 14",value:0},{name:"Value 15",value:0}],portsOut:[{name:"Result",links:[{portIn:"Number",portOut:"Result",objIn:"5r6bcf556",objOut:"tps0eu9yo"}]}],objName:"Ops.Number.SwitchNumber"},{id:"4rdqvr44r",uiAttribs:{},portsIn:[{name:"Variable",value:"currentScene"}],portsOut:[{name:"Value",links:[{portIn:"Index",portOut:"Value",objIn:"tps0eu9yo",objOut:"4rdqvr44r"}]}],objName:"Ops.Vars.VarGetNumber_v2"},{id:"5r6bcf556",uiAttribs:{},portsOut:[{name:"Result",links:[{portIn:"number1",portOut:"Result",objIn:"o0fd97apq",objOut:"5r6bcf556"}]}],objName:"Ops.Math.Floor"},{id:"8l238z8l0",uiAttribs:{},portsOut:[{name:"Output",multiPortNum:2},{name:"Output_0",links:[{portIn:"exe",portOut:"Output_0",objIn:"qzfwmoo4i",objOut:"8l238z8l0"}]},{name:"Output_1",title:"add port",links:[{portIn:"render",portOut:"Output_1",objIn:"m0ij3lpfl",objOut:"8l238z8l0"}]}],objName:"Ops.Trigger.SequenceMultiPort"},{id:"squ7m4tnn",uiAttribs:{},portsOut:[{name:"Output",multiPortNum:3},{name:"Output_0",links:[{portIn:"exe 0",portOut:"Output_0",objIn:"qzfwmoo4i",objOut:"squ7m4tnn"}]},{name:"Output_1",links:[{portIn:"render",portOut:"Output_1",objIn:"2ldgdum04",objOut:"squ7m4tnn"}]},{name:"Output_2",title:"add port",links:[{portIn:"render",portOut:"Output_2",objIn:"o1g38t951",objOut:"squ7m4tnn"}]}],objName:"Ops.Trigger.SequenceMultiPort"},{id:"2zebln2pu",uiAttribs:{},portsOut:[{name:"Output",multiPortNum:3},{name:"Output_0",links:[{portIn:"exe 2",portOut:"Output_0",objIn:"qzfwmoo4i",objOut:"2zebln2pu"}]},{name:"Output_1",links:[{portIn:"render",portOut:"Output_1",objIn:"1uzzmk3kk",objOut:"2zebln2pu"}]},{name:"Output_2",title:"add port",links:[{portIn:"render",portOut:"Output_2",objIn:"o1g38t951",objOut:"2zebln2pu"}]}],objName:"Ops.Trigger.SequenceMultiPort"},{id:"xg3kpufdb",uiAttribs:{},portsOut:[{name:"Output",multiPortNum:2},{name:"Output_0",links:[{portIn:"exe 1",portOut:"Output_0",objIn:"qzfwmoo4i",objOut:"xg3kpufdb"}]},{name:"Output_1",title:"add port",links:[{portIn:"Render",portOut:"Output_1",objIn:"le5ws96uu",objOut:"xg3kpufdb"}]}],objName:"Ops.Trigger.SequenceMultiPort"},{id:"o1g38t951",uiAttribs:{},portsIn:[{name:"posX",value:0},{name:"posY",value:-.57},{name:"posZ",value:0},{name:"scale",value:1},{name:"rotX",value:0},{name:"rotY",value:0},{name:"rotZ",value:0}],portsOut:[{name:"trigger",links:[{portIn:"Render",portOut:"trigger",objIn:"i9v4brnw0",objOut:"o1g38t951"}]}],objName:"Ops.Graphics.Transform"},{id:"m0ij3lpfl",uiAttribs:{},portsIn:[{name:"posX",value:0},{name:"posY",value:0},{name:"scale",value:.24}],portsOut:[{name:"trigger",links:[{portIn:"Render",portOut:"trigger",objIn:"omkalkhzy",objOut:"m0ij3lpfl"}]}],objName:"Ops.Graphics.Transform"},{id:"i0bcm1md7",uiAttribs:{},portsIn:[{name:"B",value:1},{name:"C",value:2},{name:"D",value:3},{name:"Expression",value:"-15-6*Math.pow(Math.abs(Math.cos(a*Math.PI)),3)"}],portsOut:[{name:"Result",links:[{portIn:"posZ",portOut:"Result",objIn:"m0ij3lpfl",objOut:"i0bcm1md7"}]},{name:"Expression Valid",value:true}],objName:"Ops.Math.MathExpression"},{id:"3hoo4cn0d",uiAttribs:{},portsIn:[{name:"B",value:1},{name:"C",value:2},{name:"D",value:3},{name:"Expression",value:"20*Math.sin(a*Math.PI)"}],portsOut:[{name:"Result",links:[{portIn:"rotY",portOut:"Result",objIn:"m0ij3lpfl",objOut:"3hoo4cn0d"}]},{name:"Expression Valid",value:true}],objName:"Ops.Math.MathExpression"},{id:"spr4dx46p",uiAttribs:{},portsIn:[{name:"B",value:1},{name:"C",value:2},{name:"D",value:3},{name:"Expression",value:"10*Math.sin(a)"}],portsOut:[{name:"Result",links:[{portIn:"rotX",portOut:"Result",objIn:"m0ij3lpfl",objOut:"spr4dx46p"}]},{name:"Expression Valid",value:true}],objName:"Ops.Math.MathExpression"},{id:"da67bgpf6",uiAttribs:{},portsIn:[{name:"B",value:1},{name:"C",value:2},{name:"D",value:3},{name:"Expression",value:"20*Math.sin(a*1.3)"}],portsOut:[{name:"Result",links:[{portIn:"rotZ",portOut:"Result",objIn:"m0ij3lpfl",objOut:"da67bgpf6"}]},{name:"Expression Valid",value:true}],objName:"Ops.Math.MathExpression"},{id:"1uzzmk3kk",uiAttribs:{},portsIn:[{name:"posX",value:-6.72},{name:"posY",value:3.1},{name:"posZ",value:-15.84},{name:"scale",value:.17},{name:"rotX",value:31.26},{name:"rotZ",value:0}],portsOut:[{name:"trigger",links:[{portIn:"Render",portOut:"trigger",objIn:"omkalkhzy",objOut:"1uzzmk3kk"}]}],objName:"Ops.Graphics.Transform"},{id:"f1xxtl44d",uiAttribs:{},portsIn:[{name:"Speed",value:62.37},{name:"Play",value:1},{name:"Sync to timeline",value:0}],portsOut:[{name:"Time",links:[{portIn:"rotY",portOut:"Time",objIn:"1uzzmk3kk",objOut:"f1xxtl44d"}]}],objName:"Ops.Anim.Timer_v2"},{id:"2letxyakd",uiAttribs:{},portsIn:[{name:"segments",value:12.07},{name:"radius",value:.09},{name:"Shape index",value:2},{name:"Shape",value:"Gear"},{name:"Length",value:37.44},{name:"Peak Z Pos",value:0},{name:"percent",value:1},{name:"Fill",value:0},{name:"Render Mesh",value:1}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"k47oy2qbh",objOut:"2letxyakd"}]}],objName:"Ops.Graphics.Meshes.Star_v2"},{id:"0z721lsdy",uiAttribs:{},portsIn:[{name:"r",value:1},{name:"g",value:.7933541655540466},{name:"b",value:.2619791626930237},{name:"a",value:1},{name:"colorizeTexture",value:0},{name:"Vertex Colors",value:0},{name:"Alpha Mask Source index",value:0},{name:"Alpha Mask Source",value:"Luminance"},{name:"Opacity TexCoords Transform",value:0},{name:"Discard Transparent Pixels",value:0},{name:"diffuseRepeatX",value:1},{name:"diffuseRepeatY",value:1},{name:"Tex Offset X",value:0},{name:"Tex Offset Y",value:0},{name:"Crop TexCoords",value:0},{name:"billboard",value:0}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"2letxyakd",objOut:"0z721lsdy"}]}],objName:"Ops.Gl.Shader.BasicMaterial_v3"},{id:"vnjr9tcq5",uiAttribs:{},portsIn:[{name:"posX",value:-.88},{name:"posY",value:.29},{name:"posZ",value:0},{name:"scale",value:1},{name:"rotX",value:0},{name:"rotY",value:0}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"0z721lsdy",objOut:"vnjr9tcq5"}]}],objName:"Ops.Graphics.Transform"},{id:"d9erzg87v",uiAttribs:{},portsIn:[{name:"Speed",value:22.99},{name:"Play",value:1},{name:"Sync to timeline",value:0}],portsOut:[{name:"Time",links:[{portIn:"rotZ",portOut:"Time",objIn:"vnjr9tcq5",objOut:"d9erzg87v"}]}],objName:"Ops.Anim.Timer_v2"},{id:"fskt2orb0",uiAttribs:{},portsOut:[{name:"Output",multiPortNum:4},{name:"Output_0",links:[{portIn:"render",portOut:"Output_0",objIn:"vnjr9tcq5",objOut:"fskt2orb0"}]},{name:"Output_1",links:[{portIn:"render",portOut:"Output_1",objIn:"2lay6f4st",objOut:"fskt2orb0"}]},{name:"Output_2",links:[{portIn:"render",portOut:"Output_2",objIn:"8a6n39fdq",objOut:"fskt2orb0"}]},{name:"Output_3",title:"add port",links:[{portIn:"render",portOut:"Output_3",objIn:"mm7n5b7pp",objOut:"fskt2orb0"}]}],objName:"Ops.Trigger.SequenceMultiPort"},{id:"qoa1rgtnh",uiAttribs:{},portsIn:[{name:"radius",value:.5},{name:"innerRadius",value:0},{name:"segments",value:174},{name:"percent",value:.311},{name:"steps",value:0},{name:"invertSteps",value:0},{name:"mapping index",value:0},{name:"mapping",value:"flat"},{name:"Spline",value:0},{name:"Draw",value:1,title:"Render mesh"}],objName:"Ops.Graphics.Meshes.Circle_v3"},{id:"p0ur6tqbx",uiAttribs:{},portsIn:[{name:"r",value:.9411764705882353},{name:"g",value:.7137254901960784},{name:"b",value:.3764705882352941},{name:"a",value:1},{name:"colorizeTexture",value:0},{name:"Vertex Colors",value:0},{name:"Alpha Mask Source index",value:0},{name:"Alpha Mask Source",value:"Luminance"},{name:"Opacity TexCoords Transform",value:0},{name:"Discard Transparent Pixels",value:0},{name:"diffuseRepeatX",value:1},{name:"diffuseRepeatY",value:1},{name:"Tex Offset X",value:0},{name:"Tex Offset Y",value:0},{name:"Crop TexCoords",value:0},{name:"billboard",value:0}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"qoa1rgtnh",objOut:"p0ur6tqbx"}]}],objName:"Ops.Gl.Shader.BasicMaterial_v3"},{id:"2lay6f4st",uiAttribs:{},portsIn:[{name:"posX",value:-.7},{name:"posY",value:-7.03},{name:"posZ",value:0},{name:"scale",value:12.19},{name:"rotX",value:0},{name:"rotY",value:0},{name:"rotZ",value:0}],portsOut:[{name:"trigger",links:[{portIn:"render",portOut:"trigger",objIn:"p0ur6tqbx",objOut:"2lay6f4st"}]}],objName:"Ops.Graphics.Transform"},{id:"rzofbyhdu",uiAttribs:{},portsIn:[{name:"data",value:""},{name:"glb File",value:"assets/6303dbda975b8e86b85d7697_ducky.glb",display:"file"},{name:"Draw",value:1},{name:"Camera index",value:0},{name:"Camera",value:"None"},{name:"Animation",value:""},{name:"Center index",value:1},{name:"Center",value:"XYZ"},{name:"Rescale",value:1},{name:"Rescale Size",value:2.5},{name:"Time",value:0},{name:"Sync to timeline",value:0},{name:"Loop",value:1},{name:"Normals Format index",value:0},{name:"Normals Format",value:"XYZ"},{name:"Vertices Format index",value:0},{name:"Vertices Format",value:"XYZ"},{name:"Calc Normals",value:0},{name:"Hide Nodes",value:0},{name:"Use Material Properties",value:0},{name:"Active",value:1}],portsOut:[{name:"Generator",value:"Khronos glTF Blender I/O v3.2.43"},{name:"GLTF Version",value:2},{name:"Anim Length",value:0},{name:"Anim Time",value:0},{name:"Loading",value:false}],objName:"Ops.Gl.GLTF.GltfScene_v3"},{id:"za36f2f5j",uiAttribs:{},portsIn:[{name:"posX",value:0},{name:"posY",value:0},{name:"posZ",value:0},{name:"scale",value:.11},{name:"rotX",value:0},{name:"rotZ",value:0}],portsOut:[{name:"trigger",links:[{portIn:"Render",portOut:"trigger",objIn:"rzofbyhdu",objOut:"za36f2f5j"}]}],objName:"Ops.Graphics.Transform"},{id:"c848f54oa",uiAttribs:{},portsIn:[{name:"Speed",value:200},{name:"Play",value:1},{name:"Sync to timeline",value:0}],portsOut:[{name:"Time",links:[{portIn:"rotY",portOut:"Time",objIn:"za36f2f5j",objOut:"c848f54oa"}]}],objName:"Ops.Anim.Timer_v2"},{id:"cp19h46pj",uiAttribs:{},portsOut:[{name:"Output",multiPortNum:4},{name:"Output_0",links:[{portIn:"Render",portOut:"Output_0",objIn:"fvf9wcln4",objOut:"cp19h46pj"}]},{name:"Output_1",title:"add port",links:[{portIn:"render",portOut:"Output_1",objIn:"7bxo7s8n8",objOut:"cp19h46pj"}]},{name:"Output_2",links:[{portIn:"render",portOut:"Output_2",objIn:"f36nr8t8r",objOut:"cp19h46pj"}]},{name:"Output_3",title:"add port",links:[{portIn:"render",portOut:"Output_3",objIn:"t45fuixyt",objOut:"cp19h46pj"}]}],objName:"Ops.Trigger.SequenceMultiPort"},{id:"fvf9wcln4",uiAttribs:{},portsIn:[{name:"r",value:1},{name:"g",value:1},{name:"b",value:1},{name:"Opacity",value:1},{name:"AO Intensity",value:1},{name:"Normal Map Intensity",value:1},{name:"Repeat X",value:1},{name:"Repeat Y",value:1},{name:"Offset X",value:0},{name:"Offset Y",value:0},{name:"Double Sided",value:0},{name:"Screen Space Normals",value:0},{name:"Calc normal tangents",value:1},{name:"Opacity TexCoords Transform",value:0},{name:"Discard Transparent Pixels",value:0},{name:"Alpha Mask Source index",value:0},{name:"Alpha Mask Source",value:"Luminance"}],portsOut:[{name:"Next",links:[{portIn:"render",portOut:"Next",objIn:"za36f2f5j",objOut:"fvf9wcln4"}]}],objName:"Ops.Gl.Shader.MatCapMaterial_v3"},{id:"pnwaduyd9",uiAttribs:{},portsIn:[{name:"File",value:"assets/lib_matcaps_droplet_01.png",display:"file"},{name:"Filter index",value:2},{name:"Filter",value:"mipmap"},{name:"Wrap index",value:0},{name:"Wrap",value:"repeat"},{name:"Anisotropic index",value:0},{name:"Anisotropic",value:"0"},{name:"Data Format index",value:3},{name:"Data Format",value:"RGBA"},{name:"Flip",value:0},{name:"Pre Multiplied Alpha",value:0},{name:"Active",value:1},{name:"Save Memory",value:1},{name:"Add Cachebuster",value:0}],portsOut:[{name:"Texture",links:[{portIn:"MatCap",portOut:"Texture",objIn:"fvf9wcln4",objOut:"pnwaduyd9"}]},{name:"Width",value:256},{name:"Height",value:256},{name:"Aspect Ratio",value:1},{name:"Loaded",value:1},{name:"Loading",value:0}],objName:"Ops.Gl.Texture_v2"},{id:"7bxo7s8n8",uiAttribs:{},portsIn:[{name:"posX",value:0},{name:"posY",value:0},{name:"posZ",value:0},{name:"scale",value:1},{name:"rotX",value:0},{name:"rotY",value:0},{name:"rotZ",value:0}],portsOut:[{name:"trigger",links:[{portIn:"Render",portOut:"trigger",objIn:"lss4eljzq",objOut:"7bxo7s8n8"}]}],objName:"Ops.Graphics.Transform"},{id:"lss4eljzq",uiAttribs:{},portsIn:[{name:"Text",value:"ENTE"},{name:"Scale Text",value:1},{name:"Scale",value:1,title:"Line Scale"},{name:"Font",value:"serif"},{name:"align index",value:1},{name:"align",value:"center"},{name:"vertical align index",value:1},{name:"vertical align",value:"Middle"},{name:"Line Height",value:1},{name:"Letter Spacing",value:0},{name:"filter index",value:2},{name:"filter",value:"mipmap"},{name:"Anisotropic index",value:0},{name:"Anisotropic",value:0},{name:"r",value:1},{name:"g",value:1},{name:"b",value:1},{name:"a",value:1}],portsOut:[{name:"Total Lines",value:1},{name:"Width",value:.912388392857143},{name:"Font Available",value:1}],objName:"Ops.Gl.Meshes.TextMesh_v2"},{id:"f36nr8t8r",uiAttribs:{},portsIn:[{name:"posX",value:0},{name:"posY",value:-.45},{name:"posZ",value:0},{name:"scale",value:.41},{name:"rotX",value:0},{name:"rotY",value:0},{name:"rotZ",value:0}],portsOut:[{name:"trigger",links:[{portIn:"Render",portOut:"trigger",objIn:"gir2mdab8",objOut:"f36nr8t8r"}]}],objName:"Ops.Graphics.Transform"},{id:"gir2mdab8",uiAttribs:{},portsIn:[{name:"Text",value:"gefeliciteerd :)"},{name:"Scale Text",value:1},{name:"Scale",value:1,title:"Line Scale"},{name:"Font",value:"Bahnschrift"},{name:"align index",value:1},{name:"align",value:"center"},{name:"vertical align index",value:1},{name:"vertical align",value:"Middle"},{name:"Line Height",value:1},{name:"Letter Spacing",value:0},{name:"filter index",value:2},{name:"filter",value:"mipmap"},{name:"Anisotropic index",value:0},{name:"Anisotropic",value:0},{name:"r",value:1},{name:"g",value:1},{name:"b",value:1},{name:"a",value:1}],portsOut:[{name:"Total Lines",value:1},{name:"Width",value:2.256731305803571},{name:"Font Available",value:1}],objName:"Ops.Gl.Meshes.TextMesh_v2"},{id:"t45fuixyt",uiAttribs:{},portsIn:[{name:"posX",value:0},{name:"posY",value:.45},{name:"posZ",value:0},{name:"scale",value:.32},{name:"rotX",value:0},{name:"rotY",value:0},{name:"rotZ",value:0}],portsOut:[{name:"trigger",links:[{portIn:"Render",portOut:"trigger",objIn:"dn6bbciez",objOut:"t45fuixyt"}]}],objName:"Ops.Graphics.Transform"},{id:"dn6bbciez",uiAttribs:{},portsIn:[{name:"Text",value:"dojoe     saga     ook"},{name:"Scale Text",value:1},{name:"Scale",value:1,title:"Line Scale"},{name:"Font",value:"Bahnschrift"},{name:"align index",value:1},{name:"align",value:"center"},{name:"vertical align index",value:1},{name:"vertical align",value:"Middle"},{name:"Line Height",value:1},{name:"Letter Spacing",value:0},{name:"filter index",value:2},{name:"filter",value:"mipmap"},{name:"Anisotropic index",value:0},{name:"Anisotropic",value:0},{name:"r",value:1},{name:"g",value:1},{name:"b",value:1},{name:"a",value:1}],portsOut:[{name:"Total Lines",value:1},{name:"Width",value:2.8152901785714284},{name:"Font Available",value:1}],objName:"Ops.Gl.Meshes.TextMesh_v2"},{id:"qzfwmoo4i",uiAttribs:{},portsOut:[{name:"trigger 0",links:[{portIn:"Render",portOut:"trigger 0",objIn:"kls82saha",objOut:"qzfwmoo4i"}]},{name:"trigger 1",links:[{portIn:"render",portOut:"trigger 1",objIn:"xivl77z3w",objOut:"qzfwmoo4i"}]}],objName:"Ops.Trigger.Sequence"},{id:"f81d3j0gg",uiAttribs:{},portsIn:[{name:"number2",value:2}],portsOut:[{name:"result",links:[{portIn:"Width",portOut:"result",objIn:"45da5689-5936-474d-9e7e-8df21bff2f4d",objOut:"f81d3j0gg"}]}],objName:"Ops.Math.Divide"},{id:"1lw2ctx0d",uiAttribs:{},portsIn:[{name:"number2",value:2}],portsOut:[{name:"result",links:[{portIn:"Height",portOut:"result",objIn:"45da5689-5936-474d-9e7e-8df21bff2f4d",objOut:"1lw2ctx0d"}]}],objName:"Ops.Math.Divide"},{id:"k47oy2qbh",uiAttribs:{},portsIn:[{name:"radius",value:.25},{name:"innerRadius",value:0},{name:"segments",value:40},{name:"percent",value:1},{name:"steps",value:0},{name:"invertSteps",value:0},{name:"mapping index",value:0},{name:"mapping",value:"flat"},{name:"Spline",value:0},{name:"Draw",value:1,title:"Render mesh"}],objName:"Ops.Graphics.Meshes.Circle_v3"}],export:{time:"2025-08-16 14:06",service:"exe",exportNumber:5}};if(!CABLES.exportedPatch){CABLES.exportedPatch=CABLES.exportedPatches["8RrHYT"]}"use strict";var CABLES=CABLES||{};CABLES.OPS=CABLES.OPS||{};var Ops=Ops||{};Ops.Gl=Ops.Gl||{};Ops.Ui=Ops.Ui||{};Ops.Anim=Ops.Anim||{};Ops.Html=Ops.Html||{};Ops.Math=Ops.Math||{};Ops.Vars=Ops.Vars||{};Ops.Array=Ops.Array||{};Ops.Patch=Ops.Patch||{};Ops.Cables=Ops.Cables||{};Ops.Number=Ops.Number||{};Ops.String=Ops.String||{};Ops.Boolean=Ops.Boolean||{};Ops.Devices=Ops.Devices||{};Ops.Gl.GLTF=Ops.Gl.GLTF||{};Ops.Sidebar=Ops.Sidebar||{};Ops.Trigger=Ops.Trigger||{};Ops.Graphics=Ops.Graphics||{};Ops.TimeLine=Ops.TimeLine||{};Ops.WebAudio=Ops.WebAudio||{};Ops.Extension=Ops.Extension||{};Ops.Gl.Meshes=Ops.Gl.Meshes||{};Ops.Gl.Shader=Ops.Gl.Shader||{};Ops.Html.Utils=Ops.Html.Utils||{};Ops.Gl.Textures=Ops.Gl.Textures||{};Ops.Math.Compare=Ops.Math.Compare||{};Ops.Devices.Mouse=Ops.Devices.Mouse||{};Ops.Patch.P8RrHYT=Ops.Patch.P8RrHYT||{};Ops.Gl.ImageCompose=Ops.Gl.ImageCompose||{};Ops.Graphics.Meshes=Ops.Graphics.Meshes||{};Ops.Graphics.Geometry=Ops.Graphics.Geometry||{};Ops.Extension.OpenType=Ops.Extension.OpenType||{};Ops.Extension.Deprecated=Ops.Extension.Deprecated||{};Ops.Gl.ImageCompose.Noise=Ops.Gl.ImageCompose.Noise||{};Ops.Ui.SubPatch=class extends CABLES.Op{constructor(){super(...arguments);const u=this;const e=u.attachments={};u.dyn=u.addInPort(new CABLES.Port(u,"create port",CABLES.OP_PORT_TYPE_DYNAMIC));u.dynOut=u.addOutPort(new CABLES.Port(u,"create port out",CABLES.OP_PORT_TYPE_DYNAMIC));const t=u.addInPort(new CABLES.Port(u,"dataStr",CABLES.OP_PORT_TYPE_VALUE,{display:"readonly"}));u.patchId=u.addInPort(new CABLES.Port(u,"patchId",CABLES.OP_PORT_TYPE_VALUE,{display:"readonly"}));t.setUiAttribs({hideParam:true});u.patchId.setUiAttribs({hidePort:true});let c={ports:[],portsOut:[]};let n=CABLES.generateUUID();u.patchId.set(n);p();d();let h=false;u.saveData=s;u.init=()=>{u.setStorage({subPatchVer:1})};u.patchId.onChange=function(){if(!u.patch.isEditorMode())return;const t=u.patch.getSubPatchOps(n);if(t.length===2){if(u.patch.isEditorMode())CABLES.UI.undo.pause();for(let e=0;e<t.length;e++){u.patch.deleteOp(t[e].id)}if(u.patch.isEditorMode())CABLES.UI.undo.resume()}};u.onLoaded=function(){};u.onLoadedValueSet=function(){c=JSON.parse(t.get());if(!c){c={ports:[],portsOut:[]}}a()};function r(){}t.onChange=function(){if(h)return;if(!t.get())return;try{r()}catch(e){u.logError("cannot load subpatch data...");u.logError(e)}};function s(){try{t.set(JSON.stringify(c))}catch(e){u.log(e)}}u.addPortListener=f;function f(n,e){if(!n.hasSubpatchLstener){n.hasSubpatchLstener=true;n.addEventListener("onUiAttrChange",function(t){if(t.title){let e=0;for(e=0;e<c.portsOut.length;e++)if(c.portsOut[e].name==n.name)c.portsOut[e].title=t.title;for(e=0;e<c.ports.length;e++)if(c.ports[e].name==n.name)c.ports[e].title=t.title;s()}})}if(n.direction==CABLES.PORT_DIR_IN){if(n.type==CABLES.OP_PORT_TYPE_FUNCTION){n.onTriggered=function(){if(e.isLinked())e.trigger()}}else{n.onChange=function(){e.set(n.get());if(!n.isLinked()){for(let e=0;e<c.ports.length;e++){if(c.ports[e].name===n.name){c.ports[e].value=n.get()}}s()}}}}}u.setupPorts=a;function a(){if(!u.patchId.get())return;const e=c.ports||[];const t=c.portsOut||[];let n=0;for(n=0;n<e.length;n++){if(!u.getPortByName(e[n].name)){const r=u.addInPort(new CABLES.Port(u,e[n].name,e[n].type));const i=p();const a=i.addOutPort(new CABLES.Port(i,e[n].name,e[n].type));r.ignoreValueSerialize=true;r.setUiAttribs({editableTitle:true});if(e[n].title){r.setUiAttribs({title:e[n].title});a.setUiAttribs({title:e[n].title})}if(e[n].objType){r.setUiAttribs({objType:e[n].objType});a.setUiAttribs({objType:e[n].objType})}if(e[n].value){r.set(e[n].value);a.set(e[n].value)}f(r,a)}}for(n=0;n<t.length;n++){if(!u.getPortByName(t[n].name)){const s=u.addOutPort(new CABLES.Port(u,t[n].name,t[n].type));const o=d();const l=o.addInPort(new CABLES.Port(o,t[n].name,t[n].type));s.ignoreValueSerialize=true;s.setUiAttribs({editableTitle:true});if(t[n].title){s.setUiAttribs({title:t[n].title});l.setUiAttribs({title:t[n].title})}if(t[n].objType){s.setUiAttribs({objType:t[n].objType});l.setUiAttribs({objType:t[n].objType})}f(l,s)}}h=true}u.addNewInPort=function(e,t,n){const r="in"+c.ports.length+" "+e.op.name+" "+e.name;const i={name:r,type:e.type};if(e.uiAttribs.objType)i.objType=e.uiAttribs.objType;c.ports.push(i);a();return r};u.dyn.onLinkChanged=function(){if(u.dyn.isLinked()){const e=u.dyn.links[0].getOtherPort(u.dyn);u.dyn.removeLinks();e.removeLinkTo(u.dyn);u.log("dyn link changed!!!");const t=u.addNewInPort(e);const n=gui.scene().link(e.op,e.getName(),u,t);h=true;s()}else{setTimeout(function(){u.dyn.removeLinks()},100)}};u.addNewOutPort=function(e,t,n){const r="out"+c.portsOut.length+" "+e.op.name+" "+e.name;const i={name:r,type:e.type};if(e.uiAttribs.objType)i.objType=e.uiAttribs.objType;c.portsOut.push(i);a();return r};u.dynOut.onLinkChanged=function(){if(u.dynOut.isLinked()){const e=u.dynOut.links[0].getOtherPort(u.dynOut);u.dynOut.removeLinks();if(e){e.removeLinkTo(u.dynOut);const t=u.addNewOutPort(e);gui.scene().link(e.op,e.getName(),u,t)}h=true;s()}else{setTimeout(function(){u.dynOut.removeLinks()},100);u.log("dynOut unlinked...")}};function d(){let e=u.patch.getSubPatchOp(u.patchId.get(),"Ops.Ui.PatchOutput");if(!e){u.patch.addOp("Ops.Ui.PatchOutput",{subPatch:u.patchId.get(),translate:{x:0,y:0}});e=u.patch.getSubPatchOp(u.patchId.get(),"Ops.Ui.PatchOutput");if(!e)u.warn("no patchoutput!")}return e}function p(){let e=u.patch.getSubPatchOp(u.patchId.get(),"Ops.Ui.PatchInput");if(!e){u.patch.addOp("Ops.Ui.PatchInput",{subPatch:u.patchId.get(),translate:{x:0,y:0}});e=u.patch.getSubPatchOp(u.patchId.get(),"Ops.Ui.PatchInput");if(!e)u.warn("no patchinput2!")}return e}u.addSubLink=function(e,t){const n=c.ports.length;const r="in"+(n-1)+" "+t.op.name+" "+t.name;if(e.direction==CABLES.PORT_DIR_IN){gui.scene().link(e.op,e.getName(),p(),r)}else{const a=c.portsOut.length;gui.scene().link(e.op,e.getName(),d(),"out"+(a-1)+" "+t.op.name+" "+t.name)}const i=gui.patchView.getSubPatchBounds(u.patchId.get());p().uiAttr({translate:{x:i.minx,y:i.miny-100}});d().uiAttr({translate:{x:i.minx,y:i.maxy+100}});s();return r};u.onDelete=function(){for(let e=u.patch.ops.length-1;e>=0;e--)if(u.patch.ops[e]&&u.patch.ops[e].uiAttribs&&u.patch.ops[e].uiAttribs.subPatch==u.patchId.get())u.patch.deleteOp(u.patch.ops[e].id)};u.rebuildListeners=()=>{u.log("rebuild listeners...");const t=d();for(let e=0;e<t.portsIn.length;e++){if(t.portsIn[e].isLinked()){f(t.portsIn[e],this.portsOut[e])}}}}};CABLES.OPS["84d9a6f0-ed7a-466d-b386-225ed9e89c60"]={f:Ops.Ui.SubPatch,objName:"Ops.Ui.SubPatch"};Ops.Trigger.Sequence=class extends CABLES.Op{constructor(){super(...arguments);const a=this;const e=a.attachments={};const t=a.inTrigger("exe"),n=a.inTriggerButton("Clean up connections");a.setUiAttrib({resizable:true,resizableY:false,stretchPorts:true});const r=[],s=[],i=16;let o=null,l=[];t.onTriggered=h;n.onTriggered=f;n.setUiAttribs({hideParam:true,hidePort:true});for(let t=0;t<i;t++){const d=a.outTrigger("trigger "+t);s.push(d);d.onLinkChanged=c;if(t<i-1){let e=a.inTrigger("exe "+t);e.onTriggered=h;r.push(e)}}u();function u(){l.length=0;for(let e=0;e<s.length;e++)if(s[e].links.length>0)l.push(s[e])}function c(){u();clearTimeout(o);o=setTimeout(()=>{let t=false;for(let e=0;e<s.length;e++)if(s[e].links.length>1)t=true;n.setUiAttribs({hideParam:!t});if(a.isCurrentUiOp())a.refreshParams()},60)}function h(){for(let e=0;e<l.length;e++)l[e].trigger()}function f(){let r=0;for(let n=0;n<s.length;n++){let t=[];if(s[n].links.length>1)for(let e=1;e<s[n].links.length;e++){while(s[r].links.length>0)r++;t.push(s[n].links[e]);const i=s[n].links[e].getOtherPort(s[n]);a.patch.link(a,"trigger "+r,i.op,i.name);r++}for(let e=0;e<t.length;e++)t[e].remove()}c();u()}}};CABLES.OPS["a466bc1f-06e9-4595-8849-bffb9fe22f99"]={f:Ops.Trigger.Sequence,objName:"Ops.Trigger.Sequence"};Ops.Ui.VizNumberBar=class extends CABLES.Op{constructor(){super(...arguments);const s=this;const e=s.attachments={};const o=s.inFloat("Number",0),t=s.outNumber("Passthrough");s.setUiAttrib({height:100,width:200,resizable:true});let l=-Number.MAX_VALUE;let u=Number.MAX_VALUE;o.onChange=()=>{t.set(o.get())};o.onLinkChanged=()=>{l=-Number.MAX_VALUE;u=Number.MAX_VALUE};s.renderVizLayer=(i,a)=>{i.fillStyle="#222";i.fillRect(a.x,a.y,a.width,a.height);{l=Math.max(l,o.get());u=Math.min(u,o.get());if(s.uiAttribs.color)i.fillStyle=s.uiAttribs.color;else i.fillStyle="#555";let e=CABLES.map(0,u,l,0,a.width);let t=CABLES.map(o.get(),u,l,0,a.width);let n=Math.min(e,t);let r=Math.max(e,t);i.fillRect(n+a.x,a.y,r-n,a.height)}{const e=10;if(s.uiAttribs.color)i.fillStyle="#fff";else i.fillStyle="#ccc";const t=a.height*.7;i.font="normal "+t+"px sourceCodePro";i.fillText(Math.round(o.get()*1e4)/1e4,a.x+e,a.y+t)}}}};CABLES.OPS["37575d2e-4ba6-4d2b-b00c-c503666867c5"]={f:Ops.Ui.VizNumberBar,objName:"Ops.Ui.VizNumberBar"};Ops.Trigger.TimedSequence=class extends CABLES.Op{constructor(){super(...arguments);const n=this;const e=n.attachments={};const t=n.inTrigger("exe");const i=n.inValueInt("current",0);const a=n.inValueBool("overwriteTime");const s=n.inValueBool("ignoreInSubPatch",false);const o=n.outTrigger("triggerAlways");const r=n.outArray("Names",[]);const l=n.outNumber("currentKeyTime");const u=n.outNumber("Current");let c=[];for(let t=0;t<32;t++){let e=n.outTrigger("trigger "+t);e.onLinkChanged=h;c.push(e)}function h(){let t=[];for(let e=0;e<c.length;e++)if(c[e].isLinked())t.push(c[e].links[0].getOtherPort(c[e]).op.uiAttribs.title);else t.push("none");r.set(t)}n.onLoaded=h;t.onTriggered=f;function f(r){let t=0;let e=Math.round(i.get()-.5);if(i.anim){let e=r;if(r===undefined)e=i.op.patch.timer.getTime();let t=i.anim.getKey(e);let n=0;if(t)n=t.time;l.set(e-n);if(i.isAnimated()){if(a.get()){i.op.patch.timer.overwriteTime=l.get()}}}if(n.patch.gui&&s.get()){for(let e=0;e<c.length;e++){for(t=0;t<c[e].links.length;t++){if(c[e].links[t]){if(c[e].links[t].portIn.op.patchId){if(CABLES.UI)if(gui.patchView.getCurrentSubPatch()==c[e].links[t].portIn.op.patchId.get()){n.patch.timer.overwriteTime=-1;c[e].trigger();return}}}}}}if(e>=0&&e<c.length){u.set(e);c[e].trigger()}n.patch.timer.overwriteTime=-1;o.trigger()}}};CABLES.OPS["73c892c9-3e81-4ddc-952a-fbe6bf00ef2c"]={f:Ops.Trigger.TimedSequence,objName:"Ops.Trigger.TimedSequence"};Ops.Vars.VarGetNumber_v2=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.outNumber("Value");e.varName=e.inValueSelect("Variable",[],"",true);new CABLES.VarGetOpWrapper(e,"number",e.varName,n)}};CABLES.OPS["421f5b52-c0fa-47c4-8b7a-012b9e1c864a"]={f:Ops.Vars.VarGetNumber_v2,objName:"Ops.Vars.VarGetNumber_v2"};Ops.Vars.VarSetNumber_v2=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValueFloat("Value",0);e.varName=e.inDropDown("Variable",[],"",true);new CABLES.VarSetOpWrapper(e,"number",n,e.varName)}};CABLES.OPS["b5249226-6095-4828-8a1c-080654e192fa"]={f:Ops.Vars.VarSetNumber_v2,objName:"Ops.Vars.VarSetNumber_v2"};Ops.Gl.Meshes.FullscreenRectangle=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={shader_frag:"UNI sampler2D tex;\nIN vec2 texCoord;\n\nvoid main()\n{\n    outColor= texture(tex,texCoord);\n}\n\n",shader_vert:"{{MODULES_HEAD}}\n\nIN vec3 vPosition;\nUNI mat4 projMatrix;\nUNI mat4 mvMatrix;\n\nOUT vec2 texCoord;\nIN vec2 attrTexCoord;\n\nvoid main()\n{\n   vec4 pos=vec4(vPosition,  1.0);\n\n   texCoord=vec2(attrTexCoord.x,(1.0-attrTexCoord.y));\n\n   gl_Position = projMatrix * mvMatrix * pos;\n}\n"};const n=e.inTrigger("render"),r=e.inSwitch("Scale",["Stretch","Fit"],"Fit"),i=e.inValueBool("Flip Y"),a=e.inValueBool("Flip X"),s=e.inTexture("Texture"),o=e.outTrigger("trigger");const l=e.patch.cgl;let u=null;let c=new CGL.Geometry("fullscreen rectangle");let h=0,f=0,d=0,p=0,g=0;e.toWorkShouldNotBeChild("Ops.Gl.TextureEffects.ImageCompose",CABLES.OP_PORT_TYPE_FUNCTION);e.toWorkPortsNeedToBeLinked(n);a.onChange=T;i.onChange=T;n.onTriggered=x;s.onLinkChanged=F;r.onChange=A;const m=new CGL.Shader(l,"fullscreenrectangle",this);m.setModules(["MODULE_VERTEX_POSITION","MODULE_COLOR","MODULE_BEGIN_FRAG"]);m.setSource(t.shader_vert,t.shader_frag);m.fullscreenRectUniform=new CGL.Uniform(m,"t","tex",0);m.aspectUni=new CGL.Uniform(m,"f","aspectTex",0);let v=false;let b=true;let _=false;let E=[];F();A();e.onDelete=function(){if(u)u.dispose()};s.onChange=function(){b=true};function F(){if(!CABLES.UI)return;i.setUiAttribs({greyout:!s.isLinked()});a.setUiAttribs({greyout:!s.isLinked()});r.setUiAttribs({greyout:!s.isLinked()})}function C(){let e=s.get();if(e)v=true;else v=false}e.preRender=function(){C();m.bind();if(u)u.render(m);x()};function A(){_=r.get()=="Fit"}function x(){if(l.getViewPort()[2]!=p||l.getViewPort()[3]!=g||!u)S();if(b)C();l.pushPMatrix();mat4.identity(l.pMatrix);mat4.ortho(l.pMatrix,0,p,g,0,-10,1e3);l.pushModelMatrix();mat4.identity(l.mMatrix);l.pushViewMatrix();mat4.identity(l.vMatrix);if(_&&s.get()){const n=s.get().width/s.get().height;let e=g;let t=g*n;if(t>p){e=p*1/n;t=p}E[0]=l.getViewPort()[0];E[1]=l.getViewPort()[1];E[2]=l.getViewPort()[2];E[3]=l.getViewPort()[3];l.setViewPort((p-t)/2,(g-e)/2,t,e)}if(v){if(s.get())l.setTexture(0,s.get().tex);u.render(m)}else{u.render(l.getShader())}l.gl.clear(l.gl.DEPTH_BUFFER_BIT);l.popPMatrix();l.popModelMatrix();l.popViewMatrix();if(_&&s.get())l.setViewPort(E[0],E[1],E[2],E[3]);o.trigger()}function T(){u=null}function S(){const e=l.getViewPort();if(e[2]==p&&e[3]==g&&u)return;let t=0,n=0;p=e[2];g=e[3];c.vertices=new Float32Array([t+p,n+g,0,t,n+g,0,t+p,n,0,t,n,0]);let r=null;if(i.get())r=new Float32Array([1,0,0,0,1,1,0,1]);else r=new Float32Array([1,1,0,1,1,0,0,0]);if(a.get()){r[0]=0;r[2]=1;r[4]=0;r[6]=1}c.setTexCoords(r);c.verticesIndices=new Uint16Array([2,1,0,3,1,2]);c.vertexNormals=new Float32Array([0,0,1,0,0,1,0,0,1,0,0,1]);c.tangents=new Float32Array([-1,0,0,-1,0,0,-1,0,0,-1,0,0]);c.biTangents==new Float32Array([0,-1,0,0,-1,0,0,-1,0,0,-1,0]);if(!u)u=new CGL.Mesh(l,c);else u.setGeom(c)}}};CABLES.OPS["255bd15b-cc91-4a12-9b4e-53c710cbb282"]={f:Ops.Gl.Meshes.FullscreenRectangle,objName:"Ops.Gl.Meshes.FullscreenRectangle"};Ops.Gl.MainLoop=class extends CABLES.Op{constructor(){super(...arguments);const r=this;const e=r.attachments={};const t=r.inValue("FPS Limit",0),n=r.outTrigger("trigger"),i=r.outNumber("width"),a=r.outNumber("height"),s=r.inValueBool("Reduce FPS not focussed",false),o=r.inValueBool("Reduce FPS loading"),l=r.inValueBool("Clear",true),u=r.inValueBool("ClearAlpha",true),c=r.inValueBool("Fullscreen Button",false),h=r.inValueBool("Active",true),f=r.inValueBool("Hires Displays",false),d=r.inSwitch("Pixel Unit",["Display","CSS"],"Display");r.onAnimFrame=S;f.onChange=function(){if(f.get())r.patch.cgl.pixelDensity=window.devicePixelRatio;else r.patch.cgl.pixelDensity=1;r.patch.cgl.updateSize();if(CABLES.UI)gui.setLayout()};h.onChange=function(){r.patch.removeOnAnimFrame(r);if(h.get()){r.setUiAttrib({extendTitle:""});r.onAnimFrame=S;r.patch.addOnAnimFrame(r);r.log("adding again!")}else{r.setUiAttrib({extendTitle:"Inactive"})}};const p=r.patch.cgl;let g=0;let m=0;let v=null;let b=false;if(!r.patch.cgl)r.uiAttr({error:"No webgl cgl context"});const _=vec3.create();vec3.set(_,0,0,0);const E=vec3.create();vec3.set(E,0,0,-2);c.onChange=T;setTimeout(T,100);let F=null;let C=true;let A=true;window.addEventListener("blur",()=>{C=false});window.addEventListener("focus",()=>{C=true});document.addEventListener("visibilitychange",()=>{A=!document.hidden});y();r.patch.tempData.mainloopOp=this;d.onChange=()=>{i.set(0);a.set(0)};function x(){if(o.get()&&r.patch.loading.getProgress()<1)return 5;if(s.get()){if(!A)return 10;if(!C)return 30}return t.get()}function T(){function e(){if(F)F.style.display="block"}function t(){if(F)F.style.display="none"}r.patch.cgl.canvas.addEventListener("mouseleave",t);r.patch.cgl.canvas.addEventListener("mouseenter",e);if(c.get()){if(!F){F=document.createElement("div");const n=r.patch.cgl.canvas.parentElement;if(n)n.appendChild(F);F.addEventListener("mouseenter",e);F.addEventListener("click",function(e){if(CABLES.UI&&!e.shiftKey)gui.toggleMaximizeCanvas();else p.fullScreen()})}F.style.padding="10px";F.style.position="absolute";F.style.right="5px";F.style.top="5px";F.style.width="20px";F.style.height="20px";F.style.cursor="pointer";F.style["border-radius"]="40px";F.style.background="#444";F.style["z-index"]="9999";F.style.display="none";F.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Capa_1" x="0px" y="0px" viewBox="0 0 490 490" style="width:20px;height:20px;" xml:space="preserve" width="512px" height="512px"><g><path d="M173.792,301.792L21.333,454.251v-80.917c0-5.891-4.776-10.667-10.667-10.667C4.776,362.667,0,367.442,0,373.333V480     c0,5.891,4.776,10.667,10.667,10.667h106.667c5.891,0,10.667-4.776,10.667-10.667s-4.776-10.667-10.667-10.667H36.416     l152.459-152.459c4.093-4.237,3.975-10.99-0.262-15.083C184.479,297.799,177.926,297.799,173.792,301.792z" fill="#FFFFFF"/><path d="M480,0H373.333c-5.891,0-10.667,4.776-10.667,10.667c0,5.891,4.776,10.667,10.667,10.667h80.917L301.792,173.792     c-4.237,4.093-4.354,10.845-0.262,15.083c4.093,4.237,10.845,4.354,15.083,0.262c0.089-0.086,0.176-0.173,0.262-0.262     L469.333,36.416v80.917c0,5.891,4.776,10.667,10.667,10.667s10.667-4.776,10.667-10.667V10.667C490.667,4.776,485.891,0,480,0z" fill="#FFFFFF"/><path d="M36.416,21.333h80.917c5.891,0,10.667-4.776,10.667-10.667C128,4.776,123.224,0,117.333,0H10.667     C4.776,0,0,4.776,0,10.667v106.667C0,123.224,4.776,128,10.667,128c5.891,0,10.667-4.776,10.667-10.667V36.416l152.459,152.459     c4.237,4.093,10.99,3.975,15.083-0.262c3.992-4.134,3.992-10.687,0-14.82L36.416,21.333z" fill="#FFFFFF"/><path d="M480,362.667c-5.891,0-10.667,4.776-10.667,10.667v80.917L316.875,301.792c-4.237-4.093-10.99-3.976-15.083,0.261     c-3.993,4.134-3.993,10.688,0,14.821l152.459,152.459h-80.917c-5.891,0-10.667,4.776-10.667,10.667s4.776,10.667,10.667,10.667     H480c5.891,0,10.667-4.776,10.667-10.667V373.333C490.667,367.442,485.891,362.667,480,362.667z" fill="#FFFFFF"/></g></svg>'}else{if(F){F.style.display="none";F.remove();F=null}}}r.onDelete=function(){p.gl.clearColor(0,0,0,0);p.gl.clear(p.gl.COLOR_BUFFER_BIT|p.gl.DEPTH_BUFFER_BIT)};function S(e){if(!h.get())return;if(p.aborted||p.canvas.clientWidth===0||p.canvas.clientHeight===0)return;r.patch.cg=p;if(f.get())r.patch.cgl.pixelDensity=window.devicePixelRatio;const t=performance.now();r.patch.config.fpsLimit=x();if(p.canvasWidth==-1){p.setCanvas(r.patch.config.glCanvasId);return}if(p.canvasWidth!=i.get()||p.canvasHeight!=a.get()){let e=1;if(d.get()=="CSS")e=r.patch.cgl.pixelDensity;i.set(p.canvasWidth/e);a.set(p.canvasHeight/e)}if(CABLES.now()-m>1e3){CGL.fpsReport=CGL.fpsReport||[];if(r.patch.loading.getProgress()>=1&&m!==0)CGL.fpsReport.push(g);g=0;m=CABLES.now()}CGL.MESH.lastShader=null;CGL.MESH.lastMesh=null;p.renderStart(p,_,E);if(l.get()){p.gl.clearColor(0,0,0,1);p.gl.clear(p.gl.COLOR_BUFFER_BIT|p.gl.DEPTH_BUFFER_BIT)}n.trigger();if(CGL.MESH.lastMesh)CGL.MESH.lastMesh.unBind();if(CGL.Texture.previewTexture){if(!CGL.Texture.texturePreviewer)CGL.Texture.texturePreviewer=new CGL.Texture.texturePreview(p);CGL.Texture.texturePreviewer.render(CGL.Texture.previewTexture)}p.renderEnd(p);r.patch.cg=null;if(u.get()){p.gl.clearColor(1,1,1,1);p.gl.colorMask(false,false,false,true);p.gl.clear(p.gl.COLOR_BUFFER_BIT);p.gl.colorMask(true,true,true,true)}if(!p.tempData.phong)p.tempData.phong={};g++;r.patch.cgl.profileData.profileMainloopMs=performance.now()-t}function y(){clearTimeout(v);v=setTimeout(()=>{if(r.patch.getOpsByObjName(r.name).length>1){r.setUiError("multimainloop","there should only be one mainloop op!");if(!b)b=r.patch.addEventListener("onOpDelete",y)}else r.setUiError("multimainloop",null,1)},500)}}};CABLES.OPS["b0472a1d-db16-4ba6-8787-f300fbdc77bb"]={f:Ops.Gl.MainLoop,objName:"Ops.Gl.MainLoop"};Ops.WebAudio.AudioBuffer_v2=class extends CABLES.Op{constructor(){super(...arguments);const r=this;const e=r.attachments={};const i=r.patch.cgl;const t=CABLES.WEBAUDIO.createAudioContext(r),n=r.inUrl("URL","audio"),a=r.inBool("Create Loading Task",true),s=r.outObject("Audio Buffer",null,"audioBuffer"),o=r.outBoolNum("Finished Loading",false),l=r.outNumber("Sample Rate",0),u=r.outNumber("Length",0),c=r.outNumber("Duration",0),h=r.outNumber("Number of Channels",0),f=r.outBool("isLoading",0);let d=null;let p=false;let g=null;let m=null;let v=false;let b=false;let _=false;let E=new FileReader;let F=null;let C=0;if(!s.isLinked()){r.setUiError("notConnected","To play back sound, connect this op to a playback operator such as SamplePlayer or AudioBufferPlayer.",0)}else{r.setUiError("notConnected",null)}s.onLinkChanged=()=>{if(s.isLinked()){r.setUiError("notConnected",null)}else{r.setUiError("notConnected","To play back sound, connect this op to a playback operator such as SamplePlayer or AudioBufferPlayer.",0)}};function A(t,e){g=t;p=true;f.set(p);if(!e){const n=t.substr(t.lastIndexOf(".")+1);if(n==="wav"){r.setUiError("wavFormat","You are using a .wav file. Make sure the .wav file is 16 bit to be supported by all browsers. Safari does not support 24 bit .wav files.",1)}else{r.setUiError("wavFormat",null)}CABLES.WEBAUDIO.loadAudioFile(r.patch,t,S,y,a.get())}else{let e=x(t);if(e.type==="audio/wav"){r.setUiError("wavFormat","You are using a .wav file. Make sure the .wav file is 16 bit to be supported by all browsers. Safari does not support 24 bit .wav files.",1)}else{r.setUiError("wavFormat",null)}if(a.get()){C=i.patch.loading.start("audiobuffer from data-url "+r.id,t,r);if(i.patch.isEditorMode())gui.jobs().start({id:"loadaudio"+C,title:" loading audio data url ("+r.id+")"})}E.readAsArrayBuffer(e)}}function x(e){let t=atob(e.split(",")[1]);let n=e.split(",")[0].split(":")[1].split(";")[0];let r=new ArrayBuffer(t.length);let i=new Uint8Array(r);for(let e=0;e<t.length;e++){i[e]=t.charCodeAt(e)}let a=new Blob([r],{type:n});return a}n.onChange=function(){if(n.get()){b=String(n.get()).indexOf("data:")==0;if(p){_=String(n.get()).indexOf("data:")==0;const t=_?n.get():r.patch.getFilePath(n.get());if(t!==g){m=t}else{m=null}v=false;return}B();const e=b?n.get():r.patch.getFilePath(n.get());A(e,b)}else{if(p){v=true;return}B();r.setUiError("wavFormat",null);r.setUiError("failedLoading",null)}};E.onloadend=()=>{F=E.result;i.patch.loading.finished(C);if(i.patch.isEditorMode())gui.jobs().finish("loadaudio"+C);T()};function T(){if(F)t.decodeAudioData(F,S,y)}function S(e){p=false;f.set(p);if(v){B();v=false;return}if(m){A(m,_);m=null}else{d=e;u.set(e.length);c.set(e.duration);h.set(e.numberOfChannels);l.set(e.sampleRate);s.setRef(e);r.setUiError("failedLoading",null);o.set(true);b=false;_=false}}function y(e){r.setUiError("failedLoading","The audio file could not be loaded. Make sure the right file URL is used.",2);p=false;B();f.set(p);d=null;if(m){A(m,_);m=null}}function B(){u.set(0);c.set(0);h.set(0);l.set(0);s.set(null);o.set(false)}}};CABLES.OPS["5f1d6a2f-1c04-4744-b0fb-910825beceee"]={f:Ops.WebAudio.AudioBuffer_v2,objName:"Ops.WebAudio.AudioBuffer_v2"};Ops.WebAudio.AudioBufferPlayer_v2=class extends CABLES.Op{constructor(){super(...arguments);const n=this;const e=n.attachments={};const r=n.inObject("Audio Buffer",null,"audioBuffer");const i=n.inBool("Start / Stop",false);const a=n.inBool("Loop",false);const t=n.inTriggerButton("Restart");const s=n.inFloat("Offset",0);const o=n.inFloat("Playback Rate",1);const l=n.inFloat("Detune",0);n.setPortGroup("Playback Controls",[i,a,t]);n.setPortGroup("Time Controls",[s]);n.setPortGroup("Miscellaneous",[o,l]);const u=n.outObject("Audio Out",null,"audioNode");const c=n.outBool("Is Playing",false);const h=n.outBool("Loading",false);let f=null;let d=false;let p=false;let g=null;let m=null;let v=false;const b=CABLES.WEBAUDIO.createAudioContext(n);const _=b.createGain();if(!r.isLinked()){n.setUiError("inputNotConnected","To be able to play back sound, you need to connect an AudioBuffer to this op.",0)}else{n.setUiError("inputNotConnected",null)}r.onLinkChanged=()=>{if(!r.isLinked()){n.setUiError("inputNotConnected","To be able to play back sound, you need to connect an AudioBuffer to this op.",0)}else{n.setUiError("inputNotConnected",null)}};if(!u.isLinked()){n.setUiError("outputNotConnected","To be able to hear sound playing, you need to connect this op to an Output op.",0)}else{n.setUiError("outputNotConnected",null)}u.onLinkChanged=()=>{if(!u.isLinked()){n.setUiError("outputNotConnected","To be able to hear sound playing, you need to connect this op to an Output op.",0)}else{n.setUiError("outputNotConnected",null)}};r.onChange=function(){if(r.get())A();else{if(v){v=false;h.set(v)}if(d){B(0);if(f)f.buffer=null;f=null}}};i.onChange=function(){if(!r.get())return;if(!f){if(!v)A()}if(i.get()){const e=0;S(e)}else{const t=0;B(t)}};a.onChange=function(){if(f){f.loop=!!a.get()}};l.onChange=E;function E(){if(!f)return;const e=l.get()||0;if(f.detune){f.detune.setValueAtTime(e,b.currentTime)}}o.onChange=F;function F(){if(!f)return;const e=o.get()||0;if(e>=f.playbackRate.minValue&&e<=f.playbackRate.maxValue){f.playbackRate.setValueAtTime(e,b.currentTime)}}let C=false;t.onTriggered=function(){if(!f)return;if(!r.get())return;else{if(!(r.get()instanceof AudioBuffer))return}if(i.get()){if(d){C=true;B(0)}else{S(0)}}};function A(e=false){if(v)return;if(!(r.get()instanceof AudioBuffer))return;v=true;h.set(v);if(f){f.onended=null;if(f.buffer){B(0);f.disconnect(_);f.buffer=null}f=null}f=b.createBufferSource();const t=r.get();if(!t){v=false;h.set(v);return}f.buffer=t;f.onended=O;f.loop=a.get();f.connect(_);F();E();u.setRef(_);v=false;h.set(v);if(C){S(0);C=false;return}if(i.get()&&!e){S(0)}}let x=false;let T=null;s.onChange=()=>{if(s.get()>=0)n.setUiError("offsetNegative",null);else{n.setUiError("offsetNegative","Offset cannot be negative. Setting to 0.",1)}if(f){if(f.buffer){if(s.get()>f.buffer.duration){n.setUiError("offsetTooLong","Your offset value is higher than the total time of your audio file. Please decrease the duration to be able to hear sound when playing back your buffer.",1)}else{n.setUiError("offsetTooLong",null)}}}};function S(t){try{if(f){let e=Math.max(0,s.get());f.start(t,e);d=true;p=false;c.set(true)}else{n.log("start() but no src...")}}catch(e){n.log("Error on start: ",e.message);c.set(false);d=false}}function y(){let e=!a.get();A(e)}function B(e){try{if(f){f.stop();if(!C)y()}d=false;c.set(false)}catch(e){n.setUiError(e);c.set(false)}}function O(){if(a.get()){d=true;p=false}else{d=false;p=true}c.set(d);y()}}};CABLES.OPS["3abd0dbb-eeee-4c65-ae31-b8bc2345e2d5"]={f:Ops.WebAudio.AudioBufferPlayer_v2,objName:"Ops.WebAudio.AudioBufferPlayer_v2"};Ops.WebAudio.Output_v2=class extends CABLES.Op{constructor(){super(...arguments);const n=this;const e=n.attachments={};const t=n.inObject("Audio In",null,"audioNode"),r=n.inFloatSlider("Volume",1),i=n.inBool("Mute",false),a=n.inBool("Show Audio Suspended Button",true),s=n.outNumber("Current Volume",0),o=n.outNumber("Number Of Channels"),l=n.outString("Context State","unknown");n.setPortGroup("Volume Settings",[i,r]);let u=false;let c=CABLES.WEBAUDIO.createAudioContext(n);let h=c.createGain();const f=c.destination;let d=null;let p=false;i.onChange=()=>{b(i.get());_()};r.onChange=v;n.onMasterVolumeChanged=v;let g=n.patch.on("pause",v);let m=n.patch.on("resume",v);c.addEventListener("statechange",_);a.onChange=E;_();E();n.onDelete=()=>{if(h)h.disconnect();h=null;if(CABLES.interActionNeededButton)CABLES.interActionNeededButton.remove("audiosuspended");if(g)n.patch.off(g);if(m)n.patch.off(m)};t.onChange=function(){n.setUiError("multipleInputs",null);if(d){try{if(d.disconnect){d.disconnect(h)}}catch(e){n.logError(e)}}if(p){if(h){h.disconnect(f)}p=false}if(t.get()){if(t.links.length>1)n.setUiError("multipleInputs","You have connected multiple inputs. It is possible that you experience unexpected behaviour. Please use a Mixer op to connect multiple audio streams.",1);else n.setUiError("multipleInputs",null);if(t.get().connect){t.get().connect(h)}}d=t.get();if(!p){if(h){h.connect(f)}p=true}if(c&&c.destination){o.set(c.destination.maxChannelCount)}else{o.set(0)}v()};function v(){const e=n.patch.config.masterVolume||0;let t=r.get()*e;if(n.patch._paused||i.get())t=0;t=CABLES.clamp(t,0,1);if(!h)n.logError("gainNode undefined");if(h)h.gain.linearRampToValueAtTime(t,c.currentTime+.05);s.set(t)}function b(e){if(e){if(c.state==="suspended"){if(h){h.gain.cancelScheduledValues(c.currentTime);h.gain.value=0;h.gain.setValueAtTime(0,c.currentTime)}s.set(0);return}}v()}function _(){l.set(c.state);n.logVerbose("audioCtx.state change",c.state);n.setUiError("ctxSusp",null);if(c.state=="suspended"){const t="Your Browser suspended audio context, use playButton op to play audio after a user interaction";let e=1;if(i.get())e=0;n.setUiError("ctxSusp",t,e)}E()}function E(){if(c.state=="suspended"){b(true);if(a.get()){u=true;if(CABLES.interActionNeededButton){CABLES.interActionNeededButton.add(n.patch,"audiosuspended",()=>{if(c&&c.state=="suspended"){c.resume();if(CABLES.interActionNeededButton)CABLES.interActionNeededButton.remove("audiosuspended")}})}}else{if(CABLES.interActionNeededButton)CABLES.interActionNeededButton.remove("audiosuspended")}}else{if(CABLES.interActionNeededButton)CABLES.interActionNeededButton.remove("audiosuspended");if(u){n.log("was suspended - set vol");v()}}}}};CABLES.OPS["90b95403-b0c4-4980-ab3b-b6c354771c81"]={f:Ops.WebAudio.Output_v2,objName:"Ops.WebAudio.Output_v2"};Ops.Cables.LoadingStatus_v2=class extends CABLES.Op{constructor(){super(...arguments);const r=this;const e=r.attachments={};const t=r.inTrigger("exe"),i=r.inBool("Play Timeline",true),n=r.outTrigger("Next"),a=r.outBoolNum("Finished Initial Loading",false),s=r.outBoolNum("Loading"),o=r.outNumber("Progress"),l=r.outArray("Jobs"),u=r.outTrigger("Trigger Loading Finished ");const c=r.patch.cgl;const h=r.patch;let f=false;const d=[];let p=true;let g=0;document.body.classList.add("cables-loading");let m=c.patch.loading.start("loadingStatusInit","loadingStatusInit",r);r.patch.loading.on("finishedTask",v.bind(this));r.patch.loading.on("startTask",v.bind(this));function v(){const e=r.patch.loading.getListJobs();o.set(h.loading.getProgress());let t=e.length===0;const n=!t;if(n){l.set(r.patch.loading.getListJobs())}if(n){if(p){r.patch.timer.setTime(0);if(i.get()){r.patch.timer.play()}else{r.patch.timer.pause()}}p=false;document.body.classList.remove("cables-loading");document.body.classList.add("cables-loaded")}else{f=true;l.set(r.patch.loading.getListJobs());if(h.loading.getProgress()<1){r.patch.timer.setTime(0);r.patch.timer.pause()}}a.set(f);if(s.get()&&t)u.trigger();s.set(n);r.setUiAttribs({loading:n})}t.onTriggered=()=>{v();n.trigger();if(m){c.patch.loading.finished(m);m=null}}}};CABLES.OPS["e62f7f4c-7436-437e-8451-6bc3c28545f7"]={f:Ops.Cables.LoadingStatus_v2,objName:"Ops.Cables.LoadingStatus_v2"};Ops.Math.Sum=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValueFloat("number1",0),r=e.inValueFloat("number2",0),i=e.outNumber("result");e.setUiAttribs({mathTitle:true});n.onChange=r.onChange=a;a();function a(){const e=n.get()+r.get();if(!isNaN(e))i.set(e)}}};CABLES.OPS["c8fb181e-0b03-4b41-9e55-06b6267bc634"]={f:Ops.Math.Sum,objName:"Ops.Math.Sum"};Ops.Math.Divide=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValueFloat("number1",1),r=e.inValueFloat("number2",2),i=e.outNumber("result");e.setUiAttribs({mathTitle:true});n.onChange=r.onChange=a;a();function a(){i.set(n.get()/r.get())}}};CABLES.OPS["86fcfd8c-038d-4b91-9820-a08114f6b7eb"]={f:Ops.Math.Divide,objName:"Ops.Math.Divide"};Ops.TimeLine.DemoPrerender=class extends CABLES.Op{constructor(){super(...arguments);const i=this;const e=i.attachments={};const t=i.inTrigger("Render"),n=i.inArray("Times"),r=i.inArray("Manual Timestamps"),a=i.inBool("Record Events",false),s=i.inTriggerButton("Reset"),o=i.inTriggerButton("Clear"),l=i.inBool("ReRender on Resize",true),u=i.outTrigger("Next"),c=i.outTrigger("Prerendered Frame"),h=i.outNumber("Progress",0),f=i.outNumber("Num Events");t.onTriggered=C;n.setUiAttribs({hidePort:true,hideParam:true});let d=true;let p=0;let g=false;let m=0;let v=0;let b=[0];i.patch.cgl.on("resize",()=>{if(l.get()){if(!d&&h.get()==1){m=i.patch.timer.getTime();v=i.patch.freeTimer.getTime();d=true;p=0}}});r.onChange=n.onChange=()=>{f.set(F().length);b=n.get()||[0]};i.patch.cgl.on("heavyEvent",e=>{if(a.get()&&!d&&CABLES.uniqueArray){b.push(Math.round(i.patch.timer.getTime()*60)/60);b=CABLES.uniqueArray(b);n.set(b)}});let _=0;s.onTriggered=()=>{d=true};o.onTriggered=()=>{b=[0];n.set(b)};function E(){return _*1e3}function F(){let e=[];e=e.concat(n.get()||[0]);if(r.get())e=e.concat(r.get());return e}function C(){if(a.get()){d=false;h.set(1);u.trigger();return}if(d){let e=F();if(p<e.length){const n=CABLES.internalNow;CABLES.internalNow=E;_=e[p];i.patch._frameNum=p+22;CABLES.overwriteTime=_;i.patch.timer.setTime(_);i.patch.freeTimer.setTime(_);CABLES.overwriteTime=undefined;CABLES.internalNow=n}const t=30;if(p>=e.length){const r=(t-(p-e.length))/t;i.patch.timer.setTime(r);i.patch.freeTimer.setTime(r)}u.trigger();u.trigger();h.set(Math.min(1,p/(e.length+t)));c.trigger();if(p>=e.length+t){i.patch.timer.setTime(m);i.patch.freeTimer.setTime(v);d=false}else p++}else{u.trigger()}}}};CABLES.OPS["962ea9e5-39ee-448c-9a2b-b71ceee47c11"]={f:Ops.TimeLine.DemoPrerender,objName:"Ops.TimeLine.DemoPrerender"};Ops.TimeLine.TimeLineControls=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.outBoolNum("Play/Stop");const r=e.outNumber("time");e.patch.timer.on("playPause",i);e.patch.timer.on("timeChange",i);function i(){n.set(false);setTimeout(function(){r.set(e.patch.timer.getTime());n.set(e.patch.timer.isPlaying())},10)}}};CABLES.OPS["53cb7b1a-56c7-405f-b427-12db78fbfd2f"]={f:Ops.TimeLine.TimeLineControls,objName:"Ops.TimeLine.TimeLineControls"};Ops.Boolean.IfTrueThen_v2=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inTrigger("exe"),r=e.inValueBool("boolean",false),i=e.outTrigger("then"),a=e.outTrigger("else");n.onTriggered=s;function s(){if(r.get())i.trigger();else a.trigger()}}};CABLES.OPS["9549e2ed-a544-4d33-a672-05c7854ccf5d"]={f:Ops.Boolean.IfTrueThen_v2,objName:"Ops.Boolean.IfTrueThen_v2"};Ops.Boolean.Not=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValueBool("Boolean"),r=e.outBoolNum("Result");n.changeAlways=true;n.onChange=function(){r.set(!n.get())}}};CABLES.OPS["6d123c9f-7485-4fd9-a5c2-76e59dcbeb34"]={f:Ops.Boolean.Not,objName:"Ops.Boolean.Not"};Ops.Cables.UIMode=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.outBoolNum("UI",e.patch.isEditorMode()),r=e.outBoolNum("Overlay Mode",false),i=e.outBoolNum("Remote Viewer",window.gui?window.gui.isRemoteClient:false),a=e.outBoolNum("Is Standalone",CABLES.platform&&CABLES.platform.frontendOptions.isElectron),s=e.outNumber("Canvas Mode"),o=e.outBoolNum("Patch Field Visible");if(CABLES.UI){r.set(gui.shouldDrawOverlay);gui.on("overlaysChanged",e=>{r.set(e)});gui.on("canvasModeChange",()=>{s.set(gui.canvasManager.mode);o.set(gui.patchView.element.classList.contains("hidden"))})}}};CABLES.OPS["7c110d60-829f-4b06-b3e4-0af911550570"]={f:Ops.Cables.UIMode,objName:"Ops.Cables.UIMode"};Ops.Devices.Mouse.Mouse_v2=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const N=e.attachments={};const t=e.inValueBool("Active",true),n=e.inValueBool("relative"),i=e.inValueBool("normalize"),r=e.inValueBool("flip y",true),a=e.inValueSelect("Area",["Canvas","Document","Parent Element"],"Canvas"),s=e.inBool("right click prevent default",true),o=e.inValueBool("Touch support",true),l=e.inValueBool("smooth"),u=e.inValueFloat("smoothSpeed",20),c=e.inValueFloat("multiply",1),h=e.outNumber("x",0),f=e.outNumber("y",0),d=e.outBoolNum("button down"),P=e.outTrigger("click"),U=e.outTrigger("Button Up"),k=e.outTrigger("click right"),p=e.outBoolNum("mouseOver"),g=e.outNumber("button");e.setPortGroup("Behavior",[n,i,r,a,s,o]);e.setPortGroup("Smoothing",[l,u,c]);let m=0;const v=e.patch.cgl;let b=null;function _(n,r){if(i.get()){let e=v.canvas.width/v.pixelDensity;let t=v.canvas.height/v.pixelDensity;if(b==document.body){e=b.clientWidth/v.pixelDensity;t=b.clientHeight/v.pixelDensity}h.set(((n||0)/e*2-1)*c.get());f.set(((r||0)/t*2-1)*c.get())}else{h.set((n||0)*c.get());f.set((r||0)*c.get())}}l.onChange=function(){if(l.get())m=setInterval(V,5);else if(m)clearTimeout(m)};let j,G;let E=0,F=0;i.onChange=function(){C=0;A=0;_(C,A)};let C=v.canvas.width/2;let A=v.canvas.height/2;E=C;F=A;h.set(C);f.set(A);let x=0;let T=0;let S=0;let y=0;w();a.onChange=w;let B=0;function V(){B=u.get();if(B<=0)B=.01;const e=Math.abs(C-E);const t=Math.round(e/B,0);E=E<C?E+t:E-t;const n=Math.abs(A-F);const r=Math.round(n/B,0);F=F<A?F+r:F-r;_(E,F)}function O(e){d.set(false);p.set(true);B=u.get()}function D(e){g.set(e.which);d.set(true)}function I(e){g.set(0);d.set(false);U.trigger()}function M(e){k.trigger();if(s.get())e.preventDefault()}function L(e){P.trigger()}function z(e){x=0;T=0;B=100;p.set(false);d.set(false)}n.onChange=function(){S=0;y=0};function H(e){if(!n.get()){if(a.get()!="Document"){S=e.offsetX;y=e.offsetY}else{S=e.clientX;y=e.clientY}if(l.get()){C=S;if(r.get())A=b.clientHeight-y;else A=y}else{if(r.get())_(S,b.clientHeight-y);else _(S,y)}}else{if(x!=0&&T!=0){S=e.offsetX-x;y=e.offsetY-T}else{}x=e.offsetX;T=e.offsetY;C+=S;A+=y;if(A>460)A=460}}function X(e){p.set(true);H(e)}function W(e){if(event.touches&&event.touches.length>0)H(e.touches[0])}function Y(e){d.set(true);if(e.touches&&e.touches.length>0)D(e.touches[0])}function q(e){d.set(false);I()}o.onChange=function(){R();w()};function R(){if(!b)return;b.removeEventListener("touchend",q);b.removeEventListener("touchstart",Y);b.removeEventListener("touchmove",W);b.removeEventListener("click",L);b.removeEventListener("mousemove",X);b.removeEventListener("mouseleave",z);b.removeEventListener("mousedown",D);b.removeEventListener("mouseup",I);b.removeEventListener("mouseenter",O);b.removeEventListener("contextmenu",M);b=null}function w(){if(b||!t.get())R();if(!t.get())return;b=v.canvas;if(a.get()=="Document")b=document.body;if(a.get()=="Parent Element")b=v.canvas.parentElement;if(o.get()){b.addEventListener("touchend",q);b.addEventListener("touchstart",Y);b.addEventListener("touchmove",W)}b.addEventListener("mousemove",X);b.addEventListener("mouseleave",z);b.addEventListener("mousedown",D);b.addEventListener("mouseup",I);b.addEventListener("mouseenter",O);b.addEventListener("contextmenu",M);b.addEventListener("click",L)}t.onChange=function(){if(b)R();if(t.get())w()};e.onDelete=function(){R()};w()}};CABLES.OPS["9fa3fc46-3147-4e3a-8ee8-a93ea9e8786e"]={f:Ops.Devices.Mouse.Mouse_v2,objName:"Ops.Devices.Mouse.Mouse_v2"};Ops.Boolean.ToggleBool=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inTriggerButton("trigger"),r=e.inTriggerButton("reset"),i=e.outBool("result"),a=e.inBool("Default",false);let s=false;i.set(s);i.ignoreValueSerialize=true;n.onTriggered=function(){s=!s;i.set(s)};r.onTriggered=function(){s=a.get();i.set(s)}}};CABLES.OPS["712a25f4-3a93-4042-b8c5-2f56169186cc"]={f:Ops.Boolean.ToggleBool,objName:"Ops.Boolean.ToggleBool"};Ops.Trigger.TriggerSend=class extends CABLES.Op{constructor(){super(...arguments);const r=this;const e=r.attachments={};const t=r.inTriggerButton("Trigger"),n=r.outTrigger("Next");r.varName=r.inValueSelect("Named Trigger",[],"",true);r.varName.onChange=a;t.onTriggered=s;r.patch.addEventListener("namedTriggersChanged",i);i();r.varName.setUiAttribs({_triggerSelect:true});function i(){if(CABLES.UI){let e=[];const t=r.patch.namedTriggers;e.push("+ create new one");for(const n in t)e.push(n);e=e.sort();r.varName.uiAttribs.values=e}}function a(){if(CABLES.UI){if(r.varName.get()=="+ create new one"){new CABLES.UI.ModalDialog({prompt:true,title:"New Trigger",text:"Enter a name for the new trigger",promptValue:"",promptOk:e=>{r.varName.set(e);r.patch.namedTriggers[e]=r.patch.namedTriggers[e]||[];i()}});return}r.refreshParams()}if(!r.patch.namedTriggers[r.varName.get()]){r.patch.namedTriggers[r.varName.get()]=r.patch.namedTriggers[r.varName.get()]||[];r.patch.emitEvent("namedTriggersChanged")}r.setTitle(">"+r.varName.get());r.refreshParams();r.patch.emitEvent("opTriggerNameChanged",r,r.varName.get())}function s(){const t=r.patch.namedTriggers[r.varName.get()];r.patch.emitEvent("namedTriggerSent",r.varName.get());if(!t){r.setUiError("unknowntrigger","unknown trigger");return}else r.setUiError("unknowntrigger",null);for(let e=0;e<t.length;e++){t[e]()}n.trigger()}}};CABLES.OPS["ce1eaf2b-943b-4dc0-ab5e-ee11b63c9ed0"]={f:Ops.Trigger.TriggerSend,objName:"Ops.Trigger.TriggerSend"};Ops.Gl.ClearDepth=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inTrigger("render"),r=e.outTrigger("trigger"),i=e.patch.cgl;n.onTriggered=function(){i.gl.clear(i.gl.DEPTH_BUFFER_BIT);r.trigger()}}};CABLES.OPS["9e8a4b73-4ba7-4c4f-b266-81c5f9db9b7a"]={f:Ops.Gl.ClearDepth,objName:"Ops.Gl.ClearDepth"};Ops.Ui.PatchInput=class extends CABLES.Op{constructor(){super(...arguments);const i=this;const e=i.attachments={};const a=i.addOutPort(new CABLES.Port(i,"create port",CABLES.OP_PORT_TYPE_DYNAMIC));function s(){for(let e in i.patch.ops){if(i.patch.ops[e].patchId){if(i.patch.ops[e].patchId.get()==i.uiAttribs.subPatch){return i.patch.ops[e]}}}}a.onLinkChanged=()=>{const e=s();if(!a.links.length||!e||!e.addNewInPort)return;const t=a.links[0].getOtherPort(a);a.removeLinks();const n=e.addNewInPort(t);const r=gui.scene().link(t.parent,t.getName(),i,n);e.saveData()}}};CABLES.OPS["e3f68bc3-892a-4c78-9974-aca25c27025d"]={f:Ops.Ui.PatchInput,objName:"Ops.Ui.PatchInput"};Ops.Ui.PatchOutput=class extends CABLES.Op{constructor(){super(...arguments);const i=this;const e=i.attachments={};const a=i.addInPort(new CABLES.Port(i,"create port",CABLES.OP_PORT_TYPE_DYNAMIC));function s(){for(let e in i.patch.ops){if(i.patch.ops[e].patchId){if(i.patch.ops[e].patchId.get()==i.uiAttribs.subPatch){return i.patch.ops[e]}}}}a.onLinkChanged=()=>{const e=s();if(!a.links.length)return;const t=a.links[0].getOtherPort(a);a.removeLinks();const n=e.addNewOutPort(t);const r=gui.scene().link(t.parent,t.getName(),i,n);e.saveData()}}};CABLES.OPS["851b44cb-5667-4140-9800-5aeb7031f1d7"]={f:Ops.Ui.PatchOutput,objName:"Ops.Ui.PatchOutput"};Ops.Math.Compare.GreaterThan=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValueFloat("number1"),r=e.inValueFloat("number2"),i=e.outBoolNum("result");e.setUiAttribs({mathTitle:true});n.onChange=r.onChange=a;function a(){i.set(n.get()>r.get())}}};CABLES.OPS["b250d606-f7f8-44d3-b099-c29efff2608a"]={f:Ops.Math.Compare.GreaterThan,objName:"Ops.Math.Compare.GreaterThan"};Ops.Boolean.TriggerChangedTrue=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};let n=e.inValueBool("Value",false);let r=e.outTrigger("Next");let i=0;n.onChange=function(){let e=n.get();if(!i&&e){i=true;r.trigger()}else{i=false}}}};CABLES.OPS["385197e1-8b34-4d1c-897f-d1386d99e3b3"]={f:Ops.Boolean.TriggerChangedTrue,objName:"Ops.Boolean.TriggerChangedTrue"};Ops.TimeLine.TimeLineTime=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.outNumber("time");e.onAnimFrame=function(e){n.set(e)}}};CABLES.OPS["3ab26f26-a12a-4c48-9411-20591a5f569d"]={f:Ops.TimeLine.TimeLineTime,objName:"Ops.TimeLine.TimeLineTime"};Ops.TimeLine.TimeLinePlay=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inTriggerButton("Play"),r=e.inTriggerButton("Pause"),i=e.outTrigger("Next");n.onTriggered=function(){e.patch.timer.play();i.trigger()};r.onTriggered=function(){e.patch.timer.pause();i.trigger()}}};CABLES.OPS["fc75b841-a55f-4474-8746-61218588598d"]={f:Ops.TimeLine.TimeLinePlay,objName:"Ops.TimeLine.TimeLinePlay"};Ops.Math.Subtract=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValue("number1",1),r=e.inValue("number2",1),i=e.outNumber("result");e.setUiAttribs({mathTitle:true});n.onChange=r.onChange=a;a();function a(){let e=n.get()-r.get();if(!isNaN(e))i.set(e)}}};CABLES.OPS["a4ffe852-d200-4b96-9347-68feb01122ca"]={f:Ops.Math.Subtract,objName:"Ops.Math.Subtract"};Ops.TimeLine.TimeLineSetTime=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inTriggerButton("Update"),r=e.inFloat("Time",0),i=e.outTrigger("Next");n.onTriggered=function(){e.patch.timer.setTime(parseFloat(r.get()));i.trigger()}}};CABLES.OPS["c65f3975-0901-4252-b040-f21f9b144d70"]={f:Ops.TimeLine.TimeLineSetTime,objName:"Ops.TimeLine.TimeLineSetTime"};Ops.TimeLine.TimeLineRewind=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inTriggerButton("exe"),r=e.outTrigger("Next");n.onTriggered=function(){e.patch.timer.setTime(0);r.trigger()}}};CABLES.OPS["d3408604-858c-4226-8d4c-1ef669956f35"]={f:Ops.TimeLine.TimeLineRewind,objName:"Ops.TimeLine.TimeLineRewind"};Ops.Html.Utils.PlayerControlPanel_v2=class extends CABLES.Op{constructor(){super(...arguments);const i=this;const e=i.attachments={css_progressui_css:".progressUI\n{\n    padding: 10px;\n    position: absolute;\n    border-radius: 10px;\n    background-color: rgba(0,0,0,0.45);\n    margin: 20px;\n    bottom: 10px;\n    height:30px;\n    margin-left:50%;\n    transform: translate(-50%);\n    display: flex;\n    align-items: center;\n}\n\n.progressUI .buttonContainer {\n    display: flex;\n    align-content: center;\n    height: 100%;\n}\n\n.progressUI .progress\n{\n    font-family: Monospace;\n    float:left;\n    color:white;\n    width: auto;\n    margin-left:15px;\n    margin-right: 10px;\n}\n\n.progressUI .progressContainer\n{\n    width:200px;\n    overflow: hidden;\n    background: rgba(0,0,0,0.4);\n    border-radius: 4px;\n    float:left;\n    display: flex;\n    flex-direction: row;\n    align-items: center;\n    height: 100%;\n}\n\n.progressUI .button\n{\n    cursor: pointer;\n    box-sizing: border-box;\n    background: rgba(0,0,0,0.4);\n    display: flex;\n    align-content: center;\n    padding: 5px;\n    padding-left: 10px;\n    padding-right: 10px;\n    margin-right: 5px;\n    border-radius: 5px;\n    float:left;\n    display: flex;\n    align-items: center;\n}\n\n.progressUIIcon\n{\n    display: inline-block;\n    vertical-align: middle;\n    width: 15px;\n    height: 15px;\n    background-color: white;\n    -webkit-mask-repeat: no-repeat !important;\n    -webkit-mask-size: 100% !important;\n}\n\n.progressUI .progressContainer .progressbar {\n    height: 100%;\n    width: 97%;\n}\n\n.progressUI_icon-play {\n    -webkit-mask: url(\"data:image/svg+xml;charset=utf8, %3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-play'%3E%3Cpath d='M5 3l14 9-14 9V3z'/%3E%3C/svg%3E\");\n    mask: url(\"data:image/svg+xml;charset=utf8, %3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-play'%3E%3Cpath d='M5 3l14 9-14 9V3z'/%3E%3C/svg%3E\");\n}\n\n.progressUI_icon-pause {\n    -webkit-mask: url(\"data:image/svg+xml;charset=utf8, %3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-pause'%3E%3Cpath d='M6 4h4v16H6zM14 4h4v16h-4z'/%3E%3C/svg%3E\");\n    mask: url(\"data:image/svg+xml;charset=utf8, %3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-pause'%3E%3Cpath d='M6 4h4v16H6zM14 4h4v16h-4z'/%3E%3C/svg%3E\");\n}\n\n.progressUI_icon-rewind {\n    -webkit-mask: url(\"data:image/svg+xml;charset=utf8, %3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-rewind'%3E%3Cpath d='M11 19l-9-7 9-7v14zM22 19l-9-7 9-7v14z'/%3E%3C/svg%3E\");\n    mask: url(\"data:image/svg+xml;charset=utf8, %3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-rewind'%3E%3Cpath d='M11 19l-9-7 9-7v14zM22 19l-9-7 9-7v14z'/%3E%3C/svg%3E\");\n}\n\n.progressUI_icon-fast-forward {\n    -webkit-mask: url(\"data:image/svg+xml;charset=utf8, %3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-fast-forward'%3E%3Cpath d='M13 19l9-7-9-7v14zM2 19l9-7-9-7v14z'/%3E%3C/svg%3E\");\n    mask: url(\"data:image/svg+xml;charset=utf8, %3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-fast-forward'%3E%3Cpath d='M13 19l9-7-9-7v14zM2 19l9-7-9-7v14z'/%3E%3C/svg%3E\");\n}\n\n.progressUI_icon-skip-back {\n    -webkit-mask: url(\"data:image/svg+xml;charset=utf8, %3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-skip-back'%3E%3Cpath d='M19 20L9 12l10-8v16zM5 19V5'/%3E%3C/svg%3E\");\n    mask: url(\"data:image/svg+xml;charset=utf8, %3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-skip-back'%3E%3Cpath d='M19 20L9 12l10-8v16zM5 19V5'/%3E%3C/svg%3E\");\n}\n"};const t=i.inFloat("Length",30),r=i.inFloat("Current",0),n=i.inBool("Clamp",false),a=i.inBool("Is Playing",false),s=i.inBool("Visible",true),o=i.inBool("Show Time"),l=i.inBool("Show Skip Buttons"),u=i.outTrigger("Play clicked"),c=i.outTrigger("Pause clicked"),h=i.outTrigger("Rewind clicked"),f=i.outTrigger("Skip Back clicked"),d=i.outTrigger("Skip Forward clicked"),p=i.outTrigger("Dragged"),g=i.outNumber("Current Value"),m=i.outBoolNum("Dragging",false),v=i.outObject("DOM Element",null,"element");let b=i.patch.getDocument().createElement("div");b.id="progressUI_"+i.id;b.classList.add("progressUI");v.set(b);const w=i.patch.cgl;let N=i.patch.cgl.canvas.parentElement;N.appendChild(b);let _=i.patch.getDocument().createElement("div");if(!s.get()){b.style.display="none"}let E=i.patch.getDocument().createElement("input");let F=i.patch.getDocument().createElement("div");const C=i.patch.getDocument().createElement("div");_.classList.add("progressContainer");_.appendChild(E);E.setAttribute("type","range");E.setAttribute("step",.01);E.setAttribute("min",0);E.setAttribute("max",t.get());E.setAttribute("value",r.get());E.classList.add("progressbar");E.addEventListener("input",j);let A=false;let x=false;b.appendChild(C);b.appendChild(_);b.appendChild(F);let P="css_progressui_"+CABLES.uuid();const T=i.patch.getDocument().createElement("style");T.type="text/css";T.id=P;T.classList.add("cablesEle");let U=i.patch.getDocument().getElementsByTagName("body")[0];U.appendChild(T);C.classList.add("buttonContainer");let S=D("","progressUI_icon-skip-back");C.appendChild(S);let y=D("","progressUI_icon-rewind","skip");if(!l.get()){y.style.display="none"}C.appendChild(y);y.addEventListener("pointerdown",()=>{f.trigger()});let B=D("","progressUI_icon-play");C.appendChild(B);let O=D("","progressUI_icon-fast-forward","skip");if(!l.get()){O.style.display="none"}C.appendChild(O);O.addEventListener("pointerdown",()=>{d.trigger()});F.classList.add("progress");F.innerHTML="00:00:000";function D(e,t,n){let r=i.patch.getDocument().createElement("div");r.classList.add("button");r.classList.add(n);r.innerHTML=e;if(t){let e=i.patch.getDocument().createElement("div");e.classList.add("progressUIIcon");e.classList.add(t);r.appendChild(e)}return r}t.onChange=()=>{E.setAttribute("max",t.get())};s.onChange=()=>{if(s.get()){b.style.removeProperty("display")}else{b.style.display="none"}};o.onChange=()=>{if(o.get()){b.classList.add("showValue");F.style.display="block"}else{b.classList.remove("showValue");F.style.display="none"}};l.onChange=()=>{if(l.get()){b.querySelectorAll(".button.skip").forEach(e=>{e.style.display="block"})}else{b.querySelectorAll(".button.skip").forEach(e=>{e.style.display="none"})}};if(!o.get()){F.style.display="none"}E.addEventListener("pointerdown",()=>{x=true;if(a.get()){A=true;c.trigger();I()}});E.addEventListener("pointermove",()=>{const e=E.value;if(x){m.set(x);R(e);g.set(e);p.trigger()}});E.addEventListener("pointerup",()=>{const e=E.value;R(e);g.set(e);if(x){p.trigger()}x=false;m.set(x);if(A){A=false;u.trigger();I()}});function k(){T.textContent=e.css_progressui_css}function I(){B.querySelector(".progressUIIcon").classList.remove("progressUI_icon-play");B.querySelector(".progressUIIcon").classList.remove("progressUI_icon-pause");if(a.get()){B.querySelector(".progressUIIcon").classList.add("progressUI_icon-pause")}else{B.querySelector(".progressUIIcon").classList.add("progressUI_icon-play")}}B.addEventListener("pointerdown",function(){if(a.get()){c.trigger()}else{u.trigger()}I()});S.addEventListener("pointerdown",()=>{g.set(0);h.trigger()});i.onDelete=function(){if(b)b.remove();if(T)T.remove()};function j(e){r.onChange=null;const t=e.target.value;g.set(t);r.onChange=M}function M(){let e=r.get();if(n.get()&&e>t.get()){e=t.get()}E.value=e;g.set(e);R()}let L=0;function R(e=null){let t=e||r.get();let n=t;if(n!=L){F.innerHTML=G(n);L=n}}function G(e){const t=String(new Date(e*1e3).getUTCMinutes()).padStart(2,"0");const n=String(new Date(e*1e3).getUTCSeconds()).padStart(2,"0");const r=String(new Date(e*1e3).getUTCMilliseconds()).padStart(2,"0").padEnd(3,"0");const i=t+":"+n+":"+r;return i}k();I();r.onChange=M;a.onChange=I}};CABLES.OPS["12ac1d94-f043-454d-92a8-60733d2908b2"]={f:Ops.Html.Utils.PlayerControlPanel_v2,objName:"Ops.Html.Utils.PlayerControlPanel_v2"};Ops.Math.Multiply=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValueFloat("number1",1),r=e.inValueFloat("number2",1),i=e.outNumber("result");e.setUiAttribs({mathTitle:true});n.onChange=r.onChange=a;a();function a(){const e=n.get();const t=r.get();i.set(e*t)}}};CABLES.OPS["1bbdae06-fbb2-489b-9bcc-36c9d65bd441"]={f:Ops.Math.Multiply,objName:"Ops.Math.Multiply"};Ops.Gl.ForceCanvasSize=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inTrigger("Trigger"),l=e.inBool("Active",true),r=e.inSwitch("Force",["Resolution","Aspect Ratio"],"Resolution"),u=e.inBool("Center In Parent",true),c=e.inBool("Scale to fit Parent",true),h=e.inInt("Set Width",300),f=e.inInt("Set Height",200),i=e.inDropDown("Aspect Ratio",["Custom","21:9","2:1","16:9","16:10","4:3","1:1","9:16","1:2","iPhoneXr Vert"],"16:9"),d=e.inFloat("Ratio",0),a=e.inDropDown("Fill Parent",["Auto","Width","Height","Both"],"Auto"),p=e.outTrigger("Next"),g=e.outNumber("Width"),m=e.outNumber("Height"),v=e.outNumber("Margin Left"),b=e.outNumber("Margin Top");e.setPortGroup("Size",[h,f]);e.setPortGroup("Proportions",[d,a,i]);let _=0;const s=0;const E=1;const F=2;const C=3;const A=4;a.onChange=S;r.onChange=o;u.onChange=n.onLinkChanged=y;i.onChange=T;const x=e.patch.cgl;S();function o(){if(r.get()=="Aspect Ratio"){d.set(100);T()}S()}function T(){const e=i.get();if(e=="Custom")return;else if(e=="16:9")d.set(16/9);else if(e=="4:3")d.set(4/3);else if(e=="16:10")d.set(16/10);else if(e=="21:9")d.set(21/9);else if(e=="2:1")d.set(2);else if(e=="1:1")d.set(1);else if(e=="9:16")d.set(9/16);else if(e=="1:2")d.set(.5);else if(e=="iPhoneXr Vert")d.set(9/19.5)}e.on("delete",()=>{y()});d.onChange=()=>{y()};l.onChange=function(){if(!l.get())y()};function S(){const e=r.get()=="Resolution";h.setUiAttribs({greyout:!e});f.setUiAttribs({greyout:!e});i.setUiAttribs({greyout:e});a.setUiAttribs({greyout:e});d.setUiAttribs({greyout:e});_=0;if(!e){const t=a.get();if(t=="Width")_=E;else if(t=="Height")_=F;else if(t=="Both")_=C;else if(t=="Auto")_=A}}function y(){x.canvas.style["margin-top"]="";x.canvas.style["margin-left"]="";x.canvas.styleMarginLeft=0;x.canvas.styleMarginTop=0;v.set(0);b.set(0);const e=x.canvas.parentNode.getBoundingClientRect();x.setSize(e.width,e.height);x.canvas.style.transform="scale(1)";x.canvas.style.position="absolute";x.updateSize()}n.onTriggered=function(){if(!l.get())return p.trigger();let e=h.get();let t=f.get();let n=x.canvas.parentNode.getBoundingClientRect();if(n.height==0){x.canvas.parentNode.style.height="100%";n=x.canvas.parentNode.getBoundingClientRect()}if(n.width==0){x.canvas.parentNode.style.width="100%";n=x.canvas.parentNode.getBoundingClientRect()}if(_==E){e=n.width;t=e*1/d.get()}else if(_==F){t=n.height;e=t*d.get()}else if(_==A){const r=n;t=r.height;e=t*d.get();if(e>r.width){e=r.width;t=e*1/d.get()}}else if(_==C){const r=n;t=r.height;e=t*d.get();if(e<r.width){e=r.width;t=e*1/d.get()}}e=Math.ceil(e);t=Math.ceil(t);if(u.get()){const r=n;const i=(r.height-t)/2;const a=(r.width-e)/2;v.set(a);b.set(i);x.canvas.style["margin-top"]=i+"px";x.canvas.style["margin-left"]=a+"px";x.canvas.styleMarginTop=i;x.canvas.styleMarginLeft=a}else{x.canvas.style["margin-top"]="0";x.canvas.style["margin-left"]="0";x.canvas.styleMarginTop=0;x.canvas.styleMarginLeft=0;v.set(0);b.set(0)}if(c.get()){const r=n;const s=r.width/h.get();const o=r.height/f.get();x.canvas.style.transform="scale("+Math.min(s,o)+")"}else{x.canvas.style.transform="scale(1)"}if(x.canvasWidth!=e||x.canvasHeight!=t){g.set(e);m.set(t);x.setSize(e,t)}p.trigger()}}};CABLES.OPS["a8b3380e-cd4a-4000-9ee9-1c65a11027dd"]={f:Ops.Gl.ForceCanvasSize,objName:"Ops.Gl.ForceCanvasSize"};Ops.Html.Cursor=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValueSelect("cursor",["auto","crosshair","pointer","hand","move","n-resize","ne-resize","e-resize","se-resize","s-resize","sw-resize","w-resize","nw-resize","text","wait","help","none"]),r=e.inTriggerButton("Set Cursor"),i=e.patch.cgl;n.onChange=r.onTriggered=a;function a(){var e=n.get();i.canvas.style.cursor=e}}};CABLES.OPS["409f94da-6264-435c-8e73-03e8d2275e04"]={f:Ops.Html.Cursor,objName:"Ops.Html.Cursor"};Ops.Html.WindowClose=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inTriggerButton("Close");n.onTriggered=function(){window.close()}}};CABLES.OPS["4f5d56b9-28a0-47fe-86f7-7b765268d694"]={f:Ops.Html.WindowClose,objName:"Ops.Html.WindowClose"};Ops.Trigger.TriggerReceive=class extends CABLES.Op{constructor(){super(...arguments);const r=this;const e=r.attachments={};const t=r.outTrigger("Triggered");r.varName=r.inValueSelect("Named Trigger",[],"",true);r.varName.setUiAttribs({_triggerSelect:true});a();r.patch.addEventListener("namedTriggersChanged",a);let n=null;function i(){t.trigger()}function a(){if(CABLES.UI){let t=[];let n=r.patch.namedTriggers;for(let e in n)t.push(e);t=t.sort();r.varName.uiAttribs.values=t}}r.varName.onChange=function(){if(n){let e=r.patch.namedTriggers[n];let t=e.indexOf(i);if(t!=-1)e.splice(t,1)}r.setTitle(">"+r.varName.get());r.patch.namedTriggers[r.varName.get()]=r.patch.namedTriggers[r.varName.get()]||[];let e=r.patch.namedTriggers[r.varName.get()];e.push(i);n=r.varName.get();s();r.patch.emitEvent("opTriggerNameChanged",r,r.varName.get())};r.on("uiParamPanel",s);function s(){if(!r.varName.get()){r.setUiError("unknowntrigger","unknown trigger")}else r.setUiError("unknowntrigger",null)}}};CABLES.OPS["0816c999-f2db-466b-9777-2814573574c5"]={f:Ops.Trigger.TriggerReceive,objName:"Ops.Trigger.TriggerReceive"};Ops.Graphics.Meshes.Circle_v2=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inTrigger("render"),r=e.inValueBool("Draw",true),D=e.inValue("radius",.5),I=e.inValueSlider("innerRadius",0),M=e.inValueInt("segments",40),L=e.inValueSlider("percent",1),R=e.inValue("steps",0),w=e.inValueBool("invertSteps",false),N=e.inSwitch("mapping",["flat","round"]),P=e.inValueBool("Spline",false),i=e.outTrigger("trigger"),U=e.outObject("geometry",null,"geometry");e.setPortGroup("Size",[D,I]);e.setPortGroup("Display",[L,R,w]);e.toWorkShouldNotBeChild("Ops.Gl.TextureEffects.ImageCompose",CABLES.OP_PORT_TYPE_FUNCTION);e.toWorkPortsNeedToBeLinked(n);r.setUiAttribs({title:"Render mesh"});N.set("flat");N.onChange=M.onChange=D.onChange=I.onChange=L.onChange=R.onChange=w.onChange=P.onChange=h;U.ignoreValueSerialize=true;const a=e.patch.cgl;let k=new CGL.Geometry("circle");let j=null;const s=-1;let o=0;let l=null;let G=true;n.onTriggered=u;e.preRender=()=>{u()};n.onLinkChanged=function(){if(!n.isLinked())U.set(null);else U.setRef(k)};function u(){if(G)c();if(!CGL.TextureEffect.checkOpNotInTextureEffect(e))return;l=e.patch.cg.getShader();if(!l)return;o=l.glPrimitive;if(P.get())l.glPrimitive=a.gl.LINE_STRIP;if(r.get()&&j)j.render(l);i.trigger();l.glPrimitive=o}function c(){const n=Math.max(3,Math.floor(M.get()));k.clear();const t=[];const r=[];const i=[];const a=[];const s=[];let o=0,l=0;let u=0,c=0;let h=0,f=0;let d=0,p=0;let g=0,m=0;let v=0,b=0;let _=0,E=0;let F=0,C=0;const A=Math.max(0,L.get());const x=[];if(P.get()){let e=0;let t=0;const T=[];for(o=0;o<=n*A;o++){l=360/n*o*CGL.DEG2RAD;F=Math.cos(l)*D.get();C=Math.sin(l)*D.get();E=.5;if(o>0){x.push(e);x.push(t);x.push(0);_=1-(o-1)/n;T.push(_,E)}x.push(F);x.push(C);x.push(0);e=F;t=C}k.setPointVertices(x)}else if(I.get()<=0){for(o=0;o<=n*A;o++){l=360/n*o*CGL.DEG2RAD;F=Math.cos(l)*D.get();C=Math.sin(l)*D.get();if(N.get()=="flat"){_=(Math.cos(l)+1)/2;E=1-(Math.sin(l)+1)/2;v=.5;b=.5}else if(N.get()=="round"){_=1-o/n;E=0;v=_;b=1}t.push([0,0,0],[u,c,0],[F,C,0]);r.push(v,b,h,f,_,E);i.push(0,0,1,0,0,1,0,0,1);a.push(1,0,0,1,0,0,1,0,0);s.push(0,-1,0,0,-1,0,0,-1,0);h=_;f=E;u=F;c=C}k=CGL.Geometry.buildFromFaces(t,"circle");k.vertexNormals=i;k.tangents=a;k.biTangents=s;k.texCoords=r}else{let e=0;const S=n*A;const y=0;for(o=0;o<=S;o++){e++;l=360/n*o*CGL.DEG2RAD;F=Math.cos(l)*D.get();C=Math.sin(l)*D.get();const B=Math.cos(l)*I.get()*D.get();const O=Math.sin(l)*I.get()*D.get();if(N.get()=="round"){_=1-o/n;E=0;v=_;b=1}if(R.get()===0||e%parseInt(R.get(),10)===0&&!w.get()||e%parseInt(R.get(),10)!==0&&w.get()){t.push([F,C,0],[u,c,0],[B,O,0]);t.push([B,O,0],[u,c,0],[d,p,0]);r.push(_,0,h,0,v,1,_,1,h,0,g,1);i.push(0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1);a.push(1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0);s.push(0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1)}g=v;m=b;h=_;f=E;u=F;c=C;d=B;p=O}k=CGL.Geometry.buildFromFaces(t,"circle");k.vertexNormals=i;k.tangents=a;k.biTangents=s;if(N.get()=="flat")k.mapTexCoords2d();else k.texCoords=r}U.setRef(k);if(k.vertices.length==0)return;if(j)j.dispose();j=null;j=e.patch.cg.createMesh(k,{opId:e.id});G=false}function h(){G=true}e.onDelete=function(){if(j)j.dispose()}}};CABLES.OPS["641eaae4-37cc-4e80-b8db-4be283ed5573"]={f:Ops.Graphics.Meshes.Circle_v2,objName:"Ops.Graphics.Meshes.Circle_v2"};Ops.Math.Fract=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValue("Value"),r=e.outNumber("Result");n.onChange=function(){const e=n.get();r.set(e-Math.floor(e))}}};CABLES.OPS["12573ba7-866d-40c4-9ddd-14d9331ffe6f"]={f:Ops.Math.Fract,objName:"Ops.Math.Fract"};Ops.Graphics.Transform=class extends CABLES.Op{constructor(){super(...arguments);const n=this;const e=n.attachments={};const t=n.inTrigger("render"),r=n.inValue("posX",0),i=n.inValue("posY",0),a=n.inValue("posZ",0),s=n.inValue("scale",1),o=n.inValue("rotX",0),l=n.inValue("rotY",0),u=n.inValue("rotZ",0),c=n.outTrigger("trigger");n.setPortGroup("Rotation",[o,l,u]);n.setPortGroup("Position",[r,i,a]);n.setPortGroup("Scale",[s]);n.setUiAxisPorts(r,i,a);n.toWorkPortsNeedToBeLinked(t,c);const h=vec3.create();const f=vec3.create();const d=mat4.create();mat4.identity(d);let p=false,g=false,m=true,v=true,b=true;o.onChange=l.onChange=u.onChange=x;r.onChange=i.onChange=a.onChange=C;s.onChange=A;t.onTriggered=function(){let e=false;if(m){E();e=true}if(v){F();e=true}if(b)e=true;if(e)_();const t=n.patch.cg||n.patch.cgl;t.pushModelMatrix();mat4.multiply(t.mMatrix,t.mMatrix,d);c.trigger();t.popModelMatrix();if(CABLES.UI){if(!r.isLinked()&&!i.isLinked()&&!a.isLinked()){gui.setTransform(n.id,r.get(),i.get(),a.get());if(n.isCurrentUiOp())gui.setTransformGizmo({posX:r,posY:i,posZ:a})}}};function _(){mat4.identity(d);if(g)mat4.translate(d,d,h);if(o.get()!==0)mat4.rotateX(d,d,o.get()*CGL.DEG2RAD);if(l.get()!==0)mat4.rotateY(d,d,l.get()*CGL.DEG2RAD);if(u.get()!==0)mat4.rotateZ(d,d,u.get()*CGL.DEG2RAD);if(p)mat4.scale(d,d,f);b=false}function E(){g=false;if(r.get()!==0||i.get()!==0||a.get()!==0)g=true;vec3.set(h,r.get(),i.get(),a.get());m=false}function F(){p=true;vec3.set(f,s.get(),s.get(),s.get());v=false}function C(){m=true}function A(){v=true}function x(){b=true}_()}};CABLES.OPS["650baeb1-db2d-4781-9af6-ab4e9d4277be"]={f:Ops.Graphics.Transform,objName:"Ops.Graphics.Transform"};Ops.Math.Modulo=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValueFloat("number1",1),r=e.inValueFloat("number2",2),i=e.inValueBool("pingpong"),a=e.outNumber("result");let s=l;n.onChange=r.onChange=o;i.onChange=c;o();function o(){let e=r.get();let t=n.get();a.set(s(t,e))}function l(e,t){let n=(e%t+t)%t;if(n!=n)n=0;return n}function u(e,t){let n=2*t;e%=n;if(e>=t)return n-e;else return e}function c(){if(i.get())s=u;else s=l}}};CABLES.OPS["ebc13b25-3705-4265-8f06-5f985b6a7bb1"]={f:Ops.Math.Modulo,objName:"Ops.Math.Modulo"};Ops.Number.Integer=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inInt("Integer",0),r=e.outNumber("Number out");n.onChange=function(){r.set(Math.floor(n.get()))}}};CABLES.OPS["17bc01d7-04ad-4aab-b88b-bb09744c4a69"]={f:Ops.Number.Integer,objName:"Ops.Number.Integer"};Ops.String.StringCompose_v3=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inString("Format","hello $a, $b $c und $d"),r=e.inString("String A","world"),i=e.inString("String B",1),a=e.inString("String C",2),s=e.inString("String D",3),o=e.inString("String E"),l=e.inString("String F"),u=e.outString("Result");n.onChange=r.onChange=i.onChange=a.onChange=s.onChange=o.onChange=l.onChange=c;c();function c(){var e=n.get()||"";if(typeof e!="string")e="";e=e.replace(/\$a/g,r.get());e=e.replace(/\$b/g,i.get());e=e.replace(/\$c/g,a.get());e=e.replace(/\$d/g,s.get());e=e.replace(/\$e/g,o.get());e=e.replace(/\$f/g,l.get());u.set(e)}}};CABLES.OPS["6afea9f4-728d-4f3c-9e75-62ddc1448bf0"]={f:Ops.String.StringCompose_v3,objName:"Ops.String.StringCompose_v3"};Ops.String.NumberToString_v2=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValue("Number"),r=e.inInt("Decimal Places",4),i=e.outString("Result");let a=false;let s=1;r.onChange=o;n.onChange=l;o();l();function o(){a=r.get()<100;s=Math.pow(10,r.get());l()}function l(){if(a)i.set(String(Math.round(n.get()*s)/s));else i.set(String(n.get()||0))}}};CABLES.OPS["5c6d375a-82db-4366-8013-93f56b4061a9"]={f:Ops.String.NumberToString_v2,objName:"Ops.String.NumberToString_v2"};Ops.Gl.Meshes.TextMesh_v2=class extends CABLES.Op{constructor(){super(...arguments);const t=this;const e=t.attachments={textmesh_frag:"{{MODULES_HEAD}}\n\n#define INSTANCING\n\nUNI sampler2D tex;\n#ifdef DO_MULTEX\n    UNI sampler2D texMul;\n#endif\n#ifdef DO_MULTEX_MASK\n    UNI sampler2D texMulMask;\n#endif\nIN vec2 texCoord;\nIN vec2 texPos;\nUNI float r;\nUNI float g;\nUNI float b;\nUNI float a;\n\nflat IN float frag_instIndex;\n\nvoid main()\n{\n    {{MODULE_BEGIN_FRAG}}\n\n    vec4 col=texture(tex,texCoord);\n    col.a=col.r;\n    col.r*=r;\n    col.g*=g;\n    col.b*=b;\n    col*=a;\n\n    if(col.a==0.0)discard;\n\n    #ifdef DO_MULTEX\n        col*=texture(texMul,texPos);\n    #endif\n\n    #ifdef DO_MULTEX_MASK\n        col*=texture(texMulMask,texPos).r;\n    #endif\n\n    {{MODULE_COLOR}}\n\n    outColor=col;\n}",textmesh_vert:"{{MODULES_HEAD}}\n\nUNI sampler2D tex;\nUNI mat4 projMatrix;\nUNI mat4 modelMatrix;\nUNI mat4 viewMatrix;\nUNI float scale;\nIN vec3 vPosition;\nIN vec2 attrTexCoord;\nIN mat4 instMat;\nIN vec2 attrTexOffsets;\nIN vec2 attrTexSize;\nIN vec2 attrTexPos;\nIN float attrVertIndex;\nIN float instanceIndex;\nflat OUT float frag_instIndex;\n\nOUT vec2 texPos;\n\nOUT vec2 texCoord;\nOUT vec4 modelPos;\n\nvoid main()\n{\n\n    texCoord=(attrTexCoord*(attrTexSize)) + attrTexOffsets;\n    mat4 instMVMat=instMat;\n    instMVMat[3][0]*=scale;\n\n    texPos=attrTexPos;\n\n    vec4 pos=vec4( vPosition.x*(attrTexSize.x/attrTexSize.y)*scale,vPosition.y*scale,vPosition.z*scale, 1. );\n\n    mat4 mvMatrix=viewMatrix * modelMatrix * instMVMat;\n    frag_instIndex=instanceIndex;\n\n    {{MODULE_VERTEX_POSITION}}\n\n    gl_Position = projMatrix * mvMatrix * pos;\n}\n\n"};const n=t.inTrigger("Render"),b=t.inString("Text","cables"),r=t.inFloat("Scale Text",1),i=t.inValueFloat("Scale",1),c=t.inString("Font","Arial"),_=t.inValueSelect("align",["left","center","right"],"center"),a=t.inValueSelect("vertical align",["Top","Middle","Bottom"],"Middle"),E=t.inValueFloat("Line Height",1),F=t.inValueFloat("Letter Spacing"),o=t.inSwitch("filter",["nearest","linear","mipmap"],"mipmap"),l=t.inSwitch("Anisotropic",[0,1,2,4,8,16],0),s=t.inTexture("Texture Color"),u=t.inTexture("Texture Mask"),N=t.outTrigger("Next"),C=t.outTexture("texture"),P=t.outNumber("Total Lines",0),U=t.outNumber("Width",0),k=t.outBoolNum("Font Available",0);const A=t.patch.cgl;const h=vec3.create();vec3.set(h,1,1,1);t.toWorkPortsNeedToBeLinked(n);t.setPortGroup("Masking",[s,u]);i.setUiAttribs({title:"Line Scale"});C.setUiAttribs({hidePort:true});const f=1024;let d=false;let p=true;_.onChange=b.onChange=E.onChange=j;function j(){p=true}let g=null;CABLES.OpTextureMeshCanvas={};let m=0;const G=null;let x=null;let T=true;let S=true;t.onDelete=function(){if(x)x.dispose()};r.onChange=()=>{vec3.set(h,r.get(),r.get(),r.get())};l.onChange=o.onChange=()=>{y().texture=null;S=true};u.onChange=s.onChange=function(){B.toggleDefine("DO_MULTEX",s.get());B.toggleDefine("DO_MULTEX_MASK",u.get())};C.setRef(null);c.onChange=function(){S=true;T=true;v()};t.patch.on("fontLoaded",e=>{if(e==c.get()){S=true;T=true}});function v(){const e=d;try{d=document.fonts.check('20px "'+c.get()+'"')}catch(e){t.logError(e)}if(!e&&d){k.set(true);S=true;T=true}if(!d)setTimeout(v,250)}a.onChange=function(){if(a.get()=="Middle")m=0;else if(a.get()=="Top")m=1;else if(a.get()=="Bottom")m=2};function y(){g=""+c.get();if(CABLES.OpTextureMeshCanvas.hasOwnProperty(g))return CABLES.OpTextureMeshCanvas[g];const e=document.createElement("canvas");e.dataset.font=c.get();e.id="texturetext_"+CABLES.generateUUID();e.style.display="none";const t=document.getElementsByTagName("body")[0];t.appendChild(e);const n=e.getContext("2d");CABLES.OpTextureMeshCanvas[g]={ctx:n,canvas:e,chars:{},characters:"",fontSize:320};return CABLES.OpTextureMeshCanvas[g]}t.onDelete=function(){if(g&&CABLES.OpTextureMeshCanvas[g])CABLES.OpTextureMeshCanvas[g].canvas.remove()};const B=new CGL.Shader(A,"TextMesh",this);B.setSource(e.textmesh_vert,e.textmesh_frag);const V=new CGL.Uniform(B,"t","tex",0);const z=new CGL.Uniform(B,"t","texMul",1);const H=new CGL.Uniform(B,"t","texMulMask",2);const X=new CGL.Uniform(B,"f","scale",i);const O=t.inValueSlider("r",1),D=t.inValueSlider("g",1),I=t.inValueSlider("b",1),W=t.inValueSlider("a",1),Y=new CGL.Uniform(B,"f","r",O),q=new CGL.Uniform(B,"f","g",D),Z=new CGL.Uniform(B,"f","b",I),J=new CGL.Uniform(B,"f","a",W);O.setUiAttribs({colorPick:true});t.setPortGroup("Display",[i,c]);t.setPortGroup("Alignment",[_,a]);t.setPortGroup("Color",[O,D,I,W]);let M=0;const L=vec3.create();let Q=-1;let R=false;n.onTriggered=function(){if(p){K();p=false}const e=y();if(e.lastChange!=Q){T=true;Q=e.lastChange}if(S)$();if(T)K();if(x&&x.numInstances>0){A.pushBlendMode(CGL.BLEND_NORMAL,true);A.pushShader(B);A.setTexture(0,C.get().tex);const t=s.get();if(t)A.setTexture(1,t.tex);const n=u.get();if(n)A.setTexture(2,n.tex);if(m===2)vec3.set(L,0,M,0);else if(m===1)vec3.set(L,0,0,0);else if(m===0)vec3.set(L,0,M/2,0);L[1]-=E.get();A.pushModelMatrix();mat4.translate(A.mMatrix,A.mMatrix,L);mat4.scale(A.mMatrix,A.mMatrix,h);if(!R)x.render(A.getShader());A.popModelMatrix();A.setTexture(0,null);A.popShader();A.popBlendMode()}N.trigger()};F.onChange=function(){T=true};function K(){const e=String(b.get()+"");if(!C.get())return;const a=y();if(!a.geom){a.geom=new CGL.Geometry("textmesh");a.geom.vertices=[1,1,0,0,1,0,1,0,0,0,0,0];a.geom.texCoords=new Float32Array([1,1,0,1,1,0,0,0]);a.geom.verticesIndices=[0,1,2,2,1,3]}if(!x)x=new CGL.Mesh(A,a.geom);const s=e.split("\n");P.set(s.length);const o=[];const l=[];const u=[];const c=[];const h=mat4.create();let f=0;let d=0;S=false;for(let i=0;i<s.length;i++){const p=s[i];const g=p.length;let t=0;let n=0;let r=0;for(let e=0;e<g;e++){const m=p.substring(e,e+1);const v=a.chars[String(m)];if(v){r+=v.texCoordWidth/v.texCoordHeight;r+=F.get()}}r-=F.get();M=0;if(_.get()=="left")n=0;else if(_.get()=="right")n=r;else if(_.get()=="center")n=r/2;M=(i+1)*E.get();for(let e=0;e<g;e++){const m=p.substring(e,e+1);const v=a.chars[String(m)];if(!v){S=true;return}else{c.push(t/r*.99+.005,(1-i/(s.length-1))*.99+.005);l.push(v.texCoordX,1-v.texCoordY-v.texCoordHeight);u.push(v.texCoordWidth,v.texCoordHeight);mat4.identity(h);mat4.translate(h,h,[t-n,0-i*E.get(),0]);t+=v.texCoordWidth/v.texCoordHeight+F.get();d=Math.max(d,t-n);o.push(Array.prototype.slice.call(h));f++}}}const t=[].concat.apply([],o);R=false;if(t.length==0)R=true;const n=t.length/16;x.setNumInstances(n);if(x.numInstances==0){R=true;return}U.set(d*i.get());x.setAttribute("instMat",new Float32Array(t),16,{instanced:true});x.setAttribute("attrTexOffsets",new Float32Array(l),2,{instanced:true});x.setAttribute("attrTexSize",new Float32Array(u),2,{instanced:true});x.setAttribute("attrTexPos",new Float32Array(c),2,{instanced:true});T=false;if(S)$()}function w(t,n){const r=y();if(!n)r.chars={};const i=r.ctx;i.font=t+"px "+c.get();i.textAlign="left";let a=0;let s=0;const o=t*1.4;const e={fits:true};for(let e=0;e<r.characters.length;e++){const l=String(r.characters.substring(e,e+1));const u=i.measureText(l).width;if(s+u>=f){a+=o+2;s=0}if(!n){r.chars[l]={str:l,texCoordX:s/f,texCoordY:a/f,texCoordWidth:u/f,texCoordHeight:o/f};i.fillText(l,s,a+t)}s+=u+12}if(a>f-o){e.fits=false}e.spaceLeft=f-a;return e}function $(){let e=CGL.Texture.FILTER_LINEAR;if(o.get()=="nearest")e=CGL.Texture.FILTER_NEAREST;if(o.get()=="mipmap")e=CGL.Texture.FILTER_MIPMAP;const t=y();let n=String(b.get());if(n==null||n==undefined)n="";for(let e=0;e<n.length;e++){const s=n.substring(e,e+1);if(t.characters.indexOf(s)==-1){t.characters+=s;S=true}}const r=t.ctx;t.canvas.width=t.canvas.height=f;if(!t.texture)t.texture=CGL.Texture.createFromImage(A,t.canvas,{filter:e,anisotropic:parseFloat(l.get())});t.texture.setSize(f,f);r.fillStyle="transparent";r.clearRect(0,0,f,f);r.fillStyle="rgba(255,255,255,255)";let i=t.fontSize+40;let a=w(i,true);while(!a.fits){i-=5;a=w(i,true)}w(i,false);r.restore();t.texture.initTexture(t.canvas,e);t.texture.unpackAlpha=true;C.setRef(t.texture);t.lastChange=CABLES.now();T=true;S=false}}};CABLES.OPS["2390f6b3-2122-412e-8c8d-5c2f574e8bd1"]={f:Ops.Gl.Meshes.TextMesh_v2,objName:"Ops.Gl.Meshes.TextMesh_v2"};Ops.Sidebar.Sidebar=class extends CABLES.Op{constructor(){super(...arguments);const s=this;const n=s.attachments={style_css:" /*\n * SIDEBAR\n  http://danielstern.ca/range.css/#/\n  https://developer.mozilla.org/en-US/docs/Web/CSS/::-webkit-progress-value\n */\n\n.sidebar-icon-undo\n{\n    width:10px;\n    height:10px;\n    background-image: url(\"data:image/svg+xml;charset=utf8, %3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='grey' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M3 7v6h6'/%3E%3Cpath d='M21 17a9 9 0 00-9-9 9 9 0 00-6 2.3L3 13'/%3E%3C/svg%3E\");\n    background-size: 19px;\n    background-repeat: no-repeat;\n    top: -19px;\n    margin-top: -7px;\n}\n\n.icon-chevron-down {\n    top: 2px;\n    right: 9px;\n}\n\n.iconsidebar-chevron-up,.sidebar__close-button {\n\tbackground-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiM4ODg4ODgiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0iZmVhdGhlciBmZWF0aGVyLWNoZXZyb24tdXAiPjxwb2x5bGluZSBwb2ludHM9IjE4IDE1IDEyIDkgNiAxNSI+PC9wb2x5bGluZT48L3N2Zz4=);\n}\n\n.iconsidebar-minimizebutton {\n    background-position: 98% center;\n    background-repeat: no-repeat;\n}\n\n.sidebar-cables-right\n{\n    right: 15px;\n    left: initial !important;\n}\n\n.sidebar-cables *\n{\n    color: #BBBBBB !important;\n    font-family: Arial;\n}\n\n.sidebar-cables {\n    --sidebar-color: #07f78c;\n    --sidebar-width: 220px;\n    --sidebar-border-radius: 10px;\n    --sidebar-monospace-font-stack: \"SFMono-Regular\", Consolas, \"Liberation Mono\", Menlo, Courier, monospace;\n    --sidebar-hover-transition-time: .2s;\n\n    position: absolute;\n    top: 15px;\n    left: 15px;\n    border-radius: var(--sidebar-border-radius);\n    z-index: 100000;\n    width: var(--sidebar-width);\n    max-height: 100%;\n    box-sizing: border-box;\n    overflow-y: auto;\n    overflow-x: hidden;\n    font-size: 13px;\n    line-height: 1em; /* prevent emojis from breaking height of the title */\n}\n\n.sidebar-cables::selection {\n    background-color: var(--sidebar-color);\n    color: #EEEEEE;\n}\n\n.sidebar-cables::-webkit-scrollbar {\n    background-color: transparent;\n    --cables-scrollbar-width: 8px;\n    width: var(--cables-scrollbar-width);\n}\n\n.sidebar-cables::-webkit-scrollbar-track {\n    background-color: transparent;\n    width: var(--cables-scrollbar-width);\n}\n\n.sidebar-cables::-webkit-scrollbar-thumb {\n    background-color: #333333;\n    border-radius: 4px;\n    width: var(--cables-scrollbar-width);\n}\n\n.sidebar-cables--closed {\n    width: auto;\n}\n\n.sidebar__close-button {\n    background-color: #222;\n    /*-webkit-user-select: none;  */\n    /*-moz-user-select: none;     */\n    /*-ms-user-select: none;      */\n    /*user-select: none;          */\n    /*transition: background-color var(--sidebar-hover-transition-time);*/\n    /*color: #CCCCCC;*/\n    height: 2px;\n    /*border-bottom:20px solid #222;*/\n\n    /*box-sizing: border-box;*/\n    /*padding-top: 2px;*/\n    /*text-align: center;*/\n    /*cursor: pointer;*/\n    /*border-radius: 0 0 var(--sidebar-border-radius) var(--sidebar-border-radius);*/\n    /*opacity: 1.0;*/\n    /*transition: opacity 0.3s;*/\n    /*overflow: hidden;*/\n}\n\n.sidebar__close-button-icon {\n    display: inline-block;\n    /*opacity: 0;*/\n    width: 20px;\n    height: 20px;\n    /*position: relative;*/\n    /*top: -1px;*/\n\n\n}\n\n.sidebar--closed {\n    width: auto;\n    margin-right: 20px;\n}\n\n.sidebar--closed .sidebar__close-button {\n    margin-top: 8px;\n    margin-left: 8px;\n    padding:10px;\n\n    height: 25px;\n    width:25px;\n    border-radius: 50%;\n    cursor: pointer;\n    opacity: 0.3;\n    background-repeat: no-repeat;\n    background-position: center center;\n    transform:rotate(180deg);\n}\n\n.sidebar--closed .sidebar__group\n{\n    display:none;\n\n}\n.sidebar--closed .sidebar__close-button-icon {\n    background-position: 0px 0px;\n}\n\n.sidebar__close-button:hover {\n    background-color: #111111;\n    opacity: 1.0 !important;\n}\n\n/*\n * SIDEBAR ITEMS\n */\n\n.sidebar__items {\n    /* max-height: 1000px; */\n    /* transition: max-height 0.5;*/\n    background-color: #222;\n    padding-bottom: 20px;\n}\n\n.sidebar--closed .sidebar__items {\n    /* max-height: 0; */\n    height: 0;\n    display: none;\n    pointer-interactions: none;\n}\n\n.sidebar__item__right {\n    float: right;\n}\n\n/*\n * SIDEBAR GROUP\n */\n\n.sidebar__group {\n    /*background-color: #1A1A1A;*/\n    overflow: hidden;\n    box-sizing: border-box;\n    animate: height;\n    /*background-color: #151515;*/\n    /* max-height: 1000px; */\n    /* transition: max-height 0.5s; */\n--sidebar-group-header-height: 33px;\n}\n\n.sidebar__group-items\n{\n    padding-top: 15px;\n    padding-bottom: 15px;\n}\n\n.sidebar__group--closed {\n    /* max-height: 13px; */\n    height: var(--sidebar-group-header-height);\n}\n\n.sidebar__group-header {\n    box-sizing: border-box;\n    color: #EEEEEE;\n    background-color: #151515;\n    -webkit-user-select: none;  /* Chrome all / Safari all */\n    -moz-user-select: none;     /* Firefox all */\n    -ms-user-select: none;      /* IE 10+ */\n    user-select: none;          /* Likely future */\n\n    /*height: 100%;//var(--sidebar-group-header-height);*/\n\n    padding-top: 7px;\n    text-transform: uppercase;\n    letter-spacing: 0.08em;\n    cursor: pointer;\n    /*transition: background-color var(--sidebar-hover-transition-time);*/\n    position: relative;\n}\n\n.sidebar__group-header:hover {\n  background-color: #111111;\n}\n\n.sidebar__group-header-title {\n  /*float: left;*/\n  overflow: hidden;\n  padding: 0 15px;\n  padding-top:5px;\n  padding-bottom:10px;\n  font-weight:bold;\n}\n\n.sidebar__group-header-undo {\n    float: right;\n    overflow: hidden;\n    padding-right: 15px;\n    padding-top:5px;\n    font-weight:bold;\n  }\n\n.sidebar__group-header-icon {\n    width: 17px;\n    height: 14px;\n    background-repeat: no-repeat;\n    display: inline-block;\n    position: absolute;\n    background-size: cover;\n\n    /* icon open */\n    /* feather icon: chevron up */\n    background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiM4ODg4ODgiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0iZmVhdGhlciBmZWF0aGVyLWNoZXZyb24tdXAiPjxwb2x5bGluZSBwb2ludHM9IjE4IDE1IDEyIDkgNiAxNSI+PC9wb2x5bGluZT48L3N2Zz4=);\n    top: 4px;\n    right: 5px;\n    opacity: 0.0;\n    transition: opacity 0.3;\n}\n\n.sidebar__group-header:hover .sidebar__group-header-icon {\n    opacity: 1.0;\n}\n\n/* icon closed */\n.sidebar__group--closed .sidebar__group-header-icon {\n    /* feather icon: chevron down */\n    background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiM4ODg4ODgiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0iZmVhdGhlciBmZWF0aGVyLWNoZXZyb24tZG93biI+PHBvbHlsaW5lIHBvaW50cz0iNiA5IDEyIDE1IDE4IDkiPjwvcG9seWxpbmU+PC9zdmc+);\n    top: 4px;\n    right: 5px;\n}\n\n/*\n * SIDEBAR ITEM\n */\n\n.sidebar__item\n{\n    box-sizing: border-box;\n    padding: 7px;\n    padding-left:15px;\n    padding-right:15px;\n\n    overflow: hidden;\n    position: relative;\n}\n\n.sidebar__item-label {\n    display: inline-block;\n    -webkit-user-select: none;  /* Chrome all / Safari all */\n    -moz-user-select: none;     /* Firefox all */\n    -ms-user-select: none;      /* IE 10+ */\n    user-select: none;          /* Likely future */\n    width: calc(50% - 7px);\n    margin-right: 7px;\n    margin-top: 2px;\n    text-overflow: ellipsis;\n    /* overflow: hidden; */\n}\n\n.sidebar__item-value-label {\n    font-family: var(--sidebar-monospace-font-stack);\n    display: inline-block;\n    text-overflow: ellipsis;\n    overflow: hidden;\n    white-space: nowrap;\n    max-width: 60%;\n}\n\n.sidebar__item-value-label::selection {\n    background-color: var(--sidebar-color);\n    color: #EEEEEE;\n}\n\n.sidebar__item + .sidebar__item,\n.sidebar__item + .sidebar__group,\n.sidebar__group + .sidebar__item,\n.sidebar__group + .sidebar__group {\n    /*border-top: 1px solid #272727;*/\n}\n\n/*\n * SIDEBAR ITEM TOGGLE\n */\n\n/*.sidebar__toggle */\n.icon_toggle{\n    cursor: pointer;\n}\n\n.sidebar__toggle-input {\n    --sidebar-toggle-input-color: #CCCCCC;\n    --sidebar-toggle-input-color-hover: #EEEEEE;\n    --sidebar-toggle-input-border-size: 2px;\n    display: inline;\n    float: right;\n    box-sizing: border-box;\n    border-radius: 50%;\n    /*outline-style: solid;*/\n    /*outline-color:red;*/\n    cursor: pointer;\n    --toggle-size: 11px;\n    margin-top: 2px;\n    background-color: transparent !important;\n    border: var(--sidebar-toggle-input-border-size) solid var(--sidebar-toggle-input-color);\n    width: var(--toggle-size);\n    height: var(--toggle-size);\n    transition: background-color var(--sidebar-hover-transition-time);\n    transition: border-color var(--sidebar-hover-transition-time);\n}\n.sidebar__toggle:hover .sidebar__toggle-input {\n    border-color: var(--sidebar-toggle-input-color-hover);\n}\n\n.sidebar__toggle .sidebar__item-value-label {\n    -webkit-user-select: none;  /* Chrome all / Safari all */\n    -moz-user-select: none;     /* Firefox all */\n    -ms-user-select: none;      /* IE 10+ */\n    user-select: none;          /* Likely future */\n    max-width: calc(50% - 12px);\n}\n.sidebar__toggle-input::after { clear: both; }\n\n.sidebar__toggle--active .icon_toggle\n{\n\n    background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjE1cHgiIHdpZHRoPSIzMHB4IiBmaWxsPSIjMDZmNzhiIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMTAwIDEwMCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGcgZGlzcGxheT0ibm9uZSI+PGcgZGlzcGxheT0iaW5saW5lIj48Zz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZmlsbD0iIzA2Zjc4YiIgZD0iTTMwLDI3QzE3LjM1LDI3LDcsMzcuMzUsNyw1MGwwLDBjMCwxMi42NSwxMC4zNSwyMywyMywyM2g0MCBjMTIuNjUsMCwyMy0xMC4zNSwyMy0yM2wwLDBjMC0xMi42NS0xMC4zNS0yMy0yMy0yM0gzMHogTTcwLDY3Yy05LjM4OSwwLTE3LTcuNjEtMTctMTdzNy42MTEtMTcsMTctMTdzMTcsNy42MSwxNywxNyAgICAgUzc5LjM4OSw2Nyw3MCw2N3oiPjwvcGF0aD48L2c+PC9nPjwvZz48Zz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTMwLDI3QzE3LjM1LDI3LDcsMzcuMzUsNyw1MGwwLDBjMCwxMi42NSwxMC4zNSwyMywyMywyM2g0MCAgIGMxMi42NSwwLDIzLTEwLjM1LDIzLTIzbDAsMGMwLTEyLjY1LTEwLjM1LTIzLTIzLTIzSDMweiBNNzAsNjdjLTkuMzg5LDAtMTctNy42MS0xNy0xN3M3LjYxMS0xNywxNy0xN3MxNyw3LjYxLDE3LDE3ICAgUzc5LjM4OSw2Nyw3MCw2N3oiPjwvcGF0aD48L2c+PGcgZGlzcGxheT0ibm9uZSI+PGcgZGlzcGxheT0iaW5saW5lIj48cGF0aCBmaWxsPSIjMDZmNzhiIiBzdHJva2U9IiMwNmY3OGIiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBkPSJNNyw1MGMwLDEyLjY1LDEwLjM1LDIzLDIzLDIzaDQwICAgIGMxMi42NSwwLDIzLTEwLjM1LDIzLTIzbDAsMGMwLTEyLjY1LTEwLjM1LTIzLTIzLTIzSDMwQzE3LjM1LDI3LDcsMzcuMzUsNyw1MEw3LDUweiI+PC9wYXRoPjwvZz48Y2lyY2xlIGRpc3BsYXk9ImlubGluZSIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGw9IiMwNmY3OGIiIHN0cm9rZT0iIzA2Zjc4YiIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIGN4PSI3MCIgY3k9IjUwIiByPSIxNyI+PC9jaXJjbGU+PC9nPjxnIGRpc3BsYXk9Im5vbmUiPjxwYXRoIGRpc3BsYXk9ImlubGluZSIgZD0iTTcwLDI1SDMwQzE2LjIxNSwyNSw1LDM2LjIxNSw1LDUwczExLjIxNSwyNSwyNSwyNWg0MGMxMy43ODUsMCwyNS0xMS4yMTUsMjUtMjVTODMuNzg1LDI1LDcwLDI1eiBNNzAsNzEgICBIMzBDMTguNDIxLDcxLDksNjEuNTc5LDksNTBzOS40MjEtMjEsMjEtMjFoNDBjMTEuNTc5LDAsMjEsOS40MjEsMjEsMjFTODEuNTc5LDcxLDcwLDcxeiBNNzAsMzFjLTEwLjQ3NywwLTE5LDguNTIzLTE5LDE5ICAgczguNTIzLDE5LDE5LDE5czE5LTguNTIzLDE5LTE5UzgwLjQ3NywzMSw3MCwzMXogTTcwLDY1Yy04LjI3MSwwLTE1LTYuNzI5LTE1LTE1czYuNzI5LTE1LDE1LTE1czE1LDYuNzI5LDE1LDE1Uzc4LjI3MSw2NSw3MCw2NXoiPjwvcGF0aD48L2c+PC9zdmc+);\n    opacity: 1;\n    transform: rotate(0deg);\n    background-position: -4px -9px;\n}\n\n\n.icon_toggle\n{\n    float: right;\n    width:40px;\n    height:18px;\n    background-image: url(data:image/svg+xml;base64,PHN2ZyBoZWlnaHQ9IjE1cHgiIHdpZHRoPSIzMHB4IiBmaWxsPSIjYWFhYWFhIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2ZXJzaW9uPSIxLjEiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgMTAwIDEwMCIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMTAwIDEwMCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGcgZGlzcGxheT0ibm9uZSI+PGcgZGlzcGxheT0iaW5saW5lIj48Zz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZmlsbD0iI2FhYWFhYSIgZD0iTTMwLDI3QzE3LjM1LDI3LDcsMzcuMzUsNyw1MGwwLDBjMCwxMi42NSwxMC4zNSwyMywyMywyM2g0MCBjMTIuNjUsMCwyMy0xMC4zNSwyMy0yM2wwLDBjMC0xMi42NS0xMC4zNS0yMy0yMy0yM0gzMHogTTcwLDY3Yy05LjM4OSwwLTE3LTcuNjEtMTctMTdzNy42MTEtMTcsMTctMTdzMTcsNy42MSwxNywxNyAgICAgUzc5LjM4OSw2Nyw3MCw2N3oiPjwvcGF0aD48L2c+PC9nPjwvZz48Zz48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTMwLDI3QzE3LjM1LDI3LDcsMzcuMzUsNyw1MGwwLDBjMCwxMi42NSwxMC4zNSwyMywyMywyM2g0MCAgIGMxMi42NSwwLDIzLTEwLjM1LDIzLTIzbDAsMGMwLTEyLjY1LTEwLjM1LTIzLTIzLTIzSDMweiBNNzAsNjdjLTkuMzg5LDAtMTctNy42MS0xNy0xN3M3LjYxMS0xNywxNy0xN3MxNyw3LjYxLDE3LDE3ICAgUzc5LjM4OSw2Nyw3MCw2N3oiPjwvcGF0aD48L2c+PGcgZGlzcGxheT0ibm9uZSI+PGcgZGlzcGxheT0iaW5saW5lIj48cGF0aCBmaWxsPSIjYWFhYWFhIiBzdHJva2U9IiNhYWFhYWEiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBkPSJNNyw1MGMwLDEyLjY1LDEwLjM1LDIzLDIzLDIzaDQwICAgIGMxMi42NSwwLDIzLTEwLjM1LDIzLTIzbDAsMGMwLTEyLjY1LTEwLjM1LTIzLTIzLTIzSDMwQzE3LjM1LDI3LDcsMzcuMzUsNyw1MEw3LDUweiI+PC9wYXRoPjwvZz48Y2lyY2xlIGRpc3BsYXk9ImlubGluZSIgZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGZpbGw9IiNhYWFhYWEiIHN0cm9rZT0iI2FhYWFhYSIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIGN4PSI3MCIgY3k9IjUwIiByPSIxNyI+PC9jaXJjbGU+PC9nPjxnIGRpc3BsYXk9Im5vbmUiPjxwYXRoIGRpc3BsYXk9ImlubGluZSIgZD0iTTcwLDI1SDMwQzE2LjIxNSwyNSw1LDM2LjIxNSw1LDUwczExLjIxNSwyNSwyNSwyNWg0MGMxMy43ODUsMCwyNS0xMS4yMTUsMjUtMjVTODMuNzg1LDI1LDcwLDI1eiBNNzAsNzEgICBIMzBDMTguNDIxLDcxLDksNjEuNTc5LDksNTBzOS40MjEtMjEsMjEtMjFoNDBjMTEuNTc5LDAsMjEsOS40MjEsMjEsMjFTODEuNTc5LDcxLDcwLDcxeiBNNzAsMzFjLTEwLjQ3NywwLTE5LDguNTIzLTE5LDE5ICAgczguNTIzLDE5LDE5LDE5czE5LTguNTIzLDE5LTE5UzgwLjQ3NywzMSw3MCwzMXogTTcwLDY1Yy04LjI3MSwwLTE1LTYuNzI5LTE1LTE1czYuNzI5LTE1LDE1LTE1czE1LDYuNzI5LDE1LDE1Uzc4LjI3MSw2NSw3MCw2NXoiPjwvcGF0aD48L2c+PC9zdmc+);\n    background-size: 50px 37px;\n    background-position: -6px -10px;\n    transform: rotate(180deg);\n    opacity: 0.4;\n}\n\n\n\n/*.sidebar__toggle--active .sidebar__toggle-input {*/\n/*    transition: background-color var(--sidebar-hover-transition-time);*/\n/*    background-color: var(--sidebar-toggle-input-color);*/\n/*}*/\n/*.sidebar__toggle--active .sidebar__toggle-input:hover*/\n/*{*/\n/*    background-color: var(--sidebar-toggle-input-color-hover);*/\n/*    border-color: var(--sidebar-toggle-input-color-hover);*/\n/*    transition: background-color var(--sidebar-hover-transition-time);*/\n/*    transition: border-color var(--sidebar-hover-transition-time);*/\n/*}*/\n\n/*\n * SIDEBAR ITEM BUTTON\n */\n\n.sidebar__button {}\n\n.sidebar__button-input:active\n{\n    background-color: #555 !important;\n}\n\n.sidebar__button-input {\n    -webkit-user-select: none;  /* Chrome all / Safari all */\n    -moz-user-select: none;     /* Firefox all */\n    -ms-user-select: none;      /* IE 10+ */\n    user-select: none;          /* Likely future */\n    min-height: 24px;\n    background-color: transparent;\n    color: #CCCCCC;\n    box-sizing: border-box;\n    padding-top: 3px;\n    text-align: center;\n    border-radius: 125px;\n    border:2px solid #555;\n    cursor: pointer;\n    padding-bottom: 3px;\n    display:block;\n}\n\n.sidebar__button-input.plus, .sidebar__button-input.minus {\n    display: inline-block;\n    min-width: 20px;\n}\n\n.sidebar__button-input:hover {\n  background-color: #333;\n  border:2px solid var(--sidebar-color);\n}\n\n/*\n * VALUE DISPLAY (shows a value)\n */\n\n.sidebar__value-display {}\n\n/*\n * SLIDER\n */\n\n.sidebar__slider {\n    --sidebar-slider-input-height: 3px;\n}\n\n.sidebar__slider-input-wrapper {\n    width: 100%;\n\n    margin-top: 8px;\n    position: relative;\n}\n\n.sidebar__slider-input {\n    -webkit-appearance: none;\n    appearance: none;\n    margin: 0;\n    width: 100%;\n    height: var(--sidebar-slider-input-height);\n    background: #555;\n    cursor: pointer;\n    /*outline: 0;*/\n\n    -webkit-transition: .2s;\n    transition: background-color .2s;\n    border: none;\n}\n\n.sidebar__slider-input:focus, .sidebar__slider-input:hover {\n    border: none;\n}\n\n.sidebar__slider-input-active-track {\n    user-select: none;\n    position: absolute;\n    z-index: 11;\n    top: 0;\n    left: 0;\n    background-color: var(--sidebar-color);\n    pointer-events: none;\n    height: var(--sidebar-slider-input-height);\n    max-width: 100%;\n}\n\n/* Mouse-over effects */\n.sidebar__slider-input:hover {\n    /*background-color: #444444;*/\n}\n\n/*.sidebar__slider-input::-webkit-progress-value {*/\n/*    background-color: green;*/\n/*    color:green;*/\n\n/*    }*/\n\n/* The slider handle (use -webkit- (Chrome, Opera, Safari, Edge) and -moz- (Firefox) to override default look) */\n\n.sidebar__slider-input::-moz-range-thumb\n{\n    position: absolute;\n    height: 15px;\n    width: 15px;\n    z-index: 900 !important;\n    border-radius: 20px !important;\n    cursor: pointer;\n    background: var(--sidebar-color) !important;\n    user-select: none;\n\n}\n\n.sidebar__slider-input::-webkit-slider-thumb\n{\n    position: relative;\n    appearance: none;\n    -webkit-appearance: none;\n    user-select: none;\n    height: 15px;\n    width: 15px;\n    display: block;\n    z-index: 900 !important;\n    border: 0;\n    border-radius: 20px !important;\n    cursor: pointer;\n    background: #777 !important;\n}\n\n.sidebar__slider-input:hover ::-webkit-slider-thumb {\n    background-color: #EEEEEE !important;\n}\n\n/*.sidebar__slider-input::-moz-range-thumb {*/\n\n/*    width: 0 !important;*/\n/*    height: var(--sidebar-slider-input-height);*/\n/*    background: #EEEEEE;*/\n/*    cursor: pointer;*/\n/*    border-radius: 0 !important;*/\n/*    border: none;*/\n/*    outline: 0;*/\n/*    z-index: 100 !important;*/\n/*}*/\n\n.sidebar__slider-input::-moz-range-track {\n    background-color: transparent;\n    z-index: 11;\n}\n\n.sidebar__slider input[type=text],\n.sidebar__slider input[type=paddword]\n{\n    box-sizing: border-box;\n    /*background-color: #333333;*/\n    text-align: right;\n    color: #BBBBBB;\n    display: inline-block;\n    background-color: transparent !important;\n\n    width: 40%;\n    height: 18px;\n    /*outline: none;*/\n    border: none;\n    border-radius: 0;\n    padding: 0 0 0 4px !important;\n    margin: 0;\n}\n\n.sidebar__slider input[type=text]:active,\n.sidebar__slider input[type=text]:focus,\n.sidebar__slider input[type=text]:hover\n.sidebar__slider input[type=password]:active,\n.sidebar__slider input[type=password]:focus,\n.sidebar__slider input[type=password]:hover\n{\n\n    color: #EEEEEE;\n}\n\n/*\n * TEXT / DESCRIPTION\n */\n\n.sidebar__text .sidebar__item-label {\n    width: auto;\n    display: block;\n    max-height: none;\n    margin-right: 0;\n    line-height: 1.1em;\n}\n\n/*\n * SIDEBAR INPUT\n */\n.sidebar__text-input textarea,\n.sidebar__text-input input[type=date],\n.sidebar__text-input input[type=datetime-local],\n.sidebar__text-input input[type=text],\n.sidebar__text-input input[type=password] {\n    box-sizing: border-box;\n    background-color: #333333;\n    color: #BBBBBB;\n    display: inline-block;\n    width: 50%;\n    height: 18px;\n\n\n    border: none;\n    border-radius: 0;\n    border:1px solid #666;\n    padding: 0 0 0 4px !important;\n    margin: 0;\n    color-scheme: dark;\n}\n\n.sidebar__text-input textarea:focus::placeholder {\n  color: transparent;\n}\n\n\n\n\n\n.sidebar__color-picker .sidebar__item-label\n{\n    width:45%;\n}\n\n.sidebar__text-input textarea,\n.sidebar__text-input input[type=text]:active,\n.sidebar__text-input input[type=text]:focus,\n.sidebar__text-input input[type=text]:hover,\n.sidebar__text-input input[type=password]:active,\n.sidebar__text-input input[type=password]:focus,\n.sidebar__text-input input[type=password]:hover {\n    background-color: transparent;\n    color: #EEEEEE;\n\n}\n\n.sidebar__text-input textarea\n{\n    margin-top:10px;\n    height:60px;\n    width:100%;\n}\n\n/*\n * SIDEBAR SELECT\n */\n\n\n\n .sidebar__select {}\n .sidebar__select-select {\n    color: #BBBBBB;\n    /*-webkit-appearance: none;*/\n    /*-moz-appearance: none;*/\n    appearance: none;\n    /*box-sizing: border-box;*/\n    width: 50%;\n    /*height: 20px;*/\n    background-color: #333333;\n    /*background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiM4ODg4ODgiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBjbGFzcz0iZmVhdGhlciBmZWF0aGVyLWNoZXZyb24tZG93biI+PHBvbHlsaW5lIHBvaW50cz0iNiA5IDEyIDE1IDE4IDkiPjwvcG9seWxpbmU+PC9zdmc+);*/\n    background-repeat: no-repeat;\n    background-position: right center;\n    background-size: 16px 16px;\n    margin: 0;\n    /*padding: 0 2 2 6px;*/\n    border-radius: 5px;\n    border: 1px solid #777;\n    background-color: #444;\n    cursor: pointer;\n    /*outline: none;*/\n    padding-left: 5px;\n\n }\n\n.sidebar__select-select:hover,\n.sidebar__select-select:active,\n.sidebar__select-select:inactive {\n    background-color: #444444;\n    color: #EEEEEE;\n}\n\n/*.sidebar__select-select option*/\n/*{*/\n/*    background-color: #444444;*/\n/*    color: #bbb;*/\n/*}*/\n\n.sidebar__select-select option:checked\n{\n    background-color: #000;\n    color: #FFF;\n}\n\n\n/*\n * COLOR PICKER\n */\n\n\n .sidebar__color-picker input[type=text] {\n    box-sizing: border-box;\n    background-color: #333333;\n    color: #BBBBBB;\n    display: inline-block;\n    width: calc(50% - 21px); /* 50% minus space of picker circle */\n    height: 18px;\n    /*outline: none;*/\n    border: none;\n    border-radius: 0;\n    padding: 0 0 0 4px !important;\n    margin: 0;\n    margin-right: 7px;\n}\n\n.sidebar__color-picker input[type=text]:active,\n.sidebar__color-picker input[type=text]:focus,\n.sidebar__color-picker input[type=text]:hover {\n    background-color: #444444;\n    color: #EEEEEE;\n}\n\ndiv.sidebar__color-picker-color-input,\n.sidebar__color-picker input[type=color],\n.sidebar__palette-picker input[type=color] {\n    display: inline-block;\n    border-radius: 100%;\n    height: 14px;\n    width: 14px;\n\n    padding: 0;\n    border: none;\n    /*border:2px solid red;*/\n    border-color: transparent;\n    outline: none;\n    background: none;\n    appearance: none;\n    -moz-appearance: none;\n    -webkit-appearance: none;\n    cursor: pointer;\n    position: relative;\n    top: 3px;\n}\n.sidebar__color-picker input[type=color]:focus,\n.sidebar__palette-picker input[type=color]:focus {\n    outline: none;\n}\n.sidebar__color-picker input[type=color]::-moz-color-swatch,\n.sidebar__palette-picker input[type=color]::-moz-color-swatch {\n    border: none;\n}\n.sidebar__color-picker input[type=color]::-webkit-color-swatch-wrapper,\n.sidebar__palette-picker input[type=color]::-webkit-color-swatch-wrapper {\n    padding: 0;\n}\n.sidebar__color-picker input[type=color]::-webkit-color-swatch,\n.sidebar__palette-picker input[type=color]::-webkit-color-swatch {\n    border: none;\n    border-radius: 100%;\n}\n\n/*\n * Palette Picker\n */\n.sidebar__palette-picker .sidebar__palette-picker-color-input.first {\n    margin-left: 0;\n}\n.sidebar__palette-picker .sidebar__palette-picker-color-input.last {\n    margin-right: 0;\n}\n.sidebar__palette-picker .sidebar__palette-picker-color-input {\n    margin: 0 4px;\n}\n\n.sidebar__palette-picker .circlebutton {\n    width: 14px;\n    height: 14px;\n    border-radius: 1em;\n    display: inline-block;\n    top: 3px;\n    position: relative;\n}\n\n/*\n * Preset\n */\n.sidebar__item-presets-preset\n{\n    padding:4px;\n    cursor:pointer;\n    padding-left:8px;\n    padding-right:8px;\n    margin-right:4px;\n    background-color:#444;\n}\n\n.sidebar__item-presets-preset:hover\n{\n    background-color:#666;\n}\n\n.sidebar__greyout\n{\n    background: #222;\n    opacity: 0.8;\n    width: 100%;\n    height: 100%;\n    position: absolute;\n    z-index: 1000;\n    right: 0;\n    top: 0;\n}\n\n.sidebar_tabs\n{\n    background-color: #151515;\n    padding-bottom: 0px;\n}\n\n.sidebar_switchs\n{\n    float: right;\n}\n\n.sidebar_tab\n{\n    float:left;\n    background-color: #151515;\n    border-bottom:1px solid transparent;\n    padding-right:7px;\n    padding-left:7px;\n    padding-bottom: 5px;\n    padding-top: 5px;\n    cursor:pointer;\n}\n\n.sidebar_tab_active\n{\n    background-color: #272727;\n    color:white;\n}\n\n.sidebar_tab:hover\n{\n    border-bottom:1px solid #777;\n    color:white;\n}\n\n\n.sidebar_switch\n{\n    float:left;\n    background-color: #444;\n    padding-right:7px;\n    padding-left:7px;\n    padding-bottom: 5px;\n    padding-top: 5px;\n    cursor:pointer;\n}\n\n.sidebar_switch:last-child\n{\n    border-top-right-radius: 7px;\n    border-bottom-right-radius: 7px;\n}\n\n.sidebar_switch:first-child\n{\n    border-top-left-radius: 7px;\n    border-bottom-left-radius: 7px;\n}\n\n\n.sidebar_switch_active\n{\n    background-color: #999;\n    color:white;\n}\n\n.sidebar_switch:hover\n{\n    color:white;\n}\n\n.sidebar__text-input-input::focus-visible,\n/*.sidebar__text-input-input:active,*/\n.sidebar__button-input:focus-visible,\n.sidebar__text-input:focus-visible\n/*.sidebar__text-input:active*/\n{\n    outline-style: solid;\n    outline-color:white;\n    outline-width: 1px;\n\n}\n\n"};const r="cables-sidebar-style";const i="cables-sidebar-dynamic-style";const o="sidebar-cables";const l="sidebar"+CABLES.uuid();const u="sidebar__items";const c="sidebar__close-button";const a="";const h="";let f=null;let w=null;let d=null;const e=s.inValueBool("Visible",true);const t=s.inValueSlider("Opacity",1);const p=s.inValueBool("Default Minimized");const g=s.inValueSlider("Minimized Opacity",.5);const m=s.inValueBool("Show undo button",false);const v=s.inValueBool("Show Minimize",false);const b=s.inString("Title","");const _=s.inValueBool("Side");const E=s.inValueBool("Default CSS",true);let F=s.patch.cgl.canvas.ownerDocument;const C=s.outObject("childs");C.setUiAttribs({title:"Children"});const A=s.outBool("Opfened");A.setUiAttribs({title:"Opened"});let x=F.querySelector("."+l);if(!x)x=P();const T=x.querySelector("."+u);C.set({parentElement:T,parentOp:s});D();R();M();E.onChange=()=>{R();M()};e.onChange=N;t.onChange=I;p.onChange=D;g.onChange=S;m.onChange=B;s.onDelete=k;function S(){M()}v.onChange=y;function y(e){if(!e||e.uiAttribs)e=F.querySelector(".sidebar-cables .sidebar__group-header");if(!e)return;const t=F.querySelector(".sidebar-cables .sidebar__group-header .sidebar__group-header-undo");if(v.get()){e.classList.add("iconsidebar-chevron-up");e.classList.add("iconsidebar-minimizebutton");if(t)t.style.marginRight="20px"}else{e.classList.remove("iconsidebar-chevron-up");e.classList.remove("iconsidebar-minimizebutton");if(t)t.style.marginRight="initial"}}_.onChange=function(){if(!x)return;if(_.get())x.classList.add("sidebar-cables-right");else x.classList.remove("sidebar-cables-right")};function B(){const e=F.querySelector(".sidebar-cables .sidebar__group-header");if(e){O(e)}}function O(e){if(e){const t=F.querySelector(".sidebar-cables .sidebar__group-header .sidebar__group-header-undo");if(t){if(!m.get()){t.remove()}}else{if(m.get()){const n=F.createElement("span");n.classList.add("sidebar__group-header-undo");n.classList.add("sidebar-icon-undo");n.addEventListener("click",function(e){e.stopPropagation();const t=F.querySelectorAll(".sidebar-cables .sidebar__reloadable");const n=F.createEvent("MouseEvents");n.initEvent("dblclick",true,true);t.forEach(e=>{e.dispatchEvent(n)})});e.appendChild(n)}}}y(e)}function D(){if(!f){return}if(p.get()){x.classList.add("sidebar--closed");if(e.get())A.set(false)}else{x.classList.remove("sidebar--closed");if(e.get())A.set(true)}}function I(){const e=t.get();x.style.opacity=e}function N(){if(!x)return;if(e.get()){x.style.display="block";if(!x.classList.contains("sidebar--closed"))A.set(true)}else{x.style.display="none";A.set(false)}}_.onChanged=function(){};function M(){const e=F.querySelectorAll("."+i);if(e){e.forEach(function(e){e.parentNode.removeChild(e)})}if(!E.get())return;const t=F.createElement("style");t.classList.add("cablesEle");t.classList.add(i);let n=".sidebar--closed .sidebar__close-button { ";n+="opacity: "+g.get();n+="}";const r=F.createTextNode(n);t.appendChild(r);F.body.appendChild(t)}function P(){const e=F.createElement("div");e.classList.add(o);e.classList.add(l);const t=s.patch.cgl.canvas.parentElement;const n=F.createElement("div");n.classList.add("sidebar__group");e.appendChild(n);const r=F.createElement("div");r.classList.add("sidebar__group-header");e.appendChild(r);const i=F.createElement("span");i.classList.add("sidebar__group-header-title");d=F.createElement("span");d.classList.add("sidebar__group-header-title-text");d.innerHTML=b.get();i.appendChild(d);r.appendChild(i);O(r);y(r);n.appendChild(r);e.appendChild(n);n.addEventListener("click",L);if(!t){s.warn("[sidebar] no canvas parentelement found...");return}t.appendChild(e);const a=F.createElement("div");a.classList.add(u);e.appendChild(a);f=F.createElement("div");f.classList.add(c);f.addEventListener("click",L);e.appendChild(f);return e}b.onChange=function(){if(d)d.innerHTML=b.get()};function U(e){}function L(e){e.stopPropagation();if(!x){s.logError("Sidebar could not be closed...");return}x.classList.toggle("sidebar--closed");const t=e.target;let n=a;if(x.classList.contains("sidebar--closed")){n=h;A.set(false)}else{A.set(true)}}function R(){const e=F.querySelectorAll("."+r);if(e){e.forEach(e=>{e.parentNode.removeChild(e)})}if(!E.get())return;const t=F.createElement("style");t.innerHTML=n.style_css;t.classList.add(r);t.classList.add("cablesEle");F.body.appendChild(t)}function k(){j(x)}function j(e){if(e&&e.parentNode&&e.parentNode.removeChild)e.parentNode.removeChild(e)}}};CABLES.OPS["5a681c35-78ce-4cb3-9858-bc79c34c6819"]={f:Ops.Sidebar.Sidebar,objName:"Ops.Sidebar.Sidebar"};Ops.Sidebar.Slider_v3=class extends CABLES.Op{constructor(){super(...arguments);const i=this;const w=i.attachments={};const e=1e-5;const t=i.inObject("link");const n=i.inString("Text","Slider");const a=i.inValue("Min",0);const s=i.inValue("Max",1);const r=i.inValue("Step",e);const o=i.inString("Suffix","");const l=i.inBool("Grey Out",false);const u=i.inBool("Visible",true);const c=i.inValue("Input",.5);const h=i.inTriggerButton("Set Default");const f=i.inTriggerButton("Reset");let d=null;const p=i.inValue("Default",.5);p.setUiAttribs({hidePort:true,greyout:true});const g=i.outObject("childs");const m=i.outNumber("Result",p.get());i.toWorkNeedsParent("Ops.Sidebar.Sidebar");i.setPortGroup("Range",[a,s,r]);i.setPortGroup("Display",[l,u]);const v=document.createElement("div");v.addEventListener("dblclick",function(){m.set(parseFloat(p.get()));c.set(parseFloat(p.get()));L(p.get())});v.dataset.op=i.id;v.classList.add("cablesEle");v.classList.add("sidebar__item");v.classList.add("sidebar__slider");v.classList.add("sidebar__reloadable");i.patch.on("sidebarStylesChanged",()=>{D()});const b=document.createElement("div");b.classList.add("sidebar__item-label");const _=document.createElement("div");_.classList.add("sidebar__greyout");v.appendChild(_);_.style.display="none";const E=document.createTextNode(n.get());b.appendChild(E);v.appendChild(b);const F=document.createElement("input");F.value=p.get();F.classList.add("sidebar__text-input-input");F.setAttribute("type","text");F.oninput=S;v.appendChild(F);const C=document.createElement("span");v.appendChild(C);o.onChange=()=>{C.innerHTML=o.get()};const A=document.createElement("div");A.classList.add("sidebar__slider-input-wrapper");v.appendChild(A);const x=document.createElement("div");x.classList.add("sidebar__slider-input-active-track");A.appendChild(x);const T=document.createElement("input");T.classList.add("sidebar__slider-input");T.setAttribute("min",a.get());T.setAttribute("max",s.get());T.setAttribute("type","range");T.setAttribute("step",r.get());T.setAttribute("value",p.get());T.style.display="block";A.appendChild(T);D();T.addEventListener("input",O);t.onChange=k;n.onChange=U;c.onChange=y;p.onChange=P;h.onTriggered=B;a.onChange=I;s.onChange=M;r.onChange=N;i.onDelete=V;i.onLoaded=i.onInit=function(){if(i.patch.config.sidebar){i.patch.config.sidebar[n.get()];m.set(i.patch.config.sidebar[n.get()])}else{m.set(parseFloat(p.get()));c.set(parseFloat(p.get()))}};f.onTriggered=function(){const e=parseFloat(p.get());m.set(e);L(e);R(e);c.set(e);D()};l.onChange=function(){_.style.display=l.get()?"block":"none"};u.onChange=function(){v.style.display=u.get()?"block":"none"};function S(e){let t=parseFloat(e.target.value);if(isNaN(t))t=0;const n=a.get();const r=s.get();if(t<n){t=n}else if(t>r){t=r}m.set(t);D();c.set(t);i.refreshParams()}function y(){let e=parseFloat(c.get());const t=a.get();const n=s.get();if(e>n){e=n}else if(e<t){e=t}R(e);m.set(e);D()}function B(){let e=parseFloat(c.get());const t=a.get();const n=s.get();if(e>n){e=n}else if(e<t){e=t}L(e);R(e);m.set(e);p.set(e);i.refreshParams();D()}function O(e){e.preventDefault();e.stopPropagation();L(e.target.value);const t=parseFloat(e.target.value);m.set(t);c.set(t);i.refreshParams();D();return false}function N(){const e=r.get();T.setAttribute("step",e);D()}function D(e){let t=parseFloat(T.value);if(typeof e!=="undefined")t=e;let n=x.parentElement.getBoundingClientRect().width||220;if(d)n=parseInt(getComputedStyle(d.parentElement).getPropertyValue("--sidebar-width"))-20;const r=CABLES.map(t,parseFloat(T.min),parseFloat(T.max),0,n-16);x.style.width=r+"px"}function I(){const e=a.get();T.setAttribute("min",e);D()}function M(){const e=s.get();T.setAttribute("max",e);D()}function P(){const e=p.get();m.set(parseFloat(e));I();M();R(e);L(e);D(e)}function U(){const e=n.get();b.textContent=e;if(CABLES.UI)i.setUiAttrib({extendTitle:e});F.setAttribute("aria-label","slider "+n.get());T.setAttribute("aria-label","slider "+n.get())}function k(){g.set(null);d=t.get();if(d&&d.parentElement){d.parentElement.appendChild(v);g.set(d)}else if(v.parentElement)v.parentElement.removeChild(v);D()}function L(e){F.value=e}function R(e){T.value=e}function j(e){if(e)e.style.display="block"}function G(e){if(e)e.style.display="none"}function V(){z(v)}function z(e){if(e&&e.parentNode&&e.parentNode.removeChild)e.parentNode.removeChild(e)}}};CABLES.OPS["74730122-5cba-4d0d-b610-df334ec6220a"]={f:Ops.Sidebar.Slider_v3,objName:"Ops.Sidebar.Slider_v3"};Ops.Html.FontFile_v2=class extends CABLES.Op{constructor(){super(...arguments);const i=this;const e=i.attachments={};const a=i.inUrl("file",[".otf",".ttf",".woff",".woff2"]),s=i.inString("family"),o=i.inBool("Active",true),l=i.outBoolNum("Loaded"),u=i.outTrigger("Loaded Trigger");let c=null;let h;let f=null;let t=null;let d=null;let p="";a.onChange=function(){l.set(false);r(null)};o.onChange=s.onChange=()=>{n()};function n(){clearTimeout(t);t=setTimeout(()=>{r(null)},50)}i.patch.on("windowChanged",e=>{h=null;r(e.document)});function r(e){if(d)d.remove();if(h){const t=f.fonts.delete(h);h=null;setTimeout(()=>{i.patch.emitEvent("fontLoaded",p)},100)}if(!o.get())return;f=e||f||i.patch.cgl.canvas.ownerDocument||document;if(c)c=i.patch.cgl.patch.loading.finished(c);i.setUiError("loadingerror",null);p=s.get();if(a.get()&&s.get()){if(f.fonts){let e='url("'+i.patch.getFilePath(String(a.get()))+'")';h=new FontFace(s.get(),e);c=i.patch.cgl.patch.loading.start("FontFile",a.get(),i);f.fonts.add(h);h.loaded.then(e=>{l.set(true);u.trigger();c=i.patch.cgl.patch.loading.finished(c);i.patch.emitEvent("fontLoaded",s.get())},e=>{i.setUiError("loadingerror","Font loading error: "+h.status+"("+a.get()+")");c=i.patch.cgl.patch.loading.finished(c);l.set(true)}).catch(e=>{c=i.patch.cgl.patch.loading.finished(c);console.error("catch ",e)});h.load()}else{const n=i.patch.getFilePath(String(a.get()));const r="".endl()+"@font-face".endl()+"{".endl()+'  font-family: "'+s.get()+'";'.endl()+'  src: url("'+n+'") format("truetype");'.endl()+"}";d=document.createElement("style");d.classList.add("cablesEle");d.type="text/css";d.innerHTML=r;document.getElementsByTagName("head")[document.getElementsByTagName("head").length-1].appendChild(d)}}}}};CABLES.OPS["68177370-116e-4c76-aef3-3b10d68e7227"]={f:Ops.Html.FontFile_v2,objName:"Ops.Html.FontFile_v2"};Ops.Gl.Shader.CustomShader_v2=class extends CABLES.Op{constructor(){super(...arguments);const v=this;const e=v.attachments={};const t=v.inTrigger("render"),n=v.inStringEditor("Fragment Code"),r=v.inStringEditor("Vertex Code"),i=v.inValueBool("Use As Material",true),a=v.outTrigger("trigger"),s=v.outObject("Shader",null,"shader"),o=v.outBool("Has Errors");const b=7;const _=v.patch.cgl;const E=[];const F=[];const C=[];v.toWorkPortsNeedToBeLinked(t);n.setUiAttribs({editorSyntax:"glsl"});r.setUiAttribs({editorSyntax:"glsl"});const A=new CGL.Shader(_,"customshader",v);A.logError=false;A.setModules(["MODULE_VERTEX_POSITION","MODULE_COLOR","MODULE_BEGIN_FRAG","MODULE_VERTEX_MODELVIEW"]);v.setPortGroup("Source Code",[n,r]);v.setPortGroup("Options",[i]);n.set(CGL.Shader.getDefaultFragmentShader());r.set(CGL.Shader.getDefaultVertexShader());n.onChange=r.onChange=function(){if(n.isLinked()&&!n.get())return;u=true};t.onTriggered=h;let l=0;let u=true;v.onLoadedValueSet=c;function c(n){m();if(!n)return;for(let t=0;t<E.length;t++)for(let e=0;e<n.portsIn.length;e++)if(E[t]&&E[t].name==n.portsIn[e].name){E[t].set(n.portsIn[e].value);E[t].deSerializeSettings(n.portsIn[e])}}v.init=function(){m()};function h(){O();if(u)m();if(i.get())_.pushShader(A);f();a.trigger();A.popTextures();if(i.get())_.popShader()}function f(){for(let e=0;e<F.length;e++)if(F[e]&&F[e].get()&&F[e].get().tex)A.pushTexture(F[e].uniform,F[e].get().tex);else A.pushTexture(F[e],CGL.Texture.getEmptyTexture(_))}function d(){for(let e=0;e<F.length;e++)if(F[e]&&F[e].get()&&F[e].get().tex)_.setTexture(0+e+b,F[e].get().tex)}function x(t){for(let e=0;e<E.length;e++)if(E[e]&&E[e].name==t)return true;for(let e=0;e<F.length;e++)if(F[e]&&F[e].name==t)return true;return false}const p=mat4.create();const T=["modelMatrix","viewMatrix","normalMatrix","mvMatrix","projMatrix","inverseViewMatrix","camPos"];let S=0;const y=[];function g(e){const t=e.split("\n");const i=[];for(let e=0;e<t.length;e++){const n=t[e].split(";");for(let e=0;e<n.length;e++){let r=n[e].split(" ");for(let e=0;e<r.length;e++)r[e]=(r[e]+"").trim();if(r[0]==="UNI"||r[0]==="uniform"){let t=r[2];if(r.length>4)for(let e=3;e<r.length;e++)t+=r[e];r=r.filter(function(e){return e!==""});const a=r[1];let n=[];if(t){n=[t];if(t.indexOf(",")>-1)n=t.split(",")}for(let e=0;e<n.length;e++){if(T.indexOf(n[e])>-1)continue;const s=n[e].trim().replace(/\[\d+\]$/,"");if(a==="float"){y.push(s);if(!x(s)){const o=n[e].trim().match(/\[\d+\]$/);if(o){const l=parseInt(o[0].trim().slice(1,-1));const u=v.inArray(s,[]);u.uniform=new CGL.Uniform(A,"f[]",s,new Float32Array(l));E.push(u);i.push(u);const c={name:s,num:l,port:u,uni:u.uniform,changed:false};u.onChange=function(){this.changed=true}.bind(c);C.push(c)}else{const u=v.inFloat(s,0);u.uniform=new CGL.Uniform(A,"f",s,u);E.push(u);i.push(u)}}}else if(a==="int"){y.push(s);if(!x(s)){const u=v.inInt(s,0);u.uniform=new CGL.Uniform(A,"i",s,u);E.push(u);i.push(u)}}else if(a==="bool"){y.push(s);if(!x(s)){const u=v.inBool(s,false);u.uniform=new CGL.Uniform(A,"b",s,u);E.push(u);i.push(u)}}else if(a==="mat4"){y.push(s);if(!x(s)){const u=v.inArray(s,0);u.uniform=new CGL.Uniform(A,"m4",s,u);E.push(u);i.push(u);const c={name:s,num:16,port:u,uni:u.uniform,changed:false};u.onChange=function(){this.changed=true}.bind(c);C.push(c)}}else if(a==="sampler2D"||a==="samplerCube"){y.push(s);if(!x(s)){const h=v.inObject(s);let e="t";if(a==="samplerCube")e="tc";h.uniform=new CGL.Uniform(A,e,s,b+F.length);F.push(h);i.push(h);h.set(CGL.Texture.getTempTexture(_));h.on("change",(e,t)=>{if(!e)t.set(CGL.Texture.getTempTexture(_))});S++}}else if(a==="vec3"||a==="vec2"||a==="vec4"){let e=2;if(a==="vec4")e=4;if(a==="vec3")e=3;y.push(s+" X");y.push(s+" Y");if(e>2)y.push(s+" Z");if(e>3)y.push(s+" W");if(!x(s+" X")){const f=[];const c={name:s,num:e,changed:false};C.push(c);B(c);const d=v.inFloat(s+" X",0);d.onChange=function(){this.changed=true}.bind(c);E.push(d);f.push(d);c.x=d;const p=v.inFloat(s+" Y",0);p.onChange=function(){this.changed=true}.bind(c);E.push(p);f.push(p);c.y=p;if(e>2){const g=v.inFloat(s+" Z",0);g.onChange=function(){this.changed=true}.bind(c);E.push(g);f.push(g);c.z=g}if(e>3){const m=v.inFloat(s+" W",0);m.onChange=function(){this.changed=true}.bind(c);E.push(m);f.push(m);c.w=m}v.setPortGroup(s,f)}}}}}}v.setPortGroup("uniforms",i)}function m(){if(!A)return;let e=false;l++;if(l>2)e=true;A.setSource(r.get(),n.get(),e);if(_.glVersion==1){_.enableExtension("OES_standard_derivatives");A.enableExtension("GL_OES_standard_derivatives")}S=0;y.length=0;g(r.get());g(n.get());for(let t=0;t<F.length;t++)for(let e=0;e<y.length;e++)if(F[t]&&y.indexOf(F[t].name)==-1){F[t].remove();F[t]=null}for(let t=0;t<E.length;t++)for(let e=0;e<y.length;e++)if(E[t]&&y.indexOf(E[t].name)==-1){E[t].remove();E[t]=null}for(let e=0;e<C.length;e++){B(C[e]);C[e].changed=true}for(let e=0;e<E.length;e++)if(E[e]&&E[e].uniform)E[e].uniform.needsUpdate=true;A.compile();v.refreshParams();s.setRef(A);u=false;if(A.hasErrors())v.setUiError("compile","Shader has errors",2,{button:"show",buttonCb:()=>{CABLES.UI.showShaderError(A)}});else v.setUiError("compile",null);o.set(A.hasErrors())}function B(e){if(e.num==2)e.uni=new CGL.Uniform(A,"2f",e.name,[0,0]);else if(e.num==3)e.uni=new CGL.Uniform(A,"3f",e.name,[0,0,0]);else if(e.num==4)e.uni=new CGL.Uniform(A,"4f",e.name,[0,0,0,0])}function O(){for(let e=0;e<C.length;e++){const t=C[e];if(t.changed){if(t.num===2)t.uni.setValue([t.x.get(),t.y.get()]);else if(t.num===3)t.uni.setValue([t.x.get(),t.y.get(),t.z.get()]);else if(t.num===4)t.uni.setValue([t.x.get(),t.y.get(),t.z.get(),t.w.get()]);else if(t.num>4){t.uni.setValue(t.port.get())}t.changed=false}}}}};CABLES.OPS["a165fc89-a35b-4d39-8930-7345b098bd9d"]={f:Ops.Gl.Shader.CustomShader_v2,objName:"Ops.Gl.Shader.CustomShader_v2"};Ops.Gl.Shader.ShaderToTexture=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inTrigger("Render"),r=e.inObject("Shader",null,"shader"),s=e.inValueBool("Use Viewport Size",true),o=e.inValueInt("Width",512),l=e.inValueInt("Height",512),u=e.inValueSelect("filter",["nearest","linear","mipmap"]),c=e.inSwitch("Anisotropic",["0","1","2","4","8","16"],"0"),h=e.inValueSelect("wrap",["clamp to edge","repeat","mirrored repeat"],"clamp to edge"),f=e.inValueBool("Floating Point",false),d=e.inSwitch("Num Textures",["1","4"],"1"),i=e.outTrigger("Next"),a=e.outTexture("Texture"),p=e.outTexture("Texture 2"),g=e.outTexture("Texture 3"),m=e.outTexture("Texture 4");e.setPortGroup("Texture Size",[s,o,l]);e.setPortGroup("Texture settings",[u,h,f,c]);let v=1;const b=e.patch.cgl;const _=[0,0,0,0];const E=null;const F=[];let C=null;let A=null;o.onChange=l.onChange=f.onChange=u.onChange=d.onChange=c.onChange=h.onChange=I;s.onChange=D;const x=false;let T=null;const S=null;let y=true;const B=CGL.MESHES.getSimpleRect(b,"shader2texture rect");e.toWorkPortsNeedToBeLinked(r);u.set("nearest");D();function O(){if(u.get()=="mipmap"&&f.get()){e.setUiError("warning","HDR and mipmap filtering at the same time is not possible")}else{e.setUiError("warning",null)}}function D(){c.setUiAttribs({greyout:u.get()!="mipmap"});o.setUiAttribs({greyout:s.get()});l.setUiAttribs({greyout:s.get()});o.set(b.getViewPort()[2]);l.set(b.getViewPort()[3])}function I(){y=true;O()}function M(){if(A)A.dispose();C=null;A=null}function L(){y=false;if(T)T.delete();const e=F.length;v=parseInt(d.get());F.length=0;for(let e=0;e<v;e++)F[e]=true;if(e!=F.length){M()}T=null;let t=o.get();let n=l.get();if(s.get()){t=b.getViewPort()[2];n=b.getViewPort()[3]}let r=CGL.Texture.FILTER_NEAREST;if(u.get()=="linear")r=CGL.Texture.FILTER_LINEAR;else if(u.get()=="mipmap")r=CGL.Texture.FILTER_MIPMAP;let i=CGL.Texture.WRAP_CLAMP_TO_EDGE;if(h.get()=="repeat")i=CGL.Texture.WRAP_REPEAT;if(h.get()=="mirrored repeat")i=CGL.Texture.WRAP_MIRRORED_REPEAT;const a=Math.min(b.maxAnisotropic,parseFloat(c.get()));if(b.glVersion>=2){T=new CGL.Framebuffer2(b,t,n,{anisotropic:a,isFloatingPointTexture:f.get(),multisampling:false,numRenderBuffers:v,wrap:i,filter:r,depth:true,multisamplingSamples:0,clear:true})}else{T=new CGL.Framebuffer(b,o.get(),l.get(),{isFloatingPointTexture:f.get(),filter:r,wrap:i})}}n.onTriggered=function(){const e=b.getViewPort();if(!T||y)L();if(s.get()&&T&&(e[2]!=T.getTextureColor().width||e[3]!=T.getTextureColor().height))L();if(!r.get()||!r.get().setDrawBuffers)return;if(r.get()!=C){C=r.get();A=r.get().copy();A.setDrawBuffers(F)}if(!A){a.set(null);return}_[0]=e[0];_[1]=e[1];_[2]=e[2];_[3]=e[3];T.renderStart(b);b.pushPMatrix();mat4.identity(b.pMatrix);b.pushViewMatrix();mat4.identity(b.vMatrix);b.pushModelMatrix();mat4.identity(b.mMatrix);b.pushShader(r.get());if(A.bindTextures)A.bindTextures();b.pushBlend(false);B.render(r.get());b.popBlend();b.popPMatrix();b.popModelMatrix();b.popViewMatrix();T.renderEnd(b);if(v>=2){a.set(T.getTextureColorNum(0));p.set(T.getTextureColorNum(1));g.set(T.getTextureColorNum(2));m.set(T.getTextureColorNum(3))}else a.set(T.getTextureColor());b.popShader();b.gl.viewport(_[0],_[1],_[2],_[3]);i.trigger()}}};CABLES.OPS["a3debb76-7d84-4548-9e7b-24891423dcce"]={f:Ops.Gl.Shader.ShaderToTexture,objName:"Ops.Gl.Shader.ShaderToTexture"};Ops.Gl.Textures.TextureInfo=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inObject("Texture",null,"texture"),r=e.outNumber("Name"),i=e.outString("PixelFormat"),a=e.outNumber("Width"),s=e.outNumber("Height"),o=e.outNumber("Ratio"),l=e.outNumber("Filter"),u=e.outNumber("Wrap"),c=e.outBoolNum("Flipped"),h=e.outBoolNum("HDR"),f=e.outBoolNum("Is Empty Default Texture",false),d=e.outBoolNum("Is Default Texture",false),p=e.outBoolNum("Is Cubemap"),g=e.outNumber("Id");h.setUiAttribs({title:"Float Texture"});const m=CGL.Texture.getEmptyTexture(e.patch.cgl);const v=CGL.Texture.getTempTexture(e.patch.cgl);n.onChange=function(){if(n.get()){r.set(n.get().name);a.set(n.get().width);s.set(n.get().height);o.set(n.get().width/n.get().height);let e="unknown";if(n.get().filter==CGL.Texture.FILTER_NEAREST)e="nearest";else if(n.get().filter==CGL.Texture.FILTER_LINEAR)e="linear";else if(n.get().filter==CGL.Texture.FILTER_MIPMAP)e="mipmap";l.set(n.get().filter+" "+e);let t="unknown";if(n.get().wrap==CGL.Texture.WRAP_CLAMP_TO_EDGE)t="clamp to edge";else if(n.get().wrap==CGL.Texture.WRAP_REPEAT)t="repeat";else if(n.get().wrap==CGL.Texture.WRAP_MIRRORED_REPEAT)t="mirrored repeat";u.set(n.get().wrap+" "+t);i.set(n.get().pixelFormat);g.set(n.get().id);c.set(n.get().flipped);h.set(n.get().isFloatingPoint&&n.get().isFloatingPoint());p.set(n.get().cubemap)}else{r.set("no texture");a.set(0);s.set(0);o.set(0);l.set(null);u.set(null);g.set(null);c.set(false);h.set(false);p.set(false)}f.set(n.get()==m);d.set(n.get()==v)}}};CABLES.OPS["71e5ee4c-3455-4c09-abb2-67abf382f35b"]={f:Ops.Gl.Textures.TextureInfo,objName:"Ops.Gl.Textures.TextureInfo"};Ops.Gl.ImageCompose.ImageCompose_v4=class extends CABLES.Op{constructor(){super(...arguments);const n=this;const e=n.attachments={imgcomp_frag:"IN vec2 texCoord;\nUNI vec4 bgColor;\nUNI sampler2D tex;\n#ifdef USE_UVTEX\nUNI sampler2D UVTex;\n#endif\n\nvoid main()\n{\n\n    #ifndef USE_TEX\n        outColor=bgColor;\n    #endif\n    #ifdef USE_TEX\n        #ifndef USE_UVTEX\n        outColor=texture(tex,texCoord);\n        #else\n        outColor=texture(tex,texture(UVTex,texCoord).xy);\n        #endif\n    #endif\n\n\n\n}\n"};const t=n.patch.cgl,r=n.inTrigger("Render"),i=n.inTexture("Base Texture"),a=n.inTexture("UV Texture"),s=n.inSwitch("Size",["Auto","Canvas","Manual"],"Auto"),o=n.inValueInt("Width",640),l=n.inValueInt("Height",480),u=n.inSwitch("Filter",["nearest","linear","mipmap"],"linear"),c=n.inValueSelect("Wrap",["clamp to edge","repeat","mirrored repeat"],"repeat"),h=n.inSwitch("Anisotropic",["0","1","2","4","8","16"],"0"),f=n.inDropDown("Pixel Format",CGL.Texture.PIXELFORMATS,CGL.Texture.PFORMATSTR_RGBA8UB),d=n.inBool("Clear",true),p=n.inValueSlider("R",0),g=n.inValueSlider("G",0),m=n.inValueSlider("B",0),v=n.inValueSlider("A",0),b=n.outTrigger("Next"),_=n.outTexture("texture_out",CGL.Texture.getEmptyTexture(t)),E=n.outNumber("Aspect Ratio"),w=n.outNumber("Texture Width"),N=n.outNumber("Texture Height");n.setPortGroup("Texture Size",[s,o,l]);n.setPortGroup("Texture Parameters",[c,h,u,f]);p.setUiAttribs({colorPick:true});n.setPortGroup("Color",[p,g,m,v,d]);n.toWorkPortsNeedToBeLinked(r);const P=[0,0,0,0];let F=null;let C=null;let A=true;let U=false;let x=null;let k=null;let j=null;let G=null;c.onChange=u.onChange=h.onChange=f.onChange=V;i.onLinkChanged=d.onChange=s.onChange=a.onChange=M;r.onTriggered=n.preRender=R;M();function T(){if(F)F.delete();if(C)C.delete();C=null;F=new CGL.TextureEffect(t,{isFloatingPointTexture:CGL.Texture.isPixelFormatFloat(f.get()),name:n.name});const e=Math.min(t.maxAnisotropic,parseFloat(h.get()));C=new CGL.Texture(t,{anisotropic:e,name:"image_compose_v2_"+n.id,pixelFormat:f.get(),filter:S(),wrap:y(),width:B(),height:O()});F.setSourceTexture(C);w.set(B());N.set(O());E.set(B()/O());_.setRef(CGL.Texture.getEmptyTexture(t));A=false;M()}function S(){if(u.get()=="nearest")return CGL.Texture.FILTER_NEAREST;else if(u.get()=="linear")return CGL.Texture.FILTER_LINEAR;else if(u.get()=="mipmap")return CGL.Texture.FILTER_MIPMAP}function y(){if(c.get()=="repeat")return CGL.Texture.WRAP_REPEAT;else if(c.get()=="mirrored repeat")return CGL.Texture.WRAP_MIRRORED_REPEAT;else if(c.get()=="clamp to edge")return CGL.Texture.WRAP_CLAMP_TO_EDGE}function B(){let e=0;if(i.get()&&s.get()=="Auto")e=i.get().width;else if(s.get()=="Auto"||s.get()=="Canvas")e=t.canvasWidth;else if(s.get()=="ViewPort")e=t.getViewPort()[2];else e=Math.ceil(o.get());return n.patch.cgl.checkTextureSize(e)}function O(){let e=0;if(i.get()&&s.get()=="Auto")e=i.get().height;else if(s.get()=="Auto"||s.get()=="Canvas")e=t.canvasHeight;else if(s.get()=="ViewPort")e=t.getViewPort()[3];else e=Math.ceil(l.get());return n.patch.cgl.checkTextureSize(e)}function V(){A=true}function z(){if((B()!=C.width||O()!=C.height||C.pixelFormat!=f.get()||C.filter!=S()||C.wrap!=y())&&(B()!==0&&O()!==0)){T();F.setSourceTexture(C);_.setRef(C);D();L()}}function D(){let e=null;if(s.get()=="Manual"){e=null}else if(s.get()=="Auto"){if(i.get())e="Input Texture";else e="Canvas Size";e+=": "+B()+" x "+O()}let t=false;t=s.uiAttribs.info!=e;s.setUiAttribs({info:e});if(t)n.refreshParams()}function I(){if(x)x.toggleDefine("USE_TEX",i.isLinked()||!d.get());if(x)x.toggleDefine("USE_UVTEX",a.isLinked())}function M(){h.setUiAttribs({greyout:S()!=CGL.Texture.FILTER_MIPMAP});p.setUiAttribs({greyout:i.isLinked()});m.setUiAttribs({greyout:i.isLinked()});g.setUiAttribs({greyout:i.isLinked()});v.setUiAttribs({greyout:i.isLinked()});d.setUiAttribs({greyout:i.isLinked()});o.setUiAttribs({greyout:s.get()!="Manual"});l.setUiAttribs({greyout:s.get()!="Manual"});if(C)if(CGL.Texture.isPixelFormatFloat(f.get())&&S()==CGL.Texture.FILTER_MIPMAP)n.setUiError("fpmipmap","Don't use mipmap and 32bit at the same time, many systems do not support this.");else n.setUiError("fpmipmap",null);D();I();L()}function L(){if(C)if(i.isLinked()&&i.get()&&C.isFloatingPoint()<i.get().isFloatingPoint())n.setUiError("textypediff","Warning: Mixing floating point and non floating point texture can result in data/precision loss",1);else n.setUiError("textypediff",null)}n.preRender=()=>{R()};function H(){if(!x){x=new CGL.Shader(t,"copytextureshader");x.setSource(x.getDefaultVertexShader(),e.imgcomp_frag);k=new CGL.Uniform(x,"t","tex",0);j=new CGL.Uniform(x,"t","UVTex",1);G=new CGL.Uniform(x,"4f","bgColor",p,g,m,v);I()}t.pushShader(x);t.currentTextureEffect.bind();if(i.get())t.setTexture(0,i.get().tex);else if(!d.get()&&_.get())t.setTexture(0,_.get().tex);if(a.get())t.setTexture(1,a.get().tex);t.currentTextureEffect.finish();t.popShader()}function R(){if(!F||A)T();t.pushBlend(false);z();const e=t.currentTextureEffect;t.currentTextureEffect=F;t.currentTextureEffect.imgCompVer=3;t.currentTextureEffect.width=o.get();t.currentTextureEffect.height=l.get();F.setSourceTexture(C);F.startEffect(i.get()||CGL.Texture.getEmptyTexture(t,U),true);H();b.trigger();t.pushViewPort(0,0,o.get(),l.get());F.endEffect();_.setRef(F.getCurrentSourceTexture());t.popViewPort();t.popBlend();t.currentTextureEffect=e}}};CABLES.OPS["17212e2b-d692-464c-8f8d-2d511dd3410a"]={f:Ops.Gl.ImageCompose.ImageCompose_v4,objName:"Ops.Gl.ImageCompose.ImageCompose_v4"};Ops.Anim.Timer_v2=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const a=e.inValue("Speed",1),n=e.inValueBool("Play",true),r=e.inTriggerButton("Reset"),i=e.inValueBool("Sync to timeline",false),s=e.outNumber("Time");e.setPortGroup("Controls",[n,r,a]);const o=new CABLES.Timer;let l=null;let u=0;let c=false;n.onChange=h;h();function h(){if(n.get()){o.play();e.patch.addOnAnimFrame(e)}else{o.pause();e.patch.removeOnAnimFrame(e)}}r.onTriggered=f;function f(){u=0;l=null;o.setTime(0);s.set(0)}i.onChange=function(){c=i.get();n.setUiAttribs({greyout:c});r.setUiAttribs({greyout:c})};e.onAnimFrame=function(e,t,n){if(o.isPlaying()){if(CABLES.overwriteTime!==undefined){s.set(CABLES.overwriteTime*a.get())}else if(c){s.set(e*a.get())}else{o.update();const r=o.get();if(l===null){l=r;return}const i=Math.abs(r-l);l=r;u+=i*a.get();if(u!=u)u=0;s.set(u)}}}}};CABLES.OPS["aac7f721-208f-411a-adb3-79adae2e471a"]={f:Ops.Anim.Timer_v2,objName:"Ops.Anim.Timer_v2"};Ops.Gl.ImageCompose.Blur=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={blur_frag:"IN vec2 texCoord;\nUNI sampler2D tex;\nUNI float dirX;\nUNI float dirY;\nUNI float amount;\n\n#ifdef HAS_MASK\n    UNI sampler2D imageMask;\n#endif\n\nfloat random(vec3 scale, float seed)\n{\n    return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);\n}\n\nvoid main()\n{\n    vec4 color = vec4(0.0);\n    float total = 0.0;\n\n    float am=amount;\n    #ifdef HAS_MASK\n        am=amount*texture(imageMask,texCoord).r;\n        if(am<=0.02)\n        {\n            outColor=texture(tex, texCoord);\n            return;\n        }\n    #endif\n\n    vec2 delta=vec2(dirX*am*0.01,dirY*am*0.01);\n\n\n    float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);\n\n    #ifdef MOBILE\n        offset = 0.1;\n    #endif\n\n    #if defined(FASTBLUR) && !defined(MOBILE)\n        const float range=5.0;\n    #else\n        const float range=20.0;\n    #endif\n\n    for (float t = -range; t <= range; t+=1.0)\n    {\n        float percent = (t + offset - 0.5) / range;\n        float weight = 1.0 - abs(percent);\n        vec4 smpl = texture(tex, texCoord + delta * percent);\n\n        smpl.rgb *= smpl.a;\n\n        color += smpl * weight;\n        total += weight;\n    }\n\n    outColor= color / total;\n\n    outColor.rgb /= outColor.a + 0.00001;\n\n\n\n}\n"};const n=e.inTrigger("render");const r=e.outTrigger("trigger");const i=e.inValueFloat("amount");const a=e.inSwitch("direction",["both","vertical","horizontal"],"both");const s=e.inValueBool("Fast",true);const o=e.patch.cgl;i.set(10);let l=new CGL.Shader(o,"blur");l.define("FASTBLUR");s.onChange=function(){if(s.get())l.define("FASTBLUR");else l.removeDefine("FASTBLUR")};l.setSource(l.getDefaultVertexShader(),t.blur_frag);let u=new CGL.Uniform(l,"t","tex",0);let c=new CGL.Uniform(l,"f","dirX",0);let h=new CGL.Uniform(l,"f","dirY",0);let f=new CGL.Uniform(l,"f","width",0);let d=new CGL.Uniform(l,"f","height",0);let p=new CGL.Uniform(l,"f","amount",i.get());i.onChange=function(){p.setValue(i.get())};let g=new CGL.Uniform(l,"t","imageMask",1);let m=false;function v(){if(o.currentTextureEffect.getCurrentSourceTexture().width==o.canvasWidth&&o.currentTextureEffect.getCurrentSourceTexture().height==o.canvasHeight){e.setUiError("warning","Full screen blurs are slow! Try reducing the resolution to 1/2 or a 1/4",0)}else{e.setUiError("warning",null)}}let b=0;a.onChange=function(){if(a.get()=="both")b=0;if(a.get()=="horizontal")b=1;if(a.get()=="vertical")b=2};let _=e.inTexture("mask");_.onChange=function(){if(_.get()&&_.get().tex)l.define("HAS_MASK");else l.removeDefine("HAS_MASK")};n.onTriggered=function(){if(!CGL.TextureEffect.checkOpInEffect(e))return;o.pushShader(l);f.setValue(o.currentTextureEffect.getCurrentSourceTexture().width);d.setValue(o.currentTextureEffect.getCurrentSourceTexture().height);v();if(b===0||b==2){o.currentTextureEffect.bind();o.setTexture(0,o.currentTextureEffect.getCurrentSourceTexture().tex);if(_.get()&&_.get().tex){o.setTexture(1,_.get().tex)}c.setValue(0);h.setValue(1);o.currentTextureEffect.finish()}if(b===0||b==1){o.currentTextureEffect.bind();o.setTexture(0,o.currentTextureEffect.getCurrentSourceTexture().tex);if(_.get()&&_.get().tex){o.setTexture(1,_.get().tex)}c.setValue(1);h.setValue(0);o.currentTextureEffect.finish()}o.popShader();r.trigger()}}};CABLES.OPS["54f26f53-f637-44c1-9bfb-a2f2b722e998"]={f:Ops.Gl.ImageCompose.Blur,objName:"Ops.Gl.ImageCompose.Blur"};Ops.Gl.ImageCompose.DrawImage_v3=class extends CABLES.Op{constructor(){super(...arguments);const r=this;const e=r.attachments={drawimage_frag:"#ifdef HAS_TEXTURES\n    IN vec2 texCoord;\n    UNI sampler2D tex;\n    UNI sampler2D image;\n#endif\n\n#ifdef TEX_TRANSFORM\n    IN mat3 transform;\n#endif\n// UNI float rotate;\n\n{{CGL.BLENDMODES}}\n\n#ifdef HAS_TEXTUREALPHA\n   UNI sampler2D imageAlpha;\n#endif\n\nUNI float amount;\n\n#ifdef ASPECT_RATIO\n    UNI float aspectTex;\n    UNI float aspectPos;\n#endif\n\nvoid main()\n{\n    vec4 blendRGBA=vec4(0.0,0.0,0.0,1.0);\n\n    #ifdef HAS_TEXTURES\n        vec2 tc=texCoord;\n\n        #ifdef TEX_FLIP_X\n            tc.x=1.0-tc.x;\n        #endif\n        #ifdef TEX_FLIP_Y\n            tc.y=1.0-tc.y;\n        #endif\n\n        #ifdef ASPECT_RATIO\n            #ifdef ASPECT_AXIS_X\n                tc.y=(1.0-aspectPos)-(((1.0-aspectPos)-tc.y)*aspectTex);\n            #endif\n            #ifdef ASPECT_AXIS_Y\n                tc.x=(1.0-aspectPos)-(((1.0-aspectPos)-tc.x)/aspectTex);\n            #endif\n        #endif\n\n        #ifdef TEX_TRANSFORM\n            vec3 coordinates=vec3(tc.x, tc.y,1.0);\n            tc=(transform * coordinates ).xy;\n        #endif\n\n        blendRGBA=texture(image,tc);\n\n        vec3 blend=blendRGBA.rgb;\n        vec4 baseRGBA=texture(tex,texCoord);\n        vec3 base=baseRGBA.rgb;\n\n\n        #ifdef PREMUL\n            blend.rgb = (blend.rgb) + (base.rgb * (1.0 - blendRGBA.a));\n        #endif\n\n        vec3 colNew=_blend(base,blend);\n\n\n\n\n        #ifdef REMOVE_ALPHA_SRC\n            blendRGBA.a=1.0;\n        #endif\n\n        #ifdef HAS_TEXTUREALPHA\n            vec4 colImgAlpha=texture(imageAlpha,tc);\n            float colImgAlphaAlpha=colImgAlpha.a;\n\n            #ifdef ALPHA_FROM_LUMINANCE\n                vec3 gray = vec3(dot(vec3(0.2126,0.7152,0.0722), colImgAlpha.rgb ));\n                colImgAlphaAlpha=(gray.r+gray.g+gray.b)/3.0;\n            #endif\n\n            #ifdef ALPHA_FROM_INV_UMINANCE\n                vec3 gray = vec3(dot(vec3(0.2126,0.7152,0.0722), colImgAlpha.rgb ));\n                colImgAlphaAlpha=1.0-(gray.r+gray.g+gray.b)/3.0;\n            #endif\n\n            #ifdef INVERT_ALPHA\n                colImgAlphaAlpha=clamp(colImgAlphaAlpha,0.0,1.0);\n                colImgAlphaAlpha=1.0-colImgAlphaAlpha;\n            #endif\n\n            blendRGBA.a=colImgAlphaAlpha*blendRGBA.a;\n        #endif\n    #endif\n\n    float am=amount;\n\n    #ifdef CLIP_REPEAT\n        if(tc.y>1.0 || tc.y<0.0 || tc.x>1.0 || tc.x<0.0)\n        {\n            // colNew.rgb=vec3(0.0);\n            am=0.0;\n        }\n    #endif\n\n    #ifdef ASPECT_RATIO\n        #ifdef ASPECT_CROP\n            if(tc.y>1.0 || tc.y<0.0 || tc.x>1.0 || tc.x<0.0)\n            {\n                colNew.rgb=base.rgb;\n                am=0.0;\n            }\n\n        #endif\n    #endif\n\n\n\n    #ifndef PREMUL\n        blendRGBA.rgb=mix(colNew,base,1.0-(am*blendRGBA.a));\n        blendRGBA.a=clamp(baseRGBA.a+(blendRGBA.a*am),0.,1.);\n    #endif\n\n    #ifdef PREMUL\n        // premultiply\n        // blendRGBA.rgb = (blendRGBA.rgb) + (baseRGBA.rgb * (1.0 - blendRGBA.a));\n        blendRGBA=vec4(\n            mix(colNew.rgb,base,1.0-(am*blendRGBA.a)),\n            blendRGBA.a*am+baseRGBA.a\n            );\n    #endif\n\n    #ifdef ALPHA_MASK\n    blendRGBA.a=baseRGBA.a;\n    #endif\n\n    outColor=blendRGBA;\n}\n\n\n\n\n\n\n\n",drawimage_vert:"IN vec3 vPosition;\nIN vec2 attrTexCoord;\nIN vec3 attrVertNormal;\n\nUNI mat4 projMatrix;\nUNI mat4 mvMatrix;\n\nOUT vec2 texCoord;\n// OUT vec3 norm;\n\n#ifdef TEX_TRANSFORM\n    UNI float posX;\n    UNI float posY;\n    UNI float scaleX;\n    UNI float scaleY;\n    UNI float rotate;\n    OUT mat3 transform;\n#endif\n\nvoid main()\n{\n   texCoord=attrTexCoord;\n//   norm=attrVertNormal;\n\n   #ifdef TEX_TRANSFORM\n        vec3 coordinates=vec3(attrTexCoord.x, attrTexCoord.y,1.0);\n        float angle = radians( rotate );\n        vec2 scale= vec2(scaleX,scaleY);\n        vec2 translate= vec2(posX,posY);\n\n        transform = mat3(   scale.x * cos( angle ), scale.x * sin( angle ), 0.0,\n            - scale.y * sin( angle ), scale.y * cos( angle ), 0.0,\n            - 0.5 * scale.x * cos( angle ) + 0.5 * scale.y * sin( angle ) - 0.5 * translate.x*2.0 + 0.5,  - 0.5 * scale.x * sin( angle ) - 0.5 * scale.y * cos( angle ) - 0.5 * translate.y*2.0 + 0.5, 1.0);\n   #endif\n\n   gl_Position = projMatrix * mvMatrix * vec4(vPosition,  1.0);\n}\n"};const t=r.inTrigger("render"),n=CGL.TextureEffect.AddBlendSelect(r,"blendMode"),i=r.inValueSlider("amount",1),a=r.inTexture("Image"),s=r.inValueBool("Premultiplied",false),o=r.inValueBool("Alpha Mask",false),l=r.inValueBool("removeAlphaSrc",false),u=r.inTexture("Mask"),c=r.inValueSelect("Mask Src",["alpha channel","luminance","luminance inv"],"luminance"),h=r.inBool("Invert alpha channel"),f=r.inValueBool("Aspect Ratio",false),d=r.inValueSelect("Stretch Axis",["X","Y"],"X"),p=r.inValueSlider("Position",0),g=r.inValueBool("Crop",false),m=r.outTrigger("trigger");n.set("normal");const v=r.patch.cgl;const b=new CGL.Shader(v,"drawimage");u.onLinkChanged=_;r.setPortGroup("Aspect Ratio",[f,p,g,d]);r.setPortGroup("Mask",[u,c,h]);function _(){if(u.isLinked()){l.setUiAttribs({greyout:true});c.setUiAttribs({greyout:false});h.setUiAttribs({greyout:false})}else{l.setUiAttribs({greyout:false});c.setUiAttribs({greyout:true});h.setUiAttribs({greyout:true})}}r.toWorkPortsNeedToBeLinked(a);b.setSource(e.drawimage_vert,e.drawimage_frag);const E=new CGL.Uniform(b,"t","tex",0),w=new CGL.Uniform(b,"t","image",1),N=new CGL.Uniform(b,"t","imageAlpha",2),F=new CGL.Uniform(b,"f","aspectTex",1),P=new CGL.Uniform(b,"f","aspectPos",p);f.onChange=g.onChange=d.onChange=C;function C(){b.removeDefine("ASPECT_AXIS_X");b.removeDefine("ASPECT_AXIS_Y");b.removeDefine("ASPECT_CROP");p.setUiAttribs({greyout:!f.get()});g.setUiAttribs({greyout:!f.get()});d.setUiAttribs({greyout:!f.get()});if(f.get()){b.define("ASPECT_RATIO");if(g.get())b.define("ASPECT_CROP");if(d.get()=="X")b.define("ASPECT_AXIS_X");if(d.get()=="Y")b.define("ASPECT_AXIS_Y")}else{b.removeDefine("ASPECT_RATIO");if(g.get())b.define("ASPECT_CROP");if(d.get()=="X")b.define("ASPECT_AXIS_X");if(d.get()=="Y")b.define("ASPECT_AXIS_Y")}}const A=r.inValueBool("flip x");const x=r.inValueBool("flip y");let T=r.inValueBool("Transform");let S=r.inValueSlider("Scale X",1);let y=r.inValueSlider("Scale Y",1);let B=r.inValue("Position X",0);let O=r.inValue("Position Y",0);let D=r.inValue("Rotation",0);const I=r.inValueBool("Clip Repeat",false);const U=new CGL.Uniform(b,"f","scaleX",S);const k=new CGL.Uniform(b,"f","scaleY",y);const j=new CGL.Uniform(b,"f","posX",B);const G=new CGL.Uniform(b,"f","posY",O);const V=new CGL.Uniform(b,"f","rotate",D);T.onChange=M;function M(){b.toggleDefine("TEX_TRANSFORM",T.get());S.setUiAttribs({greyout:!T.get()});y.setUiAttribs({greyout:!T.get()});B.setUiAttribs({greyout:!T.get()});O.setUiAttribs({greyout:!T.get()});D.setUiAttribs({greyout:!T.get()})}CGL.TextureEffect.setupBlending(r,b,n,i);const z=new CGL.Uniform(b,"f","amount",i);t.onTriggered=R;I.onChange=u.onChange=s.onChange=o.onChange=h.onChange=x.onChange=A.onChange=l.onChange=c.onChange=L;M();_();C();L();function L(){b.toggleDefine("REMOVE_ALPHA_SRC",l.get());b.toggleDefine("ALPHA_MASK",o.get());b.toggleDefine("CLIP_REPEAT",I.get());b.toggleDefine("HAS_TEXTUREALPHA",u.get()&&u.get().tex);b.toggleDefine("TEX_FLIP_X",A.get());b.toggleDefine("TEX_FLIP_Y",x.get());b.toggleDefine("INVERT_ALPHA",h.get());b.toggleDefine("ALPHA_FROM_LUMINANCE",c.get()=="luminance");b.toggleDefine("ALPHA_FROM_INV_UMINANCE",c.get()=="luminance_inv");b.toggleDefine("PREMUL",s.get())}function R(){if(!CGL.TextureEffect.checkOpInEffect(r))return;const e=a.get();if(e&&e.tex&&i.get()>0){v.pushShader(b);v.currentTextureEffect.bind();const t=v.currentTextureEffect.getCurrentSourceTexture();v.setTexture(0,t.tex);const n=1/(v.currentTextureEffect.getWidth()/v.currentTextureEffect.getHeight())*(e.width/e.height);F.setValue(n);v.setTexture(1,e.tex);if(u.get()&&u.get().tex){v.setTexture(2,u.get().tex)}v.pushBlendMode(CGL.BLEND_NONE,true);v.currentTextureEffect.finish();v.popBlendMode();v.popShader()}m.trigger()}}};CABLES.OPS["8f6b2f15-fcb0-4597-90c0-e5173f2969fe"]={f:Ops.Gl.ImageCompose.DrawImage_v3,objName:"Ops.Gl.ImageCompose.DrawImage_v3"};Ops.Gl.ValidTexture=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inTexture("Texture"),r=e.inSwitch("Default",["Empty","Stripes"],"Empty"),i=e.outTexture("Result");let a=CGL.Texture.getEmptyTexture(e.patch.cgl);r.onChange=function(){if(r.get()=="Empty")a=CGL.Texture.getEmptyTexture(e.patch.cgl);else a=CGL.Texture.getTempTexture(e.patch.cgl)};n.onChange=function(){let e=n.get();if(!e)e=a;i.set(e)}}};CABLES.OPS["51c24850-aa8b-41e4-936e-68ba718b5e39"]={f:Ops.Gl.ValidTexture,objName:"Ops.Gl.ValidTexture"};Ops.Patch.P8RrHYT.PostProcDirector=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inInt("scene",0),r=e.inBool("Bypass2",false),i=e.inFloat("PAL Phase Noise2",.2),a=e.inFloat("PAL Gain2",2.42),s=e.inFloat("PAL Amount2",1),o=e.inFloat("Bloom Amount2",.524),l=e.outNumber("PAL Phase Noise"),u=e.outNumber("PAL Gain"),c=e.outNumber("PAL Amount"),h=e.outNumber("Bloom Amount"),f=e.outString("Settings string");const d=[[.2,2.42,1,.524],[.2,2.42,1,.524],[.2,2.42,1,.524],[.2,2.42,1,.524],[.2,2.42,0,.3],[.2,2.42,1,.7],[.2,2.42,0,0]];n.onChange=r.onChange=i.onChange=a.onChange=s.onChange=o.onChange=p;p();function p(){let e;if(r.get()){e=[i.get(),a.get(),s.get(),o.get()]}else{const t=Math.min(d.length-1,Math.max(0,n.get()));e=d[t]}l.set(e[0]);u.set(e[1]);c.set(e[2]);h.set(e[3]);f.set("["+e.join(", ")+"],")}}};CABLES.OPS["06f94e62-0493-4c81-a781-3b6bfe2dc768"]={f:Ops.Patch.P8RrHYT.PostProcDirector,objName:"Ops.Patch.P8RrHYT.PostProcDirector"};Ops.Math.Compare.Equals=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValue("number1",1),r=e.inValue("number2",1),i=e.outBoolNum("result");n.onChange=r.onChange=a;a();function a(){i.set(n.get()==r.get())}}};CABLES.OPS["4dd3cc55-eebc-4187-9d4e-2e053a956fab"]={f:Ops.Math.Compare.Equals,objName:"Ops.Math.Compare.Equals"};Ops.Html.Utils.PlayButton=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={inner_css:"\nborder-style:solid;\nborder-color:transparent transparent transparent #ccc;\nbox-sizing:border-box;\nwidth:50px;\nheight:50px;\nmargin-top:25px;\nmargin-left:36px;\nborder-width:25px 0px 25px 40px;\npointer-events:none;\n",outer_css:"width:100px;\nheight:100px;\nleft:50%;\ntop:50%;\nborder-radius:100%;\nposition:absolute;\ncursor:pointer;\nopacity:0.7;\ntransform:translate(-50%,-50%);\nz-index:999999;\nbackground-color:#333;\nborder:5px solid #333;"};const n=e.inTrigger("Trigger"),r=e.inValueBool("Only if Audio Suspended"),i=e.inTriggerButton("Reset"),a=e.inStringEditor("Style Outer",t.outer_css),s=e.inStringEditor("Style Inner",t.inner_css),o=e.inBool("Active",true),l=e.outTrigger("Next"),u=e.outTrigger("Not Clicked"),c=e.outString("Audiocontext State","unknown"),h=e.outObject("Element"),f=e.outBoolNum("Clicked",false),d=e.outTrigger("Clicked Trigger");e.toWorkPortsNeedToBeLinked(n);let p=CABLES.WEBAUDIO.createAudioContext(e);const g=e.patch.cgl.canvas.parentElement;let m=false;let v=null;let b=null;_();a.onChange=s.onChange=_;p.addEventListener("statechange",E);E();o.onChange=()=>{if(!o.get())v.style.display="none";else v.style.display="block"};function _(){E();if(b)b.remove();if(v)v.remove();v=document.createElement("div");v.style=a.get();h.set(v);g.appendChild(v);b=document.createElement("div");b.style=s.get();v.appendChild(b);v.classList.add("playButton");v.addEventListener("mouseenter",x);v.addEventListener("mouseleave",A);v.addEventListener("click",F);v.addEventListener("touchStart",F);e.onDelete=C}i.onTriggered=function(){_();m=false;f.set(m)};function E(){c.set(p.state);if(r.get()&&p.state=="running")F()}n.onTriggered=function(){if(m)l.trigger();else u.trigger()};function F(){C();if(p&&p.state=="suspended")p.resume();m=true;f.set(m);d.trigger()}function C(){if(b)b.remove();if(v)v.remove()}function A(){if(v)v.style.opacity=.7}function x(){if(v)v.style.opacity=1}}};CABLES.OPS["32e53fa2-4545-4c53-a94d-2204aa079246"]={f:Ops.Html.Utils.PlayButton,objName:"Ops.Html.Utils.PlayButton"};Ops.Graphics.DepthTest=class extends CABLES.Op{constructor(){super(...arguments);const t=this;const e=t.attachments={};const n=t.inTrigger("Render"),r=t.inValueBool("Enable depth testing",true),i=t.inValueSelect("Depth Test Method",["never","always","less","less or equal","greater","greater or equal","equal","not equal"],"less or equal"),a=t.inValueBool("Write to depth buffer",true),s=t.outTrigger("Next");const o=t.patch.cgl;let l=CABLES.CG.DEPTH_COMPARE_LESSEQUAL;i.onChange=u;function u(){const e=i.get();if(e=="never")l=CABLES.CG.DEPTH_COMPARE_NEVER;else if(e=="always")l=CABLES.CG.DEPTH_COMPARE_ALWAYS;else if(e=="less")l=CABLES.CG.DEPTH_COMPARE_LESS;else if(e=="less or equal")l=CABLES.CG.DEPTH_COMPARE_LESSEQUAL;else if(e=="greater")l=CABLES.CG.DEPTH_COMPARE_GREATER;else if(e=="greater or equal")l=CABLES.CG.DEPTH_COMPARE_GREATEREQUAL;else if(e=="equal")l=CABLES.CG.DEPTH_COMPARE_EQUAL;else if(e=="not equal")l=CABLES.CG.DEPTH_COMPARE_NOTEQUAL}n.onTriggered=function(){const e=t.patch.cg;if(!e)return;t.patch.cg.pushDepthTest(r.get());t.patch.cg.pushDepthWrite(a.get());t.patch.cg.pushDepthFunc(e.DEPTH_FUNCS[l]);s.trigger();t.patch.cg.popDepthTest();t.patch.cg.popDepthWrite();t.patch.cg.popDepthFunc()}}};CABLES.OPS["3996ed5d-8143-4bec-9cfd-c1b193a295af"]={f:Ops.Graphics.DepthTest,objName:"Ops.Graphics.DepthTest"};Ops.Gl.ClearColor=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inTrigger("render"),r=e.outTrigger("trigger"),i=e.inFloatSlider("r",.1),a=e.inFloatSlider("g",.1),s=e.inFloatSlider("b",.1),o=e.inFloatSlider("a",1);i.setUiAttribs({colorPick:true});const l=e.patch.cgl;n.onTriggered=function(){l.gl.clearColor(i.get(),a.get(),s.get(),o.get());l.gl.clear(l.gl.COLOR_BUFFER_BIT|l.gl.DEPTH_BUFFER_BIT);r.trigger()}}};CABLES.OPS["19b441eb-9f63-4f35-ba08-b87841517c4d"]={f:Ops.Gl.ClearColor,objName:"Ops.Gl.ClearColor"};Ops.Gl.Shader.BasicMaterial_v2=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={basicmaterial_frag:"{{MODULES_HEAD}}\n\nIN vec2 texCoord;\nUNI vec4 color;\n// UNI float r;\n// UNI float g;\n// UNI float b;\n// UNI float a;\n\n#ifdef HAS_TEXTURES\n    IN vec2 texCoordOrig;\n    #ifdef HAS_TEXTURE_DIFFUSE\n        UNI sampler2D tex;\n    #endif\n    #ifdef HAS_TEXTURE_OPACITY\n        UNI sampler2D texOpacity;\n   #endif\n#endif\n\nvoid main()\n{\n    {{MODULE_BEGIN_FRAG}}\n    vec4 col=color;\n\n    #ifdef HAS_TEXTURES\n        // vec2 uv=vec2(texCoord.s,1.0-texCoord.t);\n        vec2 uv=texCoord;\n\n        #ifdef HAS_TEXTURE_DIFFUSE\n            col=texture(tex,uv);\n\n            #ifdef COLORIZE_TEXTURE\n                col.r*=color.r;\n                col.g*=color.g;\n                col.b*=color.b;\n            #endif\n        #endif\n        col.a*=color.a;\n        #ifdef HAS_TEXTURE_OPACITY\n            #ifdef TRANSFORMALPHATEXCOORDS\n                // uv=vec2(texCoordOrig.s,1.0-texCoordOrig.t);\n                uv=texCoordOrig;\n            #endif\n            #ifdef ALPHA_MASK_ALPHA\n                col.a*=texture(texOpacity,uv).a;\n            #endif\n            #ifdef ALPHA_MASK_LUMI\n                col.a*=dot(vec3(0.2126,0.7152,0.0722), texture(texOpacity,uv).rgb);\n            #endif\n            #ifdef ALPHA_MASK_R\n                col.a*=texture(texOpacity,uv).r;\n            #endif\n            #ifdef ALPHA_MASK_G\n                col.a*=texture(texOpacity,uv).g;\n            #endif\n            #ifdef ALPHA_MASK_B\n                col.a*=texture(texOpacity,uv).b;\n            #endif\n            // #endif\n        #endif\n    #endif\n\n    {{MODULE_COLOR}}\n\n    #ifdef DISCARDTRANS\n        if(col.a<0.2) discard;\n    #endif\n\n    outColor = col;\n}\n",basicmaterial_vert:"IN vec3 vPosition;\nIN vec2 attrTexCoord;\nIN vec3 attrVertNormal;\nIN float attrVertIndex;\n\n{{MODULES_HEAD}}\n\nOUT vec3 norm;\nOUT vec2 texCoord;\nOUT vec2 texCoordOrig;\n\nUNI mat4 projMatrix;\nUNI mat4 modelMatrix;\nUNI mat4 viewMatrix;\n\n#ifdef HAS_TEXTURES\n    UNI float diffuseRepeatX;\n    UNI float diffuseRepeatY;\n    UNI float texOffsetX;\n    UNI float texOffsetY;\n#endif\n\nvoid main()\n{\n    mat4 mMatrix=modelMatrix;\n    mat4 mvMatrix;\n\n    norm=attrVertNormal;\n    texCoordOrig=vec2(attrTexCoord.x,1.0-attrTexCoord.y);\n    texCoord=vec2(attrTexCoord.x,1.0-attrTexCoord.y);\n    #ifdef HAS_TEXTURES\n        texCoord.x=texCoord.x*diffuseRepeatX+texOffsetX;\n        texCoord.y=texCoord.y*diffuseRepeatY+texOffsetY;\n    #endif\n\n    vec4 pos = vec4(vPosition, 1.0);\n\n    #ifdef BILLBOARD\n       vec3 position=vPosition;\n       mvMatrix=viewMatrix*modelMatrix;\n\n       gl_Position = projMatrix * mvMatrix * vec4((\n           position.x * vec3(\n               mvMatrix[0][0],\n               mvMatrix[1][0],\n               mvMatrix[2][0] ) +\n           position.y * vec3(\n               mvMatrix[0][1],\n               mvMatrix[1][1],\n               mvMatrix[2][1]) ), 1.0);\n    #endif\n\n    {{MODULE_VERTEX_POSITION}}\n\n    #ifndef BILLBOARD\n        mvMatrix=viewMatrix * mMatrix;\n    #endif\n\n\n    #ifndef BILLBOARD\n        // gl_Position = projMatrix * viewMatrix * modelMatrix * pos;\n        gl_Position = projMatrix * mvMatrix * pos;\n    #endif\n}\n"};const n=e.inTrigger("render");const r=e.outTrigger("trigger");const i=e.outObject("shader");i.ignoreValueSerialize=true;const a=e.patch.cgl;e.toWorkPortsNeedToBeLinked(n);const s=new CGL.Shader(a,"basicmaterialnew");s.setModules(["MODULE_VERTEX_POSITION","MODULE_COLOR","MODULE_BEGIN_FRAG"]);s.setSource(t.basicmaterial_vert,t.basicmaterial_frag);i.set(s);n.onTriggered=o;e.preRender=function(){s.bind();o()};function o(){if(!s)return;a.pushShader(s);s.popTextures();if(p&&d.get())s.pushTexture(p,d.get().tex);if(b&&v.get())s.pushTexture(b,v.get().tex);r.trigger();a.popShader()}const l=e.inValueSlider("r",Math.random());const u=e.inValueSlider("g",Math.random());const c=e.inValueSlider("b",Math.random());const h=e.inValueSlider("a",1);l.setUiAttribs({colorPick:true});const f=new CGL.Uniform(s,"4f","color",l,u,c,h);e.setPortGroup("Color",[l,u,c,h]);var d=e.inTexture("texture");var p=null;d.onChange=g;function g(){if(d.get()){if(!s.hasDefine("HAS_TEXTURE_DIFFUSE"))s.define("HAS_TEXTURE_DIFFUSE");if(!p)p=new CGL.Uniform(s,"t","texDiffuse",0);A.setUiAttribs({greyout:false});x.setUiAttribs({greyout:false});T.setUiAttribs({greyout:false});S.setUiAttribs({greyout:false});m.setUiAttribs({greyout:false})}else{s.removeUniform("texDiffuse");s.removeDefine("HAS_TEXTURE_DIFFUSE");p=null;A.setUiAttribs({greyout:true});x.setUiAttribs({greyout:true});T.setUiAttribs({greyout:true});S.setUiAttribs({greyout:true});m.setUiAttribs({greyout:true})}}const m=e.inValueBool("colorizeTexture",false);e.setPortGroup("Color Texture",[d,m]);var v=e.inTexture("textureOpacity");var b=null;e.alphaMaskSource=e.inSwitch("Alpha Mask Source",["Luminance","R","G","B","A"],"Luminance");e.alphaMaskSource.onChange=_;e.alphaMaskSource.setUiAttribs({greyout:true});function _(){if(e.alphaMaskSource.get()=="A")s.define("ALPHA_MASK_ALPHA");else s.removeDefine("ALPHA_MASK_ALPHA");if(e.alphaMaskSource.get()=="Luminance")s.define("ALPHA_MASK_LUMI");else s.removeDefine("ALPHA_MASK_LUMI");if(e.alphaMaskSource.get()=="R")s.define("ALPHA_MASK_R");else s.removeDefine("ALPHA_MASK_R");if(e.alphaMaskSource.get()=="G")s.define("ALPHA_MASK_G");else s.removeDefine("ALPHA_MASK_G");if(e.alphaMaskSource.get()=="B")s.define("ALPHA_MASK_B");else s.removeDefine("ALPHA_MASK_B")}v.onChange=E;function E(){if(v.get()){if(b!==null)return;s.removeUniform("texOpacity");s.define("HAS_TEXTURE_OPACITY");if(!b)b=new CGL.Uniform(s,"t","texOpacity",1);e.alphaMaskSource.setUiAttribs({greyout:false});C.setUiAttribs({greyout:false});F.setUiAttribs({greyout:false})}else{s.removeUniform("texOpacity");s.removeDefine("HAS_TEXTURE_OPACITY");b=null;e.alphaMaskSource.setUiAttribs({greyout:true});C.setUiAttribs({greyout:true});F.setUiAttribs({greyout:true})}_()}var F=e.inValueBool("Opacity TexCoords Transform",false);const C=e.inValueBool("Discard Transparent Pixels");C.onChange=function(){if(C.get())s.define("DISCARDTRANS");else s.removeDefine("DISCARDTRANS")};F.onChange=function(){if(F.get())s.define("TRANSFORMALPHATEXCOORDS");else s.removeDefine("TRANSFORMALPHATEXCOORDS")};e.setPortGroup("Opacity",[v,e.alphaMaskSource,C,F]);m.onChange=function(){if(m.get())s.define("COLORIZE_TEXTURE");else s.removeDefine("COLORIZE_TEXTURE")};const A=e.inValue("diffuseRepeatX",1);const x=e.inValue("diffuseRepeatY",1);const T=e.inValue("Tex Offset X",0);const S=e.inValue("Tex Offset Y",0);const y=new CGL.Uniform(s,"f","diffuseRepeatX",A);const B=new CGL.Uniform(s,"f","diffuseRepeatY",x);const O=new CGL.Uniform(s,"f","texOffsetX",T);const D=new CGL.Uniform(s,"f","texOffsetY",S);e.setPortGroup("Texture Transform",[A,x,T,S]);const I=e.inValueBool("billboard",false);I.onChange=function(){if(I.get())s.define("BILLBOARD");else s.removeDefine("BILLBOARD")};E();g()}};CABLES.OPS["51f2207b-daaa-447f-bdbe-87fdd72f0c40"]={f:Ops.Gl.Shader.BasicMaterial_v2,objName:"Ops.Gl.Shader.BasicMaterial_v2"};Ops.Graphics.Meshes.Rectangle=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};let n=e.inTrigger("render");let r=e.outTrigger("trigger");let v=e.inValue("width",1);let b=e.inValue("height",1);let _=e.inSwitch("pivot x",["left","center","right"]);let E=e.inSwitch("pivot y",["top","center","bottom"]);let F=e.inValueInt("num columns",1);let C=e.inValueInt("num rows",1);let A=e.inSwitch("axis",["xy","xz"],"xy");let i=e.inValueBool("Active",true);let x=e.outObject("geometry");x.ignoreValueSerialize=true;let T=e.patch.cgl;A.set("xy");_.set("center");E.set("center");e.setPortGroup("Pivot",[_,E]);e.setPortGroup("Size",[v,b]);e.setPortGroup("Structure",[F,C]);let S=new CGL.Geometry("rectangle");let y=null;let B=false;A.onChange=_.onChange=E.onChange=v.onChange=b.onChange=C.onChange=F.onChange=a;s();function a(){s()}e.preRender=n.onTriggered=function(){if(!CGL.TextureEffect.checkOpNotInTextureEffect(e))return;if(B)s();if(i.get()&&y)y.render(T.getShader());r.trigger()};function s(){let e=v.get();let t=parseFloat(b.get());let n=0;let r=0;if(typeof e=="string")e=parseFloat(e);if(typeof t=="string")t=parseFloat(t);if(_.get()=="center")n=0;else if(_.get()=="right")n=-e/2;else if(_.get()=="left")n=+e/2;if(E.get()=="center")r=0;else if(E.get()=="top")r=-t/2;else if(E.get()=="bottom")r=+t/2;let i=[];let a=[];let s=[];let o=[];let l=[];let u=[];let c=Math.round(C.get());let h=Math.round(F.get());let f=e/h;let d=t/c;let p,g,m;m=A.get();for(g=0;g<=c;g++){for(p=0;p<=h;p++){i.push(p*f-v.get()/2+n);if(m=="xz")i.push(0);i.push(g*d-b.get()/2+r);if(m=="xy")i.push(0);a.push(p/h);a.push(1-g/c);if(m=="xz"){s.push(0,1,0);o.push(1,0,0);l.push(0,0,1)}else if(m=="xy"){s.push(0,0,1);o.push(-1,0,0);l.push(0,-1,0)}}}for(p=0;p<h;p++){for(g=0;g<c;g++){let e=p+(h+1)*g;let t=e;let n=e+1;let r=e+h+1;let i=e+1+h+1;u.push(t);u.push(r);u.push(n);u.push(n);u.push(r);u.push(i)}}S.clear();S.vertices=i;S.texCoords=a;S.verticesIndices=u;S.vertexNormals=s;S.tangents=o;S.biTangents=l;if(h*c>64e3)S.unIndex();if(!y)y=new CGL.Mesh(T,S);else y.setGeom(S);x.set(null);x.set(S);B=false}e.onDelete=function(){if(y)y.dispose()}}};CABLES.OPS["20f3c4e7-04d1-44e0-b868-05756d1c66c6"]={f:Ops.Graphics.Meshes.Rectangle,objName:"Ops.Graphics.Meshes.Rectangle"};Ops.Extension.Deprecated.ScaleXYZ=class extends CABLES.Op{constructor(){super(...arguments);const t=this;const e=t.attachments={};const n=t.inTrigger("render"),r=t.inValueFloat("x",1),i=t.inValueFloat("y",1),a=t.inValueFloat("z",1),s=t.outTrigger("trigger");const o=vec3.create();let l=true;r.onChange=i.onChange=a.onChange=c;c();n.onTriggered=u;function u(){const e=t.patch.cg||t.patch.cgl;if(l){vec3.set(o,r.get(),i.get(),a.get());l=false}e.pushModelMatrix();mat4.scale(e.mMatrix,e.mMatrix,o);s.trigger();e.popModelMatrix()}function c(){l=true}}};CABLES.OPS["9ba52457-5f0d-4b20-a97c-4ec4856b8e29"]={f:Ops.Extension.Deprecated.ScaleXYZ,objName:"Ops.Extension.Deprecated.ScaleXYZ"};Ops.Math.OneMinus=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValue("Value"),r=e.outNumber("Result");n.onChange=i;i();function i(){r.set(1-n.get())}}};CABLES.OPS["f34d019d-59ae-40d6-a55d-a7691bbc40e0"]={f:Ops.Math.OneMinus,objName:"Ops.Math.OneMinus"};Ops.Gl.GradientTexture=class extends CABLES.Op{constructor(){super(...arguments);const n=this;const e=n.attachments={};const y=n.inGradient("Gradient"),B=n.inValueSelect("Direction",["X","XX","Y","YY","XY","YX","Radial"],"X"),O=n.inValueBool("Smoothstep",false),D=n.inBool("Step",false),I=n.inBool("Flip",false),M=n.inBool("sRGB",false),L=n.inBool("Oklab",false),R=n.inValueInt("Size",256),w=n.inSwitch("filter",["nearest","linear","mipmap"],"linear"),N=n.inValueSelect("wrap",["clamp to edge","repeat","mirrored repeat"],"clamp to edge"),g=n.inFloatSlider("Dither",0),r=n.inArray("Gradient Array"),t=n.inTriggerButton("Randomize Colors"),P=n.outTexture("Texture"),U=n.outArray("Colors",null,3),k=n.outArray("Colors Pos",null,1);const j=n.patch.cgl;let i=null;y.setUiAttribs({editShortcut:true});const a=[221,125,40,94,163,50,214,174,69,229,135,79,25,92,217,129,103,155,16,237,168,75,212,126,203,157,104,223,50,96,115,189,0,104,199,16,185,242,83,26,123,95,191,175,247,159,32,170,0,88,203,133,106,46,227,14,35,246,66,20,240,205,36,159,74,252,148,231,132,117,6,145,254,39,222,5,111,46,67,197,228,116,181,66,25,245,98,139,172,89,190,149,127,177,64,138,210,169,58,28,70,100,206,188,164,107,60,150,203,126,235,142,56,249,38,222,148,178,195,56,115,230,45,108,7,84,234,21,44,90,110,216,178,37,226,53,14,77,212,31,86,180,100,23,82,14,162,93,122,6,81,156,24,209,75,255,163,218,196,121,237,187,9,152,247,136,158,91,128,232,169,137,251,10,216,154,188,131,211,71,200,34,236,216,129,13,179,136,32,54,99,146,33,131,202,49,84,18,64,197,245,114,21,193,52,74,118,44,243,105,173,50,252,110,63,166,41,102,199,62,117,184,15,77,250,162,69,120,231,107,213,2,177,43,67,102,159,238,171,206,64,29,233,10,151,135,185,87,247,147,223,91,241,152,225,175,3,102,220,25,191,170,36,143,81,152,209,224,133,35,93,2,145,87,124,193,97,22,228,1,120,51,171,8,26,210,108,48,205,59,179,92,147,253,124,99,237,186,11,120,19,181,229,112,198,160,220,76,42,210,160,71,202,31,78,190,130,67,86,138,115,156,243,14,46,74,57,219,28,51,90,250,59,81,140,47,255,17,58,181,243,114,56,178,239,139,228,156,251,40,167,232,28,38,82,136,206,161,9,196,106,139,167,204,150,195,218,70,172,35,132,103,146,27,89,128,16,107,96,57,119,201,15,187,239,126,194,225,112,182,234,131,174,240,72,39,109,29,8,100,122,207,231,4,166,224,198,153,217,44,183,212,4,93,143,72,99,172,64,0,97,34,85,66,20,208,3,125,243,164,186,235,156,82,191,67,248,49,80,10,253,68,23,162,244,179,49,215,24,151,246,51,214,153,251,118,45,157,98,224,53,88,134,62,42,23,116,94,140,33,121,188,169,141,113,76,33,131,227,110,11,202,78,122,168,18,141,194,221,80,187,142,177,210,18,249,144,221,180,12,201,215,106,60,91,226,200,236,150,85,61,164,185,133,42,229,187,73,55,101,27,235,59,12,35,75,113,199,101,163,237,57,152,174,234,134,1,37,53,123,193,6,208,253,34,91,145,104,8,240,211,175,129,164,109,253,123,230,171,6,50,79,27,127,73,43,19,246,161,211,103,17,172,96,46,117,70,241,219,27,162,115,88,38,4,148,204,92,189,154,63,130,217,188,111,254,208,101,86,191,144,75,180,249,65,137,233,157,18,171,192,49,66,201,137,246,218,51,71,15,43,214,29,95,239,38,139,165,7,225,124,30,59,112,221,154,28,197,217,106,58,85,209,128,232,151,15,79,182,120,238,168,134,81,248,146,173,16,88,195,65,150,183,205,242,11,41,89,126,80,8,183,121,141,3,98,180,31,108,58,196,97,24,222,107,198,2,116,70,207,52,230,22,109,47,80,165,132,199,235,170,52,148,247,165,23,242,74,45,254,170,226,155,36,142,179,60,158,48,182,223,154,124,98,178,250,140,5,231,96,68,19,116,204,32,227,43,200,113,161,213,122,87,0,130,248,77,13,241,92,229,30,102,13,244,77,160,33,209,119,55,176,143,190,255,103,71,93,186,62,223,145,12,189,68,202,47,211,114,192,41,127,203,141,65,189,40,135,198,61,89,222,158,24,216,45,1,157,213,130,239,83,104,26,55,134,238,29,159,95,63,167,149,7,78,255,119,166,212,1,233,19,105,186,37,244,110,86,135,56,173,11,151,36,176,196,230,94,149,109,184,226,20,236,215,105,175,22,219,52,87,111,174,128,248,149,78,125,63,184,227,242,118,22,220,138,252,119,76,168,39,250,10,136,84,123,54,69,194,37,95,147,241,73,153,48,68,7,194,17,207,161,31,76,201,90,166,69,4,48,215,21,204,57,73,176,200,30,249,155,133,233,163,9,197,32,183,220,205,137,232,167,94,144,9,105,181,44,111,207,99,132,155,182,85,127,219,147,42,97,184,5,83,208,108,61,125,228,21,100,39,90,114,53,218,41,252,129,61,234,143,30,192,245,12,112,236,101,2,244,113,165,225,118,47,20,176,251,142,84,117,160,254,177,26,238,121,72,193,213,153,13,55,173,79,224,65,140,34,195,158,54,17,206,62,144,240,190,72,40,214,54,192,5,146,60,82,185,3,138,169,25,83,245];const m=32;g.onChange=N.onChange=w.onChange=D.onChange=I.onChange=M.onChange=L.onChange=R.onChange=y.onChange=O.onChange=B.onChange=r.onChange=s;y.set('{"keys" : [{"pos":0,"r":0,"g":0,"b":0},{"pos":1,"r":1,"g":1,"b":1}]}');n.onLoaded=s;t.onTriggered=()=>{const e=l();if(e){e.forEach(e=>{e.r=Math.random();e.g=Math.random();e.b=Math.random()});const t=JSON.stringify({keys:e});y.set(t)}};function G(e,t,n){let r=.4122214708*e+.5363325363*t+.0514459929*n;let i=.2119034982*e+.6806995451*t+.1073969566*n;let a=.0883024619*e+.2817188376*t+.6299787005*n;r=Math.cbrt(r);i=Math.cbrt(i);a=Math.cbrt(a);return[r*+.2104542553+i*+.793617785+a*-.0040720468,r*+1.9779984951+i*-2.428592205+a*+.4505937099,r*+.0259040371+i*+.7827717662+a*-.808675766]}function V(e,t,n){let r=e+t*+.3963377774+n*+.2158037573;let i=e+t*-.1055613458+n*-.0638541728;let a=e+t*-.0894841775+n*-1.291485548;r**=3;i**=3;a**=3;let s=r*+4.0767416621+i*-3.3077115913+a*+.2309699292;let o=r*-1.2684380046+i*+2.6097574011+a*-.3413193965;let l=r*-.0041960863+i*-.7034186147+a*+1.707614701;s=CABLES.clamp(s,0,1);o=CABLES.clamp(o,0,1);l=CABLES.clamp(l,0,1);return[s,o,l]}function z(e,t,n){e/=255;const r=.0031308;let i=12.92*e;let a=1.055*Math.pow(e,.41666)-.055;return(e<r?i:a)*255}function s(){j.addNextFrameOnceCallback(o)}function o(){const e=l();if(e)u(e)}function l(){let t=null;n.setUiError("nodata",null);n.setUiError("parse",null);if(Array.isArray(r.get())){t=r.get()}else{let e=null;if(!y.get()||y.get()===""){return null}try{e=JSON.parse(y.get())}catch(e){n.setUiError("parse","could not parse gradient data")}if(!e||!e.keys){n.setUiError("nodata","gradient no data");return null}t=e.keys}return t}function v(e,t){e%=m;t%=m;return a[e+t*m]/255-.5}function H(i,a,s){if(g.get()==0)return i;for(let r=0;r<a;r++)for(let n=0;n<s;n++){const o=i[(r+n*a)*4+0];const l=i[(r+n*a)*4+1];const u=i[(r+n*a)*4+2];let e=a/8*g.get()*v(r,n);let t=s/8*g.get()*v(r+m/2,n+m/2);if(s==1)t=0;if(a==1)e=0;e=Math.round(e);t=Math.round(t);const c=CABLES.clamp(n+t,0,s-1);const h=CABLES.clamp(r+e,0,a-1);const f=i[(h+c*a)*4+0];const d=i[(h+c*a)*4+1];const p=i[(h+c*a)*4+2];i[(r+n*a)*4+0]=f;i[(r+n*a)*4+1]=d;i[(r+n*a)*4+2]=p;i[(h+c*a)*4+0]=o;i[(h+c*a)*4+1]=l;i[(h+c*a)*4+2]=u}return i}function u(t){let i=Math.round(R.get());if(i<4)i=4;y.setUiAttribs({editShortcut:true,gradEditSmoothstep:O.get(),gradEditStep:D.get(),gradOklab:L.get()});let e=0;let n=0;if(N.get()=="repeat")e=CGL.Texture.WRAP_REPEAT;else if(N.get()=="mirrored repeat")e=CGL.Texture.WRAP_MIRRORED_REPEAT;else if(N.get()=="clamp to edge")e=CGL.Texture.WRAP_CLAMP_TO_EDGE;if(w.get()=="nearest")n=CGL.Texture.FILTER_NEAREST;else if(w.get()=="linear")n=CGL.Texture.FILTER_LINEAR;else if(w.get()=="mipmap")n=CGL.Texture.FILTER_MIPMAP;const r=new CGL.Texture(j);let a=new Uint8Array(i*4);for(let e=0;e<t.length-1;e++){const l=t[e];const u=t[e+1];for(let n=l.pos*i;n<u.pos*i;n++){let e=CABLES.map(n,l.pos*i,u.pos*i,0,1);if(D.get())e=Math.round(e);if(O.get())e=CABLES.smoothStep(e);n=Math.round(n);let t=n;if(I.get())t=i-n-1;if(L.get()){const c=G(l.r,l.g,l.b);const h=c[0];const f=c[1];const d=c[2];const p=G(u.r,u.g,u.b);const g=p[0];const m=p[1];const v=p[2];const b=e*g+(1-e)*h;const _=e*m+(1-e)*f;const E=e*v+(1-e)*d;const F=V(b,_,E);a[t*4+0]=Math.round(F[0]*255);a[t*4+1]=Math.round(F[1]*255);a[t*4+2]=Math.round(F[2]*255)}else{a[t*4+0]=Math.round((e*u.r+(1-e)*l.r)*255);a[t*4+1]=Math.round((e*u.g+(1-e)*l.g)*255);a[t*4+2]=Math.round((e*u.b+(1-e)*l.b)*255)}if(typeof l.a!=="undefined"&&typeof u.a!=="undefined"){const C=Math.round((e*u.a+(1-e)*l.a)*255);a[t*4+3]=C}else{a[t*4+3]=Math.round(255)}}}if(M.get())for(let e=0;e<a.length;e+=4){a[e+0]=z(a[e+0]);a[e+1]=z(a[e+1]);a[e+2]=z(a[e+2])}if(B.get()=="X")r.initFromData(H(a,i,1),i,1,n,e);if(B.get()=="Y")r.initFromData(H(a,1,i),1,i,n,e);if(B.get()=="Radial"){const A=new Uint8Array(i*i*4);for(let r=0;r<i;r++){for(let n=0;n<i;n++){const x=r-(i-1)/2;const T=n-(i-1)/2;let e=Math.sqrt(x*x+T*T)/i*2;if(O.get())e=CABLES.smoothStep(e);let t=Math.round(e*i)*4;if(t>=i*4)t=i*4-4;A[r*4+n*4*i+0]=a[t+0];A[r*4+n*4*i+1]=a[t+1];A[r*4+n*4*i+2]=a[t+2];A[r*4+n*4*i+3]=Math.round(255)}}a=A;r.initFromData(H(a,i,i),i,i,n,e)}if(B.get()=="XX"){const A=new Uint8Array(i*i*4);for(let t=0;t<i;t++)for(let e=0;e<i;e++){const S=t*4;A[t*4+e*4*i+0]=a[S+0];A[t*4+e*4*i+1]=a[S+1];A[t*4+e*4*i+2]=a[S+2];A[t*4+e*4*i+3]=Math.round(255)}a=A;r.initFromData(H(a,i,i),i,i,n,e)}if(B.get()=="YY"){const A=new Uint8Array(i*i*4);for(let t=0;t<i;t++)for(let e=0;e<i;e++){const S=t*4;A[e*4+t*4*i+0]=a[S+0];A[e*4+t*4*i+1]=a[S+1];A[e*4+t*4*i+2]=a[S+2];A[e*4+t*4*i+3]=Math.round(255)}a=A;r.initFromData(H(a,i,i),i,i,n,e)}if(B.get()=="XY"||B.get()=="YX"){const A=new Uint8Array(i*i*4);for(let r=0;r<i;r++){let n=r;if(B.get()=="YX")n=i-r-1;for(let t=0;t<i;t++){let e=Math.round((n+t)/2)*4;A[r*4+t*4*i+0]=a[e+0];A[r*4+t*4*i+1]=a[e+1];A[r*4+t*4*i+2]=a[e+2];A[r*4+t*4*i+3]=Math.round(255)}}a=A;r.initFromData(H(a,i,i),i,i,n,e)}const s=[];for(let e=0;e<t.length-1;e++){s.push(t[e].r,t[e].g,t[e].b)}const o=[];for(let e=0;e<t.length-1;e++){o.push(t[e].pos)}U.set(s);k.set(o);P.setRef(r)}}};CABLES.OPS["01380a50-2dbb-4465-ae80-86349b0b717a"]={f:Ops.Gl.GradientTexture,objName:"Ops.Gl.GradientTexture"};Ops.Html.Cursor_v2=class extends CABLES.Op{constructor(){super(...arguments);const t=this;const e=t.attachments={};const n=t.inTriggerButton("Update"),r=t.inDropDown("CSS Cursors",["auto","crosshair","pointer","hand","move","n-resize","ne-resize","e-resize","se-resize","s-resize","sw-resize","w-resize","nw-resize","ew-resize","text","wait","help","none"],"pointer"),i=t.inBool("Set Parent Element",true),a=t.outTrigger("Next");const s="";n.onTriggered=l;let o="";n.onLinkChanged=a.onLinkChanged=()=>{t.patch.cgl.setCursor("auto")};i.onChange=()=>{if(!i.get()){o="auto";t.patch.cgl.canvas.parentElement.style.cursor="auto"}};function l(){let e=null;t.patch.cgl.setCursor(r.get(),e);if(i.get()&&o!=r.get())t.patch.cgl.canvas.parentElement.style.cursor=r.get();a.trigger()}}};CABLES.OPS["39486799-bdad-42d3-a300-4642c23578a8"]={f:Ops.Html.Cursor_v2,objName:"Ops.Html.Cursor_v2"};Ops.Boolean.TriggerChangedFalse=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};let n=e.inValueBool("Value",false);let r=e.outTrigger("Next");let i=0;n.onChange=function(){let e=n.get();if(i&&!e){i=false;r.trigger()}else{i=true}}}};CABLES.OPS["6387bcb0-6091-4199-8ab7-f96ad4aa3c7d"]={f:Ops.Boolean.TriggerChangedFalse,objName:"Ops.Boolean.TriggerChangedFalse"};Ops.Boolean.Or=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValueBool("bool 1"),r=e.inValueBool("bool 2"),i=e.inValueBool("bool 3"),a=e.inValueBool("bool 4"),s=e.inValueBool("bool 5"),o=e.inValueBool("bool 6"),l=e.inValueBool("bool 7"),u=e.inValueBool("bool 8"),c=e.inValueBool("bool 9"),h=e.inValueBool("bool 10"),f=e.outBoolNum("result");n.onChange=r.onChange=i.onChange=a.onChange=s.onChange=o.onChange=l.onChange=u.onChange=c.onChange=h.onChange=d;function d(){f.set(n.get()||r.get()||i.get()||a.get()||s.get()||o.get()||l.get()||u.get()||c.get()||h.get())}}};CABLES.OPS["b3b36238-4592-4e11-afe3-8361c4fd6be5"]={f:Ops.Boolean.Or,objName:"Ops.Boolean.Or"};Ops.Boolean.And=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValueBool("bool 1"),r=e.inValueBool("bool 2"),i=e.outBoolNum("result");n.onChange=r.onChange=a;function a(){i.set(r.get()&&n.get())}}};CABLES.OPS["c26e6ce0-8047-44bb-9bc8-5a4f911ed8ad"]={f:Ops.Boolean.And,objName:"Ops.Boolean.And"};Ops.Ui.Area=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inString("Title",""),r=e.inTriggerButton("Delete");n.setUiAttribs({hidePort:true});e.setUiAttrib({hasArea:true});e.init=n.onChange=e.onLoaded=i;i();function i(){if(CABLES.UI){gui.savedState.setUnSaved("areaOp",e.getSubPatch());e.uiAttr({comment_title:n.get()||" "});e.name=n.get()}}r.onTriggered=()=>{e.patch.deleteOp(e.id)}}};CABLES.OPS["38f79614-b0de-4960-8da5-2827e7f43415"]={f:Ops.Ui.Area,objName:"Ops.Ui.Area"};Ops.Trigger.GateTrigger=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inTrigger("Execute"),r=e.inValueBool("Pass Through",true),i=e.outTrigger("Trigger out");n.onTriggered=function(){if(r.get())i.trigger()}}};CABLES.OPS["65e8b8a2-ba13-485f-883a-2bcf377989da"]={f:Ops.Trigger.GateTrigger,objName:"Ops.Trigger.GateTrigger"};Ops.Gl.RenderToTexture_v3=class extends CABLES.Op{constructor(){super(...arguments);const i=this;const e=i.attachments={};const t=i.inTrigger("render"),n=i.inSwitch("Size",["Canvas","Manual"],"Canvas"),r=i.inValueInt("texture width",512),a=i.inValueInt("texture height",512),s=i.inBool("Auto Aspect",true),o=i.inSwitch("filter",["nearest","linear","mipmap"],"linear"),l=i.inSwitch("Wrap",["Clamp","Repeat","Mirror"],"Repeat"),u=i.inSwitch("MSAA",["none","2x","4x","8x"],"none"),c=i.outTrigger("trigger"),h=i.outTexture("texture"),f=i.outTexture("textureDepth"),d=i.inDropDown("Pixel Format",CGL.Texture.PIXELFORMATS,CGL.Texture.PFORMATSTR_RGBA8UB),p=i.inValueBool("Depth",true),g=i.inValueBool("Clear",true);const m=i.patch.cgl;let v=null;let b=true;i.setPortGroup("Size",[n,r,a,s]);d.onChange=p.onChange=g.onChange=o.onChange=l.onChange=u.onChange=E;n.onChange=_;t.onTriggered=i.preRender=F;_();function _(){r.setUiAttribs({greyout:n.get()!="Manual"});a.setUiAttribs({greyout:n.get()!="Manual"});s.setUiAttribs({greyout:n.get()!="Manual"})}function E(){b=true}function F(){CGL.TextureEffect.checkOpNotInTextureEffect(i);if(!v||b){if(v)v.delete();let n=CGL.Texture.WRAP_REPEAT;if(l.get()=="Clamp")n=CGL.Texture.WRAP_CLAMP_TO_EDGE;else if(l.get()=="Mirror")n=CGL.Texture.WRAP_MIRRORED_REPEAT;let r=CGL.Texture.FILTER_NEAREST;if(o.get()=="nearest")r=CGL.Texture.FILTER_NEAREST;else if(o.get()=="linear")r=CGL.Texture.FILTER_LINEAR;else if(o.get()=="mipmap")r=CGL.Texture.FILTER_MIPMAP;if(d.get().indexOf("loat")&&o.get()=="mipmap")i.setUiError("fpmipmap","Can't use mipmap and float texture at the same time");else i.setUiError("fpmipmap",null);if(m.glVersion>=2){let e=true;let t=4;if(u.get()=="none"){t=0;e=false}if(u.get()=="2x")t=2;if(u.get()=="4x")t=4;if(u.get()=="8x")t=8;v=new CGL.Framebuffer2(m,8,8,{name:"render2texture "+i.id,pixelFormat:d.get(),multisampling:e,multisamplingSamples:t,wrap:n,filter:r,depth:p.get(),clear:g.get()})}else{v=new CGL.Framebuffer(m,8,8,{isFloatingPointTexture:false,clear:g.get()})}if(v&&v.valid){f.setRef(v.getTextureDepth());b=false}else{v=null;b=true}}let e=s.get();if(n.get()=="Canvas"){e=true;r.set(i.patch.cgl.checkTextureSize(m.canvasWidth));a.set(i.patch.cgl.checkTextureSize(m.canvasHeight))}if(v.getWidth()!=i.patch.cgl.checkTextureSize(r.get())||v.getHeight()!=i.patch.cgl.checkTextureSize(a.get())){v.setSize(i.patch.cgl.checkTextureSize(r.get()),i.patch.cgl.checkTextureSize(a.get()))}v.renderStart(m);m.pushViewPort(0,0,r.get(),a.get());if(e)mat4.perspective(m.pMatrix,45,r.get()/a.get(),.1,1e3);c.trigger();v.renderEnd(m);m.popViewPort();f.setRef(v.getTextureDepth());h.setRef(v.getTextureColor())}}};CABLES.OPS["41eec5c7-c480-477a-be81-04c3efac8357"]={f:Ops.Gl.RenderToTexture_v3,objName:"Ops.Gl.RenderToTexture_v3"};Ops.String.StringEditor=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inStringEditor("value",""),r=e.inValueSelect("Syntax",["text","glsl","css","html","xml","json","javascript","inline-css","sql"],"text"),i=e.outString("Result");r.onChange=a;function a(){let e=r.get();if(e=="javascript")e="js";n.setUiAttribs({editorSyntax:e})}n.onChange=function(){i.set(n.get())}}};CABLES.OPS["6468b7c1-f63e-4db4-b809-4b203d27ead3"]={f:Ops.String.StringEditor,objName:"Ops.String.StringEditor"};Ops.Array.StringToArray_v2=class extends CABLES.Op{constructor(){super(...arguments);const r=this;const e=r.attachments={};const i=r.inStringEditor("text","1,2,3"),a=r.inString("separator",","),s=r.inValueBool("Numbers",true),o=r.inValueBool("Trim",true),l=r.inBool("Split Lines",false),u=r.outArray("array"),c=r.outTrigger("Parsed"),h=r.outNumber("length");i.setUiAttribs({ignoreBigPort:true});i.onChange=a.onChange=s.onChange=o.onChange=t;l.onChange=()=>{a.setUiAttribs({greyout:l.get()});t()};t();function t(){if(!i.get()){u.set(null);u.set([]);h.set(0);return}let e=i.get();if(o.get()&&e){e=e.replace(/^\s+|\s+$/g,"");e=e.trim()}let n;let t=a.get();if(a.get()==="\\n")t="\n";if(l.get())n=e.split("\n");else n=e.split(t);if(n[n.length-1]==="")n.length-=1;h.set(n.length);if(o.get()){for(let e=0;e<n.length;e++){n[e]=n[e].replace(/^\s+|\s+$/g,"");n[e]=n[e].trim()}}r.setUiError("notnum",null);if(s.get()){let t=false;for(let e=0;e<n.length;e++){n[e]=Number(n[e]);if(!CABLES.isNumeric(n[e])){t=true}}if(t){r.setUiError("notnum","Parse Error / Not all values numerical!",1)}}u.setRef(n);c.trigger()}}};CABLES.OPS["c974de41-4ce4-4432-b94d-724741109c71"]={f:Ops.Array.StringToArray_v2,objName:"Ops.Array.StringToArray_v2"};Ops.Array.ArrayGetString_v2=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const r=e.inArray("Array"),i=e.inValueInt("Index"),a=e.outString("Result"),s=e.outBoolNum("Found");r.ignoreValueSerialize=true;e.toWorkPortsNeedToBeLinked(r);r.onChange=i.onChange=n;function n(){const e=r.get();if(e){const t=e[i.get()];const n=t===undefined||t===null;if(n){a.set("");s.set(false)}else{a.set(t);s.set(true)}}else{a.set("");s.set(false)}}}};CABLES.OPS["5199b608-e895-420f-9391-da8e10370b2e"]={f:Ops.Array.ArrayGetString_v2,objName:"Ops.Array.ArrayGetString_v2"};Ops.Math.Floor=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValue("Number");const r=e.outNumber("Result");n.onChange=i;function i(){r.set(Math.floor(n.get()))}}};CABLES.OPS["0c77617c-b688-4b55-addf-2cbcaabf98af"]={f:Ops.Math.Floor,objName:"Ops.Math.Floor"};Ops.Gl.ImageCompose.Plasma_v2=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={plasma_frag:"#define PI 3.1415926535897932384626433832795\n\nIN vec2 texCoord;\n\nUNI sampler2D tex;\nUNI vec2 size;\nUNI vec2 pos;\nUNI float mul;\nUNI float amount;\nUNI float time;\nUNI float aspect;\n\n#ifdef HAS_TEX_OFFSETMAP\n    UNI sampler2D texOffsetZ;\n    UNI float offMul;\n#endif\n\n#ifdef HAS_TEX_MASK\n    UNI sampler2D texMask;\n#endif\n\n\n{{CGL.BLENDMODES3}}\n\nvoid main()\n{\n    float v = 0.0;\n\n    vec2 s=size;\n    #ifdef FIXASPECT\n        s.y=size.x/aspect;\n    #endif\n\n    vec2 c = texCoord * s - s/2.0;\n\n    c+=pos;\n\n    vec3 offset;\n    #ifdef HAS_TEX_OFFSETMAP\n        vec4 offMap=texture(texOffsetZ,texCoord);\n\n        #ifdef OFFSET_X_R\n            offset.x=offMap.r;\n        #endif\n        #ifdef OFFSET_X_G\n            offset.x=offMap.g;\n        #endif\n        #ifdef OFFSET_X_B\n            offset.x=offMap.b;\n        #endif\n\n        #ifdef OFFSET_Y_R\n            offset.y=offMap.r;\n        #endif\n        #ifdef OFFSET_Y_G\n            offset.y=offMap.g;\n        #endif\n        #ifdef OFFSET_Y_B\n            offset.y=offMap.b;\n        #endif\n\n        #ifdef OFFSET_Z_R\n            offset.z=offMap.r;\n        #endif\n        #ifdef OFFSET_Z_G\n            offset.z=offMap.g;\n        #endif\n        #ifdef OFFSET_Z_B\n            offset.z=offMap.b;\n        #endif\n        offset*=offMul;\n    #endif\n\n    c+=offset.xy;\n    float t=time+offset.z;\n\n    v += sin((c.x+t));\n    v += sin((c.y+t)/2.0);\n    v += sin((c.x+c.y+t)/2.0);\n    c += size/2.0 * vec2(sin(t/3.0), cos(t/2.0));\n\n    v += sin(sqrt(c.x*c.x+c.y*c.y+1.0)+t);\n    v = v/2.0;\n\n    vec3 newColor = vec3(sin(PI*v*mul/4.0), sin(PI*v*mul), cos(PI*v*mul))*.5 + .5;\n    vec4 base=texture(tex,texCoord);\n\n    #ifndef GREY\n       vec4 col=vec4( _blend(base.rgb,newColor) ,1.0);\n    #endif\n    #ifdef GREY\n       vec4 col=vec4( _blend(base.rgb,vec3(newColor.g)) ,1.0);\n    #endif\n\n    float str=1.0;\n    #ifdef HAS_TEX_MASK\n        str=texture(texMask,texCoord).r;\n    #endif\n\n    outColor=cgl_blendPixel(base,col,amount*str);\n}\n\n"};const n=e.inTrigger("render"),r=CGL.TextureEffect.AddBlendSelect(e,"Blend Mode","normal"),i=CGL.TextureEffect.AddBlendAlphaMask(e),a=e.inValueSlider("Amount",1),s=e.inValue("Width",20),o=e.inValue("Height",20),l=e.inBool("Aspect",true),u=e.inValue("Mul",1),c=e.inValue("X",0),h=e.inValue("Y",0),f=e.inValue("Time",1),d=e.inValueBool("Greyscale",true),p=e.inTexture("Offset"),g=e.inFloat("Offset Multiply",1),m=e.inSwitch("Offset X",["None","R","G","B"],"None"),v=e.inSwitch("Offset Y",["None","R","G","B"],"None"),b=e.inSwitch("Offset Time",["None","R","G","B"],"R"),_=e.inTexture("Mask"),E=e.outTrigger("trigger");e.setPortGroup("Offset Map",[p,b,v,m,g]);const F=e.patch.cgl;const C=new CGL.Shader(F,e.name,e);C.setSource(C.getDefaultVertexShader(),t.plasma_frag);CGL.TextureEffect.setupBlending(e,C,r,a,i);const A=new CGL.Uniform(C,"2f","pos",c,h),x=new CGL.Uniform(C,"2f","size",s,o),T=new CGL.Uniform(C,"f","time",f),S=new CGL.Uniform(C,"f","mul",u),y=new CGL.Uniform(C,"f","aspect",1),B=new CGL.Uniform(C,"f","offMul",g),O=new CGL.Uniform(C,"t","tex",0),D=new CGL.Uniform(C,"t","texOffsetZ",1),I=new CGL.Uniform(C,"t","texMask",2),M=new CGL.Uniform(C,"f","amount",a);m.onChange=l.onChange=v.onChange=b.onChange=_.onChange=d.onChange=p.onLinkChanged=L;L();function L(){C.toggleDefine("GREY",d.get());C.toggleDefine("HAS_TEX_OFFSETMAP",p.isLinked());C.toggleDefine("HAS_TEX_MASK",_.isLinked());C.toggleDefine("OFFSET_X_R",m.get()=="R");C.toggleDefine("OFFSET_X_G",m.get()=="G");C.toggleDefine("OFFSET_X_B",m.get()=="B");C.toggleDefine("OFFSET_Y_R",v.get()=="R");C.toggleDefine("OFFSET_Y_G",v.get()=="G");C.toggleDefine("OFFSET_Y_B",v.get()=="B");C.toggleDefine("OFFSET_Z_R",b.get()=="R");C.toggleDefine("OFFSET_Z_G",b.get()=="G");C.toggleDefine("OFFSET_Z_B",b.get()=="B");m.setUiAttribs({greyout:!p.isLinked()});v.setUiAttribs({greyout:!p.isLinked()});b.setUiAttribs({greyout:!p.isLinked()});g.setUiAttribs({greyout:!p.isLinked()});o.setUiAttribs({greyout:l.get()});C.toggleDefine("FIXASPECT",l.get())}n.onTriggered=function(){if(!CGL.TextureEffect.checkOpInEffect(e,3))return;F.pushShader(C);F.currentTextureEffect.bind();if(l.get())y.setValue(F.currentTextureEffect.aspectRatio);else y.setValue(1);F.setTexture(0,F.currentTextureEffect.getCurrentSourceTexture().tex);if(p.get())F.setTexture(1,p.get().tex);if(_.get())F.setTexture(2,_.get().tex);F.currentTextureEffect.finish();F.popShader();E.trigger()}}};CABLES.OPS["89b3bf34-a9a8-4dcf-a304-9dee597fcf48"]={f:Ops.Gl.ImageCompose.Plasma_v2,objName:"Ops.Gl.ImageCompose.Plasma_v2"};Ops.Gl.Meshes.FullscreenRectangle_v2=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={shader_frag:"UNI sampler2D tex;\nIN vec2 texCoord;\n\nvoid main()\n{\n    outColor= texture(tex,texCoord);\n}\n\n",shader_vert:"{{MODULES_HEAD}}\n\nIN vec3 vPosition;\nUNI mat4 projMatrix;\nUNI mat4 mvMatrix;\n\nOUT vec2 texCoord;\nIN vec2 attrTexCoord;\n\nvoid main()\n{\n   vec4 pos=vec4(vPosition,  1.0);\n\n   texCoord=vec2(attrTexCoord.x,(1.0-attrTexCoord.y));\n\n   gl_Position = projMatrix * mvMatrix * pos;\n}\n"};const n=e.inTrigger("render"),r=e.inSwitch("Scale",["Stretch","Fit"],"Fit"),i=e.inValueBool("Flip Y"),a=e.inValueBool("Flip X"),s=e.inTexture("Texture"),o=e.outTrigger("trigger");const l=e.patch.cgl;let u=null;let c=new CGL.Geometry("fullscreen rectangle");let h=0,f=0,d=0,p=0;e.toWorkShouldNotBeChild("Ops.Gl.TextureEffects.ImageCompose",CABLES.OP_PORT_TYPE_FUNCTION);e.toWorkPortsNeedToBeLinked(n);a.onChange=A;i.onChange=A;n.onTriggered=C;s.onLinkChanged=_;r.onChange=F;const g=new CGL.Shader(l,"fullscreenrectangle",this);g.setModules(["MODULE_VERTEX_POSITION","MODULE_COLOR","MODULE_BEGIN_FRAG"]);g.setSource(t.shader_vert,t.shader_frag);g.fullscreenRectUniform=new CGL.Uniform(g,"t","tex",0);g.aspectUni=new CGL.Uniform(g,"f","aspectTex",0);let m=false;let v=true;let b=false;_();F();s.onChange=function(){v=true};function _(){if(!CABLES.UI)return;i.setUiAttribs({greyout:!s.isLinked()});a.setUiAttribs({greyout:!s.isLinked()});r.setUiAttribs({greyout:!s.isLinked()})}function E(){let e=s.get();if(e)m=true;else m=false}e.preRender=function(){E();g.bind();if(u)u.render(g);C()};function F(){b=r.get()=="Fit"}function C(){if(l.viewPort[2]!=d||l.viewPort[3]!=p||!u)x();if(v)E();l.pushPMatrix();mat4.identity(l.pMatrix);mat4.ortho(l.pMatrix,0,d,p,0,-10,1e3);l.pushModelMatrix();mat4.identity(l.mMatrix);l.pushViewMatrix();mat4.identity(l.vMatrix);if(b&&s.get()){const n=s.get().width/s.get().height;let e=p;let t=p*n;if(t>d){e=d*1/n;t=d}l.pushViewPort((d-t)/2,(p-e)/2,t,e)}if(m){if(s.get())l.setTexture(0,s.get().tex);u.render(g)}else{u.render(l.getShader())}l.gl.clear(l.gl.DEPTH_BUFFER_BIT);l.popPMatrix();l.popModelMatrix();l.popViewMatrix();if(b&&s.get())l.popViewPort();o.trigger()}function A(){u=null}function x(){if(l.viewPort[2]==d&&l.viewPort[3]==p&&u)return;let e=0,t=0;d=l.viewPort[2];p=l.viewPort[3];c.vertices=new Float32Array([e+d,t+p,0,e,t+p,0,e+d,t,0,e,t,0]);let n=null;if(i.get())n=new Float32Array([1,0,0,0,1,1,0,1]);else n=new Float32Array([1,1,0,1,1,0,0,0]);if(a.get()){n[0]=0;n[2]=1;n[4]=0;n[6]=1}c.setTexCoords(n);c.verticesIndices=new Uint16Array([2,1,0,3,1,2]);c.vertexNormals=new Float32Array([0,0,1,0,0,1,0,0,1,0,0,1]);c.tangents=new Float32Array([-1,0,0,-1,0,0,-1,0,0,-1,0,0]);c.biTangents==new Float32Array([0,-1,0,0,-1,0,0,-1,0,0,-1,0]);if(!u)u=new CGL.Mesh(l,c);else u.setGeom(c)}}};CABLES.OPS["fb70721a-eac2-4ff5-a5a2-5c59e2393972"]={f:Ops.Gl.Meshes.FullscreenRectangle_v2,objName:"Ops.Gl.Meshes.FullscreenRectangle_v2"};Ops.Gl.ImageCompose.Noise.FBMNoise_v2=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={fbmnoise_frag:"UNI sampler2D tex;\nUNI float anim;\n\nUNI float scale;\nUNI float repeat;\n\nUNI float scrollX;\nUNI float scrollY;\n\nUNI float amount;\n\nUNI bool layer1;\nUNI bool layer2;\nUNI bool layer3;\nUNI bool layer4;\nUNI vec3 color;\nUNI float aspect;\n\nIN vec2 texCoord;\n\n\n{{CGL.BLENDMODES3}}\n\n// adapted from warp shader by inigo quilez/iq\n// License Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.\n\n// See here for a tutorial on how to make this: http://www.iquilezles.org/www/articles/warp/warp.htm\n\nconst mat2 m = mat2( 0.80,  0.60, -0.60,  0.80 );\n\nfloat noise( in vec2 x )\n{\n\treturn sin(1.5*x.x)*sin(1.5*x.y);\n}\n\nfloat fbm4( vec2 p )\n{\n    float f = 0.0;\n    f += 0.5000*noise( p ); p = m*p*2.02;\n    f += 0.2500*noise( p ); p = m*p*2.03;\n    f += 0.1250*noise( p ); p = m*p*2.01;\n    f += 0.0625*noise( p );\n    return f/0.9375;\n}\n\nfloat fbm6( vec2 p )\n{\n    float f = 0.0;\n    f += 0.500000*(0.5+0.5*noise( p )); p = m*p*2.02;\n    f += 0.250000*(0.5+0.5*noise( p )); p = m*p*2.03;\n    f += 0.125000*(0.5+0.5*noise( p )); p = m*p*2.01;\n    f += 0.062500*(0.5+0.5*noise( p )); p = m*p*2.04;\n    f += 0.031250*(0.5+0.5*noise( p )); p = m*p*2.01;\n    f += 0.015625*(0.5+0.5*noise( p ));\n    return f/0.96875;\n}\n\nvoid main()\n{\n    vec2 tc=texCoord;\n\t#ifdef DO_TILEABLE\n\t    tc=abs(texCoord-0.5);\n\t#endif\n\n    vec2 p=(tc-0.5)*scale;\n\n    p.y/=aspect;\n    vec2 q = vec2( fbm4( p + vec2(0.3+scrollX,0.20+scrollY) ),\n                   fbm4( p + vec2(3.1+scrollX,1.3+scrollY) ) );\n\n    vec2 q2 = vec2( fbm4( p + vec2(2.0+scrollX,1.0+scrollY) ),\n                   fbm4( p + vec2(3.1+scrollX,1.3+scrollY) ) );\n\n    vec2 q3 = vec2( fbm4( p + vec2(9.0+scrollX,4.0+scrollY) ),\n                   fbm4( p + vec2(3.1+scrollX,4.3+scrollY) ) );\n\n    float v= fbm4( ( p + 4.0*q +anim*0.1)*repeat);\n    float v2= fbm4( (p + 4.0*q2 +anim*0.1)*repeat );\n\n    float v3= fbm6( (p + 4.0*q3 +anim*0.1)*repeat );\n    float v4= fbm6( (p + 4.0*q2 +anim*0.1)*repeat );\n\n    vec4 base=texture(tex,texCoord);\n\n    vec4 finalColor;\n    float colVal=0.0;\n    float numLayers=0.0;\n\n    if(layer1)\n    {\n        colVal+=v;\n        numLayers++;\n    }\n\n    if(layer2)\n    {\n        colVal+=v2;\n        numLayers++;\n    }\n\n    if(layer3)\n    {\n        colVal+=v3;\n        numLayers++;\n    }\n\n    if(layer4)\n    {\n        colVal+=v4;\n        numLayers++;\n    }\n\n    finalColor=vec4( color*vec3(colVal/numLayers),1.0);\n\n    outColor = cgl_blendPixel(base,finalColor,amount);\n}\n"};const n=e.inTrigger("render"),r=CGL.TextureEffect.AddBlendSelect(e,"Blend Mode","normal"),i=e.inValueSlider("Amount",1),a=CGL.TextureEffect.AddBlendAlphaMask(e),s=e.inValueSlider("r",1),o=e.inValueSlider("g",1),l=e.inValueSlider("b",1),u=e.outTrigger("trigger");s.setUiAttribs({colorPick:true});const c=e.patch.cgl;const h=new CGL.Shader(c,"fbmnoise");h.setSource(h.getDefaultVertexShader(),t.fbmnoise_frag);const f=new CGL.Uniform(h,"t","tex",0),d=new CGL.Uniform(h,"f","scale",e.inValue("scale",2)),p=new CGL.Uniform(h,"f","anim",e.inValue("anim",0)),g=new CGL.Uniform(h,"f","scrollX",e.inValue("scrollX",9)),m=new CGL.Uniform(h,"f","scrollY",e.inValue("scrollY",0)),v=new CGL.Uniform(h,"f","repeat",e.inValue("repeat",1)),b=new CGL.Uniform(h,"f","aspect",e.inValue("aspect",1)),_=new CGL.Uniform(h,"b","layer1",e.inValueBool("Layer 1",true)),E=new CGL.Uniform(h,"b","layer2",e.inValueBool("Layer 2",true)),F=new CGL.Uniform(h,"b","layer3",e.inValueBool("Layer 3",true)),C=new CGL.Uniform(h,"b","layer4",e.inValueBool("Layer 4",true)),A=new CGL.Uniform(h,"3f","color",s,o,l),x=new CGL.Uniform(h,"f","amount",i);const T=e.inValueBool("Tileable",false);T.onChange=S;CGL.TextureEffect.setupBlending(e,h,r,i,a);function S(){h.toggleDefine("DO_TILEABLE",T.get())}n.onTriggered=function(){if(!CGL.TextureEffect.checkOpInEffect(e))return;c.pushShader(h);c.currentTextureEffect.bind();b.set(c.currentTextureEffect.getCurrentSourceTexture().width/c.currentTextureEffect.getCurrentSourceTexture().height);c.setTexture(0,c.currentTextureEffect.getCurrentSourceTexture().tex);c.currentTextureEffect.finish();c.popShader();u.trigger()}}};CABLES.OPS["9422eeab-b6c5-47d1-8737-d5c43dc137a3"]={f:Ops.Gl.ImageCompose.Noise.FBMNoise_v2,objName:"Ops.Gl.ImageCompose.Noise.FBMNoise_v2"};Ops.Array.PaletteLibrary=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.outArray("Palette Array out");const r=["#E6E2AF","#A7A37E","#EFECCA","#046380","002F2F","#468966","#FFF0A5","#FFB03B","#B64926","8E2800","#FCFFF5","#D1DBBD","#91AA9D","#3E606F","193441","#FF6138","#FFFF9D","#BEEB9F","#79BD8F","00A388","#105B63","#FFFAD5","#FFD34E","#DB9E36","BD4932","#225378","#1695A3","#ACF0F2","#F3FFE2","EB7F00","#2C3E50","#E74C3C","#ECF0F1","#3498DB","2980B9","#000000","#263248","#7E8AA2","#FFFFFF","FF9800","#004358","#1F8A70","#BEDB39","#FFE11A","FD7400","#DC3522","#D9CB9E","#374140","#2A2C2B","1E1E20","#7D8A2E","#C9D787","#FFFFFF","#FFC0A9","FF8598","#B9121B","#4C1B1B","#F6E497","#FCFAE1","BD8D46","#2E0927","#D90000","#FF2D00","#FF8C00","04756F","#595241","#B8AE9C","#FFFFFF","#ACCFCC","8A0917","#10222B","#95AB63","#BDD684","#E2F0D6","F6FFE0","#F6F792","#333745","#77C4D3","#DAEDE2","EA2E49","#703030","#2F343B","#7E827A","#E3CDA4","C77966","#2F2933","#01A2A6","#29D9C2","#BDF271","FFFFA6","#D8CAA8","#5C832F","#284907","#382513","363942","#FFF8E3","#CCCC9F","#33332D","#9FB4CC","DB4105","#85DB18","#CDE855","#F5F6D4","#A7C520","493F0B","#04BFBF","#CAFCD8","#F7E967","#A9CF54","588F27","#292929","#5B7876","#8F9E8B","#F2E6B6","412A22","#332532","#644D52","#F77A52","#FF974F","A49A87","#405952","#9C9B7A","#FFD393","#FF974F","F54F29","#2B3A42","#3F5765","#BDD4DE","#EFEFEF","FF530D","#962D3E","#343642","#979C9C","#F2EBC7","348899","#96CA2D","#B5E655","#EDF7F2","#4BB5C1","7FC6BC","#1C1D21","#31353D","#445878","#92CDCF","EEEFF7","#3E454C","#2185C5","#7ECEFD","#FFF6E5","FF7F66","#00585F","#009393","#FFFCC4","#F0EDBB","FF3800","#B4AF91","#787746","#40411E","#32331D","C03000","#63A69F","#F2E1AC","#F2836B","#F2594B","CD2C24","#88A825","#35203B","#911146","#CF4A30","ED8C2B","#F2385A","#F5A503","#E9F1DF","#4AD9D9","36B1BF","#CFC291","#FFF6C5","#A1E8D9","#FF712C","695D46","#FF5335","#B39C85","#306E73","#3B424D","1D181F","#000000","#333333","#FF358B","#01B0F0","AEEE00","#E8E595","#D0A825","#40627C","#26393D","FFFAE4","#E7E8D1","#D3CEAA","#FBF7E4","#424242","8E001C","#354242","#ACEBAE","#FFFF9D","#C9DE55","7D9100","#2F2933","#01A2A6","#29D9C2","#BDF271","FFFFA6","#DDDCC5","#958976","#611427","#1D2326","6A6A61","#6C6E58","#3E423A","#417378","#A4CFBE","F4F7D9","#E1E6FA","#C4D7ED","#ABC8E2","#375D81","183152","#6B0C22","#D9042B","#F4CB89","#588C8C","011C26","#304269","#91BED4","#D9E8F5","#FFFFFF","F26101","#96CEB4","#FFEEAD","#FF6F69","#FFCC5C","AAD8B0","#B0CC99","#677E52","#B7CA79","#F6E8B1","89725B","#334D5C","#45B29D","#EFC94C","#E27A3F","DF5A49","#16193B","#35478C","#4E7AC7","#7FB2F0","ADD5F7","#00261C","#044D29","#168039","#45BF55","96ED89","#36362C","#5D917D","#A8AD80","#E6D4A7","825534","#F9E4AD","#E6B098","#CC4452","#723147","31152B","#2C3E50","#FC4349","#D7DADB","#6DBCDB","FFFFFF","#002635","#013440","#AB1A25","#D97925","EFE7BE","#FF8000","#FFD933","#CCCC52","#8FB359","192B33","#272F32","#9DBDC6","#FFFFFF","#FF3D2E","DAEAEF","#B8ECD7","#083643","#B1E001","#CEF09D","476C5E","#002F32","#42826C","#A5C77F","#FFC861","C84663","#5C4B51","#8CBEB2","#F2EBBF","#F3B562","F06060","#5A1F00","#D1570D","#FDE792","#477725","A9CC66","#5E0042","#2C2233","#005869","#00856A","8DB500","#52656B","#FF3B77","#CDFF00","#FFFFFF","B8B89F","#801637","#047878","#FFB733","#F57336","C22121","#730046","#BFBB11","#FFC200","#E88801","C93C00","#24221F","#363F45","#4B5F6D","#5E7C88","FEB41C","#E64661","#FFA644","#998A2F","#2C594F","002D40","#C24704","#D9CC3C","#FFEB79","#A0E0A9","00ADA7","#484A47","#C1CE96","#ECEBF0","#687D77","353129","#588C7E","#F2E394","#F2AE72","#D96459","8C4646","#BAB293","#A39770","#EFE4BD","#A32500","2B2922","#6A7059","#FDEEA7","#9BCC93","#1A9481","003D5C","#174C4F","#207178","#FF9666","#FFE184","F5E9BE","#D5FBFF","#9FBCBF","#647678","#2F3738","59D8E6","#DB5800","#FF9000","#F0C600","#8EA106","59631E","#450003","#5C0002","#94090D","#D40D12","FF1D23","#211426","#413659","#656F8C","#9BBFAB","F2EFDF","#EA6045","#F8CA4D","#F5E5C0","#3F5666","2F3440","#F2F2F2","#C6E070","#91C46C","#287D7D","1C344D","#334D5C","#45B29D","#EFC94C","#E27A3F","DF5A49","#705B35","#C7B07B","#E8D9AC","#FFF6D9","570026","#F7F2B2","#ADCF4F","#84815B","#4A1A2C","8E3557","#1A1F2B","#30395C","#4A6491","#85A5CC","D0E4F2","#25064D","#36175E","#553285","#7B52AB","9768D1","#004056","#2C858D","#74CEB7","#C9FFD5","FFFFCB","#CFCA4C","#FCF5BF","#9FE5C2","#5EB299","745A33","#776045","#A8C545","#DFD3B6","#FFFFFF","0092B2","#CC3910","#F1F2C0","#CCC59E","#8FA68E","332F29","#FF6600","#C13B00","#5E6D70","#424E4F","1B1D1E","#690011","#BF0426","#CC2738","#F2D99C","E5B96F","#1B1D26","#425955","#778C7A","#F1F2D8","BFBD9F","#F6B1C3","#F0788C","#DE264C","#BC0D35","A20D1E","#597533","#332F28","#61B594","#E6DEA5","C44E18","#3FB8AF","#7FC7AF","#DAD8A7","#FF9E9D","FF3D7F","#0F2D40","#194759","#296B73","#3E8C84","D8F2F0","#42282F","#74A588","#D6CCAD","#DC9C76","D6655A","#002A4A","#17607D","#FFF1CE","#FF9311","D64700","#003056","#04518C","#00A1D9","#47D9BF","F2D03B","#13140F","#D4FF00","#E4FFE6","#68776C","00D6DD","#FCFAD0","#A1A194","#5B605F","#464646","A90641","#289976","#67CC8E","#B1FF91","#FFE877","FF5600","#302B1D","#3F522B","#737D26","#A99E46","D9CB84","#56626B","#6C9380","#C0CA55","#F07C6C","AD5472","#32450C","#717400","#DC8505","#EC5519","BE2805","#C7B773","#E3DB9A","#F5FCD0","#B1C2B3","778691","#E83A25","#FFE9A3","#98CC96","#004563","191B28","#3399CC","#67B8DE","#91C9E8","#B4DCED","E8F8FF","#1A212C","#1D7872","#71B095","#DEDBA7","D13F32","#7D2A35","#CC9258","#917A56","#B4BA6C","FEFFC2","#E7E9D1","#D3D4AA","#FCFAE6","#444444","901808","#FFFFFF","#AEAEAE","#E64C66","#2D3E50","1BBC9B","#E0FFB3","#61C791","#31797D","#2A2F36","F23C55","#EB5937","#1C1919","#403D3C","#456F74","D3CBBD","#E6DD00","#8CB302","#008C74","#004C66","332B40","#14A697","#F2C12E","#F29D35","#F27649","F25252","#261822","#40152A","#731630","#CC1E2C","FF5434","#261F27","#FEE169","#CDD452","#F9722E","C9313D","#5C4B51","#8CBEB2","#F2EBBF","#F3B562","F06060","#2F3837","#C5C7B6","#FFF8D3","#4C493E","222028","#E3CBAC","#9C9985","#C46D3B","#788880","324654","#3F0B1B","#7A1631","#CF423C","#FC7D49","FFD462","#14212B","#293845","#4F6373","#8F8164","D9D7AC","#98A89E","#BAC0AC","#FAFAC6","#FF4411","D40015","#FEFFFF","#3C3F36","#9FB03E","#EBE9DC","72918B","#CC6B32","#FFAB48","#FFE7AD","#A7C9AE","888A63","#262526","#404040","#8C8979","#F2F2F2","F60A20","#00305A","#004B8D","#0074D9","#4192D9","7ABAF2","#0C273D","#54D0ED","#FFFEF1","#70B85D","2C5E2E","#4C1B33","#EFE672","#98A942","#2D6960","141D14","#2F3540","#666A73","#F2EDE4","#D9D1C7","8C8681","#0D1F30","#3B6670","#8BADA3","#F0E3C0","DB6C0F","#FFBC67","#DA727E","#AC6C82","#685C79","455C7B","#092140","#024959","#F2C777","#F24738","BF2A2A","#133463","#365FB7","#799AE0","#F4EFDC","BA9B65","#C4D4CB","#55665E","#30282A","#542733","E84167","#CDDEC6","#4DAAAB","#1E4F6A","#2A423C","93A189","#EF5411","#FA5B0F","#FF6517","#FF6D1F","FF822E","#41434A","#6E9489","#DEDCC3","#F2F1E9","877963","#292929","#2BBFBD","#F2B33D","#F29B30","F22E2E","#F2385A","#F5A503","#E9F1DF","#56D9CD","3AA1BF","#D5F8B4","#A6E3A8","#8A9A85","#7E566B","422335","#3CBAC8","#93EDD4","#F3F5C4","#F9CB8F","F19181","#979926","#38CCB5","#EEFF8E","#FFD767","CC2A09","#404040","#024959","#037E8C","#F2EFDC","F24C27","#94B34D","#D3FF82","#363D52","#121D2B","111B1C","#282E33","#25373A","#164852","#495E67","FF3838","#313732","#8AA8B0","#DEDEDE","#FFFFFF","F26101","#FFFFFF","#E5E1D1","#52616D","#2C343B","C44741","#FFF6B8","#ABCCA7","#403529","#7A5E2F","A68236","#4F1025","#C5003E","#D9FF5B","#78AA00","15362D","#49404F","#596166","#D1FFCD","#A9BD8B","948A54","#FF2151","#FF7729","#FFAD29","#FFEBCA","1AB58A","#73603D","#BF8A49","#F2CA80","#5E5A59","0D0D0D","#3D4C53","#70B7BA","#F1433F","#E7E1D4","FFFFFF","#006D8D","#008A6E","#549E39","#8AB833","C0CF3A","#BDDFB3","#2BAA9C","#2F2E2E","#0F2625","465F3F","#F2F2F2","#BF0404","#8C0303","#590202","400101","#76A19A","#272123","#A68D60","#B0C5BB","D9593D","#0E3D59","#88A61B","#F29F05","#F25C05","D92525","#C1E1ED","#76C7C6","#273D3B","#131A19","E35C14","#2D112C","#530031","#820233","#CA293E","EF4339","#AF7575","#EFD8A1","#BCD693","#AFD7DB","3D9CA8","#D74B4B","#DCDDD8","#475F77","#354B5E","FFFFFF","#FFF6C9","#C8E8C7","#A4DEAB","#85CC9F","499E8D","#229396","#8BA88F","#C7C5A7","#F0DFD0","F23C3C","#57385C","#A75265","#EC7263","#FEBE7E","FFEDBC","#96526B","#D17869","#EBAD60","#F5CF66","8BAB8D","#0D1C33","#17373C","#2B6832","#4F9300","A1D700","#1B2B32","#37646F","#A3ABAF","#E1E7E8","B22E2F","#C5D9B2","#53A194","#572C2C","#3D2324","695A3B","#425957","#81AC8B","#F2E5A2","#F89883","D96666","#002E40","#2A5769","#FFFFFF","#FABD4A","FA9600","#FFFEFC","#E2E3DF","#515B5E","#2E3233","CAF200","#FFF0A3","#B8CC6E","#4B6000","#E4F8FF","004460","#3B596A","#427676","#3F9A82","#A1CD73","ECDB60","#F2E6CE","#8AB39F","#606362","#593325","1D1D1F","#212B40","#C2E078","#FFFFFF","#BADCDD","547B97","#0B3C4D","#0E5066","#136480","#127899","1A8BB3","#222130","#464D57","#D4E8D3","#FFFCFB","ED8917","#B33600","#FF8A00","#FFC887","#CC5400","B31E00","#012530","#28544B","#ACBD86","#FFD6A0","FF302C","#2E95A3","#50B8B4","#C6FFFA","#E2FFA8","D6E055","#112F41","#068587","#4FB99F","#F2B134","ED553B","#202B30","#4E7178","#4FA9B8","#74C0CF","F1F7E2","#302B2F","#696153","#FFA600","#9BB58F","FFD596","#458C6B","#F2D8A7","#D9A86C","#D94436","A62424","#22475E","#75B08A","#F0E797","#FF9D84","FF5460","#FFAA5C","#DA727E","#AC6C82","#685C79","455C7B","#686E75","#9BAAC1","#82787B","#E4F1DB","AAC19B","#F0C755","#E2AD3B","#BF5C00","#901811","5C110F","#FFFBDC","#BFBCA5","#7F7D6E","#3F3E37","E5E2C6","#BEBEBE","#F1E4D8","#594735","#94C7BA","D8F1E4","#1B1E26","#F2EFBD","#B6D051","#70A99A","2F6D7A","#F7E4A2","#A7BD5B","#DC574E","#8DC7B8","ED9355","#70E8CB","#FFE9C7","#FF5B5B","#545454","2D2D2F","#17111A","#321433","#660C47","#B33467","CCBB51","#2B2E2E","#595855","#A2ABA5","#CAE6E8","313F54","#023B47","#295E52","#F2E085","#FCAB55","EE7F38","#302C29","#D1D1BC","#A7C4BB","#6C8C84","466964","#212629","#067778","#49B8A8","#85EDB6","D9E5CD","#334D5C","#45B29D","#EFC94C","#E27A3F","DF4949","#2C3E50","#FC4349","#6DBCDB","#D7DADB","FFFFFF","#35262D","#FFFBFF","#E8ECED","#A4B7BB","76A0B0","#61E8D2","#FCEEB9","#302F25","#704623","BBE687","#E1E6B9","#C4D7A4","#ABC8A4","#375D3B","183128","#C98B2F","#803C27","#C56520","#E1B41B","807916","#A3D9B0","#93BF9E","#F2F0D5","#8C8474","40362E","#524656","#CF4747","#EA7A58","#E4DCCB","A6C4BC","#5C2849","#A73E5C","#EC4863","#FFDA66","1FCECB","#0EEAFF","#15A9FA","#1B76FF","#1C3FFD","2C1DFF","#010000","#393845","#9B96A3","#5C0009","940315","#468071","#FFE87A","#FFCA53","#FF893B","E62738","#404040","#024959","#037E8C","#F2EFDC","F24C27","#FF765E","#C2AE8B","#FCCF65","#FFE5C6","B7BDC4","#003647","#00717D","#F2D8A7","#A4A66A","515932","#FAFAC0","#C4BE90","#8C644C","#594D37","293033","#2B3A42","#3F5765","#BDD4DE","#EFEFEF","E74C3C","#3B3B3B","#A8877E","#FFA49D","#FF7474","FF476C","#0A3A4A","#196674","#33A6B2","#9AC836","D0E64B","#FFA340","#38001C","#571133","#017A74","00C2BA","#DCEBDD","#A0D5D6","#789AA1","#304345","AD9A27","#588C7E","#F2E394","#F2AE72","#D96459","8C4646","#F0E6B1","#B5D6AA","#99A37A","#70584B","3D3536","#2F400D","#8CBF26","#A8CA65","#E8E5B0","419184","#010712","#13171F","#1C1F26","#24262D","961227","#403F33","#6E755F","#AFC2AA","#FFDEA1","E64C10","#C74029","#FAE8CD","#128085","#385052","F0AD44","#CFF09E","#A8DBA8","#79BD9A","#3B8686","0B486B","#E0401C","#E6B051","#272F30","#F7EDB7","9E2B20","#FFE2C5","#FFEEDD","#FFDDAA","#FFC484","FFDD99","#FFFFE4","#F2E5BD","#B9BF8E","#A69F7C","8C6865","#5C8A2D","#AFD687","#FFFFFF","#00C3A9","008798","#4F3130","#FF1F3D","#5BE3E3","#FDFFF1","8B9698","#D23600","#D95100","#DE6D00","#EE8900","FCA600","#FFFFFA","#A1A194","#5B605F","#464646","FF6600","#F34A53","#FAE3B4","#AAC789","#437356","1E4147","#2A7A8C","#176273","#063540","#E6D9CF","403D3A","#21455B","#567D8C","#A59E8C","#8C8372","F2F2F2","#012340","#026873","#83A603","#BBBF45","F2F0CE","#FDFF98","#A7DB9E","#211426","#6B073B","DA8C25","#002F36","#142426","#D1B748","#EDDB43","FFFD84","#420000","#600000","#790000","#931111","BF1616","#3C989E","#5DB5A4","#F4CDA5","#F57A82","ED5276","#23A38F","#B7C11E","#EFF1C2","#F0563D","2E313D","#F5ECD9","#2BACB5","#B4CCB9","#E84D5B","3B3B3B","#A5EB3C","#60C21E","#159E31","#53DB50","C5FFCB","#263138","#406155","#7C9C71","#DBC297","FF5755","#0A111F","#263248","#7E8AA2","#E3E3E3","C73226","#003B59","#00996D","#A5D900","#F2E926","FF930E","#00A19A","#04BF9D","#F2E85C","#F53D54","404040","#324152","#47535E","#796466","#C1836A","DEA677","#036F73","#84CDC2","#FEF2D8","#F18C79","EF504F","#174040","#888C65","#D9CA9C","#D98162","A65858","#56797F","#87A0A4","#FCFBDC","#F2DDB6","A6937C","#A8BAA9","#FFF5CF","#DBCDAD","#B39C7D","806854","#60655F","#AB9675","#FFE0C9","#D4CCBA","CF8442","#BDDFB3","#009D57","#2C372E","#0F2925","465F3F","#3E3947","#735360","#D68684","#F1B0B0","EBD0C4","#0A7B83","#2AA876","#FFD265","#F19C65","CE4D45","#FFFFFF","#F4921E","#858585","#C5D2DB","3E6B85","#11151E","#212426","#727564","#B9AA81","690C07","#000000","#910000","#CBB370","#FFFBF1","21786C","#F78F00","#C43911","#75003C","#37154A","0F2459","#003354","#91BED4","#D9E8F5","#FFFFFF","F26101","#3DA8A4","#7ACCBE","#FFFFF7","#FF99A1","FF5879","#64C733","#F0F0F0","#3E879E","#57524D","36302B","#343844","#2AB69D","#E65848","#FDC536","FCF2D7","#E34517","#F5FF53","#B4E85E","#00BD72","0B4239","#A84B3A","#FF9F67","#233138","#FFF7F5","4C646B","#59535E","#FAEEFF","#F1BAF3","#5D4970","372049","#FF6F22","#D9984F","#FFE8A9","#3E4237","32948A","#5D7370","#7FA6A1","#B8D9B8","#D6EDBD","FFF5BC","#FFBE00","#FFDC00","#FFD10F","#FFDE20","E8CA00","#003840","#005A5B","#007369","#008C72","02A676","#E1E6FA","#C4D7ED","#ABC8E2","#375D81","183152","#BA2F1D","#FFF8A4","#F5E67F","#264A59","1E2C30","#222526","#FFBB6E","#F28D00","#D94F00","80203B","#EBD096","#D1B882","#5D8A66","#1A6566","21445B","#F00807","#5F6273","#A4ABBF","#CCC9D1","E2E1E9","#DFE0AF","#A4BAA2","#569492","#41505E","383245","#152737","#2B4E69","#799AA5","#FFFFF0","682321","#C44C51","#FFB6B8","#FFEFB6","#A2B5BF","5F8CA3","#5ADED4","#4DAAAB","#26596A","#163342","6C98A1","#FF5B2B","#B1221C","#34393E","#8CC6D7","FFDA8C","#3D4D4D","#99992E","#E6E666","#F2FFBF","800033","#242424","#437346","#97D95C","#D9FF77","E9EB9B","#FFEBB0","#FFB05A","#F84322","#C33A1A","9F3818","#4D2B2F","#E57152","#E8DE67","#FFEFC3","C0CCAB","#A82221","#DB5E31","#EDA23E","#F2CB67","BFB840","#3B3140","#BFB8A3","#F2E0C9","#F2B9AC","D97E7E","#43464D","#9197A6","#D3DCF2","#7690CF","48577D","#EFDFBB","#9EBEA6","#335D6A","#D64F2A","7A8A7F","#000001","#313634","#C7CECF","#5C0402","941515","#334D5C","#45B29D","#EFC94C","#E27A3F","DF5A49","#F5F4E1","#D6C9B5","#B4AA97","#D44917","82877A","#19162B","#1C425C","#6ABDC4","#F0E4C5","D6C28F","#00132B","#7F9DB0","#C5E2ED","#FFFFFF","F95900","#1F3642","#6D968D","#B6CCB8","#FFE2B3","56493F","#08A689","#82BF56","#C7D93D","#E9F2A0","F2F2F2","#DE3961","#A4E670","#FFFFDC","#B3EECC","00ADA7","#849972","#D9D094","#A6A23E","#4F2F1D","8F5145","#F41C54","#FF9F00","#FBD506","#A8BF12","00AAB5","#00585F","#009393","#F5F3DC","#454445","FF5828","#FF6138","#FFFF9D","#BEEB9F","#79BD8F","00A388","#140B04","#332312","#B59D75","#E3D2B4","FFF7EA","#ED3B3B","#171F26","#77B59C","#F2E7B1","635656","#46594B","#A6977C","#D9B384","#734F30","260B01","#CCB8A3","#FF8FB1","#FFF5EA","#4E382F","B29882","#B70000","#FFFFFF","#FFCA3D","#94C4F4","0092B3","#053B44","#06736C","#A53539","#B9543C","EAD075","#E8C1B9","#FFB3AB","#FFCAB8","#E8B69C","FFCEAB","#E7F2DF","#69043B","#59023B","#231E2D","161726","#E82B1E","#E5DEAF","#A0B688","#557A66","453625","#F1E6D4","#BA3D49","#791F33","#9F9694","E3E1DC","#CED59F","#F1EDC0","#B1BEA4","#647168","282828","#2C3E50","#E74C3C","#ECF0F1","#3498DB","646464","#DE7047","#FFDE8D","#FFFFFF","#CDDE47","528540","#8EAB99","#40232B","#D95829","#D97338","DEC085","#E9662C","#EBAF3C","#00AC65","#068894","2B2B2B","#46483C","#A0AA8F","#EBE3CB","#FFFFFF","F26101","#170F0E","#290418","#505217","#FFD372","FFF1AF","#263545","#C4273C","#D7DADB","#6DBCDB","FFFFFF","#DCFAC0","#B1E1AE","#85C79C","#56AE8B","00968B","#075807","#097609","#70AF1A","#B9D40B","E5EB0B","#521000","#712800","#744E1D","#879666","F1D98C","#261F26","#3F3B40","#6C7367","#BFBF8A","F2E086","#2C3E50","#FC4349","#D7DADB","#6DBCDB","FFFFFF","#506D7D","#94CCB9","#FFECA7","#FFB170","F07D65","#3F4036","#8DA681","#F2E1C2","#BF2806","8C1D04","#990700","#CC542E","#FF964F","#FFCB7C","787730","#195073","#7F8C1F","#EE913F","#F2E5BD","9FD7C7","#1B3E59","#F2F0F0","#FFAC00","#BF0404","730202","#EA6045","#F8CA4D","#F5E5C0","#3F5666","2F3440","#F95759","#FDA099","#FFFFFF","#D9F3CB","8AC2B0","#265573","#386D73","#81A68A","#9FBF8F","D4D9B0","#E1DA36","#FFEA1B","#6FE4DA","#1DB0BC","007BBC","#013859","#185E65","#F9CC7F","#F15C25","9E1617","#36CC7C","#D6FFBE","#94D794","#228765","77A668","#94201F","#D4421F","#478A80","#D9E061","F08835","#F16233","#00B5B5","#F0F0F0","#3E4651","5C6D7E","#2E806C","#76CC99","#E0FFED","#FF5F3A","D2413C","#00393B","#00766C","#44A18E","#E5EDB6","F6695B","#734854","#F2F2E9","#D9D7C5","#A69580","736766","#03497E","#0596D5","#9DEBFC","#8D7754","FEB228","#F0E14C","#FFBB20","#FA7B12","#E85305","59CC0D","#FE4365","#FC9D9A","#F9CDAD","#C8C8A9","83AF9B","#00557C","#186D94","#3488AD","#81C1DC","BBE5F3","#DEE8D7","#918773","#420A1A","#240001","4D493A","#FFFFFF","#CAC535","#97AF25","#158471","41342C","#041F3D","#0B2E41","#165751","#448C61","9AC16D","#FA8C01","#FF6405","#577700","#082400","A0A600","#78C0F9","#FFDDCE","#FFFFFF","#FFDBE6","FE86A4","#351330","#CC2A41","#E7CAA4","#759A8A","524549","#02151A","#043A47","#087891","#C8C8C8","B31D14","#F34A53","#FAE3B4","#AAC789","#437356","1E4147","#58838C","#DAD7C7","#BF996B","#BF5841","A61C1C","#556354","#E68F0D","#8C948A","#495450","42423F","#323640","#5B6470","#8C94A1","#BDC7D6","DFE2FF","#FF0000","#FF950B","#2FA88C","#DEEB00","4B2C04","#0F3D48","#174C5B","#366774","#ECECE7","E96151","#3DBB7E","#A3CD39","#FBAC1D","#F96C1E","EE4036","#23363B","#A44F3F","#F8983D","#8D9151","BBC946","#4B5657","#969481","#D2C9B0","#F4E3C1","B6B835","#E8980C","#B1F543","#F2FF00","#FF5E00","59BBAB","#849696","#FEFFFB","#232D33","#17384D","FF972C","#555555","#7BB38E","#F4F1D7","#F8AB65","F15C4C","#1D3C42","#67BFAD","#F2EC99","#F2C48D","F25050","#334D5C","#45B29D","#EFC94C","#E27A3F","DF4949","#B8E1F2","#249AA7","#ABD25E","#F8C830","F1594A","#FDEDD0","#BCF1ED","#FF634D","#FD795B","FFF0AA","#FFFFFF","#E5E1D1","#52616D","#2C343B","C44741","#FFFFF1","#D5FF9B","#8FB87F","#5A7B6C","374E5A","#010340","#0E1E8C","#0003C7","#1510F0","1441F7","#002A4A","#17607D","#FFF1CE","#FF9311","E33200","#871E31","#CCC097","#9E9D7B","#687061","262626","#F16663","#F48D6C","#F2E07B","#8ABE9B","4A6D8B","#001F11","#204709","#0C8558","#FFD96A","FF4533","#1D1626","#F2E0BD","#BFAA8F","#8C786C","594C4C","#685D47","#913420","#1E2729","#C1D9C5","FEEFB1","#1D7561","#FC8448","#FF4138","#A8282B","38141B","#BF0633","#FF484E","#FF9273","#D1D0B4","E5ECED","#8E9E63","#E6DBB0","#F5EED7","#C4BCA0","176573","#665446","#809994","#AECCB6","#DEF2C4","E6683F","#3D0D26","#660A3E","#891C56","#B0276F","C93482","#082136","#00294D","#004B8D","#0068C4","2998FF","#3C4631","#9A746F","#F8A2AB","#F1C6B3","EAE9C0","#FF534E","#FFD7AC","#BED194","#499989","176785","#006D80","#BDA44D","#3C2000","#84CECC","78A419","#352C2B","#3C555C","#9E9657","#FFEBCD","CD5510","#2C3E50","#FC4349","#6DBCDB","#D7DADB","FFFFFF","#523631","#D1BE91","#605E3A","#4D462F","592F39","#18293B","#5B5A56","#F2DEA0","#D0B580","FFFBFF","#C8DBB6","#ECEBB7","#CCC68A","#B8B165","827A5D ","#7DA88C","#EBE9A0","#BED24B","#859132","35323C","#E8574C","#F27B29","#E6A51B","#D9CC3C","399977","#324032","#B7C22C","#FFFFE1","#22A8B5","2A3F42","#B3A589","#FFB896","#FFF9B1","#9AB385","11929E","#272433","#343F4F","#3D6066","#77994D","B2D249","#250701","#6D4320","#B0925F","#E7DEC0","82ABB8","#023550","#028A9E","#04BFBF","#EFEFEF","FF530D","#594732","#40342A","#7A422E","#D4CA9A","EDE5AE","#013C4D","#BA5B22","#DB913C","#F0B650","FAD46B","#143840","#5C6B63","#A69E89","#E0C297","D96523","#3FB8AF","#7FC7AF","#DAD8A7","#FFB38B","FF3F34","#CA3995","#F58220","#FFDF05","#BED73D","61BC46","#FFE1D0","#FFBFB4","#FF837E","#FF4242","BF1616","#C4EEFF","#7BA32D","#094201","#A41717","C48726","#001325","#187072","#90BD90","#D7D8A2","F2E4C2","#1A4F63","#068587","#6FB07F","#FCB03C","FC5B3F","#97B350","#333230","#736D61","#BAAB90","FFE5BA","#403D33","#807966","#CCC2A3","#8C0000","590000","#5F8A42","#86AD59","#F6FAA1","#F28410","D66011","#BF355D","#ED8168","#FAB66A","#F2DC86","83BFA1","#E1F03E","#FFBA14","#DB3A0F","#A1003D","630024","#212226","#45433F","#687067","#BDBB99","F0EAC3","#FE4365","#FC9D9A","#F9CDAD","#C8C8A9","83AF9B","#293B47","#5F7A87","#FFFFFF","#CBFF48","00ADA9","#282A33","#697371","#FFE7A6","#F5BA52","FA8000","#0C304A","#2B79A1","#F3F4F1","#85A71E","BFD841","#008B83","#4DAE83","#A0AE79","#FFE499","FF665E","#5D7359","#E0D697","#D6AA5C","#8C5430","661C0E","#324452","#97BDBF","#F2DFBB","#F28705","BF3604","#EEEFB9","#6ACFAE","#369C93","#232928","B03831","#332F45","#015770","#2A8782","#9FD6AE","FFFED2","#2B2830","#5C504F","#ABAB8E","#D9D7A3","C7BE88","#DC941B","#EDC266","#B6952C","#E1D3A6","E9A119","#00305A","#00448D","#0074D9","#4192D9","7ABAF2","#344459","#485F73","#5DA6A6","#A9D9CB","F2EAD0","#060719","#4D1B2F","#9E332E","#EB6528","FC9D1C","#96CEB4","#FFEEAD","#FF6F69","#FFCC5C","AAD8B0","#05F2F2","#04BFBF","#EEF1D9","#A60201","7E100E","#E6F1F5","#636769","#AAB3B6","#6E7476","4B4E50","#DA0734","#F1A20D","#4AABB1","#FCF3E7","3F1833","#202D44","#FC4349","#6DBCDB","#D7DADB","FFFFFF","#CC3B37","#398899","#FFFCE8","#FF857F","CCC1A3","#5DBEA9","#EFEDDF","#EF7247","#4E3F35","D1CBBA","#FFC62D","#E49400","#DD5200","#EFE38A","91B166","#B67D14","#F2921F","#F0B23E","#A62409","441208","#C71B1B","#D6BA8A","#017467","#E08F23","0B0D0C","#474143","#A69E9D","#E7E2DA","#FFFFFF","E7E8E7","#435772","#2DA4A8","#FEAA3A","#FD6041","CF2257","#6DD19D","#99E89D","#D0E8A1","#FFF9C0","D40049","#FAF1D5","#DEC9AC","#CCA18B","#11282D","A5C4BB","#000000","#141414","#1C1919","#1A1716","24201F","#D5D8DD","#5CA2BE","#135487","#2A4353","989DA4","#73161E","#BF0F30","#BFB093","#037F8C","0A2140","#195962","#F56F6C","#FFFFFF","#252932","191C21","#F8EFB6","#FEBAC5","#6CD1EA","#FACFD7","C2EAE9","#91D6BC","#768C6A","#755F31","#B37215","FFBA4B","#F2E6BB","#DD4225","#202724","#63BD99","F8FDD8","#762B1B","#807227","#CCBF7A","#FFEF98","60B0A1","#707864","#C1D74E","#F5FF7C","#DFE6B4","A6B89C","#FFF3D2","#97B48F","#E87657","#FF9B6F","E8D495","#33262E","#733230","#CC5539","#E6D27F","86A677","#122430","#273E45","#FFFCE2","#EBD2B5","E63531","#30394F","#FF434C","#6ACEEB","#EDE8DF","FFFBED","#0A3A4A","#196A73","#32A6A6","#A1BF36","C8D94A","#FFF7CC","#CCC28F","#70995C","#33664D","142933","#43464D","#9197A6","#D3DCF2","#7690CF","48577D","#DFE0AF","#A4BAA2","#569492","#41505E","383245","#B52841","#FFC051","#FF8939","#E85F4D","590051","#473C35","#A36D5C","#9C968B","#D9CEAD","8A866A","#DB4C39","#2D3638","#109489","#44D487","D0DB86","#6F8787","#AEC2AE","#E6DFAE","#B0B57B","888F51","#C8385A","#FFCF48","#ECEABE","#1FCECB","1CA9C9","#42282E","#75A48B","#D9CFB0","#DC9B74","D6665A","#362F2D","#4C4C4C","#94B73E","#B5C0AF","FAFDF2","#98293A","#B14A58","#C86C6B","#DE9D76","EFC77F","#C1D301","#76AB01","#0E6A00","#083500","042200","#453F22","#7A6B26","#CCAD5C","#A1191F","4E1716","#541E32","#8E3557","#88A33E","#C2BD86","F7F2B2","#2B1B2E","#54344D","#FFFFD6","#B89E95","6E444F","#6EC1A5","#9FBEA6","#F5D3A3","#FF9F88","FB7878","#2F252C","#D3CCB2","#99AD93","#6E6751","5C3122","#BE333F","#F2E9CE","#C8C5B1","#939F88","307360","#F0F1F2","#232625","#647362","#B3D929","D2D9B8","#FA2B31","#FFBF1F","#FFF146","#ABE319","00C481","#09455C","#527E7C","#F5FFCC","#E0EB6E","C4D224","#F2DA91","#F2B950","#F29D35","#D96704","BF4904","#A2CFA5","#E0E7AB","#F5974E","#E96B56","D24344","#150033","#310D42","#5C2445","#AB6946","FFCE4C","#23A38F","#B7C11E","#EFF1C2","#F0563D","2E313D","#FF2468","#E0D4B1","#FFFFE3","#00A5A6","005B63","#65A683","#218777","#3F585F","#47384D","F53357","#000623","#28475C","#4A6C74","#8BA693","F0E3C0","#E65322","#D19552","#B8BF73","#B6DB83","FFF991","#112F41","#068587","#6FB07F","#FCB03C","FC5B3F","#C89B41","#A16B2B","#77312B","#1C2331","152C52","#C24366","#D9C099","#FFF8D8","#A8E0BA","00ADA7","#CC0000","#006600","#FFFFEC","#9C9178","6C644F","#3D0319","#720435","#C1140E","#FC5008","32241B","#CFC7A4","#5A9E94","#005275","#002344","A38650","#FFEBC3","#CC3A00","#FF3600","#FF851B","800C00","#EFC164","#F3835D","#F35955","#286275","00434C","#E9F29D","#B7C29D","#878E8F","#67617A","51456B","#445859","#03A696","#49C4BE","#F1F2E4","FF7746","#FA726C","#FFD794","#BAD174","#3BA686","5F6F8C","#4D2B1F","#635D61","#7992A2","#97BFD5","BFDCF5","#CC4D00","#E6CF73","#668059","#264D4D","00CCB3","#4385F5","#DC4437","#FCBE1F","#109D59","FFFFFF","#271F2E","#A4A680","#F2EBC9","#D9B166","A66B38","#0B2C3C","#FF6666","#DADFE1","#FFFFFF","444444","#CFF09E","#A8DBA8","#79BD9A","#3B8686","0B486B","#302B26","#A6B827","#EDE9DD","#98D3D4","594E7A","#4B0505","#720707","#BFB694","#004659","00292B","#B52C38","#EBD1B0","#536682","#D9964B","DE6846","#F2F1DF","#F2B705","#F2C84B","#BF820F","734002","#26140C","#3D2216","#784E3D","#AB8574","D6BCB1","#26221D","#8C2C0F","#E6E5B8","#BFB38D","402D1F","#1F8181","#F2BC79","#F28972","#BF1B39","730240","#002635","#013440","#AB1A25","#D97925","EFE7BE","#8EC447","#FFFFFF","#96D3D4","#636466","2D2D2E","#2D1E1E","#4B3C37","#96A576","#CDE196","FFFFBE","#F06060","#FA987D","#F7F2CB","#72CCA7","10A296","#1D8281","#44BF87","#FBD258","#F29A3F","DB634F","#DEDE91","#EF9950","#F34E52","#C91452","492449","#6D8EAD","#1F3447","#1A0B07","#362416","CFCDB4","#00CD73","#008148","#2D9668","#3ECD8E","004E2C","#3D8080","#628282","#858383","#A38282","C28080","#475159","#839795","#B2BDB7","#CCC9C0","F2F2F2","#0E6870","#C6B599","#C65453","#FFDDB4","EDAA7D","#CEF0B7","#A8DBA8","#79BD9A","#3B8686","0B486B","#292C44","#FF5349","#F0F0F1","#18CDCA","4F80E1","#272A2B","#383737","#473B39","#692B28","940500","#D6C274","#DB9E46","#25706B","#3D2423","AB362E","#FFA68F","#FF4867","#FFF9C8","#B5EBB9","18B29D","#A1A16A","#727D59","#366353","#133C40","03212E","#D45354","#A9DC3A","#2FCAD8","#818B85","CDCDC1","#F14B6A","#3D3C3E","#22BDAF","#BAD7D4","F4F4F4","#FFE2C5","#FFEEDD","#FFDDAA","#FFC484","FFDD99","#9FFF4A","#1ABF93","#087363","#004040","2F1933","#FFDB97","#B28F4E","#FFFDFB","#466CB2","97BBFF","#991C00","#E09A25","#FFFCDB","#008B83","262B30","#44281A","#00ACAE","#F5EFD5","#F37606","EE4717","#FF5952","#FCEEC9","#96D6D9","#4FAAC9","176075","#5C4B51","#8CBEB2","#F2EBBF","#A5C88F","EF847B","#105F73","#F7F3B2","#C6CC33","#F28322","CC5404","#137072","#56B292","#B7F5AB","#FBFFC0","BF223D","#E3F23E","#6C821C","#A6A53F","#E0E0AC","33302E","#00215E","#003CAA","#1967F7","#5E4000","AA7400","#273A3D","#54695C","#AD9970","#FFBF87","FF8F60","#FFAA00","#C2B93E","#808F5D","#576157","302F30","#BE1405","#F2DCAC","#AABEAA","#736E41","413C2D","#6B1229","#C76A61","#FAB99A","#F7D9B5","CCB1A7","#2D9993","#58B3A3","#83BFA3","#B0D9A8","FFFCB6","#334D5C","#45B29D","#EFC94C","#E27A3F","DF5A49","#F30B55","#010326","#012840","#54717F","F2E6CE","#2A3411","#73662C","#BC9847","#FFDFB2","6B0031","#637D74","#403D3A","#8C3B3B","#AB6937","D4A960","#010A26","#011640","#B6D6F2","#FFFFFF","E83338","#924847","#EB986C","#E4C678","#9C7885","372C2C","#022440","#3F95AA","#4EC6DE","#EAE2DF","F7572F","#2B1D2E","#323657","#076473","#54B087","D6F567","#052229","#004043","#BCC373","#E3FF55","D0D90C","#4C514A","#907A62","#879796","#755854","B09880","#1D2939","#1CAF9A","#FFFFFF","#EE4F4B","D1DC48","#004B67","#41CCB4","#FFEA95","#FF7C5D","C70151","#C0272D","#FCFBE7","#9FD3DA","#008C9A","05484F","#213130","#FF5E3D","#C9C83E","#FDFFF1","559398","#B1E4FC","#366D78","#39D5F1","#FFFFFF","D9FF03","#DECE6C","#FCF9B6","#BFE3B5","#5D826E","262E2B","#520A17","#668F91","#F5E6AC","#AB8E5B","52301C","#2D3032","#DD5F18","#FBA922","#F7F7F7","404333","#0C2538","#2B434F","#638270","#BCC98E","EDE059","#E85066","#F28E76","#E6CEB0","#5A8C81","382837","#BF2633","#A6242F","#D9CEAD","#C0B18F","011C26","#002A4A","#17607D","#FFF1CE","#FF9311","E33200","#0A8B91","#485956","#C4B98F","#FFF9BC","EEDF2E","#B89A7B","#9BBAAC","#F2D649","#D95D50","DBDBDB","#BD7938","#8D4421","#643001","#532700","3A1C00","#E1E6FA","#C4D7ED","#ABC8E2","#375D81","183152","#2E4259","#F7483B","#ECF0F1","#03C8FA","737373","#364656","#5D6B74","#94A4A5","#F2F5E9","FF8C31","#3E5916","#93A605","#F28705","#F25C05","E5EFFA","#248077","#74AD8D","#C82754","#F7BB21","F9E2B7","#20736A","#8BD9CA","#B1D95B","#93A651","403E34","#D74B4B","#DCDDD8","#475F77","#354B5E","FFFFFF","#252F33","#415C4F","#869C80","#93C2CC","CEEAEE","#012840","#79C7D9","#9BF2EA","#497358","9DBF8E","#EE7E94","#F8B4C4","#C7CAC9","#D8505C","41424","#282828","#505050","#FFFFFF","#2DCEDB","F20000","#004358","#1F8A70","#BEDB39","#FF5347","FD7400","#470C3B","#802F56","#C0576F","#E38679","FFBD83","#573328","#B05A3A","#FF8548","#29332E","0F1B1C","#461F2D","#E1FFBB","#BAD47F","#849C23","52533F","#333A40","#4C5E5E","#ADD0E5","#CDE4FF","729EBF","#DE5605","#F7A035","#B1DEB5","#EFECCA","65ABA6","#76D6D2","#F9E270","#EF6F56","#F4EED8","596B56","#403E3F","#F2F2F2","#D9D9D9","#9DAABB","8C8C8C","#059E9A","#F4F2ED","#F5A243","#DB3E3B","585857","#FFBF41","#EE8943","#C02221","#FFF4D3","249CA9","#024E76","#39A6B2","#FCE138","#F5B824","F08106","#FF0067","#FF3D6A","#E7FF04","#9CFF00","56FF00","#003540","#0D3F40","#487360","#8FA671","F2D795","#FF493C","#FFFFFF","#B3ECEF","#31C4F5","ADEB41","#244358","#4A8B87","#7CBCAE","#F0D4AF","C5252B","#EA5930","#F8AF1E","#F5E5C0","#097380","372560","#A1DBB2","#FEE5AD","#FACA66","#F7A541","F45D4C","#2C4A47","#6C9A7F","#BB523D","#C89D11","81810B","#F0F1F2","#232625","#647362","#FF5629","D2D9B8","#7C9B5F","#B8D197","#E3FFF3","#9BDEC7","568F84","#E54E45","#DBC390","#F2F2EF","#13A3A5","403833","#77A7FB","#E57368","#FBCB43","#34B67A","FFFFFF","#001A2E","#8F0000","#FFFFFF","#8A874B","41594F","#312F40","#49A69C","#EFEAC5","#E89063","BF5656","#047C8C","#018B8D","#F3BF81","#F49B78","F1706D","#00303E","#7096AD","#C1D1DE","#FFF9EF","EC4911","#2D6891","#70A0BF","#F5EEDC","#DC4C1A","F0986C","#040002","#3D1309","#E8B96A","#BC5D15","5C0F00","#8B929C","#5E6070","#514454","#3B313D","FF2479","#142D58","#447F6E","#E1B65B","#C8782A","9E3E17","#22104D","#2D1E5E","#483A85","#7067AB","A49CFA","#919C86","#9E373E","#2B2E36","#D1B993","C45A3B","#332F45","#015770","#2A8782","#9FD6AE","FFFED2","#37C78F","#FEE293","#FF4D38","#CC2249","380C2A","#47282C","#8C8468","#C9B37F","#DBDAB7","C4C49C","#14191A","#2D2B21","#A69055","#CCB287","FFB88C","#F5E3CD","#696158","#B6A898","#877D71","504A43","#005151","#009393","#F56200","#454445","969692","#D95F47","#FFF2C1","#80A894","#106153","072C36","#9E352C","#E6E8A9","#93C28C","#2E5A5C","2B2623","#03013A","#334A94","#6B9EDF","#83C3F2","99E6FF","#372A26","#4D4D4D","#6DA0A7","#9ED5A8","C7F5FF","#03658C","#022E40","#F2B705","#F28705","F25C05","#FF3B16","#E87826","#E8BA4A","#80A272","003045","#00748E","#E3DFBB","#F4BA4D","#E3753C","DA3B3A","#25401E","#56732C","#84A63C","#B8D943","EAF2AC","#449BB5","#043D5D","#EB5055","#68C39F","FFFCF5","#108F97","#FF8B6B","#FFE39F","#16866D","103636","#1A4F63","#068F86","#6FD57F","#FCB03C","FC5B3F","#381C19","#472E29","#948658","#F0E99A","362E29","#D7E8F7","#BBD0E3","#9CB7CF","#6A8BAB","375D81","#0F1C28","#136972","#67BFA7","#F3CF5B","F07444","#FFFFFF","#4EA9A0","#969514","#FE9C03","FCDE8E","#2F2D30","#656566","#65537A","#51386E","2A2333","#4C2916","#F05A28","#FBAF3F","#38B449","FFFFFF","#132537","#006C80","#EBCAB8","#FE8315","FA3113","#ECEEE1","#A8DACF","#F05B4F","#D8403A","221E1F","#00305A","#004B8C","#0074D9","#4192D9","7ABAF2","#72CF3F","#85FF00","#23E000","#2FB81B","00FF1C","#45CEEF","#FFF5A5","#FFD4DA","#99D2E4","D8CAB4","#FF5B00","#A1716C","#728296","#439AAB","00CABD","#EB6C2D","#D9C8A2","#939C80","#496158","232F38","#D94214","#FFF2C1","#80A894","#52736B","093844","#4D1B2F","#9E332E","#EB6528","#FC9D1C","FFCA50","#FFEEB0","#9AE8A4","#C7C12D","#F76245","ED1C43","#FFFAED","#D4DBFF","#879AC9","#242942","FF8800","#022840","#013440","#517360","#9DA67C","F2DC99","#331A0F","#519994","#BA4B3C","#EEDDAA","789F63","#577867","#EDCE82","#D68644","#AB3229","662845","#435A66","#88A6AF","#F5F2EB","#D9CDB8","424342","#FF8840","#958D4F","#737B55","#595540","513E38","#9D805A","#EBC99D","#FFE6C5","#9DCEEA","4B809E","#272D40","#364659","#55736D","#9DBF8E","D0D991","#23A38F","#B7C11E","#EFF1C2","#F0563D","2E313D","#98C000","#3D4C53","#EA2E49","#FFE11A","0CDBE8","#A20E30","#E93C4F","#DCDCD4","#ADBCC3","2D4255","#1C2640","#263357","#384C80","#4E6AB3","5979CD","#D94214","#FFF2C1","#80A894","#52736B","093844","#3B596A","#427676","#3F9A82","#A1CD73","ECDB60","#1E1E1F","#424143","#67666A","#807F83","CBC9CF","#E04946","#3BA686","#B6D15D","#FFD495","FA847E","#FFEBB0","#FFB05A","#F84322","#C33A1A","9F3818","#FFA136","#FF814A","#E6635A","#785D6B","534557","#CDCF91","#EBEACC","#D6D5B8","#6D7D80","41545E","#011526","#011C40","#4E8DA6","#F2EA79","F2B33D","#353230","#3F4E51","#7B8F70","#99B2BE","F6F4EA","#063559","#0D8C7F","#8FBF4D","#F2D13E","D95929","#158000","#199900","#20BF00","#24D900","29FF00","#0B0D0E","#137074","#7EB7A3","#F1DDBB","EC6766","#02151A","#043A47","#087891","#C8C8C8","B31D14","#59361F","#5C992E","#A3CC52","#E6E673","FF5933","#FE4365","#FC9D9A","#F9CDAD","#C8C8A9","83AF9B","#4B1E18","#F9E5C2","#BBB082","#829993","4F5D4E","#032843","#1F595B","#508C6D","#71A670","A6DB89","#191724","#4C4547","#8C594E","#D18952","FDB157","#191919","#182828","#60702D","#AAB232","E6FA87","#212A3F","#434F5B","#F2F2F2","#8AB839","2E2E2E","#004158","#026675","#038B8B","#F1EEC9","F09979","#023059","#3F7EA6","#F2F2F2","#D99E32","BF5E0A","#F21E52","#FFFFFF","#3D3B42","#0C6F73","63CFD4","#452743","#E7635E","#F8E9A8","#89E0AD","00928C","#FAAD63","#D1714D","#785E48","#39403B","3D1C24","#4C0016","#FFF7EB","#DCCEA7","#A17345","104F53","#BF2431","#F24150","#2A4557","#3B848C","EFF2E4","#3B3013","#8F6031","#E88833","#9C0C0A","FDF3C1","#1E2422","#88BEB1","#FF006D","#DAFFFF","718A94","#F1F4F7","#AF9F7B","#775E43","#40413C","251C17","#00182E","#0C6BA1","#D4D6D4","#FFFDEB","FF7500","#FFAB4A","#CCBAAB","#1E2129","#3D5E6E","47A3A3","#66B3A7","#C0D4B6","#EEF0BD","#F0563D","2C2F3B","#332525","#907465","#EDC5B5","#878C6D","63674A","#F04C16","#DBDBD0","#EDBD1F","#4CB09C","313B4A","#2B211D","#611C26","#C5003E","#8EB7A8","F1E4B7","#1A1F2B","#30395C","#4A6491","#85A5CC","D0E4F2","#03497E","#0596D5","#9DEBFC","#999999","FE4B28","#2F4159","#465E73","#88A649","#F2ECE4","D98841","#323A46","#22282F","#EB4A33","#FFFFFF","E9F0F5","#2C3E50","#FC4349","#6DBCDB","#D7DADB","FFFFFF","#F29727","#E05723","#B0382F","#982E4B","713045","#4D584A","#465943","#428552","#3E754E","4C694B","#47191C","#59574B","#829690","#B5B09A","E1E3CB","#1D5123","#B1C661","#FFDA68","#FE9257","F64448","#59323C","#260126","#F2EEB3","#BFAF80","8C6954","#4E0805","#9E0522","#FFF4D4","#B8C591","447622","#424862","#FB9A63","#BFC4D5","#F6FBF4","FEBC98","#FF2468","#E0D4B1","#FFFFE3","#00A5A6","005B63","#1C2F40","#4C6173","#8094A6","#D9D1BA","F2E9D8","#DFD7B7","#EB7707","#5C5445","#3B2323","9CBFC7","#262E3B","#9C8878","#CFCAAA","#FBF8FF","992435","#FFBC67","#DA727E","#AC6C82","#685C79","455C7B","#404A69","#516C8A","#8AC0DE","#FFFFFF","FFAC00","#485B61","#4B8C74","#74C476","#A4E66D","CFFC83","#A31180","#C42795","#DE52B4","#EA88CE","FFBFE5","#E64D2E","#FFF5F1","#7893AD","#576B9C","2D2A52","#BF0436","#8C0327","#590219","#F2CBA1","8C674C","#CF5B6F","#FFF8C8","#CAD9B1","#8FB3A0","648991","#341D44","#744D90","#BB8CDD","#3E4417","88904D","#00293E","#003D4E","#006269","#00918F","00BAB5","#43212E","#D9666F","#F2D57E","#A9A688","516057","#2A3B30","#ABFFD1","#EBFFF5","#9DFEFF","273B40","#A63343","#E65159","#F5E9DB","#F4F7CF","BAD984","#1BA68C","#54BFAC","#F2EDA7","#F2E530","D94625","#1A2A40","#3F7369","#F2DEA0","#CE5251","EA895E","#1E9382","#70A758","#EFF1C2","#F0563D","2E313D","#A991E8","#FFB4BB","#ACF7FF","#A2E891","FFEDAE","#225B66","#17A3A5","#8DBF67","#FCCB5F","FC6E59","#282624","#BFB7AA","#403D39","#807A71","ABA398","#334D5C","#45B29D","#EFC94C","#E27A3F","DF4949","#440008","#605521","#988432","#D9A54E","9E3711","#649670","#36291E","#69AD6C","#92E67C","C5FF84","#42342C","#738076","#B2B39B","#DFE5E1","294359","#1A3838","#3F7A51","#82A352","#D1C062","FFBE59","#7D8C22","#B3BF67","#F2E49B","#D9DFF4","6791BF","#8A7D6D","#2D2D38","#E86E48","#FFFFE8","9CC9C9","#CFC949","#FFF5BF","#A9E6C4","#6AB39F","665841","#A1172D","#FDFFBA","#A7DB9E","#275C57","1F1B19","#FF6C0D","#F29E00","#E6C10F","#44996F","216273","#2C3E50","#FA4248","#D7DADB","#6DBCDB","FFFFFF","#627369","#99B397","#E2F2C6","#91CCAD","376266","#04496E","#66CAFF","#A3FC7E","#70D44A","2C6B0F","#1BA68C","#97BF3F","#F2ECD8","#F2B035","F2522E","#A2D9B1","#7CBF9E","#F2F1B9","#8C8575","193741","#024959","#037E8C","#F2EFDC","#E74C30","363636","#212625","#9CA6A2","#D0D9D6","#BF0404","C2C6AF","#00FFFF","#00FF00","#FFFF00","#FF5100","FF007C","#212629","#CDCF19","#FFF77D","#96C4AB","CF2A56","#CFF9FF","#BFC7BB","#787051","#332730","57324F","#98CACB","#FDEFBE","#F0542B","#736E5B","ABA68E","#F2F1EB","#BFB9A4","#262222","#802A30","8C0303","#65356B","#AB434F","#C76347","#FFA24C","519183","#78BF82","#A4D17C","#CFD96C","#EBD464","FFD970","#806265","#FFA256","#F7DD77","#E0D054","ABA73C","#8F323C","#123943","#80BDDB","#4189AB","C98127","#683820","#8C9A89","#E7D6A2","#BEAA65","9A8234","#021B21","#032C36","#065F73","#E8DFD6","FF2A1D","#2D6C73","#3FA693","#B4D9CB","#9ABF49","C6D93B","#141F26","#2B4040","#405950","#A69E86","F2D9BB","#4A8279","#003330","#610400","#003B06","02730F","#69B5E1","#D4E4F5","#EAF2F8","#BEDBED","000000","#893660","#EF7261","#68D693","#A0D7E2","299CA8","#073A59","#2D9AA6","#F2E2DC","#F23322","A61B1B","#2A3A48","#3E6372","#B2D4DC","#FAFAFF","FF6900","#F3BD8D","#F1A280","#BE6D6B","#704A5B","3E263C","#1C2742","#3C91C7","#5A9ABE","#95C5DE","E0EEFB","#426261","#465A59","#577573","#739A97","9AC1C0","#002A4A","#17607D","#FFF1CE","#FF9311","D64700","#589373","#BFBD99","#F2D6B3","#C2512F","241E1E","#1F518B","#1488C8","#F7E041","#E2413E","B5292A","#549494","#E85649","#232C2E","#E6E8D2","706558","#392133","#FFECBE","#D9D098","#C4AB6D","AB7D3A","#F0F0F0","#1C1C1C","#A2FDF5","#1CCDC7","27EDDF","#011526","#025959","#027353","#03A678","03A696","#004358","#1F8A70","#BEDB39","#FFE11A","FD7400","#37465D","#F2F2F2","#9DC02E","#779324","051A37","#580022","#AA2C30","#FFBE8D","#487B80","011D24","#F9F9F9","#03A678","#E9EDEB","#F44647","00707F","#800000","#BF0000","#E2D6C2","#F6EDD8","FFFFFF","#F7F6AF","#1B2124","#D62822","#97D6A6","468263","#432852","#992255","#FF3D4C","#28656E","00968F","#444344","#52BBB2","#2B344D","#EE5555","F8F7EE","#45334A","#796B7D","#CCC4B0","#FFF1B5","FFA3A3","#5A4B53","#9C3C58","#DE2B5B","#D86A41","D2A825","#14151C","#0C242B","#297059","#84D66E","D1FB7A","#272D40","#364659","#55736D","#9DBF8E","D0D991","#23A38F","#B7C11E","#EFF1C2","#F0563D","2E313D","#2E064D","#80176B","#B356A1","#59580B","FFFF00","#CC3333","#FF9D33","#F7F7F0","#3EBBA7","00747A","#5C4B51","#8CBEB2","#F2EBBF","#F3B562","BD6060","#0D3E58","#1C848C","#19C0C2","#F3EDD6","DA6260","#022629","#2A5945","#FAFFED","#E6DCC0","B3371C","#F4FAC7","#7BAD8D","#FFB159","#F77F45","C2454E","#A2C1C6","#86B1B7","#AECBAD","#CFDCB0","D6E1D1","#B0DAFF","#325B80","#64B7FF","#586D80","5092CC","#0F808C","#6C8C26","#F2A71B","#F26A1B","D91818","#FFBC6C","#FE9F6C","#BD716E","#74495F","3B2C4D","#FF4D41","#F2931F","#E6CA21","#91B321","1E8C65","#302821","#453629","#5C4837","#8A735F","BDA895","#415457","#5F7B7F","#9ACCAF","#E6EBC4","F9F7C8","#474143","#A69E9D","#E7E2DA","#FFFFFF","E7E8E7","#805939","#BD9962","#E6CD7D","#578072","2D4B4D","#03588C","#1763A6","#419CA6","#54BF83","8DBF41","#00CCFF","#A1FCFF","#040438","#004878","C9FAFF","#534C64","#B7DECF","#F0F3D7","#7E858C","D96557","#7F7364","#CBB08E","#CBC1B7","#789DCB","646F7F","#5C2849","#A73E5C","#EC7263","#FE9551","FFD285","#FF0012","#FF7D00","#FFD900","#5BE300","0084B0","#F24C32","#F29471","#FCDFA6","#36B898","3D7585","#083157","#0A6C87","#459C97","#92CCA5","C9F0B1","#DC941B","#EDC266","#B6952C","#E1D3A6","E9A119","#323836","#BAD1B5","#DBE8CF","#F0F7E8","FFFEF5","#081724","#589494","#8EBBB4","#D0DCD0","F5EED2","#50781C","#9CAD1C","#EAF7E6","#40A5DE","0B5191","#537F79","#78A68F","#CBD49C","#FED457","CB252A","#F23C13","#CBAB78","#FFFFFF","#898373","1F1C17","#450003","#5C0002","#94090D","#D40D12","FFED75","#0770A2","#82D9F7","#FEFEFE","#AEC844","F36622","#30394F","#FF434C","#6ACEEB","#EDE8DF","0E6569","#FF6B6B","#556270","#C7F464","#4ECDC4","EDC8BB","#D9B500","#FFED9C","#BFCC85","#748F74","454545","#452E32","#A34B1B","#B5A187","#EDDF9A","A7CC31","#2C2B33","#596664","#909980","#CCC08D","FF8A00","#C21F1F","#FFFFFC","#E34446","#FFFFDB","E36D6F","#282828","#00AAB5","#C1C923","#F41C54","F5F0F0","#3A3F40","#202627","#151B1E","#EFF4FF","41444D","#DEBB73","#4D0017","#010000","#4D0F30","9A002F","#EB9328","#FFA754","#FFD699","#FFF5DC","4FA6B3","#025E73","#037F8C","#D9D59A","#D9BD6A","590202","#636266","#E0CEA4","#E8A579","#7D6855","42403E","#FF0000","#FF4000","#FF7F00","#FFBF00","FFFF00","#FFFFFF","#74ADA6","#1E5E6F","#241B1F","68A81E","#5A0532","#FF6745","#FFC861","#9DAE64","27404A","#ACCBBC","#467847","#E8E4C1","#A60303","730202","#5C4B51","#8CBEB2","#F2EBBF","#F3B562","F06060","#0D2557","#93A8C9","#FFFFFF","#F5DED5","558D96","#F53C4A","#565157","#10CFC8","#F2EEE7","F5D662","#FFD97B","#E65029","#A60027","#660033","191C26","#595408","#A6800D","#A66D03","#A63F03","730C02","#2E031F","#590424","#8C072B","#BF0A2B","DEEFC5","#E0C882","#A6874E","#BFA169","#D9B779","F2D399","#D88681","#A67673","#746566","#535A5D","324F54","#FC297D","#FB607A","#FDA286","#FDC188","FEE78A","#FFECA1","#B3B27F","#4C5E52","#2F3436","FFBE2C","#D93312","#B3AB82","#45735F","#394D47","2C3233","#324143","#6595A3","#C8E3E8","#FCFFED","B6C28B","#477984","#FEF5EB","#C03C44","#EEAA4D","313E4A","#334D5C","#45B29D","#EFC94C","#E27A3F","DF4949","#630B11","#33322F","#2A2927","#1E1D1C","000000","#D94214","#FFF2C1","#80A894","#52736B","093844","#051E21","#00302D","#856434","#F28C28","FFAD4E","#D7DADD","#DDDEE3","#E1E1E9","#EDEFF4","F2F3F8","#BF495E","#41A693","#F2EC9B","#D9CF48","D9583B","#067072","#14A589","#DECFA6","#BAAE8C","F94B06","#423A38","#47B8C8","#E7EEE2","#BDB9B1","D7503E","#730324","#DFE3E6","#B4C4D4","#8BA2BD","456382","#537374","#F9BD7F","#EBD7A5","#ADC9A5","5C9E99","#88B59E","#B6DEC8","#39464D","#C04229","ABD1AB","#11A7FC","#95D127","#F2E415","#FF8638","EE3551","#212640","#5D718C","#4B95A6","#60BFBF","EFF2D8","#D8A64D","#9B5422","#351411","#5B0D0D","991C11","#53324F","#668D6E","#F2E0A0","#F19B7A","F0756E","#DFE0AF","#A4BAA2","#569492","#41505E","383245","#7BBADE","#93DE7F","#FFED5D","#F29E4A","FF7050","#133800","#1B4F1B","#398133","#5C9548","93E036","#D9D7AD","#91A685","#FF6A00","#37485C","1C232E","#008767","#FFB27A","#FF6145","#AB2141","5E1638","#727B7F","#CCEAEA","#7A7556","#2E2125","44CACC","#FFFFED","#FF2C38","#FF9A3A","#FFF040","67D9FF","#007148","#60A859","#9BDA6A","#C7F774","F9FFEF","#092740","#45698B","#90B0CC","#F1FAFF","8FD36F","#E2FFA0","#7D8076","#FAFFED","#C2CCBE","8F7D70","#00736A","#00BC9F","#F1EEC7","#FEA301","F2561A","#26282E","#AD5138","#F7F7F7","#DDDAE0","8594AE","#1A191F","#35352F","#484042","#4E5252","E64D38","#49454A","#E69B02","#FAF4C6","#B1D631","324052","#5F1A2B","#1D2834","#6F8B78","#E4D49E","C96466","#012D3D","#38AD9E","#FFEB9E","#FF6867","D0DBED","#0D1F36","#104954","#1E9C89","#38CC85","60EB7B","#8C4E03","#9FA66A","#F2EC94","#F23005","8B0F03","#000001","#20201F","#E2E2E4","#590402","B80000","#344059","#465973","#F2D272","#A69460","595139","#33454C","#608F85","#B6E5CB","#8BAF95","54584E","#FBFEF6","#B7BFA4","#687F70","#1A3841","BF3847","#D7E836","#86FFC7","#FFB048","#E8366C","593BFF","#34A9FF","#5982DB","#665EB8","#684682","632E62","#004056","#2C858D","#74CEB7","#C9FFD5","FFFFCB","#BFB978","#84945C","#516967","#4D3130","281B24","#103B73","#20638C","#3786A6","#4EABBF","EBEFF2","#9FB1BF","#1D2D63","#1C5357","#1F6E56","196331","#FFEBBA","#C3BD91","#88947B","#4C3F3F","2A2727","#347373","#4EA6A6","#91D9D9","#FFFFFD","F2E205","#828948","#EFDFC2","#006971","#DC533E","840000","#000137","#29003F","#79003D","#D04D14","F89801","#370005","#4B0005","#5F0005","#730005","870005","#C3AE8D","#F25260","#2D5F73","#6BADC9","8FCED6","#9E1B36","#F7EDBA","#E69B3D","#EB3355","3D241D","#1D8281","#44BF87","#FBD258","#F29A3F","DB634F","#035C75","#1B808C","#31A6A8","#F3F1BC","F3AD14","#FF7500","#665130","#EBB643","#CEDAA8","668E84","#384D3A","#3E6653","#728053","#A68357","D97C71","#012326","#17455C","#E1CAAB","#FE8333","FA4913","#1A2944","#2DA7C7","#56ACBA","#98C4C9","CBD5D2","#BF3542","#CDC5BA","#EBE3D6","#3C3C3C","2E2E2E","#231921","#695F74","#BEB4CB","#EBEBF0","D2DCEB","#34373F","#686C75","#F3E9D0","#BEB7A7","8E867C","#661510","#D9351A","#F2C76F","#BF9727","204D3F","#3CFFEE","#24AABC","#356781","#2C3D51","1C1F24","#DA3537","#FFFCC4","#00585F","#6A6A61","2A2C2B","#AE3135","#D1AF87","#8C826B","#3D3C33","F2F0CE","#FF0894","#FF5E9F","#FF91A7","#FFB5CA","F5F0BA","#99878D","#323232","#646464","#7E4A5C","372129","#3FB8AF","#7FC7AF","#DAD8A7","#FFB38B","FF3F34","#402B3C","#6AA6A6","#D9CCA7","#F2B263","F26835","#6AA690","#F2BC1B","#F2DC99","#F29057","BF1F1F","#F4FAC7","#7BAD8D","#FFB158","#F77F45","C2454E","#E5533C","#F5E346","#93D06D","#50AC6A","227864","#39588A","#A9BDD7","#FFFFFF","#FFEADD","FFD0BB","#B0B595","#615F4F","#828567","#91A380","EAFFCD","#00427F","#0066BD","#66B5CC","#F0E4C5","D6C28F","#FF6313","#F9E4B3","#C29689","#74474B","45232E","#00585F","#009393","#FFFCC4","#C7C49B","EB0A00","#091840","#44A2FF","#F7F7EA","#B3CC63","4C6620","#5CBBE3","#FCF1BC","#5C8182","#383A47","B4F257","#9E9E9E","#E5E1D1","#E0393D","#253746","425563","#4D9453","#FFFFB1","#ADDE4E","#FF9D27","A62A16","#B70046","#FF850B","#FFEBC5","#109679","675A4C","#363636","#0599B0","#A4BD0A","#FFA615","FF2E00","#7D8077","#BBBFB2","#FAFFED","#E82A33","E3DEBC","#FD9F44","#FC5C65","#007269","#03A679","FAF0B9","#134B57","#81A489","#F1D8B5","#F2A054","C04D31","#946E49","#394042","#EDDBAC","#872A0C","BA8E3A","#404040","#024959","#037E8C","#FFFFFF","F24C27","#2A3342","#163C6E","#4E5F61","#E6A015","EDE7BE","#445060","#829AB5","#849E91","#C14543","D6D5D1","#8A9126","#B7BF5E","#FFE9C4","#F5B776","F58E45","#9B2D1E","#3C3A28","#78A080","#9BCD9E","FFFFAE","#FF6138","#FFFF9D","#BEEB9F","#79BD8F","00A388","#990000","#FF6600","#FF9900","#996633","CC9966","#DCE6DA","#B8CCBB","#98B3A5","#7A9994","62858C","#0B1C29","#3B7C8F","#73A5A3","#98C1B7","F0EBD2","#F6CB51","#E25942","#13A89E","#3F4953","F2E7DA","#282F36","#FFFEFC","#BDA21D","#BFBC5B","D2E098","#8C182D","#DE7140","#FCB95A","#FAE285","6A7349","#6B9100","#FFE433","#FF841F","#E03D19","A6001C","#FFEAA7","#D9D697","#9FC49F","#718C6A","543122","#CFF09E","#A8DBA8","#79BD9A","#3B8686","0B486B","#0C2233","#065471","#0A91AB","#FFC045","F2F2F2","#BEE8E0","#373C40","#2E2621","#73320B","FF5E00","#1B2C35","#A3BFC6","#FF005D","#222A30","293A42","#FF8400","#3B4044","#494948","#E6E1D8","F7F2E9","#6A482D","#518C86","#F6BF3D","#EF7C27","BF2424","#261C2B","#292B39","#226468","#608D80","829D8F","#B2AD9A","#110E00","#363226","#A9A695","ECE9D8","#1B1B26","#26394D","#286480","#13B3BF","A3FF57","#F2C2A7","#F5E5C5","#593D28","#422C21","93DEDB","#001028","#033140","#1E5A5B","#7BA78C","EBEDC6","#544E6E","#808CB0","#ABD1D9","#D9FFF7","DDF556","#323A45","#596677","#758194","#FFFFFF","E74C3C","#45291A","#AB926D","#DBD1BC","#4999C3","5FCBEC","#6B151D","#2E1615","#A8553A","#DB8F5A","F2C18E","#000623","#28475C","#4A6C74","#8BA693","F0E3B1","#60807B","#81B37A","#BCCC5F","#FFEE65","E64964","#FFFFFA","#A1A194","#5B605F","#464646","FF6600","#1E1B17","#577270","#9C9A79","#C7BDA1","580E0C","#452F27","#5E504A","#6B6865","#9BBAB2","B0FFED","#1B5257","#F7F6C3","#F28159","#CC5850","4F1C2E","#FAA51B","#BF511F","#2C445E","#2F6D82","5EE4EB","#BF3952","#59364A","#556D73","#D9D1A9","D95F5F","#024959","#037E8C","#F2EFDC","#E74C30","363636","#221A26","#544759","#A197A6","#F27405","D93D04","#C4A44A","#E6D399","#9AB8A9","#7C8A7F","4E4B44","#FFFEC8","#B1BF99","#5B604D","#39382B","26181E","#4E3C51","#21A68D","#3BBF9A","#F2E8B6","F25749","#102144","#1B325E","#254580","#3C63B0","5D8AEA","#2A3A48","#3E6372","#B2D4DC","#FAFAFF","FF4B00","#FFF1BF","#F20058","#FFAEAC","#000001","7D7A96","#FDFFC6","#F2F096","#FF0080","#DE0049","521218","#5B0E00","#FBB500","#FBD864","#807D1A","59233C","#1E1E1F","#424143","#67666A","#807F83","CBC9CF","#3C3658","#3EC8B7","#7CD0B4","#B9D8B1","F7E0AE","#FFFFFF","#99B75F","#D5DD98","#EBF4DB","D8D8D8","#248A8A","#C9FA58","#F9E555","#FAAC38","F2572A","#086B63","#77A490","#E2D8C1","#BFAE95","7C7159","#5C4B51","#8CBEB2","#F2EBBF","#A5C88F","EF847B","#17162F","#89346D","#C76058","#FFB248","E8C475","#6E8F4A","#65D9C5","#F2E7B6","#EDA430","AB3E2C","#30394F","#FF434C","#6ACEEB","#EDE8DF","0E6569","#8E1B13","#F9E4B3","#849689","#46464A","29232E","#686B30","#AB9A52","#E8BA67","#D68F4F","BA512E","#E54E45","#DBC390","#F2F2EF","#13A3A5","403833","#65BA99","#59A386","#F1DDBB","#D6C4A6","E74C3C","#A6FFBC","#4ACFAF","#00A995","#006161","003D4C","#33271E","#8B7653","#C8D9A0","#FDEE9D","233331","#048789","#503D2E","#D44D27","#E2A72E","EFEBC8","#E5FF1E","#A9D943","#75A660","#698070","494D4B","#2DEBA2","#91F57F","#EBAA69","#E70049","2B0027","#990000","#336699","#DDDDDD","#999999","333333","#F13A4B","#3D3C3E","#22BDAF","#F4F4F4","D7D7D7","#F53A59","#001D2D","#15A88C","#B7D9C8","F3F5F4"];n.set(r)}};CABLES.OPS["a96020ac-0832-478e-bbb7-d6246d0eeedf"]={f:Ops.Array.PaletteLibrary,objName:"Ops.Array.PaletteLibrary"};Ops.Gl.ImageCompose.ColorMap_v2=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={colormap_frag:"IN vec2 texCoord;\nUNI sampler2D tex;\nUNI sampler2D gradient;\nUNI float pos;\nUNI float amount;\nUNI float vmin;\nUNI float vmax;\n\n{{CGL.BLENDMODES3}}\n\n\nfloat lumi(vec3 color)\n{\n   return vec3(dot(vec3(0.2126,0.7152,0.0722), color)).r;\n}\n\nvoid main()\n{\n    vec4 base=texture(tex,texCoord);\n    float a=base.a;\n\n    base=clamp(base,vmin,vmax);\n\n    #ifdef METH_LUMI\n        vec4 color=texture(gradient,vec2(lumi(base.rgb),pos));\n    #endif\n\n    #ifdef METH_CHANNELS\n        vec4 color=vec4(1.0);\n        color.r=texture(gradient,vec2(base.r,pos)).r;\n        color.g=texture(gradient,vec2(base.g,pos)).g;\n        color.b=texture(gradient,vec2(base.b,pos)).b;\n    #endif\n\n    base.a=color.a=a;\n\n\n    outColor=cgl_blendPixel(base,color,amount);\n\n}\n"};let n=e.inTrigger("render");let r=e.outTrigger("trigger");const i=CGL.TextureEffect.AddBlendSelect(e,"Blend Mode","normal");const a=e.inValueSlider("Amount",1);let s=e.inTexture("Gradient");let o=e.inSwitch("Method",["Luminance","Channels"],"Luminance");let l=e.inFloatSlider("Min",0);let u=e.inFloatSlider("Max",1);let c=e.inValueSlider("Position",.5);e.setPortGroup("Vertical Position",[l,u,c]);let h=e.patch.cgl;let f=new CGL.Shader(h,e.name,e);f.define("METH_LUMI");f.setSource(f.getDefaultVertexShader(),t.colormap_frag);let d=new CGL.Uniform(f,"t","tex",0);let p=new CGL.Uniform(f,"t","gradient",1);let g=new CGL.Uniform(f,"f","pos",c);let m=new CGL.Uniform(f,"f","vmin",l);let v=new CGL.Uniform(f,"f","vmax",u);let b=new CGL.Uniform(f,"f","amount",a);CGL.TextureEffect.setupBlending(e,f,i,a);o.onChange=()=>{f.toggleDefine("METH_LUMI",o.get()=="Luminance");f.toggleDefine("METH_CHANNELS",o.get()=="Channels")};n.onTriggered=function(){if(!CGL.TextureEffect.checkOpInEffect(e,3))return;if(!s.get())return;h.pushShader(f);h.currentTextureEffect.bind();h.setTexture(0,h.currentTextureEffect.getCurrentSourceTexture().tex);h.setTexture(1,s.get().tex);h.currentTextureEffect.finish();h.popShader();r.trigger()}}};CABLES.OPS["440c1675-122d-411f-b848-16c60b677120"]={f:Ops.Gl.ImageCompose.ColorMap_v2,objName:"Ops.Gl.ImageCompose.ColorMap_v2"};Ops.Array.ArrayChunk=class extends CABLES.Op{constructor(){super(...arguments);const s=this;const e=s.attachments={};const o=s.inArray("Input Array"),l=s.inValueInt("Begin Index",0),u=s.inValueInt("Chunk Size",1),c=s.inValueBool("Circular",false),h=s.outArray("Output Array"),f=s.outNumber("Array length");let d=[];o.onChange=t;l.onChange=t;u.onChange=t;c.onChange=t;function t(){let t=o.get();let n=Math.floor(l.get());let e=Math.floor(u.get());let r=c.get();if(!t){h.set(null);return}if(n<0){n=0}if(r&&n>=t.length){n%=t.length}if(!t||e<1){h.set(null);return}let i=e+n;let a=Math.min(t.length,n+i)-n;if(a<0){a=0}else s.setUiError("idx",null);a=Math.min(a,e);if(a>e)a=t.length;d.length=a;for(let e=n;e<a+n;e++){d[e-n]=t[e]}f.set(a);h.setRef(d)}}};CABLES.OPS["c7ee6c6e-ca88-4c24-b289-78bb922bf5f7"]={f:Ops.Array.ArrayChunk,objName:"Ops.Array.ArrayChunk"};Ops.Gl.Textures.PaletteTexture=class extends CABLES.Op{constructor(){super(...arguments);const a=this;const e=a.attachments={};const s=a.inArray("Palette array"),o=a.inValueBool("Smooth"),l=a.outArray("Color Array"),u=a.outTexture("Texture");const t=a.patch.cgl;let c=document.createElement("canvas");c.id="canvas_"+CABLES.generateUUID();c.width=5;c.height=8;c.style.display="none";let n=document.getElementsByTagName("body")[0];n.appendChild(c);let h=c.getContext("2d");u.setRef(CGL.Texture.getEmptyTexture(t));let f=[];let d=null;let p=0;let g=0;let m=0;o.onChange=s.onChange=i;function v(e){return parseInt(r(e).substring(0,2),16)}function b(e){return parseInt(r(e).substring(2,4),16)}function _(e){return parseInt(r(e).substring(4,6),16)}function r(e=""){return e.charAt(0)=="#"?e.substring(1,7):e}function i(){let t=s.get();let n;if(!t){return}let e=t[0];let r=0;if(typeof e==="string"){n=true;r=t.length;c.width=r;f.length=t.length}else{n=false;r=Math.floor(t.length/3);c.width=r;f.length=r}for(let e=0;e<r;e++){if(n){p=v(t[e]);g=b(t[e]);m=_(t[e]);f[e*3+0]=p/255;f[e*3+1]=g/255;f[e*3+2]=m/255}else{p=Math.floor(t[e*3+0]*255);g=Math.floor(t[e*3+1]*255);m=Math.floor(t[e*3+2]*255);f[e*3+0]=t[e*3+0];f[e*3+1]=t[e*3+1];f[e*3+2]=t[e*3+2]}h.fillStyle="rgb("+p+","+g+","+m+")";h.fillRect(c.width/r*e,0,c.width/r,c.height)}let i=CGL.Texture.FILTER_NEAREST;if(o.get())i=CGL.Texture.FILTER_LINEAR;if(d==i&&u.get())u.get().initTexture(c,i);else u.setRef(new CGL.Texture.createFromImage(a.patch.cgl,c,{filter:i}));l.setRef(f);u.get().unpackAlpha=false;d=i}s.onLinkChanged=function(){if(!s.isLinked()){l.setRef([]);u.setRef(CGL.Texture.getEmptyTexture(t));d=null}};a.onDelete=function(){c.remove()};i()}};CABLES.OPS["8117ed3b-a264-4a46-83a4-3cdb3f743d10"]={f:Ops.Gl.Textures.PaletteTexture,objName:"Ops.Gl.Textures.PaletteTexture"};Ops.Gl.Texture_v2=class extends CABLES.Op{constructor(){super(...arguments);const i=this;const e=i.attachments={};const a=i.inUrl("File",[".jpg",".png",".webp",".jpeg",".avif"]),t=i.inSwitch("Filter",["nearest","linear","mipmap"]),n=i.inValueSelect("Wrap",["repeat","mirrored repeat","clamp to edge"],"clamp to edge"),r=i.inSwitch("Anisotropic",["0","1","2","4","8","16"],"0"),s=i.inSwitch("Data Format",["R","RG","RGB","RGBA","SRGBA"],"RGBA"),o=i.inValueBool("Flip",false),l=i.inValueBool("Pre Multiplied Alpha",false),u=i.inValueBool("Active",true),c=i.inBool("Save Memory",true),h=i.outTexture("Texture"),f=i.inBool("Add Cachebuster",false),d=i.inTriggerButton("Reload"),p=i.outNumber("Width"),g=i.outNumber("Height"),m=i.outNumber("Aspect Ratio"),v=i.outBoolNum("Loaded",0),b=i.outBoolNum("Loading",0);const _=i.patch.cgl;i.toWorkPortsNeedToBeLinked(h);i.setPortGroup("Size",[p,g]);let E=null;let F=null;let C=null;let A=CGL.Texture.FILTER_MIPMAP;let x=CGL.Texture.WRAP_REPEAT;let T=0;let S=0;l.setUiAttribs({hidePort:true});l.onChange=a.onChange=s.onChange=f.onChange=o.onChange=B;r.onChange=t.onChange=I;n.onChange=M;t.set("mipmap");n.set("repeat");h.setRef(CGL.Texture.getEmptyTexture(_));d.onTriggered=B;u.onChange=function(){if(u.get()){if(E!=a.get()||!C)B();else h.setRef(C)}else{h.setRef(CGL.Texture.getEmptyTexture(_));p.set(CGL.Texture.getEmptyTexture(_).width);g.set(CGL.Texture.getEmptyTexture(_).height);if(C)C.delete();i.setUiAttrib({extendTitle:""});C=null}};const y=function(){const e=CGL.Texture.getTempTexture(_);h.setRef(e)};function B(e){clearTimeout(S);S=setTimeout(function(){D(e)},1)}function O(){if(s.get()=="R")return CGL.Texture.PFORMATSTR_R8UB;if(s.get()=="RG")return CGL.Texture.PFORMATSTR_RG8UB;if(s.get()=="RGB")return CGL.Texture.PFORMATSTR_RGB8UB;if(s.get()=="SRGBA")return CGL.Texture.PFORMATSTR_SRGBA8;return CGL.Texture.PFORMATSTR_RGBA8UB}function D(e){i.checkMainloopExists();if(!u.get())return;if(F)F=_.patch.loading.finished(F);F=_.patch.loading.start(i.objName,a.get(),i);let t=i.patch.getFilePath(String(a.get()));if(f.get()||e===true)t=CABLES.cacheBust(t);if(String(a.get()).indexOf("data:")==0)t=a.get();let n=false;E=a.get();if(a.get()&&a.get().length>1){v.set(false);b.set(true);const r=a.get();i.setUiAttrib({extendTitle:CABLES.basename(t)});if(n)i.refreshParams();_.patch.loading.addAssetLoadingTask(()=>{i.setUiError("urlerror",null);CGL.Texture.load(_,t,function(e,t){if(a.get()!=r){F=_.patch.loading.finished(F);return}if(C)C.delete();if(e){const n=CGL.Texture.getErrorTexture(_);h.setRef(n);i.setUiError("urlerror",'could not load texture: "'+a.get()+'"',2);F=_.patch.loading.finished(F);return}p.set(t.width);g.set(t.height);m.set(t.width/t.height);C=t;h.setRef(C);b.set(false);v.set(true);if(c.get())C.image=null;if(F){F=_.patch.loading.finished(F)}i.checkMainloopExists()},{anisotropic:T,wrap:x,flip:o.get(),unpackAlpha:l.get(),pixelFormat:O(),filter:A});i.checkMainloopExists()})}else{y();F=_.patch.loading.finished(F)}}function I(){if(t.get()=="nearest")A=CGL.Texture.FILTER_NEAREST;else if(t.get()=="linear")A=CGL.Texture.FILTER_LINEAR;else if(t.get()=="mipmap")A=CGL.Texture.FILTER_MIPMAP;else if(t.get()=="Anisotropic")A=CGL.Texture.FILTER_ANISOTROPIC;r.setUiAttribs({greyout:A!=CGL.Texture.FILTER_MIPMAP});T=parseFloat(r.get());B()}function M(){if(n.get()=="repeat")x=CGL.Texture.WRAP_REPEAT;if(n.get()=="mirrored repeat")x=CGL.Texture.WRAP_MIRRORED_REPEAT;if(n.get()=="clamp to edge")x=CGL.Texture.WRAP_CLAMP_TO_EDGE;B()}i.onFileChanged=function(e){if(a.get()&&a.get().indexOf(e)>-1){h.setRef(CGL.Texture.getEmptyTexture(i.patch.cgl));h.setRef(CGL.Texture.getTempTexture(_));D(true)}}}};CABLES.OPS["790f3702-9833-464e-8e37-6f0f813f7e16"]={f:Ops.Gl.Texture_v2,objName:"Ops.Gl.Texture_v2"};Ops.Graphics.Meshes.Rectangle_v4=class extends CABLES.Op{constructor(){super(...arguments);const t=this;const e=t.attachments={};const n=t.inTrigger("render"),r=t.inValueBool("Render Mesh",true),y=t.inValue("width",1),B=t.inValue("height",1),O=t.inSwitch("pivot x",["left","center","right"],"center"),D=t.inSwitch("pivot y",["top","center","bottom"],"center"),I=t.inSwitch("axis",["xy","xz"],"xy"),M=t.inBool("Flip TexCoord X",false),L=t.inBool("Flip TexCoord Y",true),R=t.inValueInt("num columns",1),w=t.inValueInt("num rows",1),i=t.outTrigger("trigger"),N=t.outObject("geometry",null,"geometry");N.ignoreValueSerialize=true;const P=new CGL.Geometry("rectangle");r.setUiAttribs({title:"Render"});n.setUiAttribs({title:"Trigger"});i.setUiAttribs({title:"Next"});t.setPortGroup("Pivot",[O,D,I]);t.setPortGroup("Size",[y,B]);t.setPortGroup("Structure",[R,w]);t.toWorkPortsNeedToBeLinked(n);t.toWorkShouldNotBeChild("Ops.Gl.TextureEffects.ImageCompose",CABLES.OP_PORT_TYPE_TRIGGER);const U=0;const k=1;let j=U;let G=null;let V=true;let z=true;const a=vec3.create();vec3.set(a,1,1,1);I.onChange=O.onChange=D.onChange=M.onChange=L.onChange=w.onChange=R.onChange=s;H();y.onChange=B.onChange=()=>{if(z)H();else V=true};function H(){if(j===U)vec3.set(a,y.get(),B.get(),1);if(j===k)vec3.set(a,y.get(),1,B.get())}N.onLinkChanged=()=>{z=!N.isLinked();H();V=true};function s(){V=true}n.onTriggered=()=>{if(V)o();const e=t.patch.cg;if(e&&G&&r.get()){if(z){e.pushModelMatrix();mat4.scale(e.mMatrix,e.mMatrix,a)}G.render(e.getShader());if(z)e.popModelMatrix()}i.trigger()};t.onDelete=function(){if(G)G.dispose()};function o(){if(I.get()=="xy")j=U;if(I.get()=="xz")j=k;H();let n=y.get();let r=B.get();if(z)n=r=1;let i=0;let a=0;if(O.get()=="center")i=0;else if(O.get()=="right")i=-n/2;else if(O.get()=="left")i=+n/2;if(D.get()=="center")a=0;else if(D.get()=="top")a=-r/2;else if(D.get()=="bottom")a=+r/2;const s=Math.max(1,Math.round(w.get()));const o=Math.max(1,Math.round(R.get()));const l=n/o;const u=r/s;const c=[];const h=new Float32Array((o+1)*(s+1)*2);const f=new Float32Array((o+1)*(s+1)*3);const d=new Float32Array((o+1)*(s+1)*3);const p=new Float32Array((o+1)*(s+1)*3);const g=new Float32Array((o+1)*(s+1)*3);let m=0;let v=0;let b=0;let _=0;let E=0;for(let t=0;t<=s;t++){for(let e=0;e<=o;e++){f[v++]=e*l-n/2+i;if(j==k)f[v++]=0;f[v++]=t*u-r/2+a;if(j==U)f[v++]=0;h[m++]=e/o;h[m++]=t/s;if(j==U){d[b++]=0;d[b++]=0;d[b++]=1;p[_++]=1;p[_++]=0;p[_++]=0;g[E++]=0;g[E++]=1;g[E++]=0}else if(j==k){d[b++]=0;d[b++]=1;d[b++]=0;g[E++]=0;g[E++]=0;g[E++]=1}}}c.length=o*s*6;let F=0;for(let t=0;t<o;t++){for(let e=0;e<s;e++){const C=t+(o+1)*e;const A=C;const x=C+1;const T=C+o+1;const S=C+1+o+1;if(j==U){c[F++]=A;c[F++]=x;c[F++]=T;c[F++]=T;c[F++]=x;c[F++]=S}else if(j==k){c[F++]=A;c[F++]=T;c[F++]=x;c[F++]=x;c[F++]=T;c[F++]=S}}}if(L.get())for(let e=0;e<h.length;e+=2)h[e+1]=1-h[e+1];if(M.get())for(let e=0;e<h.length;e+=2)h[e]=1-h[e];P.clear();P.vertices=f;P.texCoords=h;P.verticesIndices=c;P.vertexNormals=d;P.tangents=p;P.biTangents=g;if(t.patch.cg)if(!G)G=t.patch.cg.createMesh(P,{opId:t.id});else G.setGeom(P);N.setRef(P);V=false}}};CABLES.OPS["cc8c3ede-7103-410b-849f-a645793cab39"]={f:Ops.Graphics.Meshes.Rectangle_v4,objName:"Ops.Graphics.Meshes.Rectangle_v4"};Ops.Gl.Shader.BasicMaterial_v3=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={basicmaterial_frag:"{{MODULES_HEAD}}\n\nIN vec2 texCoord;\n\n#ifdef VERTEX_COLORS\nIN vec4 vertCol;\n#endif\n\n#ifdef HAS_TEXTURES\n    IN vec2 texCoordOrig;\n    #ifdef HAS_TEXTURE_DIFFUSE\n        UNI sampler2D tex;\n    #endif\n    #ifdef HAS_TEXTURE_OPACITY\n        UNI sampler2D texOpacity;\n   #endif\n#endif\n\n\n\nvoid main()\n{\n    {{MODULE_BEGIN_FRAG}}\n    vec4 col=color;\n\n\n    #ifdef HAS_TEXTURES\n        vec2 uv=texCoord;\n\n        #ifdef CROP_TEXCOORDS\n            if(uv.x<0.0 || uv.x>1.0 || uv.y<0.0 || uv.y>1.0) discard;\n        #endif\n\n        #ifdef HAS_TEXTURE_DIFFUSE\n            col=texture(tex,uv);\n\n            #ifdef COLORIZE_TEXTURE\n                col.r*=color.r;\n                col.g*=color.g;\n                col.b*=color.b;\n            #endif\n        #endif\n        col.a*=color.a;\n        #ifdef HAS_TEXTURE_OPACITY\n            #ifdef TRANSFORMALPHATEXCOORDS\n                uv=texCoordOrig;\n            #endif\n            #ifdef ALPHA_MASK_IR\n                col.a*=1.0-texture(texOpacity,uv).r;\n            #endif\n            #ifdef ALPHA_MASK_IALPHA\n                col.a*=1.0-texture(texOpacity,uv).a;\n            #endif\n            #ifdef ALPHA_MASK_ALPHA\n                col.a*=texture(texOpacity,uv).a;\n            #endif\n            #ifdef ALPHA_MASK_LUMI\n                col.a*=dot(vec3(0.2126,0.7152,0.0722), texture(texOpacity,uv).rgb);\n            #endif\n            #ifdef ALPHA_MASK_R\n                col.a*=texture(texOpacity,uv).r;\n            #endif\n            #ifdef ALPHA_MASK_G\n                col.a*=texture(texOpacity,uv).g;\n            #endif\n            #ifdef ALPHA_MASK_B\n                col.a*=texture(texOpacity,uv).b;\n            #endif\n            // #endif\n        #endif\n    #endif\n\n    {{MODULE_COLOR}}\n\n    #ifdef DISCARDTRANS\n        if(col.a<0.2) discard;\n    #endif\n\n    #ifdef VERTEX_COLORS\n        col*=vertCol;\n    #endif\n\n    outColor = col;\n}\n",basicmaterial_vert:"\n{{MODULES_HEAD}}\n\nOUT vec2 texCoord;\nOUT vec2 texCoordOrig;\n\nUNI mat4 projMatrix;\nUNI mat4 modelMatrix;\nUNI mat4 viewMatrix;\n\n#ifdef HAS_TEXTURES\n    UNI float diffuseRepeatX;\n    UNI float diffuseRepeatY;\n    UNI float texOffsetX;\n    UNI float texOffsetY;\n#endif\n\n#ifdef VERTEX_COLORS\n    in vec4 attrVertColor;\n    out vec4 vertCol;\n\n#endif\n\n\nvoid main()\n{\n    mat4 mMatrix=modelMatrix;\n    mat4 modelViewMatrix;\n\n    norm=attrVertNormal;\n    texCoordOrig=attrTexCoord;\n    texCoord=attrTexCoord;\n    #ifdef HAS_TEXTURES\n        texCoord.x=texCoord.x*diffuseRepeatX+texOffsetX;\n        texCoord.y=(1.0-texCoord.y)*diffuseRepeatY+texOffsetY;\n    #endif\n\n    #ifdef VERTEX_COLORS\n        vertCol=attrVertColor;\n    #endif\n\n    vec4 pos = vec4(vPosition, 1.0);\n\n    #ifdef BILLBOARD\n       vec3 position=vPosition;\n       modelViewMatrix=viewMatrix*modelMatrix;\n\n       gl_Position = projMatrix * modelViewMatrix * vec4((\n           position.x * vec3(\n               modelViewMatrix[0][0],\n               modelViewMatrix[1][0],\n               modelViewMatrix[2][0] ) +\n           position.y * vec3(\n               modelViewMatrix[0][1],\n               modelViewMatrix[1][1],\n               modelViewMatrix[2][1]) ), 1.0);\n    #endif\n\n    {{MODULE_VERTEX_POSITION}}\n\n    #ifndef BILLBOARD\n        modelViewMatrix=viewMatrix * mMatrix;\n\n        {{MODULE_VERTEX_MODELVIEW}}\n\n    #endif\n\n    // mat4 modelViewMatrix=viewMatrix*mMatrix;\n\n    #ifndef BILLBOARD\n        // gl_Position = projMatrix * viewMatrix * modelMatrix * pos;\n        gl_Position = projMatrix * modelViewMatrix * pos;\n    #endif\n}\n"};const n=e.inTrigger("render");const r=e.outTrigger("trigger");const i=e.outObject("shader",null,"shader");i.ignoreValueSerialize=true;e.toWorkPortsNeedToBeLinked(n);e.toWorkShouldNotBeChild("Ops.Gl.TextureEffects.ImageCompose",CABLES.OP_PORT_TYPE_FUNCTION);const a=e.patch.cgl;const s=new CGL.Shader(a,"basicmaterial",this);s.addAttribute({type:"vec3",name:"vPosition"});s.addAttribute({type:"vec2",name:"attrTexCoord"});s.addAttribute({type:"vec3",name:"attrVertNormal",nameFrag:"norm"});s.addAttribute({type:"float",name:"attrVertIndex"});s.setModules(["MODULE_VERTEX_POSITION","MODULE_COLOR","MODULE_BEGIN_FRAG","MODULE_VERTEX_MODELVIEW"]);s.setSource(t.basicmaterial_vert,t.basicmaterial_frag);i.setRef(s);n.onTriggered=y;const o=e.inValueSlider("r",Math.random());const l=e.inValueSlider("g",Math.random());const u=e.inValueSlider("b",Math.random());const c=e.inValueSlider("a",1);o.setUiAttribs({colorPick:true});const h=s.addUniformFrag("4f","color",o,l,u,c);s.uniformColorDiffuse=h;const f=e.inTexture("texture");let d=null;f.onChange=O;const p=e.inValueBool("colorizeTexture",false);const g=e.inValueBool("Vertex Colors",false);const m=e.inTexture("textureOpacity");let v=null;const b=e.inSwitch("Alpha Mask Source",["Luminance","R","G","B","A","1-A","1-R"],"Luminance");b.setUiAttribs({greyout:true});m.onChange=B;const _=e.inValueBool("Opacity TexCoords Transform",false);const E=e.inValueBool("Discard Transparent Pixels");const F=e.inValue("diffuseRepeatX",1),C=e.inValue("diffuseRepeatY",1),A=e.inValue("Tex Offset X",0),x=e.inValue("Tex Offset Y",0),T=e.inBool("Crop TexCoords",false);s.addUniformFrag("f","diffuseRepeatX",F);s.addUniformFrag("f","diffuseRepeatY",C);s.addUniformFrag("f","texOffsetX",A);s.addUniformFrag("f","texOffsetY",x);const S=e.inValueBool("billboard",false);b.onChange=S.onChange=E.onChange=_.onChange=T.onChange=g.onChange=p.onChange=I;e.setPortGroup("Color",[o,l,u,c]);e.setPortGroup("Color Texture",[f,g,p]);e.setPortGroup("Opacity",[m,b,E,_]);e.setPortGroup("Texture Transform",[F,C,A,x,T]);B();O();e.preRender=function(){s.bind();y();if(!s)return};function y(){e.checkGraphicsApi();a.pushShader(s);s.popTextures();if(d&&f.get())s.pushTexture(d,f.get());if(v&&m.get())s.pushTexture(v,m.get());r.trigger();a.popShader()}function B(){if(m.get()){if(v!==null)return;s.removeUniform("texOpacity");s.define("HAS_TEXTURE_OPACITY");if(!v)v=new CGL.Uniform(s,"t","texOpacity")}else{s.removeUniform("texOpacity");s.removeDefine("HAS_TEXTURE_OPACITY");v=null}I()}function O(){if(f.get()){if(!s.hasDefine("HAS_TEXTURE_DIFFUSE"))s.define("HAS_TEXTURE_DIFFUSE");if(!d)d=new CGL.Uniform(s,"t","texDiffuse")}else{s.removeUniform("texDiffuse");s.removeDefine("HAS_TEXTURE_DIFFUSE");d=null}D()}function D(){const e=f.isLinked()||m.isLinked();F.setUiAttribs({greyout:!e});C.setUiAttribs({greyout:!e});A.setUiAttribs({greyout:!e});x.setUiAttribs({greyout:!e});p.setUiAttribs({greyout:!e});b.setUiAttribs({greyout:!m.get()});_.setUiAttribs({greyout:!m.get()});let t=true;t=f.get()&&!p.get();o.setUiAttribs({greyout:t});l.setUiAttribs({greyout:t});u.setUiAttribs({greyout:t})}function I(){s.toggleDefine("VERTEX_COLORS",g.get());s.toggleDefine("CROP_TEXCOORDS",T.get());s.toggleDefine("COLORIZE_TEXTURE",p.get());s.toggleDefine("TRANSFORMALPHATEXCOORDS",_.get());s.toggleDefine("DISCARDTRANS",E.get());s.toggleDefine("BILLBOARD",S.get());s.toggleDefine("ALPHA_MASK_ALPHA",b.get()=="A");s.toggleDefine("ALPHA_MASK_IALPHA",b.get()=="1-A");s.toggleDefine("ALPHA_MASK_IR",b.get()=="1-R");s.toggleDefine("ALPHA_MASK_LUMI",b.get()=="Luminance");s.toggleDefine("ALPHA_MASK_R",b.get()=="R");s.toggleDefine("ALPHA_MASK_G",b.get()=="G");s.toggleDefine("ALPHA_MASK_B",b.get()=="B");D()}}};CABLES.OPS["ec55d252-3843-41b1-b731-0482dbd9e72b"]={f:Ops.Gl.Shader.BasicMaterial_v3,objName:"Ops.Gl.Shader.BasicMaterial_v3"};Ops.Extension.OpenType.OpentypeFont=class extends CABLES.Op{constructor(){super(...arguments);const n=this;const e=n.attachments={};const r=n.inUrl("Font File",[".otf",".ttf",".woff",".woff2"]),i=n.outObject("Opentype Font",null,"opentype");r.onChange=async function(){const e=n.patch.getFilePath(String(r.get()));n.setUiError("exc",null);try{const t=await opentype.load(e);i.set(t)}catch(e){console.log(e);let t=e.toString();t=t.replaceAll("<","&lt;");t=t.replaceAll(">","&gt;");n.setUiError("exc","opentype error "+t)}}}};CABLES.OPS["f85574bb-3869-4a14-8dcc-70414bd8cfcd"]={f:Ops.Extension.OpenType.OpentypeFont,objName:"Ops.Extension.OpenType.OpentypeFont"};Ops.Extension.OpenType.OpentypeToSvgPath=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const a=e.inObject("Opentype Font"),s=e.inString("Text","cables"),o=e.inFloat("Letter Spacing",0),l=e.outString("Path String");s.onChange=o.onChange=a.onChange=async function(){const e=a.get();if(!e||!e.getPath){l.set("");return}const n=e.getPaths(s.get(),0,0,72);let r="";let i=o.get();for(let t=0;t<n.length;t++){for(let e=0;e<n[t].commands.length;e++){if(n[t].commands[e].hasOwnProperty("x"))n[t].commands[e].x+=t*i;if(n[t].commands[e].hasOwnProperty("x1"))n[t].commands[e].x1+=t*i}r+=n[t].toPathData()}l.set(r)}}};CABLES.OPS["4d901c72-b8dc-45dc-ac2e-608e5da40677"]={f:Ops.Extension.OpenType.OpentypeToSvgPath,objName:"Ops.Extension.OpenType.OpentypeToSvgPath"};Ops.Graphics.Geometry.GeometryExtrude=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const h=e.inObject("Geometry",null,"geometry"),f=e.inFloat("Height",.5),d=e.inBool("Smooth",true),p=e.inBool("Walls",true),g=e.inBool("Top",true),m=e.inBool("Bottom",true),v=e.outObject("Result Geometry",null,"geometry");function b(t){let n=0;for(let e=0;e<t.length-3;e+=3){n+=(t[e+3]-t[e])*(t[e+3+1]+t[e])}return n>0}d.onChange=p.onChange=g.onChange=m.onChange=f.onChange=h.onChange=()=>{const i=h.get();if(!i){v.set(null);return}function t(t,n){let r=0;for(let e=0;e<i.verticesIndices.length;e+=3){if((i.verticesIndices[e]==t||i.verticesIndices[e+1]==t||i.verticesIndices[e+2]==t)&&(i.verticesIndices[e]==n||i.verticesIndices[e+1]==n||i.verticesIndices[e+2]==n)){r++;if(r==2)return true}}return false}let n=[];const e=[];const r=f.get();if(p.get())for(let e=0;e<i.verticesIndices.length;e+=3){const s=i.verticesIndices[e];const o=i.verticesIndices[e+1];const l=i.verticesIndices[e+2];if(!t(s,o)){const u=[];u.push([i.vertices[s*3+0],i.vertices[s*3+1],i.vertices[s*3+2]]);u.push([i.vertices[s*3+0],i.vertices[s*3+1],i.vertices[s*3+2]+r]);u.push([i.vertices[o*3+0],i.vertices[o*3+1],i.vertices[o*3+2]]);if(!b(u))n=n.concat(u);else n=n.concat(u.reverse());u.length=0;u.push([i.vertices[o*3+0],i.vertices[o*3+1],i.vertices[o*3+2]+r]);u.push([i.vertices[o*3+0],i.vertices[o*3+1],i.vertices[o*3+2]]);u.push([i.vertices[s*3+0],i.vertices[s*3+1],i.vertices[s*3+2]+r]);if(!b(u))n=n.concat(u);else n=n.concat(u.reverse())}if(!t(l,o)){const u=[];u.push([i.vertices[l*3+0],i.vertices[l*3+1],i.vertices[l*3+2]]);u.push([i.vertices[l*3+0],i.vertices[l*3+1],i.vertices[l*3+2]+r]);u.push([i.vertices[o*3+0],i.vertices[o*3+1],i.vertices[o*3+2]]);if(b(u))n=n.concat(u);else n=n.concat(u.reverse());u.length=0;u.push([i.vertices[o*3+0],i.vertices[o*3+1],i.vertices[o*3+2]+r]);u.push([i.vertices[o*3+0],i.vertices[o*3+1],i.vertices[o*3+2]]);u.push([i.vertices[l*3+0],i.vertices[l*3+1],i.vertices[l*3+2]+r]);if(b(u))n=n.concat(u);else n=n.concat(u.reverse())}if(!t(l,s)){const u=[];u.push([i.vertices[l*3+0],i.vertices[l*3+1],i.vertices[l*3+2]]);u.push([i.vertices[l*3+0],i.vertices[l*3+1],i.vertices[l*3+2]+r]);u.push([i.vertices[s*3+0],i.vertices[s*3+1],i.vertices[s*3+2]]);if(!b(u))n=n.concat(u);else n=n.concat(u.reverse());u.length=0;u.push([i.vertices[s*3+0],i.vertices[s*3+1],i.vertices[s*3+2]+r]);u.push([i.vertices[s*3+0],i.vertices[s*3+1],i.vertices[s*3+2]]);u.push([i.vertices[l*3+0],i.vertices[l*3+1],i.vertices[l*3+2]+r]);if(!b(u))n=n.concat(u);else n=n.concat(u.reverse())}}const a=CGL.Geometry.buildFromFaces(n,"extrude",true);a.calculateNormals();a.calcTangentsBitangents();if(m.get()){a.merge(i)}if(g.get()){const c=i.copy();for(let e=0;e<c.vertices.length;e+=3)c.vertices[e+2]+=r;c.flipVertDir();c.flipNormals();a.merge(c)}a.flipVertDir();if(!d.get()){a.unIndex();a.calculateNormals({forceZUp:true});a.flipNormals()}v.set(null);v.set(a)}}};CABLES.OPS["64a34a29-000d-4350-875f-5b72b97a314f"]={f:Ops.Graphics.Geometry.GeometryExtrude,objName:"Ops.Graphics.Geometry.GeometryExtrude"};Ops.Graphics.Geometry.SvgPathToGeometry_v2=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const p=e.inString("SVG Path"),n=e.inFloat("Bezier Stepsize",3),g=e.inFloat("Rescale",1),m=e.outObject("Geometry",null,"geometry");n.onChange=g.onChange=p.onChange=()=>{let e=p.get();if(!e||e.length<2){m.set(null);return}e=e.replace(/([A-Z,a-z])/g," $1 ");const t=v(e);const o=[];t.forEach(({type:e,x:t,y:n,x1:r,y1:i,x2:a,y2:s})=>{switch(e){case"M":o.push(new b);o[o.length-1].moveTo({x:t,y:n});break;case"L":o[o.length-1].moveTo({x:t,y:n});break;case"C":o[o.length-1].cubicTo({x:t,y:n},{x:r,y:i},{x:a,y:s});break;case"Q":o[o.length-1].conicTo({x:t,y:n},{x:r,y:i});break;case"Z":o[o.length-1].close();break}});o.sort((e,t)=>{return Math.abs(t.area)-Math.abs(e.area)});const r=[];for(let n=0;n<o.length;++n){let t=null;for(let e=n-1;e>=0;--e){if(o[e].inside(o[n].points[0])&&o[n].area*o[e].area<0){t=o[e];break}}if(t){t.children.push(o[n])}else{r.push(o[n])}}const n=o.reduce((e,t)=>{return e+t.points.length},0);const i=new Float32Array(n*2);let a=0;const s=[];function l(e){const n=[];const t=[];e.points.forEach(({x:e,y:t})=>{return n.push(e,t)});e.children.forEach(e=>{e.children.forEach(l);t.push(n.length/2);e.points.forEach(({x:e,y:t})=>{return n.push(e,t)})});i.set(n,a*2);earcut(n,t).forEach(e=>{return s.push(e+a)});a+=n.length/2}r.forEach(l);const u=new Float32Array(n*3);let c=-99999;for(let e=0;e<u.length/3;e++){u[e*3+0]=i[e*2+0];u[e*3+1]=i[e*2+1]*-1;c=Math.max(u[e*3+1],c);u[e*3+2]=0}let h=g.get();let f=new CGL.Geometry("circle");f.setVertices(u);f.verticesIndices=s;if(h!=0){const d=f.getBounds();for(let e=0;e<u.length/3;e++){u[e*3+0]=u[e*3+0]/(d.size[0]/2)*h;u[e*3+1]=u[e*3+1]/(d.size[0]/2)*h}f.setVertices(u)}f.mapTexCoords2d();f.flipVertDir();f.calculateNormals();f.calcTangentsBitangents();m.set(f)};const s={M:["x","y"],m:["dx","dy"],H:["x"],h:["dx"],V:["y"],v:["dy"],L:["x","y"],l:["dx","dy"],Z:[],C:["x1","y1","x2","y2","x","y"],c:["dx1","dy1","dx2","dy2","dx","dy"],S:["x2","y2","x","y"],s:["dx2","dy2","dx","dy"],Q:["x1","y1","x","y"],q:["dx1","dy1","dx","dy"],T:["x","y"],t:["dx","dy"],A:["rx","ry","rotation","large-arc","sweep","x","y"],a:["rx","ry","rotation","large-arc","sweep","dx","dy"]};function v(e){const n=e.replace(/[\n\r]/g,"").replace(/-/g," -").replace(/(\d*\.)(\d+)(?=\.)/g,"$1$2 ").trim().split(/\s*,|\s+/);const r=[];let i="";let a={};while(n.length>0){let t=n.shift();if(s.hasOwnProperty(t)){i=t}else{n.unshift(t)}a={type:i};s[i].forEach(e=>{t=n.shift();a[e]=parseFloat(t)});if(i==="M"){i="L"}else if(i==="m"){i="l"}r.push(a)}return r}const u=15;const o=1e-6;class b{constructor(){this.points=[];this.children=[];this.area=0;this.BEZIER_STEP_SIZE=n.get()}moveTo(e){this.points.push(e)}lineTo(e){this.points.push(e)}close(){let t=this.points[this.points.length-1];this.points.forEach(e=>{this.area+=.5*r(t,e);t=e})}conicTo(t,n){const r=this.points[this.points.length-1];const e=c(r,n)+c(n,t);const i=Math.max(2,Math.min(u,e/this.BEZIER_STEP_SIZE));for(let e=1;e<=i;++e){const a=e/i;this.points.push(h(h(r,n,a),h(n,t,a),a))}}cubicTo(t,n,r){const i=this.points[this.points.length-1];const e=c(i,n)+c(n,r)+c(r,t);const a=Math.max(2,Math.min(u,e/this.BEZIER_STEP_SIZE));for(let e=1;e<=a;++e){const s=e/a;const o=h(h(i,n,s),h(n,r,s),s);const l=h(h(n,r,s),h(r,t,s),s);this.points.push(h(o,l,s))}}inside(r){let i=0,a=this.points[this.points.length-1];this.points.forEach(e=>{const t=a.y<e.y?a:e;const n=a.y<e.y?e:a;if(t.y<r.y+o&&n.y>r.y+o){if((n.x-t.x)*(r.y-t.y)>(r.x-t.x)*(n.y-t.y)){i+=1}}a=e});return i%2!==0}}function c(e,t){const n=e.x-t.x,r=e.y-t.y;return Math.sqrt(n*n+r*r)}function h(e,t,n){return{x:(1-n)*e.x+n*t.x,y:(1-n)*e.y+n*t.y}}function r(e,t){return e.x*t.y-e.y*t.x}}};CABLES.OPS["4267b3e7-1285-4a3e-acc8-ea92a72a6bc0"]={f:Ops.Graphics.Geometry.SvgPathToGeometry_v2,objName:"Ops.Graphics.Geometry.SvgPathToGeometry_v2"};Ops.Gl.RenderGeometry=class extends CABLES.Op{constructor(){super(...arguments);const t=this;const e=t.attachments={};const n=t.inTrigger("render"),r=t.inObject("Geometry",null,"geometry"),i=t.inValueBool("Update All",true),a=t.inValueBool("Update Face Indices",false),s=t.inValueBool("Update Vertices",false),o=t.inValueBool("Update Texcoords",false),l=t.inValueBool("Vertex Numbers",true),u=t.outTrigger("trigger");r.ignoreValueSerialize=true;l.onChange=r.onChange=h;let c=null;t.toWorkPortsNeedToBeLinked(r,n);n.onTriggered=function(){if(c)c.render(t.patch.cgl.getShader());u.trigger()};function h(){const e=r.get();if(e&&e instanceof CGL.Geometry){if(c){c.dispose();c=null}if(!c){c=new CGL.Mesh(t.patch.cgl,e);c.addVertexNumbers=l.get();c.setGeom(e)}if(a.get()||i.get())c.setVertexIndices(e.verticesIndices);if(o.get()||i.get())c.updateTexCoords(e);if(s.get()||i.get())c.updateVertices(e);c.addVertexNumbers=l.get();if(i.get()){if(e.hasOwnProperty("tangents")&&e.tangents&&e.tangents.length>0)c.setAttribute("attrTangent",e.tangents,3);if(e.hasOwnProperty("biTangents")&&e.biTangents&&e.biTangents.length>0)c.setAttribute("attrBiTangent",e.biTangents,3)}}else{c=null}}}};CABLES.OPS["40fa6f13-ee0e-4386-a86b-711e1fbcf1bc"]={f:Ops.Gl.RenderGeometry,objName:"Ops.Gl.RenderGeometry"};Ops.Gl.Shader.MatCapMaterial_v3=class extends CABLES.Op{constructor(){super(...arguments);const t=this;const e=t.attachments={matcap_frag:"{{MODULES_HEAD}}\n\n#ifdef HAS_TEXTURES\n    IN vec2 texCoord;\n#endif\n\nIN vec3 transformedNormal;\nIN vec3 viewSpacePosition;\n\nUNI vec4 inColor;\n\nUNI sampler2D texMatcap;\n\n#ifdef HAS_DIFFUSE_TEXTURE\n   UNI sampler2D texDiffuse;\n#endif\n\n#ifdef USE_SPECULAR_TEXTURE\n   UNI sampler2D texSpec;\n   UNI sampler2D texSpecMatCap;\n#endif\n\n#ifdef HAS_AO_TEXTURE\n    UNI sampler2D texAo;\n    UNI float aoIntensity;\n#endif\n\n#ifdef HAS_NORMAL_TEXTURE\n    IN vec3 vBiTangent;\n    IN vec3 vTangent;\n    IN mat3 normalMatrix;\n\n    UNI sampler2D texNormal;\n    UNI float normalMapIntensity;\n#endif\n\n#ifdef HAS_TEXTURE_OPACITY\n    UNI sampler2D texOpacity;\n#endif\n\n#ifdef CALC_SSNORMALS\n    IN vec3 eye_relative_pos;\n\n    // from https://www.enkisoftware.com/devlogpost-20150131-1-Normal_generation_in_the_pixel_shader\n    vec3 CalculateScreenSpaceNormals() {\n    \tvec3 dFdxPos = dFdx(eye_relative_pos);\n    \tvec3 dFdyPos = dFdy(eye_relative_pos);\n    \tvec3 screenSpaceNormal = normalize( cross(dFdxPos, dFdyPos));\n        return normalize(screenSpaceNormal);\n    }\n#endif\n\n// * taken & modified from https://github.com/mrdoob/three.js/blob/dev/src/renderers/shaders/ShaderLib/meshmatcap_frag.glsl.js\nvec2 getMatCapUV(vec3 viewSpacePosition, vec3 normal) {\n    vec3 viewDir = normalize(-viewSpacePosition);\n\tvec3 x = normalize(vec3(viewDir.z, 0.0, - viewDir.x));\n\tvec3 y = normalize(cross(viewDir, x));\n\tvec2 uv = vec2(dot(x, normal), dot(y, normal)) * 0.495 + 0.5; // 0.495 to remove artifacts caused by undersized matcap disks\n\treturn uv;\n}\n\nvoid main()\n{\n    vec3 normal = normalize(transformedNormal);\n    {{MODULE_NORMAL}}\n\n\n\n    #ifdef HAS_TEXTURES\n        vec2 texCoords = texCoord;\n        {{MODULE_BEGIN_FRAG}}\n    #endif\n\n\n\n    #ifdef DOUBLE_SIDED\n        if(!gl_FrontFacing) normal *= -1.0;\n    #endif\n\n    #ifdef CALC_SSNORMALS\n        normal = CalculateScreenSpaceNormals();\n    #endif\n\n\n\n   #ifdef HAS_NORMAL_TEXTURE\n        vec3 normalFromMap = texture( texNormal, texCoord ).xyz * 2.0 - 1.0;\n        normalFromMap = normalize(normalFromMap);\n\n        vec3 tangent;\n        vec3 binormal;\n\n        #ifdef CALC_TANGENT\n            vec3 c1 = cross(normalFromMap, vec3(0.0, 0.0, 1.0));\n            vec3 c2 = cross(normalFromMap, vec3(0.0, 1.0, 0.0));\n\n            tangent = c1;\n            tangent = normalize(tangent);\n            binormal = cross(normal, tangent);\n            binormal = normalize(binormal);\n        #endif\n\n        #ifndef CALC_TANGENT\n            tangent = normalize(normalMatrix * vTangent);\n            vec3 bitangent = normalize(normalMatrix * vBiTangent);\n            binormal = normalize(cross(normal, bitangent));\n        #endif\n\n        normalFromMap = normalize(\n            tangent * normalFromMap.x\n            + binormal * normalFromMap.y\n            + normal * normalFromMap.z\n        );\n\n        vec3 mixedNormal = normalize(normal + normalFromMap * normalMapIntensity);\n\n        normal = mixedNormal;\n    #endif\n\n    vec4 col = texture(texMatcap, getMatCapUV(viewSpacePosition, normal));\n\n    #ifdef HAS_DIFFUSE_TEXTURE\n        col = col*texture(texDiffuse, texCoords);\n    #endif\n\n    col.rgb *= inColor.rgb;\n\n\n    #ifdef HAS_AO_TEXTURE\n        col = col\n            * mix(\n                vec4(1.0,1.0,1.0,1.0),\n                texture(texAo, texCoords),\n                aoIntensity\n            );\n    #endif\n\n    #ifdef USE_SPECULAR_TEXTURE\n        vec4 spec = texture(texSpecMatCap, getMatCapUV(viewSpacePosition, normal));\n        spec *= texture(texSpec, texCoords);\n        col += spec;\n    #endif\n\n    col.a *= inColor.a;\n\n    #ifdef HAS_TEXTURE_OPACITY\n        #ifdef TRANSFORMALPHATEXCOORDS\n            texCoords=vec2(texCoord.s,1.0-texCoord.t);\n            texCoords.y = 1. - texCoords.y;\n        #endif\n        #ifdef ALPHA_MASK_ALPHA\n            col.a*=texture(texOpacity,texCoords).a;\n        #endif\n        #ifdef ALPHA_MASK_LUMI\n            col.a*=dot(vec3(0.2126,0.7152,0.0722), texture(texOpacity,texCoords).rgb);\n        #endif\n        #ifdef ALPHA_MASK_R\n            col.a*=texture(texOpacity,texCoords).r;\n        #endif\n        #ifdef ALPHA_MASK_G\n            col.a*=texture(texOpacity,texCoords).g;\n        #endif\n        #ifdef ALPHA_MASK_B\n            col.a*=texture(texOpacity,texCoords).b;\n        #endif\n\n        #ifdef DISCARDTRANS\n            if(col.a < 0.2) discard;\n        #endif\n    #endif\n\n    {{MODULE_COLOR}}\n\n    outColor = col;\n}",matcap_vert:"IN vec3 vPosition;\n\n#ifdef HAS_TEXTURES\n    IN vec2 attrTexCoord;\n#endif\n\nIN vec3 attrVertNormal;\nIN float attrVertIndex;\n\n#ifdef HAS_NORMAL_TEXTURE\n    IN vec3 attrTangent;\n    IN vec3 attrBiTangent;\n    OUT vec3 vBiTangent;\n    OUT vec3 vTangent;\n#endif\n\nUNI mat4 projMatrix;\nUNI mat4 modelMatrix;\nUNI mat4 viewMatrix;\nUNI vec3 camPos;\n\n#ifdef HAS_TEXTURES\n    UNI vec2 texOffset;\n    UNI vec2 texRepeat;\n    OUT vec2 texCoord;\n#endif\n\nOUT mat3 normalMatrix;\nOUT vec3 viewSpacePosition;\nOUT vec3 transformedNormal;\n\n{{MODULES_HEAD}}\n\n#ifdef CALC_SSNORMALS\n    // from https://www.enkisoftware.com/devlogpost-20150131-1-Normal_generation_in_the_pixel_shader\n    OUT vec3 eye_relative_pos;\n#endif\n\nmat3 transposeMat3(mat3 m) {\n    return mat3(m[0][0], m[1][0], m[2][0],\n        m[0][1], m[1][1], m[2][1],\n        m[0][2], m[1][2], m[2][2]);\n}\n\n mat3 inverseMat3(mat3 m) {\n    float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];\n    float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];\n    float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];\n\n    float b01 = a22 * a11 - a12 * a21;\n    float b11 = -a22 * a10 + a12 * a20;\n    float b21 = a21 * a10 - a11 * a20;\n\n    float det = a00 * b01 + a01 * b11 + a02 * b21;\n\n    return mat3(b01, (-a22 * a01 + a02 * a21), (a12 * a01 - a02 * a11),\n        b11, (a22 * a00 - a02 * a20), (-a12 * a00 + a02 * a10),\n        b21, (-a21 * a00 + a01 * a20), (a11 * a00 - a01 * a10)) / det;\n}\n\nvoid main()\n{\n    #ifdef HAS_TEXTURES\n        texCoord = texRepeat * vec2(attrTexCoord.x, attrTexCoord.y) + texOffset;\n        texCoord.y = 1. - texCoord.y;\n    #endif\n\n    mat4 mMatrix = modelMatrix;\n    mat4 mvMatrix;\n\n    #ifdef HAS_NORMAL_TEXTURE\n        vec3 tangent = attrTangent;\n        vec3 bitangent = attrBiTangent;\n        vTangent = attrTangent;\n        vBiTangent = attrBiTangent;\n    #endif\n\n    vec4 pos = vec4(vPosition, 1.);\n    vec3 norm = attrVertNormal;\n\n    {{MODULE_VERTEX_POSITION}}\n\n    mvMatrix = viewMatrix * mMatrix;\n    vec3 normal = norm;\n\n    normalMatrix = transposeMat3(inverseMat3(mat3(mvMatrix)));\n\n    vec3 fragPos = vec3((mvMatrix) * pos);\n    viewSpacePosition = normalize(fragPos);\n\n    #ifdef CALC_SSNORMALS\n        eye_relative_pos = -(vec3(viewMatrix * vec4(camPos, 1.)) - fragPos);\n    #endif\n\n    transformedNormal = normalize(mat3(normalMatrix) * normal);\n\n    mat4 modelViewMatrix=mvMatrix;\n    {{MODULE_VERTEX_MODELVIEW}}\n\n    gl_Position = projMatrix * modelViewMatrix * pos;\n\n}\n"};const n=t.patch.cgl;const N=t.inTrigger("Render"),r=t.inTexture("MatCap"),i=t.inTexture("Diffuse"),a=t.inTexture("Normal"),s=t.inTexture("Specular Mask"),o=t.inTexture("Specular MatCap"),l=t.inTexture("AO Texture"),u=t.inTexture("Opacity Texture"),c=t.inValueSlider("r",1),h=t.inValueSlider("g",1),f=t.inValueSlider("b",1),d=t.inValueSlider("Opacity",1),p=t.inValueSlider("AO Intensity",1),g=t.inFloatSlider("Normal Map Intensity",1),m=t.inValue("Repeat X",1),v=t.inValue("Repeat Y",1),b=t.inValue("Offset X",0),_=t.inValue("Offset Y",0),E=t.inValueBool("Double Sided"),F=t.inValueBool("Screen Space Normals"),C=t.inValueBool("Calc normal tangents",true),A=t.inValueBool("Opacity TexCoords Transform",false),x=t.inValueBool("Discard Transparent Pixels"),P=t.outTrigger("Next"),U=t.outObject("Shader");c.setUiAttribs({colorPick:true});const T=t.inSwitch("Alpha Mask Source",["Luminance","R","G","B","A"],"Luminance");T.setUiAttribs({greyout:true});t.setPortGroup("Normals",[C,F,E]);t.setPortGroup("Texture Opacity",[T,A,x]);t.setPortGroup("Texture Transforms",[p,g,m,v,b,_]);t.setPortGroup("Texture Maps",[i,a,s,o,l,u]);t.setPortGroup("Color",[c,h,f,d]);const S=new CGL.Shader(n,"MatCapMaterialNew3");const k=new CGL.Uniform(S,"f","opacity",d);S.setModules(["MODULE_VERTEX_POSITION","MODULE_COLOR","MODULE_NORMAL","MODULE_BEGIN_FRAG","MODULE_VERTEX_MODELVIEW"]);S.setSource(e.matcap_vert,e.matcap_frag);U.setRef(S);const j=new CGL.Uniform(S,"t","texMatcap");let y=null;let B=null;let O=null;let D=null;let I=null;let M=null;const G=new CGL.Uniform(S,"2f","texOffset",b,_);const V=new CGL.Uniform(S,"2f","texRepeat",m,v);const z=new CGL.Uniform(S,"f","aoIntensity",p);const H=new CGL.Uniform(S,"4f","inColor",c,h,f,d);E.onChange=C.onChange=L;L();function L(){S.toggleDefine("DOUBLE_SIDED",E.get());if(C.get())S.define("CALC_TANGENT");else S.removeDefine("CALC_TANGENT")}F.onChange=function(){if(F.get()){if(n.glVersion<2){n.gl.getExtension("OES_standard_derivatives");S.enableExtension("GL_OES_standard_derivatives")}S.define("CALC_SSNORMALS")}else S.removeDefine("CALC_SSNORMALS")};r.onChange=R;function R(){if(!n.defaultMatcapTex3){const r=new Uint8Array(256*4);for(let n=0;n<16;n++){for(let t=0;t<16;t++){let e=t*16;e*=Math.min(1,(n+t/3)/8);r[(n+t*16)*4+0]=r[(n+t*16)*4+1]=r[(n+t*16)*4+2]=e;r[(n+t*16)*4+3]=255}}n.defaultMatcapTex3=new CGL.Texture(n);n.defaultMatcapTex3.initFromData(r,16,16,CGL.Texture.FILTER_LINEAR,CGL.Texture.WRAP_REPEAT)}}i.onChange=function(){if(i.get()){if(y!==null)return;S.define("HAS_DIFFUSE_TEXTURE");S.removeUniform("texDiffuse");y=new CGL.Uniform(S,"t","texDiffuse")}else{S.removeDefine("HAS_DIFFUSE_TEXTURE");S.removeUniform("texDiffuse");y=null}};a.onChange=function(){if(a.get()){if(B!==null)return;S.define("HAS_NORMAL_TEXTURE");S.removeUniform("texNormal");B=new CGL.Uniform(S,"t","texNormal");if(!O)O=new CGL.Uniform(S,"f","normalMapIntensity",g)}else{S.removeDefine("HAS_NORMAL_TEXTURE");S.removeUniform("texNormal");B=null}};l.onChange=function(){if(l.get()){if(M!==null)return;S.define("HAS_AO_TEXTURE");S.removeUniform("texAo");M=new CGL.Uniform(S,"t","texAo")}else{S.removeDefine("HAS_AO_TEXTURE");S.removeUniform("texAo");M=null}};s.onChange=o.onChange=function(){if(s.get()&&o.get()){if(D!==null)return;S.define("USE_SPECULAR_TEXTURE");S.removeUniform("texSpec");S.removeUniform("texSpecMatCap");D=new CGL.Uniform(S,"t","texSpec");I=new CGL.Uniform(S,"t","texSpecMatCap")}else{S.removeDefine("USE_SPECULAR_TEXTURE");S.removeUniform("texSpec");S.removeUniform("texSpecMatCap");D=null;I=null}};function X(){if(T.get()=="Alpha Channel")S.define("ALPHA_MASK_ALPHA");else S.removeDefine("ALPHA_MASK_ALPHA");if(T.get()=="Luminance")S.define("ALPHA_MASK_LUMI");else S.removeDefine("ALPHA_MASK_LUMI");if(T.get()=="R")S.define("ALPHA_MASK_R");else S.removeDefine("ALPHA_MASK_R");if(T.get()=="G")S.define("ALPHA_MASK_G");else S.removeDefine("ALPHA_MASK_G");if(T.get()=="B")S.define("ALPHA_MASK_B");else S.removeDefine("ALPHA_MASK_B")}T.onChange=X;u.onChange=W;let w=null;function W(){if(u.get()){if(w!==null)return;S.removeUniform("texOpacity");S.define("HAS_TEXTURE_OPACITY");if(!w)w=new CGL.Uniform(S,"t","texOpacity");T.setUiAttribs({greyout:false});x.setUiAttribs({greyout:false});A.setUiAttribs({greyout:false})}else{S.removeUniform("texOpacity");S.removeDefine("HAS_TEXTURE_OPACITY");w=null;T.setUiAttribs({greyout:true});x.setUiAttribs({greyout:true});A.setUiAttribs({greyout:true})}X()}x.onChange=function(){if(x.get())S.define("DISCARDTRANS");else S.removeDefine("DISCARDTRANS")};A.onChange=function(){if(A.get())S.define("TRANSFORMALPHATEXCOORDS");else S.removeDefine("TRANSFORMALPHATEXCOORDS")};function Y(){if(s.get()&&!o.get()){t.setUiError("specNoMatCapSpec","You connected a specular texture but have not connected a specular matcap texture. You need to connect both texture inputs for the specular input to work.",1);t.setUiError("noSpecMatCapSpec",null)}else if(!s.get()&&o.get()){t.setUiError("noSpecMatCapSpec","You connected a specular matcap texture but have not connected a specular texture. You need to connect both texture inputs for the specular input to work.",1);t.setUiError("specNoMatCapSpec",null)}else if(s.get()&&o.get()){t.setUiError("specNoMatCapSpec",null);t.setUiError("noSpecMatCapSpec",null)}else{t.setUiError("specNoMatCapSpec",null);t.setUiError("noSpecMatCapSpec",null)}}N.onTriggered=function(){Y();t.checkGraphicsApi();if(!n.defaultMatcapTex3)R();S.popTextures();const e=r.get()||n.defaultMatcapTex3;S.pushTexture(j,e.tex);if(i.get()&&y)S.pushTexture(y,i.get().tex);if(a.get()&&B)S.pushTexture(B,a.get().tex);if(s.get()&&D)S.pushTexture(D,s.get().tex);if(o.get()&&I)S.pushTexture(I,o.get().tex);if(l.get()&&M)S.pushTexture(M,l.get().tex);if(u.get()&&w)S.pushTexture(w,u.get().tex);n.pushShader(S);P.trigger();n.popShader()}}};CABLES.OPS["c1dd6e76-61b4-471a-b8d1-f550a5a9a4f4"]={f:Ops.Gl.Shader.MatCapMaterial_v3,objName:"Ops.Gl.Shader.MatCapMaterial_v3"};Ops.Graphics.Geometry.AlignGeometry=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inObject("Geometry"),r=e.inValueSelect("X",["Ignore","Center","Max","Min"],"Ignore"),s=e.inValueSelect("Y",["Ignore","Center","Max","Min"],"Ignore"),o=e.inValueSelect("Z",["Ignore","Center","Max","Min"],"Ignore"),l=e.outObject("Result");r.onChange=s.onChange=o.onChange=n.onChange=i;const u=[0,0,0],c=0,h=1,f=2,d=3;let p=null;function g(e){if(e.get()=="Ignore")return c;if(e.get()=="Center")return h;if(e.get()=="Max")return f;if(e.get()=="Min")return d}function i(){const i=n.get();if(!i){l.set(null);return}u[0]=g(r);u[1]=g(s);u[2]=g(o);const e=i.getBounds();p=i.copy();for(let r=0;r<3;r++){let t=0,n=0;if(r===0){t=e.minX;n=e.maxX}else if(r==1){t=e.minY;n=e.maxY}else if(r==2){t=e.minZ;n=e.maxZ}if(u[r]==c){for(let e=0;e<p.vertices.length;e+=3)p.vertices[e+r]=i.vertices[e+r]}else if(u[r]==h){const a=t+(n-t)/2;for(let e=0;e<p.vertices.length;e+=3)p.vertices[e+r]=i.vertices[e+r]-a}else if(u[r]==f){for(let e=0;e<p.vertices.length;e+=3)p.vertices[e+r]=i.vertices[e+r]-n}else if(u[r]==d){for(let e=0;e<p.vertices.length;e+=3)p.vertices[e+r]=i.vertices[e+r]-t}}l.setRef(p)}}};CABLES.OPS["955c1a40-17ca-4944-8cf6-07e14212be2d"]={f:Ops.Graphics.Geometry.AlignGeometry,objName:"Ops.Graphics.Geometry.AlignGeometry"};Ops.Patch.P8RrHYT.SceneSwitcher=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const i=e.inFloat("beat");const a=e.outNumber("scene"),s=e.outNumber("scene beat");const o=[32,64,64+48,64+48*2,64+48*3];i.onChange=n;function n(){let t=i.get();let n=0;let r=t;o.forEach(e=>{if(t>=e){n++;r=t-e}});a.set(n);s.set(r)}}};CABLES.OPS["93859984-51be-4055-95ce-b58ab3fb1e16"]={f:Ops.Patch.P8RrHYT.SceneSwitcher,objName:"Ops.Patch.P8RrHYT.SceneSwitcher"};Ops.Math.Max=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValueFloat("value",1),r=e.inValueFloat("Maximum",1),i=e.outNumber("result");r.onChange=n.onChange=a;a();function a(){let e=Math.max(n.get(),r.get());if(e==e)i.set(e)}}};CABLES.OPS["07f0be49-c226-4029-8039-3b620145dc2a"]={f:Ops.Math.Max,objName:"Ops.Math.Max"};Ops.Math.Pow=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inValueFloat("Base"),r=e.inValueFloat("Exponent"),i=e.outNumber("Result");r.set(2);n.onChange=a;r.onChange=a;function a(){let e=Math.pow(n.get(),r.get());if(isNaN(e))e=0;i.set(e)}}};CABLES.OPS["3bb3f98f-27d6-44c4-b4e5-186e10f0809d"]={f:Ops.Math.Pow,objName:"Ops.Math.Pow"};Ops.Math.MapRange=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const f=e.inValueFloat("value",0),d=e.inValueFloat("old min",0),p=e.inValueFloat("old max",1),g=e.inValueFloat("new min",0),m=e.inValueFloat("new max",1),n=e.inValueSelect("Easing",["Linear","Smoothstep","Smootherstep"],"Linear"),r=e.inBool("Clamp",true),v=e.outNumber("result",0);e.setPortGroup("Input Range",[d,p]);e.setPortGroup("Output Range",[g,m]);let b=true;let _=0;let E=0;f.onChange=d.onChange=p.onChange=g.onChange=m.onChange=i;i();r.onChange=()=>{b=r.get();i()};n.onChange=function(){if(n.get()=="Smoothstep")_=1;else if(n.get()=="Smootherstep")_=2;else _=0};function i(){const e=g.get();const t=m.get();const n=d.get();const r=p.get();let i=f.get();if(b){if(i>=Math.max(r,n)){v.set(t);return}else if(i<=Math.min(r,n)){v.set(e);return}}let a=false;const s=Math.min(n,r);const o=Math.max(n,r);if(s!=n)a=true;let l=false;const u=Math.min(e,t);const c=Math.max(e,t);if(u!=e)l=true;let h=0;if(a)h=(o-i)*(c-u)/(o-s);else h=(i-s)*(c-u)/(o-s);if(l)E=c-h;else E=h+u;if(_===0){v.set(E)}else if(_==1){i=Math.max(0,Math.min(1,(E-e)/(t-e)));v.set(e+i*i*(3-2*i)*(t-e))}else if(_==2){i=Math.max(0,Math.min(1,(E-e)/(t-e)));v.set(e+i*i*i*(i*(i*6-15)+10)*(t-e))}}}};CABLES.OPS["2617b407-60a0-4ff6-b4a7-18136cfa7817"]={f:Ops.Math.MapRange,objName:"Ops.Math.MapRange"};Ops.Number.SwitchNumber=class extends CABLES.Op{constructor(){super(...arguments);const n=this;const e=n.attachments={};const t=n.inValueInt("Index");const r=[];const i=n.outNumber("Result");t.onChange=a;for(let t=0;t<16;t++){let e=n.inValueFloat("Value "+t);r.push(e);e.onChange=a}function a(){const e=t.get();if(e>=0&&r[e]){i.set(r[e].get())}}}};CABLES.OPS["fbb89f72-f2e3-4d34-ad01-7d884a1bcdc0"]={f:Ops.Number.SwitchNumber,objName:"Ops.Number.SwitchNumber"};Ops.Trigger.SequenceMultiPort=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inMultiPort("Input",CABLES.OP_PORT_TYPE_FUNCTION),r=e.outMultiPort("Output",CABLES.OP_PORT_TYPE_FUNCTION);n.onTriggered=e=>{const t=r.get();for(let e=0;e<t.length;e++){t[e].trigger()}}}};CABLES.OPS["be066ff6-85e2-408a-9570-59fb7abff7b2"]={f:Ops.Trigger.SequenceMultiPort,objName:"Ops.Trigger.SequenceMultiPort"};Ops.Math.MathExpression=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inFloat("A",0);const r=e.inFloat("B",1);const i=e.inFloat("C",2);const a=e.inFloat("D",3);e.setPortGroup("Parameters",[n,r,i,a]);const s=e.inString("Expression","a*(b+c+d)");e.setPortGroup("Expression",[s]);const o=e.outNumber("Result");const l=e.outBool("Expression Valid");let u=s.get();let c=false;const h=()=>{try{u=new Function("m","a","b","c","d",`with(m) { return ${s.get()} }`);c=true;f();l.set(c)}catch(e){c=false;l.set(c);if(e instanceof ReferenceError||e instanceof SyntaxError)return}};const f=()=>{if(c){o.set(u(Math,n.get(),r.get(),i.get(),a.get()));if(!s.get())o.set(0)}l.set(c)};n.onChange=r.onChange=i.onChange=a.onChange=f;s.onChange=h;h()}};CABLES.OPS["d2343a1e-64ea-45b2-99ed-46e167bbdcd3"]={f:Ops.Math.MathExpression,objName:"Ops.Math.MathExpression"};Ops.Graphics.Meshes.Star_v2=class extends CABLES.Op{constructor(){super(...arguments);const S=this;const e=S.attachments={};const t=S.inTrigger("render"),y=S.inValue("segments",40),B=S.inValue("radius",1),O=S.inValueSelect("Shape",["Star","Saw","Gear"],"Star"),D=S.inValue("Length",1.5),I=S.inFloat("Peak Z Pos",0),M=S.inValueSlider("percent",1),L=S.inValueBool("Fill"),n=S.inValueBool("Render Mesh",true),r=S.outTrigger("trigger"),R=S.addOutPort(new CABLES.Port(S,"geometry",CABLES.OP_PORT_TYPE_OBJECT));S.toWorkPortsNeedToBeLinked(t);R.ignoreValueSerialize=true;const i=S.patch.cgl;let a=0;let w=new CGL.Geometry("circle");let N=null;let s=-1;I.onChange=y.onChange=B.onChange=M.onChange=O.onChange=L.onChange=D.onChange=()=>{N=null};t.onTriggered=function(){if(!N)o();if(n.get()&&N)N.render();r.trigger()};function o(){let n=Math.max(3,Math.floor(y.get()));w.clear();let r=[],i=[],a=[],s=[];let o=0,l=0;let u=0,c=0;let e=0,t=0;let h=0,f=0;let d=0,p=0;let g=0,m=0;let v=0,b=0;let _=0,E=0;let F=[];let C=0,A=0;let x=0;if(O.get()=="Saw")x=1;if(O.get()=="Gear")x=2;let T=true;for(o=0;o<=n*M.get();o++){l=360/n*o*CGL.DEG2RAD;_=Math.cos(l)*B.get();E=Math.sin(l)*B.get();T=!T;switch(x){case 0:C=(_+u)*.5*D.get();A=(E+c)*.5*D.get();break;case 1:C=_*D.get();A=E*D.get();break;case 2:if(T){C=_*D.get();A=E*D.get();l=360/n*(o-1)*CGL.DEG2RAD;let e=Math.cos(l)*B.get();let t=Math.sin(l)*B.get();e*=D.get();t*=D.get();r.push([e,t,0],[C,A,0],[u,c,0]);i.push(0,0,1,0,0,1,0,0,1);a.push(1,0,0,1,0,0,1,0,0);s.push(0,1,0,0,1,0,0,1,0)}break}if(L.get()){r.push([0,0,0],[u,c,0],[_,E,0]);i.push(0,0,1,0,0,1,0,0,1);a.push(1,0,0,1,0,0,1,0,0);s.push(0,1,0,0,1,0,0,1,0)}if(x!=2||T){r.push([_,E,0],[u,c,0],[C,A,I.get()]);i.push(0,0,1,0,0,1,0,0,1);a.push(1,0,0,1,0,0,1,0,0);s.push(0,1,0,0,1,0,0,1,0)}u=_;c=E}w=CGL.Geometry.buildFromFaces(r);w.vertexNormals=i;w.tangents=a;w.biTangents=s;w.mapTexCoords2d();R.set(null);R.set(w);if(w.vertices.length==0)return;if(!N)N=S.patch.cg.createMesh(w,{opId:S.id});N.setGeom(w)}}};CABLES.OPS["67833a2d-4c11-4492-9a33-1b2d707ff58c"]={f:Ops.Graphics.Meshes.Star_v2,objName:"Ops.Graphics.Meshes.Star_v2"};Ops.Graphics.Meshes.Circle_v3=class extends CABLES.Op{constructor(){super(...arguments);const e=this;const t=e.attachments={};const n=e.inTrigger("render"),D=e.inValue("radius",.5),I=e.inValueSlider("innerRadius",0),M=e.inValueInt("segments",40),L=e.inValueSlider("percent",1),R=e.inValue("steps",0),w=e.inValueBool("invertSteps",false),N=e.inSwitch("mapping",["flat","round"]),P=e.inValueBool("Spline",false),r=e.inValueBool("Draw",true),i=e.outTrigger("trigger"),U=e.outObject("geometry",null,"geometry");e.setPortGroup("Size",[D,I]);e.setPortGroup("Display",[L,R,w]);e.toWorkShouldNotBeChild("Ops.Gl.TextureEffects.ImageCompose",CABLES.OP_PORT_TYPE_FUNCTION);r.setUiAttribs({title:"Render mesh"});N.set("flat");N.onChange=M.onChange=D.onChange=I.onChange=L.onChange=R.onChange=w.onChange=P.onChange=h;U.ignoreValueSerialize=true;const a=e.patch.cgl;let k=new CGL.Geometry("circle");let j=null;const s=-1;let o=0;let l=null;let G=true;n.onTriggered=u;e.onDelete=function(){if(j)j.dispose()};e.preRender=()=>{u()};n.onLinkChanged=function(){if(!n.isLinked())U.set(null);else U.setRef(k)};function u(){if(!e.patch.cg)return;if(G)c();if(!CGL.TextureEffect.checkOpNotInTextureEffect(e))return;l=e.patch.cg.getShader();if(!l)return;o=l.glPrimitive;if(P.get())l.glPrimitive=a.gl.LINE_STRIP;if(r.get()&&j){j.render(l)}i.trigger();l.glPrimitive=o}function c(){const n=Math.max(3,Math.floor(M.get()));k.clear();const t=[];const r=[];const i=[];const a=[];const s=[];let o=0,l=0;let u=0,c=0;let h=0,f=0;let d=0,p=0;let g=0,m=0;let v=0,b=0;let _=0,E=0;let F=0,C=0;const A=Math.max(0,L.get());const x=[];if(P.get()){let e=0;let t=0;const T=[];for(o=0;o<=n*A;o++){l=360/n*o*CGL.DEG2RAD;F=Math.cos(l)*D.get();C=Math.sin(l)*D.get();E=.5;if(o>0){x.push(e);x.push(t);x.push(0);_=1-(o-1)/n;T.push(_,E)}x.push(F);x.push(C);x.push(0);e=F;t=C}k.setPointVertices(x)}else if(I.get()<=0){for(o=0;o<=n*A;o++){l=360/n*o*CGL.DEG2RAD;F=Math.cos(l)*D.get();C=Math.sin(l)*D.get();if(N.get()=="flat"){_=(Math.cos(l)+1)/2;E=1-(Math.sin(l)+1)/2;v=.5;b=.5}else if(N.get()=="round"){_=1-o/n;E=0;v=_;b=1}t.push([0,0,0],[u,c,0],[F,C,0]);r.push(v,b,h,f,_,E);i.push(0,0,1,0,0,1,0,0,1);a.push(1,0,0,1,0,0,1,0,0);s.push(0,-1,0,0,-1,0,0,-1,0);h=_;f=E;u=F;c=C}k=CGL.Geometry.buildFromFaces(t,"circle");k.vertexNormals=i;k.tangents=a;k.biTangents=s;k.texCoords=r}else{let e=0;const S=n*A;const y=0;for(o=0;o<=S;o++){e++;l=360/n*o*CGL.DEG2RAD;F=Math.cos(l)*D.get();C=Math.sin(l)*D.get();const B=Math.cos(l)*I.get()*D.get();const O=Math.sin(l)*I.get()*D.get();if(N.get()=="round"){_=1-o/n;E=0;v=_;b=1}if(R.get()===0||e%parseInt(R.get(),10)===0&&!w.get()||e%parseInt(R.get(),10)!==0&&w.get()){t.push([B,O,0],[u,c,0],[F,C,0]);t.push([d,p,0],[u,c,0],[B,O,0]);r.push(_,0,h,0,v,1,_,1,h,0,g,1);i.push(0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1);a.push(1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0);s.push(0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,-1)}g=v;m=b;h=_;f=E;u=F;c=C;d=B;p=O}k=CGL.Geometry.buildFromFaces(t,"circle");k.vertexNormals=i;k.tangents=a;k.biTangents=s;if(N.get()=="flat")k.mapTexCoords2d();else k.texCoords=r}U.setRef(k);if(k.vertices.length==0)return;if(j)j.dispose();j=null;if(e.patch.cg)j=e.patch.cg.createMesh(k,{opId:e.id});G=false}function h(){G=true}}};CABLES.OPS["ae07830b-91c3-4cbe-a7d6-d3b737392c16"]={f:Ops.Graphics.Meshes.Circle_v3,objName:"Ops.Graphics.Meshes.Circle_v3"};Ops.Gl.GLTF.GltfScene_v3=class extends CABLES.Op{constructor(){super(...arguments);const E=this;const l=E.attachments={inc_camera_js:"const gltfCamera = class\n{\n    constructor(gltf, node)\n    {\n        this.node = node;\n        this.name = node.name;\n        // console.log(gltf);\n        this.config = gltf.json.cameras[node.camera];\n\n        this.pos = vec3.create();\n        this.quat = quat.create();\n        this.vCenter = vec3.create();\n        this.vUp = vec3.create();\n        this.vMat = mat4.create();\n    }\n\n    updateAnim(time)\n    {\n        if (this.node && this.node._animTrans)\n        {\n            vec3.set(this.pos,\n                this.node._animTrans[0].getValue(time),\n                this.node._animTrans[1].getValue(time),\n                this.node._animTrans[2].getValue(time));\n\n            quat.set(this.quat,\n                this.node._animRot[0].getValue(time),\n                this.node._animRot[1].getValue(time),\n                this.node._animRot[2].getValue(time),\n                this.node._animRot[3].getValue(time));\n        }\n    }\n\n    start(time)\n    {\n        if (cgl.tempData.shadowPass) return;\n\n        this.updateAnim(time);\n        const asp = cgl.getViewPort()[2] / cgl.getViewPort()[3];\n\n        cgl.pushPMatrix();\n        // mat4.perspective(\n        //     cgl.pMatrix,\n        //     this.config.perspective.yfov*0.5,\n        //     asp,\n        //     this.config.perspective.znear,\n        //     this.config.perspective.zfar);\n\n        cgl.pushViewMatrix();\n        // mat4.identity(cgl.vMatrix);\n\n        // if(this.node && this.node.parent)\n        // {\n        //     console.log(this.node.parent)\n        // vec3.add(this.pos,this.pos,this.node.parent._node.translation);\n        // vec3.sub(this.vCenter,this.vCenter,this.node.parent._node.translation);\n        // mat4.translate(cgl.vMatrix,cgl.vMatrix,\n        // [\n        //     -this.node.parent._node.translation[0],\n        //     -this.node.parent._node.translation[1],\n        //     -this.node.parent._node.translation[2]\n        // ])\n        // }\n\n        // vec3.set(this.vUp, 0, 1, 0);\n        // vec3.set(this.vCenter, 0, -1, 0);\n        // // vec3.set(this.vCenter, 0, 1, 0);\n        // vec3.transformQuat(this.vCenter, this.vCenter, this.quat);\n        // vec3.normalize(this.vCenter, this.vCenter);\n        // vec3.add(this.vCenter, this.vCenter, this.pos);\n\n        // mat4.lookAt(cgl.vMatrix, this.pos, this.vCenter, this.vUp);\n\n        let mv = mat4.create();\n        mat4.invert(mv, this.node.modelMatAbs());\n\n        // console.log(this.node.modelMatAbs());\n\n        this.vMat = mv;\n\n        mat4.identity(cgl.vMatrix);\n        // console.log(mv);\n        mat4.mul(cgl.vMatrix, cgl.vMatrix, mv);\n    }\n\n    end()\n    {\n        if (cgl.tempData.shadowPass) return;\n        cgl.popPMatrix();\n        cgl.popViewMatrix();\n    }\n};\n",inc_gltf_js:'const CHUNK_HEADER_SIZE = 8;\n\nconst Gltf = class\n{\n    constructor()\n    {\n        this.json = {};\n        this.accBuffers = [];\n        this.meshes = [];\n        this.nodes = [];\n        this.shaders = [];\n        this.timing = [];\n        this.cams = [];\n        this.startTime = performance.now();\n        this.bounds = new CABLES.CG.BoundingBox();\n        this.loaded = Date.now();\n        this.accBuffersDelete = [];\n    }\n\n    getNode(n)\n    {\n        for (let i = 0; i < this.nodes.length; i++)\n        {\n            if (this.nodes[i].name == n) return this.nodes[i];\n        }\n    }\n\n    unHideAll()\n    {\n        for (let i = 0; i < this.nodes.length; i++)\n        {\n            this.nodes[i].unHide();\n        }\n    }\n};\n\nfunction Utf8ArrayToStr(array)\n{\n    if (window.TextDecoder) return new TextDecoder("utf-8").decode(array);\n\n    let out, i, len, c;\n    let char2, char3;\n\n    out = "";\n    len = array.length;\n    i = 0;\n    while (i < len)\n    {\n        c = array[i++];\n        switch (c >> 4)\n        {\n        case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:\n            // 0xxxxxxx\n            out += String.fromCharCode(c);\n            break;\n        case 12: case 13:\n            // 110x xxxx   10xx xxxx\n            char2 = array[i++];\n            out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));\n            break;\n        case 14:\n            // 1110 xxxx  10xx xxxx  10xx xxxx\n            char2 = array[i++];\n            char3 = array[i++];\n            out += String.fromCharCode(((c & 0x0F) << 12) |\n                    ((char2 & 0x3F) << 6) |\n                    ((char3 & 0x3F) << 0));\n            break;\n        }\n    }\n\n    return out;\n}\n\nfunction readChunk(dv, bArr, arrayBuffer, offset)\n{\n    const chunk = {};\n\n    if (offset >= dv.byteLength)\n    {\n        op.log("could not read chunk...");\n        return;\n    }\n    chunk.size = dv.getUint32(offset + 0, le);\n\n    // chunk.type = new TextDecoder("utf-8").decode(bArr.subarray(offset+4, offset+4+4));\n    chunk.type = Utf8ArrayToStr(bArr.subarray(offset + 4, offset + 4 + 4));\n\n    if (chunk.type == "BIN\\0")\n    {\n        // console.log(chunk.size,arrayBuffer.length,offset);\n        // try\n        // {\n        chunk.dataView = new DataView(arrayBuffer, offset + 8, chunk.size);\n        // }\n        // catch(e)\n        // {\n        //     chunk.dataView = null;\n        //     console.log(e);\n        // }\n    }\n    else\n    if (chunk.type == "JSON")\n    {\n        const json = Utf8ArrayToStr(bArr.subarray(offset + 8, offset + 8 + chunk.size));\n\n        try\n        {\n            const obj = JSON.parse(json);\n            chunk.data = obj;\n            outGenerator.set(obj.asset.generator);\n        }\n        catch (e)\n        {\n        }\n    }\n    else\n    {\n        op.warn("unknown type", chunk.type);\n    }\n\n    return chunk;\n}\n\nfunction loadAnims(gltf)\n{\n    const uniqueAnimNames = {};\n\n    for (let i = 0; i < gltf.json.animations.length; i++)\n    {\n        const an = gltf.json.animations[i];\n\n        for (let ia = 0; ia < an.channels.length; ia++)\n        {\n            const chan = an.channels[ia];\n\n            const node = gltf.nodes[chan.target.node];\n            const sampler = an.samplers[chan.sampler];\n\n            const acc = gltf.json.accessors[sampler.input];\n            const bufferIn = gltf.accBuffers[sampler.input];\n\n            const accOut = gltf.json.accessors[sampler.output];\n            const bufferOut = gltf.accBuffers[sampler.output];\n\n            gltf.accBuffersDelete.push(sampler.output, sampler.input);\n\n            if (bufferIn && bufferOut)\n            {\n                let numComps = 1;\n                if (accOut.type == "VEC2")numComps = 2;\n                else if (accOut.type == "VEC3")numComps = 3;\n                else if (accOut.type == "VEC4")numComps = 4;\n                else op.warn("unknown accOut.type", accOut.type);\n\n                const anims = [];\n\n                uniqueAnimNames[an.name] = true;\n\n                for (let k = 0; k < numComps; k++)\n                {\n                    const newAnim = new CABLES.Anim();\n                    // newAnim.name=an.name;\n                    anims.push(newAnim);\n                }\n\n                if (sampler.interpolation === "LINEAR") {}\n                else if (sampler.interpolation === "STEP") for (let k = 0; k < numComps; k++) anims[k].defaultEasing = CABLES.EASING_ABSOLUTE;\n                else if (sampler.interpolation === "CUBICSPLINE") for (let k = 0; k < numComps; k++) anims[k].defaultEasing = CABLES.EASING_CUBICSPLINE;\n                else op.warn("unknown interpolation", sampler.interpolation);\n\n                // console.log(bufferOut)\n\n                // if there is no keyframe for time 0 copy value of first keyframe at time 0\n                if (bufferIn[0] !== 0.0)\n                    for (let k = 0; k < numComps; k++)\n                        anims[k].setValue(0, bufferOut[0 * numComps + k]);\n\n                // console.log(sampler.interpolation,bufferOut.length/numComps)\n\n                for (let j = 0; j < bufferIn.length; j++)\n                {\n                    maxTime = Math.max(bufferIn[j], maxTime);\n\n                    for (let k = 0; k < numComps; k++)\n                    {\n                        if (anims[k].defaultEasing === CABLES.EASING_CUBICSPLINE)\n                        {\n                            const idx = ((j * numComps) * 3 + k);\n\n                            const key = anims[k].setValue(bufferIn[j], bufferOut[idx + numComps]);\n                            key.bezTangIn = bufferOut[idx];\n                            key.bezTangOut = bufferOut[idx + (numComps * 2)];\n\n                            // console.log(an.name,k,bufferOut[idx+1]);\n                        }\n                        else\n                        {\n                            // console.log(an.name,k,bufferOut[j * numComps + k]);\n                            anims[k].setValue(bufferIn[j], bufferOut[j * numComps + k]);\n                        }\n                    }\n                }\n\n                node.setAnim(chan.target.path, an.name, anims);\n            }\n            else\n            {\n                op.warn("loadAmins bufferIn undefined ", bufferIn === undefined);\n                op.warn("loadAmins bufferOut undefined ", bufferOut === undefined);\n                op.warn("loadAmins ", sampler, accOut);\n                op.warn("loadAmins num accBuffers", gltf.accBuffers.length);\n                op.warn("loadAmins num accessors", gltf.json.accessors.length);\n            }\n        }\n    }\n\n    gltf.uniqueAnimNames = uniqueAnimNames;\n\n    outAnims.setRef(Object.keys(uniqueAnimNames));\n}\n\nfunction loadCams(gltf)\n{\n    if (!gltf || !gltf.json.cameras) return;\n\n    gltf.cameras = gltf.cameras || [];\n\n    for (let i = 0; i < gltf.nodes.length; i++)\n    {\n        if (gltf.nodes[i].hasOwnProperty("camera"))\n        {\n            const cam = new gltfCamera(gltf, gltf.nodes[i]);\n            gltf.cameras.push(cam);\n        }\n    }\n}\n\nfunction loadAfterDraco()\n{\n    if (!window.DracoDecoder)\n    {\n        setTimeout(() =>\n        {\n            loadAfterDraco();\n        }, 100);\n    }\n\n    reloadSoon();\n}\n\nfunction parseGltf(arrayBuffer)\n{\n    let j = 0, i = 0;\n\n    const gltf = new Gltf();\n    gltf.timing.push(["Start parsing", Math.round((performance.now() - gltf.startTime))]);\n\n    if (!arrayBuffer) return;\n    const byteArray = new Uint8Array(arrayBuffer);\n    let pos = 0;\n\n    // var string = new TextDecoder("utf-8").decode(byteArray.subarray(pos, 4));\n    const string = Utf8ArrayToStr(byteArray.subarray(pos, 4));\n    pos += 4;\n    if (string != "glTF") return;\n\n    gltf.timing.push(["dataview", Math.round((performance.now() - gltf.startTime))]);\n\n    const dv = new DataView(arrayBuffer);\n    const version = dv.getUint32(pos, le);\n    pos += 4;\n    const size = dv.getUint32(pos, le);\n    pos += 4;\n\n    outVersion.set(version);\n\n    const chunks = [];\n    gltf.chunks = chunks;\n\n    chunks.push(readChunk(dv, byteArray, arrayBuffer, pos));\n    pos += chunks[0].size + CHUNK_HEADER_SIZE;\n    gltf.json = chunks[0].data;\n\n    gltf.cables = {\n        "fileUrl": inFile.get(),\n        "shortFileName": CABLES.basename(inFile.get())\n    };\n\n    outJson.set(gltf.json);\n    outExtensions.set(gltf.json.extensionsUsed || []);\n\n    let ch = readChunk(dv, byteArray, arrayBuffer, pos);\n    while (ch)\n    {\n        chunks.push(ch);\n        pos += ch.size + CHUNK_HEADER_SIZE;\n        ch = readChunk(dv, byteArray, arrayBuffer, pos);\n    }\n\n    gltf.chunks = chunks;\n\n    const views = chunks[0].data.bufferViews;\n    const accessors = chunks[0].data.accessors;\n\n    gltf.timing.push(["Parse buffers", Math.round((performance.now() - gltf.startTime))]);\n\n    if (gltf.json.extensionsUsed && gltf.json.extensionsUsed.indexOf("KHR_draco_mesh_compression") > -1)\n    {\n        if (!window.DracoDecoder)\n        {\n            op.setUiError("gltfdraco", "GLTF draco compression lib not found / add draco op to your patch!");\n\n            loadAfterDraco();\n            return gltf;\n        }\n        else\n        {\n            gltf.useDraco = true;\n        }\n    }\n\n    op.setUiError("gltfdraco", null);\n    // let accPos = (view.byteOffset || 0) + (acc.byteOffset || 0);\n\n    if (views)\n    {\n        for (i = 0; i < accessors.length; i++)\n        {\n            const acc = accessors[i];\n            const view = views[acc.bufferView];\n\n            let numComps = 0;\n            if (acc.type == "SCALAR")numComps = 1;\n            else if (acc.type == "VEC2")numComps = 2;\n            else if (acc.type == "VEC3")numComps = 3;\n            else if (acc.type == "VEC4")numComps = 4;\n            else if (acc.type == "MAT4")numComps = 16;\n            else console.error("unknown accessor type", acc.type);\n\n            //   const decoder = new decoderModule.Decoder();\n            //   const decodedGeometry = decodeDracoData(data, decoder);\n            //   // Encode mesh\n            //   encodeMeshToFile(decodedGeometry, decoder);\n\n            //   decoderModule.destroy(decoder);\n            //   decoderModule.destroy(decodedGeometry);\n\n            // 5120 (BYTE)\t1\n            // 5121 (UNSIGNED_BYTE)\t1\n            // 5122 (SHORT)\t2\n\n            if (chunks[1].dataView)\n            {\n                if (view)\n                {\n                    const num = acc.count * numComps;\n                    let accPos = (view.byteOffset || 0) + (acc.byteOffset || 0);\n                    let stride = view.byteStride || 0;\n                    let dataBuff = null;\n\n                    if (acc.componentType == 5126 || acc.componentType == 5125) // 4byte FLOAT or INT\n                    {\n                        stride = stride || 4;\n\n                        const isInt = acc.componentType == 5125;\n                        if (isInt)dataBuff = new Uint32Array(num);\n                        else dataBuff = new Float32Array(num);\n\n                        for (j = 0; j < num; j++)\n                        {\n                            if (isInt) dataBuff[j] = chunks[1].dataView.getUint32(accPos, le);\n                            else dataBuff[j] = chunks[1].dataView.getFloat32(accPos, le);\n\n                            if (stride != 4 && (j + 1) % numComps === 0)accPos += stride - (numComps * 4);\n                            accPos += 4;\n                        }\n                    }\n                    else if (acc.componentType == 5123) // UNSIGNED_SHORT\n                    {\n                        stride = stride || 2;\n\n                        dataBuff = new Uint16Array(num);\n\n                        for (j = 0; j < num; j++)\n                        {\n                            dataBuff[j] = chunks[1].dataView.getUint16(accPos, le);\n\n                            if (stride != 2 && (j + 1) % numComps === 0) accPos += stride - (numComps * 2);\n\n                            accPos += 2;\n                        }\n                    }\n                    else if (acc.componentType == 5121) // UNSIGNED_BYTE\n                    {\n                        stride = stride || 1;\n\n                        dataBuff = new Uint8Array(num);\n\n                        for (j = 0; j < num; j++)\n                        {\n                            dataBuff[j] = chunks[1].dataView.getUint8(accPos, le);\n\n                            if (stride != 1 && (j + 1) % numComps === 0) accPos += stride - (numComps * 1);\n\n                            accPos += 1;\n                        }\n                    }\n\n                    else\n                    {\n                        console.error("unknown component type", acc.componentType);\n                    }\n\n                    gltf.accBuffers.push(dataBuff);\n                }\n                else\n                {\n                    // console.log("has no dataview");\n                }\n            }\n        }\n    }\n\n    gltf.timing.push(["Parse mesh groups", Math.round((performance.now() - gltf.startTime))]);\n\n    gltf.json.meshes = gltf.json.meshes || [];\n\n    if (gltf.json.meshes)\n    {\n        for (i = 0; i < gltf.json.meshes.length; i++)\n        {\n            const mesh = new gltfMeshGroup(gltf, gltf.json.meshes[i]);\n            gltf.meshes.push(mesh);\n        }\n    }\n\n    gltf.timing.push(["Parse nodes", Math.round((performance.now() - gltf.startTime))]);\n\n    for (i = 0; i < gltf.json.nodes.length; i++)\n    {\n        if (gltf.json.nodes[i].children)\n            for (j = 0; j < gltf.json.nodes[i].children.length; j++)\n            {\n                gltf.json.nodes[gltf.json.nodes[i].children[j]].isChild = true;\n            }\n    }\n\n    for (i = 0; i < gltf.json.nodes.length; i++)\n    {\n        const node = new gltfNode(gltf.json.nodes[i], gltf);\n        gltf.nodes.push(node);\n    }\n\n    for (i = 0; i < gltf.nodes.length; i++)\n    {\n        const node = gltf.nodes[i];\n\n        if (!node.children) continue;\n        for (let j = 0; j < node.children.length; j++)\n        {\n            gltf.nodes[node.children[j]].parent = node;\n        }\n    }\n\n    for (i = 0; i < gltf.nodes.length; i++)\n    {\n        gltf.nodes[i].initSkin();\n    }\n\n    needsMatUpdate = true;\n\n    gltf.timing.push(["load anims", Math.round((performance.now() - gltf.startTime))]);\n\n    if (gltf.json.animations) loadAnims(gltf);\n\n    gltf.timing.push(["load cameras", Math.round((performance.now() - gltf.startTime))]);\n\n    if (gltf.json.cameras) loadCams(gltf);\n\n    gltf.timing.push(["finished", Math.round((performance.now() - gltf.startTime))]);\n    return gltf;\n}\n',inc_mesh_js:'let gltfMesh = class\n{\n    constructor(name, prim, gltf, finished)\n    {\n        this.POINTS = 0;\n        this.LINES = 1;\n        this.LINE_LOOP = 2;\n        this.LINE_STRIP = 3;\n        this.TRIANGLES = 4;\n        this.TRIANGLE_STRIP = 5;\n        this.TRIANGLE_FAN = 6;\n\n        this.test = 0;\n        this.name = name;\n        this.submeshIndex = 0;\n        this.material = prim.material;\n        this.mesh = null;\n        this.geom = new CGL.Geometry("gltf_" + this.name);\n        this.geom.verticesIndices = [];\n        this.bounds = null;\n        this.primitive = 4;\n        if (prim.hasOwnProperty("mode")) this.primitive = prim.mode;\n\n        if (prim.hasOwnProperty("indices")) this.geom.verticesIndices = gltf.accBuffers[prim.indices];\n\n        gltf.loadingMeshes = gltf.loadingMeshes || 0;\n        gltf.loadingMeshes++;\n\n        this.materialJson =\n            this._matPbrMetalness =\n            this._matPbrRoughness =\n            this._matDiffuseColor = null;\n\n        if (gltf.json.materials)\n        {\n            if (this.material != -1) this.materialJson = gltf.json.materials[this.material];\n\n            if (this.materialJson && this.materialJson.pbrMetallicRoughness)\n            {\n                if (!this.materialJson.pbrMetallicRoughness.hasOwnProperty("baseColorFactor"))\n                {\n                    this._matDiffuseColor = [1, 1, 1, 1];\n                }\n                else\n                {\n                    this._matDiffuseColor = this.materialJson.pbrMetallicRoughness.baseColorFactor;\n                }\n\n                this._matDiffuseColor = this.materialJson.pbrMetallicRoughness.baseColorFactor;\n\n                if (!this.materialJson.pbrMetallicRoughness.hasOwnProperty("metallicFactor"))\n                {\n                    this._matPbrMetalness = 1.0;\n                }\n                else\n                {\n                    this._matPbrMetalness = this.materialJson.pbrMetallicRoughness.metallicFactor || null;\n                }\n\n                if (!this.materialJson.pbrMetallicRoughness.hasOwnProperty("roughnessFactor"))\n                {\n                    this._matPbrRoughness = 1.0;\n                }\n                else\n                {\n                    this._matPbrRoughness = this.materialJson.pbrMetallicRoughness.roughnessFactor || null;\n                }\n            }\n        }\n\n        if (gltf.useDraco && prim.extensions.KHR_draco_mesh_compression)\n        {\n            const view = gltf.chunks[0].data.bufferViews[prim.extensions.KHR_draco_mesh_compression.bufferView];\n            const num = view.byteLength;\n            const dataBuff = new Int8Array(num);\n            let accPos = (view.byteOffset || 0);// + (acc.byteOffset || 0);\n            for (let j = 0; j < num; j++)\n            {\n                dataBuff[j] = gltf.chunks[1].dataView.getInt8(accPos, le);\n                accPos++;\n            }\n\n            const dracoDecoder = window.DracoDecoder;\n            dracoDecoder.decodeGeometry(dataBuff.buffer, (geometry) =>\n            {\n                const geom = new CGL.Geometry("draco mesh " + name);\n\n                for (let i = 0; i < geometry.attributes.length; i++)\n                {\n                    const attr = geometry.attributes[i];\n\n                    if (attr.name === "position") geom.vertices = attr.array;\n                    else if (attr.name === "normal") geom.vertexNormals = attr.array;\n                    else if (attr.name === "uv") geom.texCoords = attr.array;\n                    else if (attr.name === "color") geom.vertexColors = this.calcVertexColors(attr.array);\n                    else if (attr.name === "joints") geom.setAttribute("attrJoints", Array.from(attr.array), 4);\n                    else if (attr.name === "weights")\n                    {\n                        const arr4 = new Float32Array(attr.array.length / attr.itemSize * 4);\n\n                        for (let k = 0; k < attr.array.length / attr.itemSize; k++)\n                        {\n                            arr4[k * 4] = arr4[k * 4 + 1] = arr4[k * 4 + 2] = arr4[k * 4 + 3] = 0;\n                            for (let j = 0; j < attr.itemSize; j++)\n                                arr4[k * 4 + j] = attr.array[k * attr.itemSize + j];\n                        }\n                        geom.setAttribute("attrWeights", arr4, 4);\n                    }\n                    else op.logWarn("unknown draco attrib", attr);\n                }\n\n                geometry.attributes = null;\n                geom.verticesIndices = geometry.index.array;\n\n                this.setGeom(geom);\n\n                this.mesh = null;\n                gltf.loadingMeshes--;\n                gltf.timing.push(["draco decode", Math.round((performance.now() - gltf.startTime))]);\n\n                if (finished)finished(this);\n            }, (error) => { op.logError(error); });\n        }\n        else\n        {\n            gltf.loadingMeshes--;\n            this.fillGeomAttribs(gltf, this.geom, prim.attributes);\n\n            if (prim.targets)\n            {\n                // console.log("prim.targets", prim.targets.length);\n                for (let j = 0; j < prim.targets.length; j++)\n                {\n                    // var tgeom=new CGL.Geometry("gltf_"+this.name);\n                    let tgeom = this.geom.copy();\n\n                    if (prim.hasOwnProperty("indices")) tgeom.verticesIndices = gltf.accBuffers[prim.indices];\n\n                    this.fillGeomAttribs(gltf, tgeom, prim.targets[j], false);\n\n                    { // calculate normals for final position of morphtarget for later...\n                        for (let i = 0; i < tgeom.vertices.length; i++) tgeom.vertices[i] += this.geom.vertices[i];\n                        tgeom.calculateNormals();\n                        for (let i = 0; i < tgeom.vertices.length; i++) tgeom.vertices[i] -= this.geom.vertices[i];\n                    }\n\n                    this.geom.morphTargets.push(tgeom);\n                }\n            }\n            if (finished)finished(this);\n        }\n    }\n\n    _linearToSrgb(x)\n    {\n        if (x <= 0)\n            return 0;\n        else if (x >= 1)\n            return 1;\n        else if (x < 0.0031308)\n            return x * 12.92;\n        else\n            return x ** (1 / 2.2) * 1.055 - 0.055;\n    }\n\n    calcVertexColors(arr)\n    {\n        let vertexColors = null;\n        if (arr instanceof Float32Array)\n        {\n            let div = false;\n            for (let i = 0; i < arr.length; i++)\n            {\n                if (arr[i] > 1)\n                {\n                    div = true;\n                    continue;\n                }\n            }\n\n            if (div)\n                for (let i = 0; i < arr.length; i++) arr[i] /= 65535;\n\n            vertexColors = arr;\n        }\n\n        else if (arr instanceof Uint16Array)\n        {\n            const fb = new Float32Array(arr.length);\n            for (let i = 0; i < arr.length; i++) fb[i] = arr[i] / 65535;\n\n            vertexColors = fb;\n        }\n        else vertexColors = arr;\n\n        for (let i = 0; i < vertexColors.length; i++)\n        {\n            vertexColors[i] = this._linearToSrgb(vertexColors[i]);\n        }\n\n        return vertexColors;\n    }\n\n    fillGeomAttribs(gltf, tgeom, attribs, setGeom)\n    {\n        if (attribs.hasOwnProperty("POSITION")) tgeom.vertices = gltf.accBuffers[attribs.POSITION];\n        if (attribs.hasOwnProperty("NORMAL")) tgeom.vertexNormals = gltf.accBuffers[attribs.NORMAL];\n        if (attribs.hasOwnProperty("TANGENT")) tgeom.tangents = gltf.accBuffers[attribs.TANGENT];\n\n        if (attribs.hasOwnProperty("COLOR_0")) tgeom.vertexColors = this.calcVertexColors(gltf.accBuffers[attribs.COLOR_0]);\n        if (attribs.hasOwnProperty("COLOR_1")) tgeom.setAttribute("attrVertColor1", this.calcVertexColors(gltf.accBuffers[attribs.COLOR_1]), 4);\n        if (attribs.hasOwnProperty("COLOR_2")) tgeom.setAttribute("attrVertColor2", this.calcVertexColors(gltf.accBuffers[attribs.COLOR_2]), 4);\n        if (attribs.hasOwnProperty("COLOR_3")) tgeom.setAttribute("attrVertColor3", this.calcVertexColors(gltf.accBuffers[attribs.COLOR_3]), 4);\n        if (attribs.hasOwnProperty("COLOR_4")) tgeom.setAttribute("attrVertColor4", this.calcVertexColors(gltf.accBuffers[attribs.COLOR_4]), 4);\n\n        if (attribs.hasOwnProperty("TEXCOORD_0"))tgeom.texCoords = gltf.accBuffers[attribs.TEXCOORD_0];\n        if (attribs.hasOwnProperty("TEXCOORD_1"))tgeom.setAttribute("attrTexCoord1", gltf.accBuffers[attribs.TEXCOORD_1], 2);\n        if (attribs.hasOwnProperty("TEXCOORD_2"))tgeom.setAttribute("attrTexCoord2", gltf.accBuffers[attribs.TEXCOORD_2], 2);\n        if (attribs.hasOwnProperty("TEXCOORD_3"))tgeom.setAttribute("attrTexCoord3", gltf.accBuffers[attribs.TEXCOORD_3], 2);\n        if (attribs.hasOwnProperty("TEXCOORD_4"))tgeom.setAttribute("attrTexCoord4", gltf.accBuffers[attribs.TEXCOORD_4], 2);\n\n        if (attribs.hasOwnProperty("WEIGHTS_0"))\n        {\n            tgeom.setAttribute("attrWeights", gltf.accBuffers[attribs.WEIGHTS_0], 4);\n        }\n        if (attribs.hasOwnProperty("JOINTS_0"))\n        {\n            if (!gltf.accBuffers[attribs.JOINTS_0])console.log("no !gltf.accBuffers[attribs.JOINTS_0]");\n            tgeom.setAttribute("attrJoints", gltf.accBuffers[attribs.JOINTS_0], 4);\n        }\n\n        if (attribs.hasOwnProperty("POSITION")) gltf.accBuffersDelete.push(attribs.POSITION);\n        if (attribs.hasOwnProperty("NORMAL")) gltf.accBuffersDelete.push(attribs.NORMAL);\n        if (attribs.hasOwnProperty("TEXCOORD_0")) gltf.accBuffersDelete.push(attribs.TEXCOORD_0);\n        if (attribs.hasOwnProperty("TANGENT")) gltf.accBuffersDelete.push(attribs.TANGENT);\n        if (attribs.hasOwnProperty("COLOR_0"))gltf.accBuffersDelete.push(attribs.COLOR_0);\n        if (attribs.hasOwnProperty("COLOR_0"))gltf.accBuffersDelete.push(attribs.COLOR_0);\n        if (attribs.hasOwnProperty("COLOR_1"))gltf.accBuffersDelete.push(attribs.COLOR_1);\n        if (attribs.hasOwnProperty("COLOR_2"))gltf.accBuffersDelete.push(attribs.COLOR_2);\n        if (attribs.hasOwnProperty("COLOR_3"))gltf.accBuffersDelete.push(attribs.COLOR_3);\n\n        if (attribs.hasOwnProperty("TEXCOORD_1")) gltf.accBuffersDelete.push(attribs.TEXCOORD_1);\n        if (attribs.hasOwnProperty("TEXCOORD_2")) gltf.accBuffersDelete.push(attribs.TEXCOORD_2);\n        if (attribs.hasOwnProperty("TEXCOORD_3")) gltf.accBuffersDelete.push(attribs.TEXCOORD_3);\n        if (attribs.hasOwnProperty("TEXCOORD_4")) gltf.accBuffersDelete.push(attribs.TEXCOORD_4);\n\n        if (setGeom !== false) if (tgeom && tgeom.verticesIndices) this.setGeom(tgeom);\n    }\n\n    setGeom(geom)\n    {\n        if (inNormFormat.get() == "X-ZY")\n        {\n            for (let i = 0; i < geom.vertexNormals.length; i += 3)\n            {\n                let t = geom.vertexNormals[i + 2];\n                geom.vertexNormals[i + 2] = geom.vertexNormals[i + 1];\n                geom.vertexNormals[i + 1] = -t;\n            }\n        }\n\n        if (inVertFormat.get() == "XZ-Y")\n        {\n            for (let i = 0; i < geom.vertices.length; i += 3)\n            {\n                let t = geom.vertices[i + 2];\n                geom.vertices[i + 2] = -geom.vertices[i + 1];\n                geom.vertices[i + 1] = t;\n            }\n        }\n\n        if (this.primitive == this.TRIANGLES)\n        {\n            if (!geom.vertexNormals.length || inCalcNormals.get()) geom.calculateNormals();\n\n            if ((!geom.biTangents || geom.biTangents.length == 0) && geom.tangents)\n            {\n                const bitan = vec3.create();\n                const tan = vec3.create();\n\n                const tangents = geom.tangents;\n                geom.tangents = new Float32Array(tangents.length / 4 * 3);\n                geom.biTangents = new Float32Array(tangents.length / 4 * 3);\n\n                for (let i = 0; i < tangents.length; i += 4)\n                {\n                    const idx = i / 4 * 3;\n\n                    vec3.cross(\n                        bitan,\n                        [geom.vertexNormals[idx], geom.vertexNormals[idx + 1], geom.vertexNormals[idx + 2]],\n                        [tangents[i], tangents[i + 1], tangents[i + 2]]\n                    );\n\n                    vec3.div(bitan, bitan, [tangents[i + 3], tangents[i + 3], tangents[i + 3]]);\n                    vec3.normalize(bitan, bitan);\n\n                    geom.biTangents[idx + 0] = bitan[0];\n                    geom.biTangents[idx + 1] = bitan[1];\n                    geom.biTangents[idx + 2] = bitan[2];\n\n                    geom.tangents[idx + 0] = tangents[i + 0];\n                    geom.tangents[idx + 1] = tangents[i + 1];\n                    geom.tangents[idx + 2] = tangents[i + 2];\n                }\n            }\n\n            if (geom.tangents.length === 0 || inCalcNormals.get()) geom.calcTangentsBitangents();\n        }\n\n        this.geom = geom;\n\n        this.bounds = geom.getBounds();\n    }\n\n    render(cgl, ignoreMaterial, skinRenderer)\n    {\n        if (!this.mesh && this.geom && this.geom.verticesIndices)\n        {\n            let g = this.geom;\n            if (this.geom.vertices.length / 3 > 64000)\n            {\n                g = this.geom.copy();\n                g.unIndex(false, true);\n            }\n\n            let glprim;\n            if (this.primitive == this.TRIANGLES)glprim = cgl.gl.TRIANGLES;\n            else if (this.primitive == this.LINES)glprim = cgl.gl.LINES;\n            else if (this.primitive == this.LINE_STRIP)glprim = cgl.gl.LINE_STRIP;\n            else if (this.primitive == this.POINTS)glprim = cgl.gl.POINTS;\n            else\n            {\n                op.logWarn("unknown primitive type", this);\n            }\n\n            this.mesh = new CGL.Mesh(cgl, g, glprim);\n            // this.mesh._geom = null;\n        }\n        else\n        {\n            // update morphTargets\n            if (this.geom && this.geom.morphTargets.length)\n            {\n                this.morphGeom = this.geom.copy();\n\n                this.test = time * 11.7;\n\n                if (this.test >= this.geom.morphTargets.length - 1) this.test = 0;\n\n                const mt = this.geom.morphTargets[Math.floor(this.test)];\n                const mt2 = this.geom.morphTargets[Math.floor(this.test + 1)];\n\n                if (mt && mt.vertices && mt2)\n                {\n                    if (this.morphGeom.vertexNormals.length != mt.vertexNormals.length)\n                        this.morphGeom.vertexNormals = new Float32Array(mt.vertexNormals.length);\n\n                    const fract = this.test % 1;\n                    for (let i = 0; i < this.morphGeom.vertices.length; i++)\n                    {\n                        this.morphGeom.vertices[i] =\n                            this.geom.vertices[i] +\n                            (1.0 - fract) * mt.vertices[i] +\n                            fract * mt2.vertices[i];\n\n                        this.morphGeom.vertexNormals[i] =\n                            (1.0 - fract) * mt.vertexNormals[i] +\n                            fract * mt2.vertexNormals[i];\n                    }\n\n                    this.mesh.updateNormals(this.morphGeom);\n                    this.mesh.updateVertices(this.morphGeom);\n                }\n            }\n\n            let useMat = !ignoreMaterial && this.material != -1 && gltf.shaders[this.material];\n            if (skinRenderer)useMat = false;\n\n            if (useMat) cgl.pushShader(gltf.shaders[this.material]);\n\n            const currentShader = cgl.getShader() || {};\n            const uniDiff = currentShader.uniformColorDiffuse;\n\n            const uniPbrMetalness = currentShader.uniformPbrMetalness;\n            const uniPbrRoughness = currentShader.uniformPbrRoughness;\n\n            if (!gltf.shaders[this.material] && inUseMatProps.get())\n            {\n                if (uniDiff && this._matDiffuseColor)\n                {\n                    this._matDiffuseColorOrig = [uniDiff.getValue()[0], uniDiff.getValue()[1], uniDiff.getValue()[2], uniDiff.getValue()[3]];\n                    uniDiff.setValue(this._matDiffuseColor);\n                }\n\n                if (uniPbrMetalness)\n                    if (this._matPbrMetalness != null)\n                    {\n                        this._matPbrMetalnessOrig = uniPbrMetalness.getValue();\n                        uniPbrMetalness.setValue(this._matPbrMetalness);\n                    }\n                    else\n                        uniPbrMetalness.setValue(0);\n\n                if (uniPbrRoughness)\n                    if (this._matPbrRoughness != null)\n                    {\n                        this._matPbrRoughnessOrig = uniPbrRoughness.getValue();\n                        uniPbrRoughness.setValue(this._matPbrRoughness);\n                    }\n                    else\n                    {\n                        uniPbrRoughness.setValue(0);\n                    }\n            }\n\n            if (this.mesh) this.mesh.render(cgl.getShader(), ignoreMaterial);\n\n            if (inUseMatProps.get())\n            {\n                if (uniDiff && this._matDiffuseColor) uniDiff.setValue(this._matDiffuseColorOrig);\n                if (uniPbrMetalness && this._matPbrMetalnessOrig != undefined) uniPbrMetalness.setValue(this._matPbrMetalnessOrig);\n                if (uniPbrRoughness && this._matPbrRoughnessOrig != undefined) uniPbrRoughness.setValue(this._matPbrRoughnessOrig);\n            }\n\n            if (useMat) cgl.popShader();\n        }\n    }\n};\n',inc_meshGroup_js:"const gltfMeshGroup = class\n{\n    constructor(gltf, m)\n    {\n        this.bounds = new CABLES.CG.BoundingBox();\n        this.meshes = [];\n        this.name = m.name;\n        const prims = m.primitives;\n\n        for (let i = 0; i < prims.length; i++)\n        {\n            const mesh = new gltfMesh(this.name, prims[i], gltf,\n                (mesh) =>\n                {\n                    this.bounds.apply(mesh.bounds);\n                });\n\n            mesh.submeshIndex = i;\n            this.meshes.push(mesh);\n        }\n    }\n\n    render(cgl, ignoreMat, skinRenderer, _time)\n    {\n        for (let i = 0; i < this.meshes.length; i++)\n        {\n            const useMat = gltf.shaders[this.meshes[i].material];\n\n            if (!ignoreMat && useMat) cgl.pushShader(gltf.shaders[this.meshes[i].material]);\n            // console.log(gltf.shaders[this.meshes[i].material],this.meshes[i].material)\n            if (skinRenderer)skinRenderer.renderStart(cgl, _time);\n\n            this.meshes[i].render(cgl, ignoreMat, skinRenderer, _time);\n            if (skinRenderer)skinRenderer.renderFinish(cgl);\n            if (!ignoreMat && useMat) cgl.popShader();\n        }\n    }\n};\n",inc_node_js:'const gltfNode = class\n{\n    constructor(node, gltf)\n    {\n        this.isChild = node.isChild || false;\n        this.name = node.name;\n        if (node.hasOwnProperty("camera")) this.camera = node.camera;\n        this.hidden = false;\n        this.mat = mat4.create();\n        this._animMat = mat4.create();\n        this._tempMat = mat4.create();\n        this._tempQuat = quat.create();\n        this._tempRotmat = mat4.create();\n        this.mesh = null;\n        this.children = [];\n        this._node = node;\n        this._gltf = gltf;\n        this.absMat = mat4.create();\n        this.addTranslate = null;\n        this._tempAnimScale = null;\n        this.addMulMat = null;\n        this.updateMatrix();\n        this._animActions = {};\n        this.skinRenderer = null;\n        this.copies = [];\n    }\n\n    get skin()\n    {\n        if (this._node.hasOwnProperty("skin")) return this._node.skin;\n        else return -1;\n    }\n\n    copy()\n    {\n        this.isCopy = true;\n        const n = new gltfNode(this._node, this._gltf);\n        n.copyOf = this;\n\n        n._animActions = this._animActions;\n        n.children = this.children;\n        n.skinRenderer = new GltfSkin(n);\n\n        this.updateMatrix();\n        return n;\n    }\n\n    hasSkin()\n    {\n        if (this._node.hasOwnProperty("skin")) return this._gltf.json.skins[this._node.skin].name || "unknown";\n        return false;\n    }\n\n    initSkin()\n    {\n        if (this.skin > -1)\n        {\n            this.skinRenderer = new GltfSkin(this);\n        }\n    }\n\n    updateMatrix()\n    {\n        mat4.identity(this.mat);\n        if (this._node.translation) mat4.translate(this.mat, this.mat, this._node.translation);\n\n        if (this._node.rotation)\n        {\n            const rotmat = mat4.create();\n            this._rot = this._node.rotation;\n\n            mat4.fromQuat(rotmat, this._node.rotation);\n            mat4.mul(this.mat, this.mat, rotmat);\n        }\n\n        if (this._node.scale)\n        {\n            this._scale = this._node.scale;\n            mat4.scale(this.mat, this.mat, this._scale);\n        }\n\n        if (this._node.hasOwnProperty("mesh"))\n        {\n            this.mesh = this._gltf.meshes[this._node.mesh];\n            if (this.isCopy)\n            {\n                console.log(this.mesh);\n            }\n        }\n\n        if (this._node.children)\n        {\n            for (let i = 0; i < this._node.children.length; i++)\n            {\n                this._gltf.json.nodes[i].isChild = true;\n                if (this._gltf.nodes[this._node.children[i]]) this._gltf.nodes[this._node.children[i]].isChild = true;\n                this.children.push(this._node.children[i]);\n            }\n        }\n    }\n\n    unHide()\n    {\n        this.hidden = false;\n        for (let i = 0; i < this.children.length; i++)\n            if (this.children[i].unHide) this.children[i].unHide();\n    }\n\n    calcBounds(gltf, mat, bounds)\n    {\n        const localMat = mat4.create();\n\n        if (mat) mat4.copy(localMat, mat);\n        if (this.mat) mat4.mul(localMat, localMat, this.mat);\n\n        if (this.mesh)\n        {\n            const bb = this.mesh.bounds.copy();\n            bb.mulMat4(localMat);\n            bounds.apply(bb);\n\n            if (bounds.changed)\n            {\n                boundingPoints.push(\n                    bb._min[0] || 0, bb._min[1] || 0, bb._min[2] || 0,\n                    bb._max[0] || 0, bb._max[1] || 0, bb._max[2] || 0);\n            }\n        }\n\n        for (let i = 0; i < this.children.length; i++)\n        {\n            if (gltf.nodes[this.children[i]] && gltf.nodes[this.children[i]].calcBounds)\n            {\n                const b = gltf.nodes[this.children[i]].calcBounds(gltf, localMat, bounds);\n\n                bounds.apply(b);\n            }\n        }\n\n        if (bounds.changed) return bounds;\n        else return null;\n    }\n\n    setAnimAction(name)\n    {\n        // console.log("setAnimAction:", name);\n        if (!name) return;\n\n        this._currentAnimaction = name;\n\n        if (name && !this._animActions[name])\n        {\n            // console.log("no action found:", name,this._animActions);\n            return null;\n        }\n\n        // else console.log("YES action found:", name);\n        // console.log(this._animActions);\n\n        for (let path in this._animActions[name])\n        {\n            if (path == "translation") this._animTrans = this._animActions[name][path];\n            else if (path == "rotation") this._animRot = this._animActions[name][path];\n            else if (path == "scale") this._animScale = this._animActions[name][path];\n            else console.warn("unknown anim path", path, this._animActions[name][path]);\n        }\n    }\n\n    setAnim(path, name, anims)\n    {\n        if (!path || !name || !anims) return;\n\n        // console.log("setanim", this._node.name, path, name, anims);\n\n        this._animActions[name] = this._animActions[name] || {};\n\n        // console.log(this._animActions);\n        // debugger;\n\n        // for (let i = 0; i < this.copies.length; i++) this.copies[i]._animActions = this._animActions;\n\n        if (this._animActions[name][path]) op.warn("animation action path already exists", name, path, this._animActions[name][path]);\n\n        this._animActions[name][path] = anims;\n\n        if (path == "translation") this._animTrans = anims;\n        else if (path == "rotation") this._animRot = anims;\n        else if (path == "scale") this._animScale = anims;\n        else console.warn("unknown anim path", path, anims);\n    }\n\n    modelMatLocal()\n    {\n        return this._animMat || this.mat;\n    }\n\n    modelMatAbs()\n    {\n        return this.absMat;\n    }\n\n    transform(cgl, _time)\n    {\n        if (!_time && _time != 0)_time = time;\n\n        this._lastTimeTrans = _time;\n\n        // console.log(this._rot)\n\n        gltfTransforms++;\n\n        if (!this._animTrans && !this._animRot && !this._animScale)\n        {\n            mat4.mul(cgl.mMatrix, cgl.mMatrix, this.mat);\n            this._animMat = null;\n        }\n        else\n        {\n            this._animMat = this._animMat || mat4.create();\n            mat4.identity(this._animMat);\n\n            const playAnims = true;\n\n            if (playAnims && this._animTrans)\n            {\n                mat4.translate(this._animMat, this._animMat, [\n                    this._animTrans[0].getValue(_time),\n                    this._animTrans[1].getValue(_time),\n                    this._animTrans[2].getValue(_time)]);\n            }\n            else\n            if (this._node.translation) mat4.translate(this._animMat, this._animMat, this._node.translation);\n\n            if (playAnims && this._animRot)\n            {\n                if (this._animRot[0].defaultEasing == CABLES.EASING_LINEAR) CABLES.Anim.slerpQuaternion(_time, this._tempQuat, this._animRot[0], this._animRot[1], this._animRot[2], this._animRot[3]);\n                else if (this._animRot[0].defaultEasing == CABLES.EASING_ABSOLUTE)\n                {\n                    this._tempQuat[0] = this._animRot[0].getValue(_time);\n                    this._tempQuat[1] = this._animRot[1].getValue(_time);\n                    this._tempQuat[2] = this._animRot[2].getValue(_time);\n                    this._tempQuat[3] = this._animRot[3].getValue(_time);\n                }\n                else if (this._animRot[0].defaultEasing == CABLES.EASING_CUBICSPLINE)\n                {\n                    CABLES.Anim.slerpQuaternion(_time, this._tempQuat, this._animRot[0], this._animRot[1], this._animRot[2], this._animRot[3]);\n                }\n\n                mat4.fromQuat(this._tempMat, this._tempQuat);\n                mat4.mul(this._animMat, this._animMat, this._tempMat);\n            }\n            else if (this._rot)\n            {\n                // mat4.fromQuat(this._tempRotmat, this._rot);\n                // mat4.mul(this._animMat, this._animMat, this._tempRotmat);\n            }\n\n            if (playAnims && this._animScale)\n            {\n                if (!this._tempAnimScale) this._tempAnimScale = [1, 1, 1];\n                this._tempAnimScale[0] = this._animScale[0].getValue(_time);\n                this._tempAnimScale[1] = this._animScale[1].getValue(_time);\n                this._tempAnimScale[2] = this._animScale[2].getValue(_time);\n                mat4.scale(this._animMat, this._animMat, this._tempAnimScale);\n            }\n            else if (this._scale) mat4.scale(this._animMat, this._animMat, this._scale);\n\n            mat4.mul(cgl.mMatrix, cgl.mMatrix, this._animMat);\n        }\n\n        if (this.addTranslate) mat4.translate(cgl.mMatrix, cgl.mMatrix, this.addTranslate);\n\n        if (this.addMulMat) mat4.mul(cgl.mMatrix, cgl.mMatrix, this.addMulMat);\n\n        mat4.copy(this.absMat, cgl.mMatrix);\n    }\n\n    render(cgl, dontTransform, dontDrawMesh, ignoreMaterial, ignoreChilds, drawHidden, _time)\n    {\n        if (!dontTransform) cgl.pushModelMatrix();\n\n        if (_time === undefined) _time = gltf.time;\n\n        if (!dontTransform || this.skinRenderer) this.transform(cgl, _time);\n\n        if (this.hidden && !drawHidden)\n        {\n        }\n        else\n        {\n            if (this.skinRenderer)\n            {\n                this.skinRenderer.time = _time;\n                if (!dontDrawMesh)\n                    this.mesh.render(cgl, ignoreMaterial, this.skinRenderer, _time);\n            }\n            else\n            {\n                if (this.mesh && !dontDrawMesh)\n                    this.mesh.render(cgl, ignoreMaterial, null, _time);\n            }\n        }\n\n        if (!ignoreChilds && !this.hidden)\n            for (let i = 0; i < this.children.length; i++)\n                if (gltf.nodes[this.children[i]])\n                    gltf.nodes[this.children[i]].render(cgl, dontTransform, dontDrawMesh, ignoreMaterial, ignoreChilds, drawHidden, _time);\n\n        if (!dontTransform)cgl.popModelMatrix();\n    }\n};\n',inc_print_js:'let tab = null;\n\nfunction closeTab()\n{\n    if (tab)gui.mainTabs.closeTab(tab.id);\n    tab = null;\n}\n\nfunction formatVec(arr)\n{\n    const nums = [];\n    for (let i = 0; i < arr.length; i++)\n    {\n        nums.push(Math.round(arr[i] * 1000) / 1000);\n    }\n\n    return nums.join(",");\n}\n\nfunction printNode(html, node, level)\n{\n    if (!gltf) return;\n\n    html += "<tr class=\\"row\\">";\n\n    let ident = "";\n    let identSpace = "";\n\n    for (let i = 1; i < level; i++)\n    {\n        identSpace += "&nbsp;&nbsp;&nbsp;";\n        let identClass = "identBg";\n        if (i == 1)identClass = "identBgLevel0";\n        ident += "<td class=\\"ident " + identClass + "\\" ><div style=\\"\\"></div></td>";\n    }\n    let id = CABLES.uuid();\n    html += ident;\n    html += "<td colspan=\\"" + (21 - level) + "\\">";\n\n    if (node.mesh && node.mesh.meshes.length)html += "<span class=\\"icon icon-cube\\"></span>&nbsp;";\n    else html += "<span class=\\"icon icon-box-select\\"></span> &nbsp;";\n\n    html += node.name + "</td><td></td>";\n\n    if (node.mesh)\n    {\n        html += "<td>";\n        for (let i = 0; i < node.mesh.meshes.length; i++)\n        {\n            if (i > 0)html += ", ";\n            html += node.mesh.meshes[i].name;\n        }\n\n        html += "</td>";\n\n        html += "<td>";\n        html += node.hasSkin() || "-";\n        html += "</td>";\n\n        html += "<td>";\n        let countMats = 0;\n        for (let i = 0; i < node.mesh.meshes.length; i++)\n        {\n            if (countMats > 0)html += ", ";\n            if (gltf.json.materials && node.mesh.meshes[i].hasOwnProperty("material"))\n            {\n                if (gltf.json.materials[node.mesh.meshes[i].material])\n                {\n                    html += gltf.json.materials[node.mesh.meshes[i].material].name;\n                    countMats++;\n                }\n            }\n        }\n        if (countMats == 0)html += "none";\n        html += "</td>";\n    }\n    else\n    {\n        html += "<td>-</td><td>-</td><td>-</td>";\n    }\n\n    html += "<td>";\n\n    if (node._node.translation || node._node.rotation || node._node.scale)\n    {\n        let info = "";\n\n        if (node._node.translation)info += "Translate: `" + formatVec(node._node.translation) + "` || ";\n        if (node._node.rotation)info += "Rotation: `" + formatVec(node._node.rotation) + "` || ";\n        if (node._node.scale)info += "Scale: `" + formatVec(node._node.scale) + "` || ";\n\n        html += "<span class=\\"icon icon-gizmo info\\" data-info=\\"" + info + "\\"></span> &nbsp;";\n    }\n\n    if (node._animRot || node._animScale || node._animTrans)\n    {\n        let info = "Animated: ";\n        if (node._animRot) info += "Rot ";\n        if (node._animScale) info += "Scale ";\n        if (node._animTrans) info += "Trans ";\n\n        html += "<span class=\\"icon icon-clock info\\" data-info=\\"" + info + "\\"></span>&nbsp;";\n    }\n\n    if (!node._node.translation && !node._node.rotation && !node._node.scale && !node._animRot && !node._animScale && !node._animTrans) html += "-";\n\n    html += "</td>";\n\n    html += "<td>";\n    let hideclass = "";\n    if (node.hidden)hideclass = "node-hidden";\n\n    // html+=\'\';\n    html += "<a onclick=\\"gui.corePatch().getOpById(\'" + op.id + "\').exposeNode(\'" + node.name + "\',\'transform\')\\" class=\\"treebutton\\">Transform</a>";\n    html += " <a onclick=\\"gui.corePatch().getOpById(\'" + op.id + "\').exposeNode(\'" + node.name + "\',\'hierarchy\')\\" class=\\"treebutton\\">Hierarchy</a>";\n    html += " <a onclick=\\"gui.corePatch().getOpById(\'" + op.id + "\').exposeNode(\'" + node.name + "\')\\" class=\\"treebutton\\">Node</a>";\n\n    if (node.hasSkin())\n        html += " <a onclick=\\"gui.corePatch().getOpById(\'" + op.id + "\').exposeNode(\'" + node.name + "\',false,{skin:true});\\" class=\\"treebutton\\">Skin</a>";\n\n    html += "</td><td>";\n    html += "&nbsp;<span class=\\"icon iconhover icon-eye " + hideclass + "\\" onclick=\\"gui.corePatch().getOpById(\'" + op.id + "\').toggleNodeVisibility(\'" + node.name + "\');this.classList.toggle(\'node-hidden\');\\"></span>";\n    html += "</td>";\n\n    html += "</tr>";\n\n    if (node.children)\n    {\n        for (let i = 0; i < node.children.length; i++)\n            html = printNode(html, gltf.nodes[node.children[i]], level + 1);\n    }\n\n    return html;\n}\n\nfunction printMaterial(mat, idx)\n{\n    let html = "<tr>";\n    html += " <td>" + idx + "</td>";\n    html += " <td>" + mat.name + "</td>";\n    // html+=\' <td><a onclick="" class="treebutton">Assign</a><td>\';\n\n    html += " <td>";\n\n    const info = JSON.stringify(mat, null, 4).replaceAll("\\"", "").replaceAll("\\n", "<br/>");\n\n    html += "<span class=\\"icon icon-info\\" onclick=\\"new CABLES.UI.ModalDialog({ \'html\': \'<pre>" + info + "</pre>\', \'title\': \'" + mat.name + "\' });\\"></span>&nbsp;";\n\n    if (mat.pbrMetallicRoughness && mat.pbrMetallicRoughness.baseColorFactor)\n    {\n        let rgb = "";\n        rgb += "" + Math.round(mat.pbrMetallicRoughness.baseColorFactor[0] * 255);\n        rgb += "," + Math.round(mat.pbrMetallicRoughness.baseColorFactor[1] * 255);\n        rgb += "," + Math.round(mat.pbrMetallicRoughness.baseColorFactor[2] * 255);\n\n        html += "<div style=\\"width:15px;height:15px;background-color:rgb(" + rgb + ");display:inline-block\\">&nbsp;</a>";\n    }\n    html += " <td style=\\"\\">" + (gltf.shaders[idx] ? "-" : "<a onclick=\\"gui.corePatch().getOpById(\'" + op.id + "\').assignMaterial(\'" + mat.name + "\')\\" class=\\"treebutton\\">Assign</a>") + "<td>";\n    html += "<td>";\n\n    html += "</tr>";\n    return html;\n}\n\nfunction printInfo()\n{\n    if (!gltf) return;\n\n    const startTime = performance.now();\n    const sizes = {};\n    let html = "<div style=\\"overflow:scroll;width:100%;height:100%\\">";\n\n    html += "File: <a href=\\"" + CABLES.platform.getCablesUrl() + "/asset/patches/?filename=" + inFile.get() + "\\" target=\\"_blank\\">" + CABLES.basename(inFile.get()) + "</a><br/>";\n\n    html += "Generator:" + gltf.json.asset.generator;\n\n    let numNodes = 0;\n    if (gltf.json.nodes)numNodes = gltf.json.nodes.length;\n    html += "<div id=\\"groupNodes\\">Nodes (" + numNodes + ")</div>";\n\n    html += "<table id=\\"sectionNodes\\" class=\\"table treetable\\">";\n\n    html += "<tr>";\n    html += " <th colspan=\\"21\\">Name</th>";\n    html += " <th>Mesh</th>";\n    html += " <th>Skin</th>";\n    html += " <th>Material</th>";\n    html += " <th>Transform</th>";\n    html += " <th>Expose</th>";\n    html += " <th></th>";\n    html += "</tr>";\n\n    for (let i = 0; i < gltf.nodes.length; i++)\n    {\n        if (!gltf.nodes[i].isChild)\n            html = printNode(html, gltf.nodes[i], 1);\n    }\n    html += "</table>";\n\n    // / //////////////////\n\n    let numMaterials = 0;\n    if (gltf.json.materials)numMaterials = gltf.json.materials.length;\n    html += "<div id=\\"groupMaterials\\">Materials (" + numMaterials + ")</div>";\n\n    if (!gltf.json.materials || gltf.json.materials.length == 0)\n    {\n    }\n    else\n    {\n        html += "<table id=\\"materialtable\\"  class=\\"table treetable\\">";\n        html += "<tr>";\n        html += " <th>Index</th>";\n        html += " <th>Name</th>";\n        html += " <th>Color</th>";\n        html += " <th>Function</th>";\n        html += " <th></th>";\n        html += "</tr>";\n        for (let i = 0; i < gltf.json.materials.length; i++)\n        {\n            html += printMaterial(gltf.json.materials[i], i);\n        }\n        html += "</table>";\n    }\n\n    // / ///////////////////////\n\n    html += "<div id=\\"groupMeshes\\">Meshes (" + gltf.json.meshes.length + ")</div>";\n\n    html += "<table id=\\"meshestable\\"  class=\\"table treetable\\">";\n    html += "<tr>";\n    html += " <th>Name</th>";\n    html += " <th>Node</th>";\n    html += " <th>Material</th>";\n    html += " <th>Vertices</th>";\n    html += " <th>Attributes</th>";\n    html += "</tr>";\n\n    let sizeBufferViews = [];\n    sizes.meshes = 0;\n\n    for (let i = 0; i < gltf.json.meshes.length; i++)\n    {\n        html += "<tr>";\n        html += "<td>" + gltf.json.meshes[i].name + "</td>";\n\n        html += "<td>";\n        let count = 0;\n        let nodename = "";\n        for (var j = 0; j < gltf.json.nodes.length; j++)\n        {\n            if (gltf.json.nodes[j].mesh == i)\n            {\n                count++;\n                if (count == 1)\n                {\n                    nodename = gltf.json.nodes[j].name;\n                }\n            }\n        }\n        if (count > 1) html += (count) + " nodes (" + nodename + " ...)";\n        else html += nodename;\n        html += "</td>";\n\n        // -------\n\n        html += "<td>";\n        for (var j = 0; j < gltf.json.meshes[i].primitives.length; j++)\n        {\n            if (gltf.json.meshes[i].primitives[j].hasOwnProperty("material"))\n            {\n                if (gltf.json.materials[gltf.json.meshes[i]])\n                {\n                    html += gltf.json.materials[gltf.json.meshes[i].primitives[j].material].name + " ";\n                }\n            }\n            else html += "None";\n        }\n        html += "</td>";\n\n        html += "<td>";\n        let numVerts = 0;\n        for (var j = 0; j < gltf.json.meshes[i].primitives.length; j++)\n        {\n            if (gltf.json.meshes[i].primitives[j].attributes.POSITION != undefined)\n            {\n                let v = parseInt(gltf.json.accessors[gltf.json.meshes[i].primitives[j].attributes.POSITION].count);\n                numVerts += v;\n                html += "" + v + "<br/>";\n            }\n            else html += "-<br/>";\n        }\n\n        if (gltf.json.meshes[i].primitives.length > 0)\n            html += "=" + numVerts;\n        html += "</td>";\n\n        html += "<td style=\\"vertical-align:top;\\">";\n        for (let j = 0; j < gltf.json.meshes[i].primitives.length; j++)\n        {\n            html += Object.keys(gltf.json.meshes[i].primitives[j].attributes);\n            html += " <a onclick=\\"gui.corePatch().getOpById(\'" + op.id + "\').exposeGeom(\'" + gltf.json.meshes[i].name + "\'," + j + ")\\" class=\\"treebutton\\">Geometry</a>";\n            html += "<br/>";\n        }\n        html += "</td>";\n        html += "</tr>";\n\n        for (let j = 0; j < gltf.json.meshes[i].primitives.length; j++)\n        {\n            const accessor = gltf.json.accessors[gltf.json.meshes[i].primitives[j].indices];\n            if (accessor)\n            {\n                let bufView = accessor.bufferView;\n\n                if (sizeBufferViews.indexOf(bufView) == -1)\n                {\n                    sizeBufferViews.push(bufView);\n                    if (gltf.json.bufferViews[bufView])sizes.meshes += gltf.json.bufferViews[bufView].byteLength;\n                }\n            }\n\n            for (let k in gltf.json.meshes[i].primitives[j].attributes)\n            {\n                const attr = gltf.json.meshes[i].primitives[j].attributes[k];\n                const bufView2 = gltf.json.accessors[attr].bufferView;\n\n                if (sizeBufferViews.indexOf(bufView2) == -1)\n                {\n                    sizeBufferViews.push(bufView2);\n                    if (gltf.json.bufferViews[bufView2])sizes.meshes += gltf.json.bufferViews[bufView2].byteLength;\n                }\n            }\n        }\n    }\n    html += "</table>";\n\n    // / //////////////////////////////////\n\n    let numSamplers = 0;\n    let numAnims = 0;\n\n    if (gltf.json.animations)\n    {\n        numAnims = gltf.json.animations.length;\n        for (let i = 0; i < gltf.json.animations.length; i++)\n            numSamplers += gltf.json.animations[i].samplers.length;\n    }\n\n    html += "<div id=\\"groupAnims\\">Animations (" + numAnims + "/" + numSamplers + ")</div>";\n\n    if (gltf.json.animations)\n    {\n        html += "<table id=\\"sectionAnim\\" class=\\"table treetable\\">";\n        html += "<tr>";\n        html += "  <th>Name</th>";\n        html += "  <th>Target node</th>";\n        html += "  <th>Path</th>";\n        html += "  <th>Interpolation</th>";\n        html += "  <th>Keys</th>";\n        html += "</tr>";\n\n        sizes.animations = 0;\n\n        for (let i = 0; i < gltf.json.animations.length; i++)\n        {\n            for (let j = 0; j < gltf.json.animations[i].samplers.length; j++)\n            {\n                let bufView = gltf.json.accessors[gltf.json.animations[i].samplers[j].input].bufferView;\n                if (sizeBufferViews.indexOf(bufView) == -1)\n                {\n                    sizeBufferViews.push(bufView);\n                    sizes.animations += gltf.json.bufferViews[bufView].byteLength;\n                }\n\n                bufView = gltf.json.accessors[gltf.json.animations[i].samplers[j].output].bufferView;\n                if (sizeBufferViews.indexOf(bufView) == -1)\n                {\n                    sizeBufferViews.push(bufView);\n                    sizes.animations += gltf.json.bufferViews[bufView].byteLength;\n                }\n            }\n\n            for (let j = 0; j < gltf.json.animations[i].channels.length; j++)\n            {\n                html += "<tr>";\n                html += "  <td> Anim " + i + ": " + gltf.json.animations[i].name + "</td>";\n\n                html += "  <td>" + gltf.nodes[gltf.json.animations[i].channels[j].target.node].name + "</td>";\n                html += "  <td>";\n                html += gltf.json.animations[i].channels[j].target.path + " ";\n                html += "  </td>";\n\n                const smplidx = gltf.json.animations[i].channels[j].sampler;\n                const smplr = gltf.json.animations[i].samplers[smplidx];\n\n                html += "  <td>" + smplr.interpolation + "</td>";\n\n                html += "  <td>" + gltf.json.accessors[smplr.output].count;\n\n                // html += "&nbsp;&nbsp;<a onclick=\\"gui.corePatch().getOpById(\'" + op.id + "\').showAnim(\'" + i + "\',\'" + j + "\')\\" class=\\"icon icon-search\\"></a>";\n\n                html += "</td>";\n\n                html += "</tr>";\n            }\n        }\n        html += "</table>";\n    }\n    else\n    {\n\n    }\n\n    // / ///////////////////\n\n    let numImages = 0;\n    if (gltf.json.images)numImages = gltf.json.images.length;\n    html += "<div id=\\"groupImages\\">Images (" + numImages + ")</div>";\n\n    if (gltf.json.images)\n    {\n        html += "<table id=\\"sectionImages\\" class=\\"table treetable\\">";\n\n        html += "<tr>";\n        html += "  <th>name</th>";\n        html += "  <th>type</th>";\n        html += "  <th>func</th>";\n\n        html += "</tr>";\n\n        sizes.images = 0;\n\n        for (let i = 0; i < gltf.json.images.length; i++)\n        {\n            if (gltf.json.images[i].bufferView)\n                sizes.images += gltf.json.bufferViews[gltf.json.images[i].bufferView].byteLength;\n\n            html += "<tr>";\n            html += "<td>" + gltf.json.images[i].name + "</td>";\n            html += "<td>" + gltf.json.images[i].mimeType + "</td>";\n            html += "<td>";\n\n            let name = gltf.json.images[i].name;\n            if (name === undefined)name = gltf.json.images[i].bufferView;\n\n            html += "<a onclick=\\"gui.corePatch().getOpById(\'" + op.id + "\').exposeTexture(\'" + name + "\')\\" class=\\"treebutton\\">Expose</a>";\n            html += "</td>";\n\n            html += "<tr>";\n        }\n        html += "</table>";\n    }\n\n    // / ///////////////////////\n\n    let numCameras = 0;\n    if (gltf.json.cameras)numCameras = gltf.json.cameras.length;\n    html += "<div id=\\"groupCameras\\">Cameras (" + numCameras + ")</div>";\n\n    if (gltf.json.cameras)\n    {\n        html += "<table id=\\"sectionCameras\\" class=\\"table treetable\\">";\n\n        html += "<tr>";\n        html += "  <th>name</th>";\n        html += "  <th>type</th>";\n        html += "  <th>info</th>";\n        html += "</tr>";\n\n        for (let i = 0; i < gltf.json.cameras.length; i++)\n        {\n            html += "<tr>";\n            html += "<td>" + gltf.json.cameras[i].name + "</td>";\n            html += "<td>" + gltf.json.cameras[i].type + "</td>";\n            html += "<td>";\n\n            if (gltf.json.cameras[i].perspective)\n            {\n                html += "yfov: " + Math.round(gltf.json.cameras[i].perspective.yfov * 100) / 100;\n                html += ", ";\n                html += "zfar: " + Math.round(gltf.json.cameras[i].perspective.zfar * 100) / 100;\n                html += ", ";\n                html += "znear: " + Math.round(gltf.json.cameras[i].perspective.znear * 100) / 100;\n            }\n            html += "</td>";\n\n            html += "<tr>";\n        }\n        html += "</table>";\n    }\n\n    // / ////////////////////////////////////\n\n    let numSkins = 0;\n    if (gltf.json.skins)numSkins = gltf.json.skins.length;\n    html += "<div id=\\"groupSkins\\">Skins (" + numSkins + ")</div>";\n\n    if (gltf.json.skins)\n    {\n        // html += "<h3>Skins (" + gltf.json.skins.length + ")</h3>";\n        html += "<table id=\\"sectionSkins\\" class=\\"table treetable\\">";\n\n        html += "<tr>";\n        html += "  <th>name</th>";\n        html += "  <th></th>";\n        html += "  <th>total joints</th>";\n        html += "</tr>";\n\n        for (let i = 0; i < gltf.json.skins.length; i++)\n        {\n            html += "<tr>";\n            html += "<td>" + gltf.json.skins[i].name + "</td>";\n            html += "<td>" + "</td>";\n            html += "<td>" + gltf.json.skins[i].joints.length + "</td>";\n            html += "<td>";\n            html += "</td>";\n            html += "<tr>";\n        }\n        html += "</table>";\n    }\n\n    // / ////////////////////////////////////\n\n    if (gltf.timing)\n    {\n        html += "<div id=\\"groupTiming\\">Debug Loading Timing </div>";\n\n        html += "<table id=\\"sectionTiming\\" class=\\"table treetable\\">";\n\n        html += "<tr>";\n        html += "  <th>task</th>";\n        html += "  <th>time used</th>";\n        html += "</tr>";\n\n        let lt = 0;\n        for (let i = 0; i < gltf.timing.length - 1; i++)\n        {\n            html += "<tr>";\n            html += "  <td>" + gltf.timing[i][0] + "</td>";\n            html += "  <td>" + (gltf.timing[i + 1][1] - gltf.timing[i][1]) + " ms</td>";\n            html += "</tr>";\n            // lt = gltf.timing[i][1];\n        }\n        html += "</table>";\n    }\n\n    // / //////////////////////////\n\n    let sizeBin = 0;\n    if (gltf.json.buffers)\n        sizeBin = gltf.json.buffers[0].byteLength;\n\n    html += "<div id=\\"groupBinary\\">File Size Allocation (" + Math.round(sizeBin / 1024) + "k )</div>";\n\n    html += "<table id=\\"sectionBinary\\" class=\\"table treetable\\">";\n    html += "<tr>";\n    html += "  <th>name</th>";\n    html += "  <th>size</th>";\n    html += "  <th>%</th>";\n    html += "</tr>";\n    let sizeUnknown = sizeBin;\n    for (let i in sizes)\n    {\n        // html+=i+\':\'+Math.round(sizes[i]/1024);\n        html += "<tr>";\n        html += "<td>" + i + "</td>";\n        html += "<td>" + readableSize(sizes[i]) + " </td>";\n        html += "<td>" + Math.round(sizes[i] / sizeBin * 100) + "% </td>";\n        html += "<tr>";\n        sizeUnknown -= sizes[i];\n    }\n\n    if (sizeUnknown != 0)\n    {\n        html += "<tr>";\n        html += "<td>unknown</td>";\n        html += "<td>" + readableSize(sizeUnknown) + " </td>";\n        html += "<td>" + Math.round(sizeUnknown / sizeBin * 100) + "% </td>";\n        html += "<tr>";\n    }\n\n    html += "</table>";\n    html += "</div>";\n\n    tab = new CABLES.UI.Tab("GLTF " + CABLES.basename(inFile.get()), { "icon": "cube", "infotext": "tab_gltf", "padding": true, "singleton": true });\n    gui.mainTabs.addTab(tab, true);\n\n    tab.addEventListener("close", closeTab);\n    tab.html(html);\n\n    CABLES.UI.Collapsable.setup(ele.byId("groupNodes"), ele.byId("sectionNodes"), false);\n    CABLES.UI.Collapsable.setup(ele.byId("groupMaterials"), ele.byId("materialtable"), true);\n    CABLES.UI.Collapsable.setup(ele.byId("groupAnims"), ele.byId("sectionAnim"), true);\n    CABLES.UI.Collapsable.setup(ele.byId("groupMeshes"), ele.byId("meshestable"), true);\n    CABLES.UI.Collapsable.setup(ele.byId("groupCameras"), ele.byId("sectionCameras"), true);\n    CABLES.UI.Collapsable.setup(ele.byId("groupImages"), ele.byId("sectionImages"), true);\n    CABLES.UI.Collapsable.setup(ele.byId("groupSkins"), ele.byId("sectionSkins"), true);\n    CABLES.UI.Collapsable.setup(ele.byId("groupBinary"), ele.byId("sectionBinary"), true);\n    CABLES.UI.Collapsable.setup(ele.byId("groupTiming"), ele.byId("sectionTiming"), true);\n\n    gui.maintabPanel.show(true);\n}\n\nfunction readableSize(n)\n{\n    if (n > 1024) return Math.round(n / 1024) + " kb";\n    if (n > 1024 * 500) return Math.round(n / 1024) + " mb";\n    else return n + " bytes";\n}\n',inc_skin_js:'const GltfSkin = class\n{\n    constructor(node)\n    {\n        this._mod = null;\n        this._node = node;\n        this._lastTime = 0;\n        this._matArr = [];\n        this._m = mat4.create();\n        this._invBindMatrix = mat4.create();\n        this.identity = true;\n    }\n\n    renderFinish(cgl)\n    {\n        cgl.popModelMatrix();\n        this._mod.unbind();\n    }\n\n    renderStart(cgl, time)\n    {\n        if (!this._mod)\n        {\n            this._mod = new CGL.ShaderModifier(cgl, op.name + this._node.name);\n\n            this._mod.addModule({\n                "priority": -2,\n                "name": "MODULE_VERTEX_POSITION",\n                "srcHeadVert": attachments.skin_head_vert || "",\n                "srcBodyVert": attachments.skin_vert || ""\n            });\n\n            this._mod.addUniformVert("m4[]", "MOD_boneMats", []);// bohnenmatze\n            const tr = vec3.create();\n        }\n\n        const skinIdx = this._node.skin;\n        const arrLength = gltf.json.skins[skinIdx].joints.length * 16;\n\n        // if (this._lastTime != time || !time)\n        {\n            // this._lastTime=inTime.get();\n            if (this._matArr.length != arrLength) this._matArr.length = arrLength;\n\n            for (let i = 0; i < gltf.json.skins[skinIdx].joints.length; i++)\n            {\n                const i16 = i * 16;\n                const jointIdx = gltf.json.skins[skinIdx].joints[i];\n                const nodeJoint = gltf.nodes[jointIdx];\n\n                for (let j = 0; j < 16; j++)\n                    this._invBindMatrix[j] = gltf.accBuffers[gltf.json.skins[skinIdx].inverseBindMatrices][i16 + j];\n\n                mat4.mul(this._m, nodeJoint.modelMatAbs(), this._invBindMatrix);\n\n                for (let j = 0; j < this._m.length; j++) this._matArr[i16 + j] = this._m[j];\n            }\n\n            this._mod.setUniformValue("MOD_boneMats", this._matArr);\n            this._lastTime = time;\n        }\n\n        this._mod.define("SKIN_NUM_BONES", gltf.json.skins[skinIdx].joints.length);\n        this._mod.bind();\n\n        // draw mesh...\n        cgl.pushModelMatrix();\n        if (this.identity)mat4.identity(cgl.mMatrix);\n    }\n};\n',skin_vert:"int index=int(attrJoints.x);\nvec4 newPos = (MOD_boneMats[index] * pos) * attrWeights.x;\nvec3 newNorm = (vec4((MOD_boneMats[index] * vec4(norm.xyz, 0.0)) * attrWeights.x).xyz);\n\nindex=int(attrJoints.y);\nnewPos += (MOD_boneMats[index] * pos) * attrWeights.y;\nnewNorm = (vec4((MOD_boneMats[index] * vec4(norm.xyz, 0.0)) * attrWeights.y).xyz)+newNorm;\n\nindex=int(attrJoints.z);\nnewPos += (MOD_boneMats[index] * pos) * attrWeights.z;\nnewNorm = (vec4((MOD_boneMats[index] * vec4(norm.xyz, 0.0)) * attrWeights.z).xyz)+newNorm;\n\nindex=int(attrJoints.w);\nnewPos += (MOD_boneMats[index] * pos) * attrWeights.w ;\nnewNorm = (vec4((MOD_boneMats[index] * vec4(norm.xyz, 0.0)) * attrWeights.w).xyz)+newNorm;\n\npos=newPos;\n\nnorm=normalize(newNorm.xyz);\n\n\n",skin_head_vert:"\nIN vec4 attrWeights;\nIN vec4 attrJoints;\nUNI mat4 MOD_boneMats[SKIN_NUM_BONES];\n"};const r=class{constructor(e,t){this.node=t;this.name=t.name;this.config=e.json.cameras[t.camera];this.pos=vec3.create();this.quat=quat.create();this.vCenter=vec3.create();this.vUp=vec3.create();this.vMat=mat4.create()}updateAnim(e){if(this.node&&this.node._animTrans){vec3.set(this.pos,this.node._animTrans[0].getValue(e),this.node._animTrans[1].getValue(e),this.node._animTrans[2].getValue(e));quat.set(this.quat,this.node._animRot[0].getValue(e),this.node._animRot[1].getValue(e),this.node._animRot[2].getValue(e),this.node._animRot[3].getValue(e))}}start(e){if(g.tempData.shadowPass)return;this.updateAnim(e);const t=g.getViewPort()[2]/g.getViewPort()[3];g.pushPMatrix();g.pushViewMatrix();let n=mat4.create();mat4.invert(n,this.node.modelMatAbs());this.vMat=n;mat4.identity(g.vMatrix);mat4.mul(g.vMatrix,g.vMatrix,n)}end(){if(g.tempData.shadowPass)return;g.popPMatrix();g.popViewMatrix()}};const N=8;const P=class{constructor(){this.json={};this.accBuffers=[];this.meshes=[];this.nodes=[];this.shaders=[];this.timing=[];this.cams=[];this.startTime=performance.now();this.bounds=new CABLES.CG.BoundingBox;this.loaded=Date.now();this.accBuffersDelete=[]}getNode(t){for(let e=0;e<this.nodes.length;e++){if(this.nodes[e].name==t)return this.nodes[e]}}unHideAll(){for(let e=0;e<this.nodes.length;e++){this.nodes[e].unHide()}}};function F(e){if(window.TextDecoder)return new TextDecoder("utf-8").decode(e);let t,n,r,i;let a,s;t="";r=e.length;n=0;while(n<r){i=e[n++];switch(i>>4){case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:t+=String.fromCharCode(i);break;case 12:case 13:a=e[n++];t+=String.fromCharCode((i&31)<<6|a&63);break;case 14:a=e[n++];s=e[n++];t+=String.fromCharCode((i&15)<<12|(a&63)<<6|(s&63)<<0);break}}return t}function C(e,t,n,r){const i={};if(r>=e.byteLength){E.log("could not read chunk...");return}i.size=e.getUint32(r+0,T);i.type=F(t.subarray(r+4,r+4+4));if(i.type=="BIN\0"){i.dataView=new DataView(n,r+8,i.size)}else if(i.type=="JSON"){const a=F(t.subarray(r+8,r+8+i.size));try{const s=JSON.parse(a);i.data=s;ae.set(s.asset.generator)}catch(e){}}else{E.warn("unknown type",i.type)}return i}function U(t){const r={};for(let e=0;e<t.json.animations.length;e++){const i=t.json.animations[e];for(let e=0;e<i.channels.length;e++){const a=i.channels[e];const s=t.nodes[a.target.node];const o=i.samplers[a.sampler];const n=t.json.accessors[o.input];const l=t.accBuffers[o.input];const u=t.json.accessors[o.output];const c=t.accBuffers[o.output];t.accBuffersDelete.push(o.output,o.input);if(l&&c){let n=1;if(u.type=="VEC2")n=2;else if(u.type=="VEC3")n=3;else if(u.type=="VEC4")n=4;else E.warn("unknown accOut.type",u.type);const h=[];r[i.name]=true;for(let e=0;e<n;e++){const f=new CABLES.Anim;h.push(f)}if(o.interpolation==="LINEAR"){}else if(o.interpolation==="STEP")for(let e=0;e<n;e++)h[e].defaultEasing=CABLES.EASING_ABSOLUTE;else if(o.interpolation==="CUBICSPLINE")for(let e=0;e<n;e++)h[e].defaultEasing=CABLES.EASING_CUBICSPLINE;else E.warn("unknown interpolation",o.interpolation);if(l[0]!==0)for(let e=0;e<n;e++)h[e].setValue(0,c[0*n+e]);for(let t=0;t<l.length;t++){y=Math.max(l[t],y);for(let e=0;e<n;e++){if(h[e].defaultEasing===CABLES.EASING_CUBICSPLINE){const d=t*n*3+e;const p=h[e].setValue(l[t],c[d+n]);p.bezTangIn=c[d];p.bezTangOut=c[d+n*2]}else{h[e].setValue(l[t],c[t*n+e])}}}s.setAnim(a.target.path,i.name,h)}else{E.warn("loadAmins bufferIn undefined ",l===undefined);E.warn("loadAmins bufferOut undefined ",c===undefined);E.warn("loadAmins ",o,u);E.warn("loadAmins num accBuffers",t.accBuffers.length);E.warn("loadAmins num accessors",t.json.accessors.length)}}}t.uniqueAnimNames=r;he.setRef(Object.keys(r))}function k(n){if(!n||!n.json.cameras)return;n.cameras=n.cameras||[];for(let t=0;t<n.nodes.length;t++){if(n.nodes[t].hasOwnProperty("camera")){const e=new r(n,n.nodes[t]);n.cameras.push(e)}}}function j(){if(!window.DracoDecoder){setTimeout(()=>{j()},100)}L()}function G(e){let i=0,t=0;const a=new P;a.timing.push(["Start parsing",Math.round(performance.now()-a.startTime)]);if(!e)return;const n=new Uint8Array(e);let r=0;const s=F(n.subarray(r,4));r+=4;if(s!="glTF")return;a.timing.push(["dataview",Math.round(performance.now()-a.startTime)]);const o=new DataView(e);const l=o.getUint32(r,T);r+=4;const u=o.getUint32(r,T);r+=4;se.set(l);const c=[];a.chunks=c;c.push(C(o,n,e,r));r+=c[0].size+N;a.json=c[0].data;a.cables={fileUrl:x.get(),shortFileName:CABLES.basename(x.get())};ce.set(a.json);oe.set(a.json.extensionsUsed||[]);let h=C(o,n,e,r);while(h){c.push(h);r+=h.size+N;h=C(o,n,e,r)}a.chunks=c;const f=c[0].data.bufferViews;const d=c[0].data.accessors;a.timing.push(["Parse buffers",Math.round(performance.now()-a.startTime)]);if(a.json.extensionsUsed&&a.json.extensionsUsed.indexOf("KHR_draco_mesh_compression")>-1){if(!window.DracoDecoder){E.setUiError("gltfdraco","GLTF draco compression lib not found / add draco op to your patch!");j();return a}else{a.useDraco=true}}E.setUiError("gltfdraco",null);if(f){for(t=0;t<d.length;t++){const p=d[t];const g=f[p.bufferView];let r=0;if(p.type=="SCALAR")r=1;else if(p.type=="VEC2")r=2;else if(p.type=="VEC3")r=3;else if(p.type=="VEC4")r=4;else if(p.type=="MAT4")r=16;else console.error("unknown accessor type",p.type);if(c[1].dataView){if(g){const m=p.count*r;let e=(g.byteOffset||0)+(p.byteOffset||0);let t=g.byteStride||0;let n=null;if(p.componentType==5126||p.componentType==5125){t=t||4;const v=p.componentType==5125;if(v)n=new Uint32Array(m);else n=new Float32Array(m);for(i=0;i<m;i++){if(v)n[i]=c[1].dataView.getUint32(e,T);else n[i]=c[1].dataView.getFloat32(e,T);if(t!=4&&(i+1)%r===0)e+=t-r*4;e+=4}}else if(p.componentType==5123){t=t||2;n=new Uint16Array(m);for(i=0;i<m;i++){n[i]=c[1].dataView.getUint16(e,T);if(t!=2&&(i+1)%r===0)e+=t-r*2;e+=2}}else if(p.componentType==5121){t=t||1;n=new Uint8Array(m);for(i=0;i<m;i++){n[i]=c[1].dataView.getUint8(e,T);if(t!=1&&(i+1)%r===0)e+=t-r*1;e+=1}}else{console.error("unknown component type",p.componentType)}a.accBuffers.push(n)}else{}}}}a.timing.push(["Parse mesh groups",Math.round(performance.now()-a.startTime)]);a.json.meshes=a.json.meshes||[];if(a.json.meshes){for(t=0;t<a.json.meshes.length;t++){const b=new z(a,a.json.meshes[t]);a.meshes.push(b)}}a.timing.push(["Parse nodes",Math.round(performance.now()-a.startTime)]);for(t=0;t<a.json.nodes.length;t++){if(a.json.nodes[t].children)for(i=0;i<a.json.nodes[t].children.length;i++){a.json.nodes[a.json.nodes[t].children[i]].isChild=true}}for(t=0;t<a.json.nodes.length;t++){const _=new H(a.json.nodes[t],a);a.nodes.push(_)}for(t=0;t<a.nodes.length;t++){const _=a.nodes[t];if(!_.children)continue;for(let e=0;e<_.children.length;e++){a.nodes[_.children[e]].parent=_}}for(t=0;t<a.nodes.length;t++){a.nodes[t].initSkin()}O=true;a.timing.push(["load anims",Math.round(performance.now()-a.startTime)]);if(a.json.animations)U(a);a.timing.push(["load cameras",Math.round(performance.now()-a.startTime)]);if(a.json.cameras)k(a);a.timing.push(["finished",Math.round(performance.now()-a.startTime)]);return a}let V=class{constructor(e,n,a,s){this.POINTS=0;this.LINES=1;this.LINE_LOOP=2;this.LINE_STRIP=3;this.TRIANGLES=4;this.TRIANGLE_STRIP=5;this.TRIANGLE_FAN=6;this.test=0;this.name=e;this.submeshIndex=0;this.material=n.material;this.mesh=null;this.geom=new CGL.Geometry("gltf_"+this.name);this.geom.verticesIndices=[];this.bounds=null;this.primitive=4;if(n.hasOwnProperty("mode"))this.primitive=n.mode;if(n.hasOwnProperty("indices"))this.geom.verticesIndices=a.accBuffers[n.indices];a.loadingMeshes=a.loadingMeshes||0;a.loadingMeshes++;this.materialJson=this._matPbrMetalness=this._matPbrRoughness=this._matDiffuseColor=null;if(a.json.materials){if(this.material!=-1)this.materialJson=a.json.materials[this.material];if(this.materialJson&&this.materialJson.pbrMetallicRoughness){if(!this.materialJson.pbrMetallicRoughness.hasOwnProperty("baseColorFactor")){this._matDiffuseColor=[1,1,1,1]}else{this._matDiffuseColor=this.materialJson.pbrMetallicRoughness.baseColorFactor}this._matDiffuseColor=this.materialJson.pbrMetallicRoughness.baseColorFactor;if(!this.materialJson.pbrMetallicRoughness.hasOwnProperty("metallicFactor")){this._matPbrMetalness=1}else{this._matPbrMetalness=this.materialJson.pbrMetallicRoughness.metallicFactor||null}if(!this.materialJson.pbrMetallicRoughness.hasOwnProperty("roughnessFactor")){this._matPbrRoughness=1}else{this._matPbrRoughness=this.materialJson.pbrMetallicRoughness.roughnessFactor||null}}}if(a.useDraco&&n.extensions.KHR_draco_mesh_compression){const r=a.chunks[0].data.bufferViews[n.extensions.KHR_draco_mesh_compression.bufferView];const i=r.byteLength;const o=new Int8Array(i);let t=r.byteOffset||0;for(let e=0;e<i;e++){o[e]=a.chunks[1].dataView.getInt8(t,T);t++}const l=window.DracoDecoder;l.decodeGeometry(o.buffer,t=>{const n=new CGL.Geometry("draco mesh "+e);for(let e=0;e<t.attributes.length;e++){const r=t.attributes[e];if(r.name==="position")n.vertices=r.array;else if(r.name==="normal")n.vertexNormals=r.array;else if(r.name==="uv")n.texCoords=r.array;else if(r.name==="color")n.vertexColors=this.calcVertexColors(r.array);else if(r.name==="joints")n.setAttribute("attrJoints",Array.from(r.array),4);else if(r.name==="weights"){const i=new Float32Array(r.array.length/r.itemSize*4);for(let t=0;t<r.array.length/r.itemSize;t++){i[t*4]=i[t*4+1]=i[t*4+2]=i[t*4+3]=0;for(let e=0;e<r.itemSize;e++)i[t*4+e]=r.array[t*r.itemSize+e]}n.setAttribute("attrWeights",i,4)}else E.logWarn("unknown draco attrib",r)}t.attributes=null;n.verticesIndices=t.index.array;this.setGeom(n);this.mesh=null;a.loadingMeshes--;a.timing.push(["draco decode",Math.round(performance.now()-a.startTime)]);if(s)s(this)},e=>{E.logError(e)})}else{a.loadingMeshes--;this.fillGeomAttribs(a,this.geom,n.attributes);if(n.targets){for(let e=0;e<n.targets.length;e++){let t=this.geom.copy();if(n.hasOwnProperty("indices"))t.verticesIndices=a.accBuffers[n.indices];this.fillGeomAttribs(a,t,n.targets[e],false);{for(let e=0;e<t.vertices.length;e++)t.vertices[e]+=this.geom.vertices[e];t.calculateNormals();for(let e=0;e<t.vertices.length;e++)t.vertices[e]-=this.geom.vertices[e]}this.geom.morphTargets.push(t)}}if(s)s(this)}}_linearToSrgb(e){if(e<=0)return 0;else if(e>=1)return 1;else if(e<.0031308)return e*12.92;else return e**(1/2.2)*1.055-.055}calcVertexColors(n){let r=null;if(n instanceof Float32Array){let t=false;for(let e=0;e<n.length;e++){if(n[e]>1){t=true;continue}}if(t)for(let e=0;e<n.length;e++)n[e]/=65535;r=n}else if(n instanceof Uint16Array){const t=new Float32Array(n.length);for(let e=0;e<n.length;e++)t[e]=n[e]/65535;r=t}else r=n;for(let e=0;e<r.length;e++){r[e]=this._linearToSrgb(r[e])}return r}fillGeomAttribs(e,t,n,r){if(n.hasOwnProperty("POSITION"))t.vertices=e.accBuffers[n.POSITION];if(n.hasOwnProperty("NORMAL"))t.vertexNormals=e.accBuffers[n.NORMAL];if(n.hasOwnProperty("TANGENT"))t.tangents=e.accBuffers[n.TANGENT];if(n.hasOwnProperty("COLOR_0"))t.vertexColors=this.calcVertexColors(e.accBuffers[n.COLOR_0]);if(n.hasOwnProperty("COLOR_1"))t.setAttribute("attrVertColor1",this.calcVertexColors(e.accBuffers[n.COLOR_1]),4);if(n.hasOwnProperty("COLOR_2"))t.setAttribute("attrVertColor2",this.calcVertexColors(e.accBuffers[n.COLOR_2]),4);if(n.hasOwnProperty("COLOR_3"))t.setAttribute("attrVertColor3",this.calcVertexColors(e.accBuffers[n.COLOR_3]),4);if(n.hasOwnProperty("COLOR_4"))t.setAttribute("attrVertColor4",this.calcVertexColors(e.accBuffers[n.COLOR_4]),4);if(n.hasOwnProperty("TEXCOORD_0"))t.texCoords=e.accBuffers[n.TEXCOORD_0];if(n.hasOwnProperty("TEXCOORD_1"))t.setAttribute("attrTexCoord1",e.accBuffers[n.TEXCOORD_1],2);if(n.hasOwnProperty("TEXCOORD_2"))t.setAttribute("attrTexCoord2",e.accBuffers[n.TEXCOORD_2],2);if(n.hasOwnProperty("TEXCOORD_3"))t.setAttribute("attrTexCoord3",e.accBuffers[n.TEXCOORD_3],2);if(n.hasOwnProperty("TEXCOORD_4"))t.setAttribute("attrTexCoord4",e.accBuffers[n.TEXCOORD_4],2);if(n.hasOwnProperty("WEIGHTS_0")){t.setAttribute("attrWeights",e.accBuffers[n.WEIGHTS_0],4)}if(n.hasOwnProperty("JOINTS_0")){if(!e.accBuffers[n.JOINTS_0])console.log("no !gltf.accBuffers[attribs.JOINTS_0]");t.setAttribute("attrJoints",e.accBuffers[n.JOINTS_0],4)}if(n.hasOwnProperty("POSITION"))e.accBuffersDelete.push(n.POSITION);if(n.hasOwnProperty("NORMAL"))e.accBuffersDelete.push(n.NORMAL);if(n.hasOwnProperty("TEXCOORD_0"))e.accBuffersDelete.push(n.TEXCOORD_0);if(n.hasOwnProperty("TANGENT"))e.accBuffersDelete.push(n.TANGENT);if(n.hasOwnProperty("COLOR_0"))e.accBuffersDelete.push(n.COLOR_0);if(n.hasOwnProperty("COLOR_0"))e.accBuffersDelete.push(n.COLOR_0);if(n.hasOwnProperty("COLOR_1"))e.accBuffersDelete.push(n.COLOR_1);if(n.hasOwnProperty("COLOR_2"))e.accBuffersDelete.push(n.COLOR_2);if(n.hasOwnProperty("COLOR_3"))e.accBuffersDelete.push(n.COLOR_3);if(n.hasOwnProperty("TEXCOORD_1"))e.accBuffersDelete.push(n.TEXCOORD_1);if(n.hasOwnProperty("TEXCOORD_2"))e.accBuffersDelete.push(n.TEXCOORD_2);if(n.hasOwnProperty("TEXCOORD_3"))e.accBuffersDelete.push(n.TEXCOORD_3);if(n.hasOwnProperty("TEXCOORD_4"))e.accBuffersDelete.push(n.TEXCOORD_4);if(r!==false)if(t&&t.verticesIndices)this.setGeom(t)}setGeom(n){if(ee.get()=="X-ZY"){for(let t=0;t<n.vertexNormals.length;t+=3){let e=n.vertexNormals[t+2];n.vertexNormals[t+2]=n.vertexNormals[t+1];n.vertexNormals[t+1]=-e}}if(te.get()=="XZ-Y"){for(let t=0;t<n.vertices.length;t+=3){let e=n.vertices[t+2];n.vertices[t+2]=-n.vertices[t+1];n.vertices[t+1]=e}}if(this.primitive==this.TRIANGLES){if(!n.vertexNormals.length||h.get())n.calculateNormals();if((!n.biTangents||n.biTangents.length==0)&&n.tangents){const t=vec3.create();const e=vec3.create();const r=n.tangents;n.tangents=new Float32Array(r.length/4*3);n.biTangents=new Float32Array(r.length/4*3);for(let e=0;e<r.length;e+=4){const i=e/4*3;vec3.cross(t,[n.vertexNormals[i],n.vertexNormals[i+1],n.vertexNormals[i+2]],[r[e],r[e+1],r[e+2]]);vec3.div(t,t,[r[e+3],r[e+3],r[e+3]]);vec3.normalize(t,t);n.biTangents[i+0]=t[0];n.biTangents[i+1]=t[1];n.biTangents[i+2]=t[2];n.tangents[i+0]=r[e+0];n.tangents[i+1]=r[e+1];n.tangents[i+2]=r[e+2]}}if(n.tangents.length===0||h.get())n.calcTangentsBitangents()}this.geom=n;this.bounds=n.getBounds()}render(n,t,r){if(!this.mesh&&this.geom&&this.geom.verticesIndices){let e=this.geom;if(this.geom.vertices.length/3>64e3){e=this.geom.copy();e.unIndex(false,true)}let t;if(this.primitive==this.TRIANGLES)t=n.gl.TRIANGLES;else if(this.primitive==this.LINES)t=n.gl.LINES;else if(this.primitive==this.LINE_STRIP)t=n.gl.LINE_STRIP;else if(this.primitive==this.POINTS)t=n.gl.POINTS;else{E.logWarn("unknown primitive type",this)}this.mesh=new CGL.Mesh(n,e,t)}else{if(this.geom&&this.geom.morphTargets.length){this.morphGeom=this.geom.copy();this.test=B*11.7;if(this.test>=this.geom.morphTargets.length-1)this.test=0;const l=this.geom.morphTargets[Math.floor(this.test)];const u=this.geom.morphTargets[Math.floor(this.test+1)];if(l&&l.vertices&&u){if(this.morphGeom.vertexNormals.length!=l.vertexNormals.length)this.morphGeom.vertexNormals=new Float32Array(l.vertexNormals.length);const c=this.test%1;for(let e=0;e<this.morphGeom.vertices.length;e++){this.morphGeom.vertices[e]=this.geom.vertices[e]+(1-c)*l.vertices[e]+c*u.vertices[e];this.morphGeom.vertexNormals[e]=(1-c)*l.vertexNormals[e]+c*u.vertexNormals[e]}this.mesh.updateNormals(this.morphGeom);this.mesh.updateVertices(this.morphGeom)}}let e=!t&&this.material!=-1&&S.shaders[this.material];if(r)e=false;if(e)n.pushShader(S.shaders[this.material]);const i=n.getShader()||{};const a=i.uniformColorDiffuse;const s=i.uniformPbrMetalness;const o=i.uniformPbrRoughness;if(!S.shaders[this.material]&&re.get()){if(a&&this._matDiffuseColor){this._matDiffuseColorOrig=[a.getValue()[0],a.getValue()[1],a.getValue()[2],a.getValue()[3]];a.setValue(this._matDiffuseColor)}if(s)if(this._matPbrMetalness!=null){this._matPbrMetalnessOrig=s.getValue();s.setValue(this._matPbrMetalness)}else s.setValue(0);if(o)if(this._matPbrRoughness!=null){this._matPbrRoughnessOrig=o.getValue();o.setValue(this._matPbrRoughness)}else{o.setValue(0)}}if(this.mesh)this.mesh.render(n.getShader(),t);if(re.get()){if(a&&this._matDiffuseColor)a.setValue(this._matDiffuseColorOrig);if(s&&this._matPbrMetalnessOrig!=undefined)s.setValue(this._matPbrMetalnessOrig);if(o&&this._matPbrRoughnessOrig!=undefined)o.setValue(this._matPbrRoughnessOrig)}if(e)n.popShader()}}};const z=class{constructor(t,e){this.bounds=new CABLES.CG.BoundingBox;this.meshes=[];this.name=e.name;const n=e.primitives;for(let e=0;e<n.length;e++){const r=new V(this.name,n[e],t,e=>{this.bounds.apply(e.bounds)});r.submeshIndex=e;this.meshes.push(r)}}render(t,n,r,i){for(let e=0;e<this.meshes.length;e++){const a=S.shaders[this.meshes[e].material];if(!n&&a)t.pushShader(S.shaders[this.meshes[e].material]);if(r)r.renderStart(t,i);this.meshes[e].render(t,n,r,i);if(r)r.renderFinish(t);if(!n&&a)t.popShader()}}};const H=class{constructor(e,t){this.isChild=e.isChild||false;this.name=e.name;if(e.hasOwnProperty("camera"))this.camera=e.camera;this.hidden=false;this.mat=mat4.create();this._animMat=mat4.create();this._tempMat=mat4.create();this._tempQuat=quat.create();this._tempRotmat=mat4.create();this.mesh=null;this.children=[];this._node=e;this._gltf=t;this.absMat=mat4.create();this.addTranslate=null;this._tempAnimScale=null;this.addMulMat=null;this.updateMatrix();this._animActions={};this.skinRenderer=null;this.copies=[]}get skin(){if(this._node.hasOwnProperty("skin"))return this._node.skin;else return-1}copy(){this.isCopy=true;const e=new H(this._node,this._gltf);e.copyOf=this;e._animActions=this._animActions;e.children=this.children;e.skinRenderer=new q(e);this.updateMatrix();return e}hasSkin(){if(this._node.hasOwnProperty("skin"))return this._gltf.json.skins[this._node.skin].name||"unknown";return false}initSkin(){if(this.skin>-1){this.skinRenderer=new q(this)}}updateMatrix(){mat4.identity(this.mat);if(this._node.translation)mat4.translate(this.mat,this.mat,this._node.translation);if(this._node.rotation){const e=mat4.create();this._rot=this._node.rotation;mat4.fromQuat(e,this._node.rotation);mat4.mul(this.mat,this.mat,e)}if(this._node.scale){this._scale=this._node.scale;mat4.scale(this.mat,this.mat,this._scale)}if(this._node.hasOwnProperty("mesh")){this.mesh=this._gltf.meshes[this._node.mesh];if(this.isCopy){console.log(this.mesh)}}if(this._node.children){for(let e=0;e<this._node.children.length;e++){this._gltf.json.nodes[e].isChild=true;if(this._gltf.nodes[this._node.children[e]])this._gltf.nodes[this._node.children[e]].isChild=true;this.children.push(this._node.children[e])}}}unHide(){this.hidden=false;for(let e=0;e<this.children.length;e++)if(this.children[e].unHide)this.children[e].unHide()}calcBounds(t,e,n){const r=mat4.create();if(e)mat4.copy(r,e);if(this.mat)mat4.mul(r,r,this.mat);if(this.mesh){const i=this.mesh.bounds.copy();i.mulMat4(r);n.apply(i);if(n.changed){b.push(i._min[0]||0,i._min[1]||0,i._min[2]||0,i._max[0]||0,i._max[1]||0,i._max[2]||0)}}for(let e=0;e<this.children.length;e++){if(t.nodes[this.children[e]]&&t.nodes[this.children[e]].calcBounds){const a=t.nodes[this.children[e]].calcBounds(t,r,n);n.apply(a)}}if(n.changed)return n;else return null}setAnimAction(t){if(!t)return;this._currentAnimaction=t;if(t&&!this._animActions[t]){return null}for(let e in this._animActions[t]){if(e=="translation")this._animTrans=this._animActions[t][e];else if(e=="rotation")this._animRot=this._animActions[t][e];else if(e=="scale")this._animScale=this._animActions[t][e];else console.warn("unknown anim path",e,this._animActions[t][e])}}setAnim(e,t,n){if(!e||!t||!n)return;this._animActions[t]=this._animActions[t]||{};if(this._animActions[t][e])E.warn("animation action path already exists",t,e,this._animActions[t][e]);this._animActions[t][e]=n;if(e=="translation")this._animTrans=n;else if(e=="rotation")this._animRot=n;else if(e=="scale")this._animScale=n;else console.warn("unknown anim path",e,n)}modelMatLocal(){return this._animMat||this.mat}modelMatAbs(){return this.absMat}transform(e,t){if(!t&&t!=0)t=B;this._lastTimeTrans=t;me++;if(!this._animTrans&&!this._animRot&&!this._animScale){mat4.mul(e.mMatrix,e.mMatrix,this.mat);this._animMat=null}else{this._animMat=this._animMat||mat4.create();mat4.identity(this._animMat);const n=true;if(n&&this._animTrans){mat4.translate(this._animMat,this._animMat,[this._animTrans[0].getValue(t),this._animTrans[1].getValue(t),this._animTrans[2].getValue(t)])}else if(this._node.translation)mat4.translate(this._animMat,this._animMat,this._node.translation);if(n&&this._animRot){if(this._animRot[0].defaultEasing==CABLES.EASING_LINEAR)CABLES.Anim.slerpQuaternion(t,this._tempQuat,this._animRot[0],this._animRot[1],this._animRot[2],this._animRot[3]);else if(this._animRot[0].defaultEasing==CABLES.EASING_ABSOLUTE){this._tempQuat[0]=this._animRot[0].getValue(t);this._tempQuat[1]=this._animRot[1].getValue(t);this._tempQuat[2]=this._animRot[2].getValue(t);this._tempQuat[3]=this._animRot[3].getValue(t)}else if(this._animRot[0].defaultEasing==CABLES.EASING_CUBICSPLINE){CABLES.Anim.slerpQuaternion(t,this._tempQuat,this._animRot[0],this._animRot[1],this._animRot[2],this._animRot[3])}mat4.fromQuat(this._tempMat,this._tempQuat);mat4.mul(this._animMat,this._animMat,this._tempMat)}else if(this._rot){}if(n&&this._animScale){if(!this._tempAnimScale)this._tempAnimScale=[1,1,1];this._tempAnimScale[0]=this._animScale[0].getValue(t);this._tempAnimScale[1]=this._animScale[1].getValue(t);this._tempAnimScale[2]=this._animScale[2].getValue(t);mat4.scale(this._animMat,this._animMat,this._tempAnimScale)}else if(this._scale)mat4.scale(this._animMat,this._animMat,this._scale);mat4.mul(e.mMatrix,e.mMatrix,this._animMat)}if(this.addTranslate)mat4.translate(e.mMatrix,e.mMatrix,this.addTranslate);if(this.addMulMat)mat4.mul(e.mMatrix,e.mMatrix,this.addMulMat);mat4.copy(this.absMat,e.mMatrix)}render(t,n,r,i,a,s,o){if(!n)t.pushModelMatrix();if(o===undefined)o=S.time;if(!n||this.skinRenderer)this.transform(t,o);if(this.hidden&&!s){}else{if(this.skinRenderer){this.skinRenderer.time=o;if(!r)this.mesh.render(t,i,this.skinRenderer,o)}else{if(this.mesh&&!r)this.mesh.render(t,i,null,o)}}if(!a&&!this.hidden)for(let e=0;e<this.children.length;e++)if(S.nodes[this.children[e]])S.nodes[this.children[e]].render(t,n,r,i,a,s,o);if(!n)t.popModelMatrix()}};let _=null;function A(){if(_)gui.mainTabs.closeTab(_.id);_=null}function o(t){const n=[];for(let e=0;e<t.length;e++){n.push(Math.round(t[e]*1e3)/1e3)}return n.join(",")}function X(n,r,i){if(!S)return;n+='<tr class="row">';let a="";let s="";for(let t=1;t<i;t++){s+="&nbsp;&nbsp;&nbsp;";let e="identBg";if(t==1)e="identBgLevel0";a+='<td class="ident '+e+'" ><div style=""></div></td>'}let e=CABLES.uuid();n+=a;n+='<td colspan="'+(21-i)+'">';if(r.mesh&&r.mesh.meshes.length)n+='<span class="icon icon-cube"></span>&nbsp;';else n+='<span class="icon icon-box-select"></span> &nbsp;';n+=r.name+"</td><td></td>";if(r.mesh){n+="<td>";for(let e=0;e<r.mesh.meshes.length;e++){if(e>0)n+=", ";n+=r.mesh.meshes[e].name}n+="</td>";n+="<td>";n+=r.hasSkin()||"-";n+="</td>";n+="<td>";let t=0;for(let e=0;e<r.mesh.meshes.length;e++){if(t>0)n+=", ";if(S.json.materials&&r.mesh.meshes[e].hasOwnProperty("material")){if(S.json.materials[r.mesh.meshes[e].material]){n+=S.json.materials[r.mesh.meshes[e].material].name;t++}}}if(t==0)n+="none";n+="</td>"}else{n+="<td>-</td><td>-</td><td>-</td>"}n+="<td>";if(r._node.translation||r._node.rotation||r._node.scale){let e="";if(r._node.translation)e+="Translate: `"+o(r._node.translation)+"` || ";if(r._node.rotation)e+="Rotation: `"+o(r._node.rotation)+"` || ";if(r._node.scale)e+="Scale: `"+o(r._node.scale)+"` || ";n+='<span class="icon icon-gizmo info" data-info="'+e+'"></span> &nbsp;'}if(r._animRot||r._animScale||r._animTrans){let e="Animated: ";if(r._animRot)e+="Rot ";if(r._animScale)e+="Scale ";if(r._animTrans)e+="Trans ";n+='<span class="icon icon-clock info" data-info="'+e+'"></span>&nbsp;'}if(!r._node.translation&&!r._node.rotation&&!r._node.scale&&!r._animRot&&!r._animScale&&!r._animTrans)n+="-";n+="</td>";n+="<td>";let t="";if(r.hidden)t="node-hidden";n+="<a onclick=\"gui.corePatch().getOpById('"+E.id+"').exposeNode('"+r.name+"','transform')\" class=\"treebutton\">Transform</a>";n+=" <a onclick=\"gui.corePatch().getOpById('"+E.id+"').exposeNode('"+r.name+"','hierarchy')\" class=\"treebutton\">Hierarchy</a>";n+=" <a onclick=\"gui.corePatch().getOpById('"+E.id+"').exposeNode('"+r.name+'\')" class="treebutton">Node</a>';if(r.hasSkin())n+=" <a onclick=\"gui.corePatch().getOpById('"+E.id+"').exposeNode('"+r.name+'\',false,{skin:true});" class="treebutton">Skin</a>';n+="</td><td>";n+='&nbsp;<span class="icon iconhover icon-eye '+t+'" onclick="gui.corePatch().getOpById(\''+E.id+"').toggleNodeVisibility('"+r.name+"');this.classList.toggle('node-hidden');\"></span>";n+="</td>";n+="</tr>";if(r.children){for(let e=0;e<r.children.length;e++)n=X(n,S.nodes[r.children[e]],i+1)}return n}function W(t,e){let n="<tr>";n+=" <td>"+e+"</td>";n+=" <td>"+t.name+"</td>";n+=" <td>";const r=JSON.stringify(t,null,4).replaceAll('"',"").replaceAll("\n","<br/>");n+="<span class=\"icon icon-info\" onclick=\"new CABLES.UI.ModalDialog({ 'html': '<pre>"+r+"</pre>', 'title': '"+t.name+"' });\"></span>&nbsp;";if(t.pbrMetallicRoughness&&t.pbrMetallicRoughness.baseColorFactor){let e="";e+=""+Math.round(t.pbrMetallicRoughness.baseColorFactor[0]*255);e+=","+Math.round(t.pbrMetallicRoughness.baseColorFactor[1]*255);e+=","+Math.round(t.pbrMetallicRoughness.baseColorFactor[2]*255);n+='<div style="width:15px;height:15px;background-color:rgb('+e+');display:inline-block">&nbsp;</a>'}n+=' <td style="">'+(S.shaders[e]?"-":"<a onclick=\"gui.corePatch().getOpById('"+E.id+"').assignMaterial('"+t.name+'\')" class="treebutton">Assign</a>')+"<td>";n+="<td>";n+="</tr>";return n}function e(){if(!S)return;const e=performance.now();const i={};let a='<div style="overflow:scroll;width:100%;height:100%">';a+='File: <a href="'+CABLES.platform.getCablesUrl()+"/asset/patches/?filename="+x.get()+'" target="_blank">'+CABLES.basename(x.get())+"</a><br/>";a+="Generator:"+S.json.asset.generator;let t=0;if(S.json.nodes)t=S.json.nodes.length;a+='<div id="groupNodes">Nodes ('+t+")</div>";a+='<table id="sectionNodes" class="table treetable">';a+="<tr>";a+=' <th colspan="21">Name</th>';a+=" <th>Mesh</th>";a+=" <th>Skin</th>";a+=" <th>Material</th>";a+=" <th>Transform</th>";a+=" <th>Expose</th>";a+=" <th></th>";a+="</tr>";for(let e=0;e<S.nodes.length;e++){if(!S.nodes[e].isChild)a=X(a,S.nodes[e],1)}a+="</table>";let n=0;if(S.json.materials)n=S.json.materials.length;a+='<div id="groupMaterials">Materials ('+n+")</div>";if(!S.json.materials||S.json.materials.length==0){}else{a+='<table id="materialtable"  class="table treetable">';a+="<tr>";a+=" <th>Index</th>";a+=" <th>Name</th>";a+=" <th>Color</th>";a+=" <th>Function</th>";a+=" <th></th>";a+="</tr>";for(let e=0;e<S.json.materials.length;e++){a+=W(S.json.materials[e],e)}a+="</table>"}a+='<div id="groupMeshes">Meshes ('+S.json.meshes.length+")</div>";a+='<table id="meshestable"  class="table treetable">';a+="<tr>";a+=" <th>Name</th>";a+=" <th>Node</th>";a+=" <th>Material</th>";a+=" <th>Vertices</th>";a+=" <th>Attributes</th>";a+="</tr>";let s=[];i.meshes=0;for(let r=0;r<S.json.meshes.length;r++){a+="<tr>";a+="<td>"+S.json.meshes[r].name+"</td>";a+="<td>";let e=0;let t="";for(var o=0;o<S.json.nodes.length;o++){if(S.json.nodes[o].mesh==r){e++;if(e==1){t=S.json.nodes[o].name}}}if(e>1)a+=e+" nodes ("+t+" ...)";else a+=t;a+="</td>";a+="<td>";for(var o=0;o<S.json.meshes[r].primitives.length;o++){if(S.json.meshes[r].primitives[o].hasOwnProperty("material")){if(S.json.materials[S.json.meshes[r]]){a+=S.json.materials[S.json.meshes[r].primitives[o].material].name+" "}}else a+="None"}a+="</td>";a+="<td>";let n=0;for(var o=0;o<S.json.meshes[r].primitives.length;o++){if(S.json.meshes[r].primitives[o].attributes.POSITION!=undefined){let e=parseInt(S.json.accessors[S.json.meshes[r].primitives[o].attributes.POSITION].count);n+=e;a+=""+e+"<br/>"}else a+="-<br/>"}if(S.json.meshes[r].primitives.length>0)a+="="+n;a+="</td>";a+='<td style="vertical-align:top;">';for(let e=0;e<S.json.meshes[r].primitives.length;e++){a+=Object.keys(S.json.meshes[r].primitives[e].attributes);a+=" <a onclick=\"gui.corePatch().getOpById('"+E.id+"').exposeGeom('"+S.json.meshes[r].name+"',"+e+')" class="treebutton">Geometry</a>';a+="<br/>"}a+="</td>";a+="</tr>";for(let t=0;t<S.json.meshes[r].primitives.length;t++){const p=S.json.accessors[S.json.meshes[r].primitives[t].indices];if(p){let e=p.bufferView;if(s.indexOf(e)==-1){s.push(e);if(S.json.bufferViews[e])i.meshes+=S.json.bufferViews[e].byteLength}}for(let e in S.json.meshes[r].primitives[t].attributes){const g=S.json.meshes[r].primitives[t].attributes[e];const m=S.json.accessors[g].bufferView;if(s.indexOf(m)==-1){s.push(m);if(S.json.bufferViews[m])i.meshes+=S.json.bufferViews[m].byteLength}}}}a+="</table>";let r=0;let l=0;if(S.json.animations){l=S.json.animations.length;for(let e=0;e<S.json.animations.length;e++)r+=S.json.animations[e].samplers.length}a+='<div id="groupAnims">Animations ('+l+"/"+r+")</div>";if(S.json.animations){a+='<table id="sectionAnim" class="table treetable">';a+="<tr>";a+="  <th>Name</th>";a+="  <th>Target node</th>";a+="  <th>Path</th>";a+="  <th>Interpolation</th>";a+="  <th>Keys</th>";a+="</tr>";i.animations=0;for(let n=0;n<S.json.animations.length;n++){for(let t=0;t<S.json.animations[n].samplers.length;t++){let e=S.json.accessors[S.json.animations[n].samplers[t].input].bufferView;if(s.indexOf(e)==-1){s.push(e);i.animations+=S.json.bufferViews[e].byteLength}e=S.json.accessors[S.json.animations[n].samplers[t].output].bufferView;if(s.indexOf(e)==-1){s.push(e);i.animations+=S.json.bufferViews[e].byteLength}}for(let e=0;e<S.json.animations[n].channels.length;e++){a+="<tr>";a+="  <td> Anim "+n+": "+S.json.animations[n].name+"</td>";a+="  <td>"+S.nodes[S.json.animations[n].channels[e].target.node].name+"</td>";a+="  <td>";a+=S.json.animations[n].channels[e].target.path+" ";a+="  </td>";const v=S.json.animations[n].channels[e].sampler;const b=S.json.animations[n].samplers[v];a+="  <td>"+b.interpolation+"</td>";a+="  <td>"+S.json.accessors[b.output].count;a+="</td>";a+="</tr>"}}a+="</table>"}else{}let u=0;if(S.json.images)u=S.json.images.length;a+='<div id="groupImages">Images ('+u+")</div>";if(S.json.images){a+='<table id="sectionImages" class="table treetable">';a+="<tr>";a+="  <th>name</th>";a+="  <th>type</th>";a+="  <th>func</th>";a+="</tr>";i.images=0;for(let t=0;t<S.json.images.length;t++){if(S.json.images[t].bufferView)i.images+=S.json.bufferViews[S.json.images[t].bufferView].byteLength;a+="<tr>";a+="<td>"+S.json.images[t].name+"</td>";a+="<td>"+S.json.images[t].mimeType+"</td>";a+="<td>";let e=S.json.images[t].name;if(e===undefined)e=S.json.images[t].bufferView;a+="<a onclick=\"gui.corePatch().getOpById('"+E.id+"').exposeTexture('"+e+'\')" class="treebutton">Expose</a>';a+="</td>";a+="<tr>"}a+="</table>"}let c=0;if(S.json.cameras)c=S.json.cameras.length;a+='<div id="groupCameras">Cameras ('+c+")</div>";if(S.json.cameras){a+='<table id="sectionCameras" class="table treetable">';a+="<tr>";a+="  <th>name</th>";a+="  <th>type</th>";a+="  <th>info</th>";a+="</tr>";for(let e=0;e<S.json.cameras.length;e++){a+="<tr>";a+="<td>"+S.json.cameras[e].name+"</td>";a+="<td>"+S.json.cameras[e].type+"</td>";a+="<td>";if(S.json.cameras[e].perspective){a+="yfov: "+Math.round(S.json.cameras[e].perspective.yfov*100)/100;a+=", ";a+="zfar: "+Math.round(S.json.cameras[e].perspective.zfar*100)/100;a+=", ";a+="znear: "+Math.round(S.json.cameras[e].perspective.znear*100)/100}a+="</td>";a+="<tr>"}a+="</table>"}let h=0;if(S.json.skins)h=S.json.skins.length;a+='<div id="groupSkins">Skins ('+h+")</div>";if(S.json.skins){a+='<table id="sectionSkins" class="table treetable">';a+="<tr>";a+="  <th>name</th>";a+="  <th></th>";a+="  <th>total joints</th>";a+="</tr>";for(let e=0;e<S.json.skins.length;e++){a+="<tr>";a+="<td>"+S.json.skins[e].name+"</td>";a+="<td>"+"</td>";a+="<td>"+S.json.skins[e].joints.length+"</td>";a+="<td>";a+="</td>";a+="<tr>"}a+="</table>"}if(S.timing){a+='<div id="groupTiming">Debug Loading Timing </div>';a+='<table id="sectionTiming" class="table treetable">';a+="<tr>";a+="  <th>task</th>";a+="  <th>time used</th>";a+="</tr>";let e=0;for(let e=0;e<S.timing.length-1;e++){a+="<tr>";a+="  <td>"+S.timing[e][0]+"</td>";a+="  <td>"+(S.timing[e+1][1]-S.timing[e][1])+" ms</td>";a+="</tr>"}a+="</table>"}let f=0;if(S.json.buffers)f=S.json.buffers[0].byteLength;a+='<div id="groupBinary">File Size Allocation ('+Math.round(f/1024)+"k )</div>";a+='<table id="sectionBinary" class="table treetable">';a+="<tr>";a+="  <th>name</th>";a+="  <th>size</th>";a+="  <th>%</th>";a+="</tr>";let d=f;for(let e in i){a+="<tr>";a+="<td>"+e+"</td>";a+="<td>"+Y(i[e])+" </td>";a+="<td>"+Math.round(i[e]/f*100)+"% </td>";a+="<tr>";d-=i[e]}if(d!=0){a+="<tr>";a+="<td>unknown</td>";a+="<td>"+Y(d)+" </td>";a+="<td>"+Math.round(d/f*100)+"% </td>";a+="<tr>"}a+="</table>";a+="</div>";_=new CABLES.UI.Tab("GLTF "+CABLES.basename(x.get()),{icon:"cube",infotext:"tab_gltf",padding:true,singleton:true});gui.mainTabs.addTab(_,true);_.addEventListener("close",A);_.html(a);CABLES.UI.Collapsable.setup(ele.byId("groupNodes"),ele.byId("sectionNodes"),false);CABLES.UI.Collapsable.setup(ele.byId("groupMaterials"),ele.byId("materialtable"),true);CABLES.UI.Collapsable.setup(ele.byId("groupAnims"),ele.byId("sectionAnim"),true);CABLES.UI.Collapsable.setup(ele.byId("groupMeshes"),ele.byId("meshestable"),true);CABLES.UI.Collapsable.setup(ele.byId("groupCameras"),ele.byId("sectionCameras"),true);CABLES.UI.Collapsable.setup(ele.byId("groupImages"),ele.byId("sectionImages"),true);CABLES.UI.Collapsable.setup(ele.byId("groupSkins"),ele.byId("sectionSkins"),true);CABLES.UI.Collapsable.setup(ele.byId("groupBinary"),ele.byId("sectionBinary"),true);CABLES.UI.Collapsable.setup(ele.byId("groupTiming"),ele.byId("sectionTiming"),true);gui.maintabPanel.show(true)}function Y(e){if(e>1024)return Math.round(e/1024)+" kb";if(e>1024*500)return Math.round(e/1024)+" mb";else return e+" bytes"}const q=class{constructor(e){this._mod=null;this._node=e;this._lastTime=0;this._matArr=[];this._m=mat4.create();this._invBindMatrix=mat4.create();this.identity=true}renderFinish(e){e.popModelMatrix();this._mod.unbind()}renderStart(e,t){if(!this._mod){this._mod=new CGL.ShaderModifier(e,E.name+this._node.name);this._mod.addModule({priority:-2,name:"MODULE_VERTEX_POSITION",srcHeadVert:l.skin_head_vert||"",srcBodyVert:l.skin_vert||""});this._mod.addUniformVert("m4[]","MOD_boneMats",[]);const i=vec3.create()}const n=this._node.skin;const r=S.json.skins[n].joints.length*16;{if(this._matArr.length!=r)this._matArr.length=r;for(let e=0;e<S.json.skins[n].joints.length;e++){const a=e*16;const s=S.json.skins[n].joints[e];const o=S.nodes[s];for(let e=0;e<16;e++)this._invBindMatrix[e]=S.accBuffers[S.json.skins[n].inverseBindMatrices][a+e];mat4.mul(this._m,o.modelMatAbs(),this._invBindMatrix);for(let e=0;e<this._m.length;e++)this._matArr[a+e]=this._m[e]}this._mod.setUniformValue("MOD_boneMats",this._matArr);this._lastTime=t}this._mod.define("SKIN_NUM_BONES",S.json.skins[n].joints.length);this._mod.bind();e.pushModelMatrix();if(this.identity)mat4.identity(e.mMatrix)}};const Z=E.inTrigger("Render"),t=E.inString("data"),x=E.inUrl("glb File",[".glb"]),J=E.inBool("Draw",true),n=E.inDropDown("Camera",["None"],"None"),Q=E.inString("Animation",""),K=E.inTriggerButton("Show Structure"),i=E.inSwitch("Center",["None","XYZ","XZ"],"XYZ"),a=E.inBool("Rescale",true),s=E.inFloat("Rescale Size",2.5),u=E.inFloat("Time"),c=E.inBool("Sync to timeline",false),$=E.inBool("Loop",true),ee=E.inSwitch("Normals Format",["XYZ","X-ZY"],"XYZ"),te=E.inSwitch("Vertices Format",["XYZ","XZ-Y"],"XYZ"),h=E.inBool("Calc Normals",false),f=E.inObject("Materials"),ne=E.inArray("Hide Nodes"),re=E.inBool("Use Material Properties",false),d=E.inBool("Active",true),ie=E.outTrigger("Render Before"),p=E.outTrigger("Next"),ae=E.outString("Generator"),se=E.outNumber("GLTF Version"),oe=E.outArray("GLTF Extensions Used"),le=E.outNumber("Anim Length",0),ue=E.outNumber("Anim Time",0),ce=E.outObject("Json"),he=E.outArray("Anims"),fe=E.outArray("BoundingPoints"),de=E.outObject("Bounds"),pe=E.outTrigger("Finished"),ge=E.outBool("Loading");E.setPortGroup("Timing",[u,c,$]);const T=true;const g=E.patch.cgl;x.onChange=te.onChange=h.onChange=ee.onChange=L;E.toWorkPortsNeedToBeLinked(Z);let me=0;let m=false;let v=null;let b=[];let S=null;let y=0;let B=0;let O=true;let ve=null;let D=null;let I=null;const be=vec3.create();let _e=0;let Ee=false;const M=vec3.create();K.onTriggered=e;t.setUiAttribs({hideParam:true,hidePort:true});t.onChange=Be;ne.onChange=R;Q.onChange=De;E.setPortGroup("Transform",[a,s,i]);i.onChange=Ce;function Fe(){const t=["None"];if(S){for(let e=0;e<S.nodes.length;e++){if(S.nodes[e].camera>=0){t.push(S.nodes[e].name)}}}n.uiAttribs.values=t}function Ce(){Ee=i.get()!="None";if(S&&S.bounds){M.set(S.bounds.center);M[0]=-M[0];M[1]=-M[1];M[2]=-M[2];if(i.get()=="XZ")M[1]=-S.bounds.minY}}a.onChange=function(){s.setUiAttribs({greyout:!a.get()})};f.onChange=function(){O=true};E.onDelete=function(){A()};c.onChange=function(){u.setUiAttribs({greyout:c.get()})};n.onChange=Ae;function Ae(){v=null;if(!S)return;for(let e=0;e<S.nodes.length;e++){if(S.nodes[e].name==n.get())v=new r(S,S.nodes[e])}}Z.onTriggered=function(){if(!m)return;if(!d.get())return;me=0;if(c.get())B=E.patch.timer.getTime();else B=Math.max(0,u.get());if($.get()){B%=y;if(B<_e)pe.trigger()}else{if(y>0&&B>=y)pe.trigger()}_e=B;g.pushModelMatrix();ue.set(B||0);if(m&&S&&S.bounds){if(a.get()){let e=s.get()/S.bounds.maxAxis;S.scale=e;vec3.set(be,e,e,e);mat4.scale(g.mMatrix,g.mMatrix,be)}if(Ee){mat4.translate(g.mMatrix,g.mMatrix,M)}}let e=g.tempData.currentScene||null;g.tempData.currentScene=S;ie.trigger();if(m){if(O)Se();if(v)v.start(B);if(S){S.time=B;{if(S.bounds&&g.shouldDrawHelpers(E)){if(CABLES.UI&&gui.shouldDrawOverlay)g.pushShader(CABLES.GL_MARKER.getDefaultShader(g));else g.pushShader(CABLES.GL_MARKER.getSelectedShader(g));S.bounds.render(g);g.popShader()}if(J.get()){for(let e=0;e<S.nodes.length;e++)if(!S.nodes[e].isChild)S.nodes[e].render(g)}else{for(let e=0;e<S.nodes.length;e++)if(!S.nodes[e].isChild)S.nodes[e].render(g,false,true)}}}}p.trigger();g.tempData.currentScene=e;g.popModelMatrix();if(v)v.end()};function xe(){if(!S){E.setUiError("nogltf","gltf not found");return}E.setUiError("nogltf",null);if(S.loadingMeshes>0){setTimeout(xe,100);return}S.timing.push(["finishLoading()",Math.round(performance.now()-S.startTime)]);O=true;le.set(y);S.bounds=new CABLES.CG.BoundingBox;if(!S)E.setUiError("urlerror",'could not load gltf:<br/>"'+x.get()+'"',2);else E.setUiError("urlerror",null);S.timing.push(["start calc bounds",Math.round(performance.now()-S.startTime)]);for(let e=0;e<S.nodes.length;e++){const t=S.nodes[e];t.updateMatrix();if(!t.isChild)t.calcBounds(S,null,S.bounds)}if(S.bounds)de.set(S.bounds);S.timing.push(["calced bounds",Math.round(performance.now()-S.startTime)]);R();S.timing.push(["hideNodesFromData",Math.round(performance.now()-S.startTime)]);if(_)e();S.timing.push(["printinfo",Math.round(performance.now()-S.startTime)]);Fe();Ae();fe.set(b);if(S){if(x.get()&&!x.get().startsWith("data:")){E.setUiAttrib({extendTitle:CABLES.basename(x.get())})}S.loaded=Date.now()}if(S){for(let e=0;e<S.nodes.length;e++){if(!S.nodes[e].isChild){S.nodes[e].render(g,false,true,true,false,true,0)}}for(let e=0;e<S.nodes.length;e++){const t=S.nodes[e];t.children=Me(t.children)}}Ce();De();ge.set(false);g.patch.loading.finished(D);D=null;E.setUiAttrib({accBuffersDelete:CABLES.basename(x.get())});if(S.accBuffersDelete){for(let e=0;e<S.accBuffersDelete.length;e++){S.accBuffers[S.accBuffersDelete[e]]=null}}S.chunks=null;m=true}function Te(e){if(!d.get())return;if(!D)D=g.patch.loading.start("gltfScene",x.get(),E);let t=x.get();let n=E.patch.getFilePath(String(x.get()));if(x.get()&&!x.get().startsWith("data:")){if(e===true)n+="?rnd="+CABLES.generateUUID()}m=false;ge.set(true);fetch(n).then(e=>{return e.arrayBuffer()}).then(e=>{if(x.get()!=t){g.patch.loading.finished(D);D=null;return}b=[];y=0;S=G(e);xe()}).catch(e=>{console.log(e)});A();const r=new XMLHttpRequest;r.open("GET",n,true);r.responseType="arraybuffer";g.patch.loading.addAssetLoadingTask(()=>{})}E.onFileChanged=function(e){if(x.get()&&x.get().indexOf(e)>-1){L(true)}};d.onChange=()=>{if(d.get())L();if(!d.get()){S=null}};function L(e){clearTimeout(ve);ve=setTimeout(function(){Te(e)},30)}function Se(){if(!S)return;S.shaders={};if(f.links.length==1&&f.get()){const n=f.links[0].portOut.op;const r=n.getPort("Shader");const i=n.getPort("Material Name");if(!r&&!i){const a=f.get();for(let t in a){if(a[t]&&S.json.materials)for(let e=0;e<S.json.materials.length;e++){if(S.json.materials[e].name==t){if(S.shaders[e]){n.warn("double material assignment:",name)}S.shaders[e]=a[t]}}}}}if(f.get()){for(let e=0;e<f.links.length;e++){const t=f.links[e].portOut.op;const r=t.getPort("Shader");const i=t.getPort("Material Name");if(r&&i&&r.get()){const name=i.get();if(S.json.materials)for(let e=0;e<S.json.materials.length;e++)if(S.json.materials[e].name==name){if(S.shaders[e]){t.warn("double material assignment:",name)}S.shaders[e]=r.get()}}}}O=false;if(_)e()}function ye(){const t=ne.get();if(!S||!I||!I.hiddenNodes)return;if(!t){return}for(let e=0;e<t.length;e++){const n=S.getNode(t[e]);if(n)n.hidden=true}}function R(){if(!I)Be();if(!S)return;S.unHideAll();if(I&&I.hiddenNodes){for(const e in I.hiddenNodes){const t=S.getNode(e);if(t)t.hidden=true;else E.verbose("node to be hidden not found",e,t)}}ye()}function Be(){I=t.get();if(!I||I==="")I={};else I=JSON.parse(I);if(S)R();return I}function Oe(){t.set(JSON.stringify(I))}function De(){if(S&&S.nodes){for(let e=0;e<S.nodes.length;e++){S.nodes[e].setAnimAction(Q.get())}}}function Ie(t,n){for(let e=0;e<S.nodes.length;e++){if(S.nodes[e].children.indexOf(n)>=0){t.push(S.nodes[e]);if(S.nodes[e].isChild)Ie(t,e)}}}E.exposeTexture=function(e){const t=gui.corePatch().addOp("Ops.Gl.GLTF.GltfTexture");t.getPort("Name").set(e);w(t,1);E.patch.link(E,p.name,t,"Render");gui.patchView.testCollision(t);gui.patchView.centerSelectOp(t.id,true)};E.exposeGeom=function(e,t){const n=gui.corePatch().addOp("Ops.Gl.GLTF.GltfGeometry");n.getPort("Name").set(e);n.getPort("Submesh").set(t);w(n,1);E.patch.link(E,p.name,n,"Update");gui.patchView.testCollision(n);gui.patchView.centerSelectOp(n.id,true)};function w(e,t){t=t||1;e.setUiAttrib({subPatch:E.uiAttribs.subPatch,translate:{x:E.uiAttribs.translate.x,y:E.uiAttribs.translate.y+t*CABLES.GLUI.glUiConfig.newOpDistanceY}})}E.exposeNode=function(n,e,r){let t=e=="hierarchy";if(t){let i=[];for(let e=0;e<S.nodes.length;e++){if(S.nodes[e].name==n){let t=[];const a=S.nodes[e];Ie(t,e);t=t.reverse();t.push(a,a);let n=p.name;let r=E;for(let e=0;e<t.length;e++){const s=gui.corePatch().addOp("Ops.Gl.GLTF.GltfNode_v2");s.getPort("Node Name").set(t[e].name);E.patch.link(r,n,s,"Render");w(s,e);if(e==t.length-1){s.getPort("Transformation").set(false)}else{s.getPort("Draw Mesh").set(false);s.getPort("Draw Childs").set(false)}n="Next";r=s;i.push(s);gui.patchView.testCollision(s)}}}for(let e=0;e<i.length;e++){i[e].selectChilds()}}else{let t="Ops.Gl.GLTF.GltfNode_v2";if(r&&r.skin)t="Ops.Gl.GLTF.GltfSkin";if(e=="transform")t="Ops.Gl.GLTF.GltfNodeTransform_v2";gui.serverOps.loadOpLibs(t,()=>{let e=gui.corePatch().addOp(t);e.getPort("Node Name").set(n);w(e);E.patch.link(E,p.name,e,"Render");gui.patchView.testCollision(e);gui.patchView.centerSelectOp(e.id,true)})}gui.closeModal()};E.assignMaterial=function(e){const t=gui.corePatch().addOp("Ops.Gl.GLTF.GltfSetMaterial");t.getPort("Material Name").set(e);E.patch.link(E,f.name,t,"Material");w(t);gui.patchView.testCollision(t);gui.patchView.centerSelectOp(t.id,true);gui.closeModal()};E.toggleNodeVisibility=function(e){const t=S.getNode(e);t.hidden=!t.hidden;I.hiddenNodes=I.hiddenNodes||{};if(t)if(t.hidden)I.hiddenNodes[e]=true;else delete I.hiddenNodes[e];Oe()};function Me(n){const r={},i=[];for(let e=0,t=n.length;e<t;++e){if(!r.hasOwnProperty(n[e])){i.push(n[e]);r[n[e]]=1}}return i}}};CABLES.OPS["a9c59d94-8aea-4c20-ab5d-63ce46ecfa16"]={f:Ops.Gl.GLTF.GltfScene_v3,objName:"Ops.Gl.GLTF.GltfScene_v3"};window.addEventListener("load",function(e){CABLES.jsLoaded=new Event("CABLES.jsLoaded");document.dispatchEvent(CABLES.jsLoaded)});(function(e,t){typeof exports==="object"&&typeof module!=="undefined"?t(exports):typeof define==="function"&&define.amd?define(["exports"],t):(e=e||self,t(e.opentype={}))})(this,function(T){"use strict";if(!String.prototype.codePointAt){(function(){var e=function(){try{var e={};var t=Object.defineProperty;var n=t(e,e,e)&&t}catch(e){}return n}();var t=function(e){if(this==null){throw TypeError()}var t=String(this);var n=t.length;var r=e?Number(e):0;if(r!=r){r=0}if(r<0||r>=n){return undefined}var i=t.charCodeAt(r);var a;if(i>=55296&&i<=56319&&n>r+1){a=t.charCodeAt(r+1);if(a>=56320&&a<=57343){return(i-55296)*1024+a-56320+65536}}return i};if(e){e(String.prototype,"codePointAt",{value:t,configurable:true,writable:true})}else{String.prototype.codePointAt=t}})()}var L=0;var R=-3;function w(){this.table=new Uint16Array(16);this.trans=new Uint16Array(288)}function N(e,t){this.source=e;this.sourceIndex=0;this.tag=0;this.bitcount=0;this.dest=t;this.destLen=0;this.ltree=new w;this.dtree=new w}var P=new w;var G=new w;var V=new Uint8Array(30);var z=new Uint16Array(30);var H=new Uint8Array(30);var X=new Uint16Array(30);var W=new Uint8Array([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]);var Y=new w;var f=new Uint8Array(288+32);function q(e,t,n,r){var i,a;for(i=0;i<n;++i){e[i]=0}for(i=0;i<30-n;++i){e[i+n]=i/n|0}for(a=r,i=0;i<30;++i){t[i]=a;a+=1<<e[i]}}function Z(e,t){var n;for(n=0;n<7;++n){e.table[n]=0}e.table[7]=24;e.table[8]=152;e.table[9]=112;for(n=0;n<24;++n){e.trans[n]=256+n}for(n=0;n<144;++n){e.trans[24+n]=n}for(n=0;n<8;++n){e.trans[24+144+n]=280+n}for(n=0;n<112;++n){e.trans[24+144+8+n]=144+n}for(n=0;n<5;++n){t.table[n]=0}t.table[5]=32;for(n=0;n<32;++n){t.trans[n]=n}}var J=new Uint16Array(16);function Q(e,t,n,r){var i,a;for(i=0;i<16;++i){e.table[i]=0}for(i=0;i<r;++i){e.table[t[n+i]]++}e.table[0]=0;for(a=0,i=0;i<16;++i){J[i]=a;a+=e.table[i]}for(i=0;i<r;++i){if(t[n+i]){e.trans[J[t[n+i]]++]=i}}}function K(e){if(!e.bitcount--){e.tag=e.source[e.sourceIndex++];e.bitcount=7}var t=e.tag&1;e.tag>>>=1;return t}function d(e,t,n){if(!t){return n}while(e.bitcount<24){e.tag|=e.source[e.sourceIndex++]<<e.bitcount;e.bitcount+=8}var r=e.tag&65535>>>16-t;e.tag>>>=t;e.bitcount-=t;return r+n}function $(e,t){while(e.bitcount<24){e.tag|=e.source[e.sourceIndex++]<<e.bitcount;e.bitcount+=8}var n=0,r=0,i=0;var a=e.tag;do{r=2*r+(a&1);a>>>=1;++i;n+=t.table[i];r-=t.table[i]}while(r>=0);e.tag=a;e.bitcount-=i;return t.trans[n+r]}function ee(e,t,n){var r,i,a;var s,o,l;r=d(e,5,257);i=d(e,5,1);a=d(e,4,4);for(s=0;s<19;++s){f[s]=0}for(s=0;s<a;++s){var u=d(e,3,0);f[W[s]]=u}Q(Y,f,0,19);for(o=0;o<r+i;){var c=$(e,Y);switch(c){case 16:var h=f[o-1];for(l=d(e,2,3);l;--l){f[o++]=h}break;case 17:for(l=d(e,3,3);l;--l){f[o++]=0}break;case 18:for(l=d(e,7,11);l;--l){f[o++]=0}break;default:f[o++]=c;break}}Q(t,f,0,r);Q(n,f,r,i)}function te(e,t,n){while(1){var r=$(e,t);if(r===256){return L}if(r<256){e.dest[e.destLen++]=r}else{var i,a,s;var o;r-=257;i=d(e,V[r],z[r]);a=$(e,n);s=e.destLen-d(e,H[a],X[a]);for(o=s;o<s+i;++o){e.dest[e.destLen++]=e.dest[o]}}}}function ne(e){var t,n;var r;while(e.bitcount>8){e.sourceIndex--;e.bitcount-=8}t=e.source[e.sourceIndex+1];t=256*t+e.source[e.sourceIndex];n=e.source[e.sourceIndex+3];n=256*n+e.source[e.sourceIndex+2];if(t!==(~n&65535)){return R}e.sourceIndex+=4;for(r=t;r;--r){e.dest[e.destLen++]=e.source[e.sourceIndex++]}e.bitcount=0;return L}function re(e,t){var n=new N(e,t);var r,i,a;do{r=K(n);i=d(n,2,0);switch(i){case 0:a=ne(n);break;case 1:a=te(n,P,G);break;case 2:ee(n,n.ltree,n.dtree);a=te(n,n.ltree,n.dtree);break;default:a=R}if(a!==L){throw new Error("Data error")}}while(!r);if(n.destLen<n.dest.length){if(typeof n.dest.slice==="function"){return n.dest.slice(0,n.destLen)}else{return n.dest.subarray(0,n.destLen)}}return n.dest}Z(P,G);q(V,z,4,3);q(H,X,2,1);V[28]=0;z[28]=258;var ie=re;function ae(e,t,n,r,i){return Math.pow(1-i,3)*e+3*Math.pow(1-i,2)*i*t+3*(1-i)*Math.pow(i,2)*n+Math.pow(i,3)*r}function o(){this.x1=Number.NaN;this.y1=Number.NaN;this.x2=Number.NaN;this.y2=Number.NaN}o.prototype.isEmpty=function(){return isNaN(this.x1)||isNaN(this.y1)||isNaN(this.x2)||isNaN(this.y2)};o.prototype.addPoint=function(e,t){if(typeof e==="number"){if(isNaN(this.x1)||isNaN(this.x2)){this.x1=e;this.x2=e}if(e<this.x1){this.x1=e}if(e>this.x2){this.x2=e}}if(typeof t==="number"){if(isNaN(this.y1)||isNaN(this.y2)){this.y1=t;this.y2=t}if(t<this.y1){this.y1=t}if(t>this.y2){this.y2=t}}};o.prototype.addX=function(e){this.addPoint(e,null)};o.prototype.addY=function(e){this.addPoint(null,e)};o.prototype.addBezier=function(e,t,n,r,i,a,s,o){var l=[e,t];var u=[n,r];var c=[i,a];var h=[s,o];this.addPoint(e,t);this.addPoint(s,o);for(var f=0;f<=1;f++){var d=6*l[f]-12*u[f]+6*c[f];var p=-3*l[f]+9*u[f]-9*c[f]+3*h[f];var g=3*u[f]-3*l[f];if(p===0){if(d===0){continue}var m=-g/d;if(0<m&&m<1){if(f===0){this.addX(ae(l[f],u[f],c[f],h[f],m))}if(f===1){this.addY(ae(l[f],u[f],c[f],h[f],m))}}continue}var v=Math.pow(d,2)-4*g*p;if(v<0){continue}var b=(-d+Math.sqrt(v))/(2*p);if(0<b&&b<1){if(f===0){this.addX(ae(l[f],u[f],c[f],h[f],b))}if(f===1){this.addY(ae(l[f],u[f],c[f],h[f],b))}}var _=(-d-Math.sqrt(v))/(2*p);if(0<_&&_<1){if(f===0){this.addX(ae(l[f],u[f],c[f],h[f],_))}if(f===1){this.addY(ae(l[f],u[f],c[f],h[f],_))}}}};o.prototype.addQuad=function(e,t,n,r,i,a){var s=e+2/3*(n-e);var o=t+2/3*(r-t);var l=s+1/3*(i-e);var u=o+1/3*(a-t);this.addBezier(e,t,s,o,l,u,i,a)};function p(){this.commands=[];this.fill="black";this.stroke=null;this.strokeWidth=1}p.prototype.moveTo=function(e,t){this.commands.push({type:"M",x:e,y:t})};p.prototype.lineTo=function(e,t){this.commands.push({type:"L",x:e,y:t})};p.prototype.curveTo=p.prototype.bezierCurveTo=function(e,t,n,r,i,a){this.commands.push({type:"C",x1:e,y1:t,x2:n,y2:r,x:i,y:a})};p.prototype.quadTo=p.prototype.quadraticCurveTo=function(e,t,n,r){this.commands.push({type:"Q",x1:e,y1:t,x:n,y:r})};p.prototype.close=p.prototype.closePath=function(){this.commands.push({type:"Z"})};p.prototype.extend=function(e){if(e.commands){e=e.commands}else if(e instanceof o){var t=e;this.moveTo(t.x1,t.y1);this.lineTo(t.x2,t.y1);this.lineTo(t.x2,t.y2);this.lineTo(t.x1,t.y2);this.close();return}Array.prototype.push.apply(this.commands,e)};p.prototype.getBoundingBox=function(){var e=new o;var t=0;var n=0;var r=0;var i=0;for(var a=0;a<this.commands.length;a++){var s=this.commands[a];switch(s.type){case"M":e.addPoint(s.x,s.y);t=r=s.x;n=i=s.y;break;case"L":e.addPoint(s.x,s.y);r=s.x;i=s.y;break;case"Q":e.addQuad(r,i,s.x1,s.y1,s.x,s.y);r=s.x;i=s.y;break;case"C":e.addBezier(r,i,s.x1,s.y1,s.x2,s.y2,s.x,s.y);r=s.x;i=s.y;break;case"Z":r=t;i=n;break;default:throw new Error("Unexpected path command "+s.type)}}if(e.isEmpty()){e.addPoint(0,0)}return e};p.prototype.draw=function(e){e.beginPath();for(var t=0;t<this.commands.length;t+=1){var n=this.commands[t];if(n.type==="M"){e.moveTo(n.x,n.y)}else if(n.type==="L"){e.lineTo(n.x,n.y)}else if(n.type==="C"){e.bezierCurveTo(n.x1,n.y1,n.x2,n.y2,n.x,n.y)}else if(n.type==="Q"){e.quadraticCurveTo(n.x1,n.y1,n.x,n.y)}else if(n.type==="Z"){e.closePath()}}if(this.fill){e.fillStyle=this.fill;e.fill()}if(this.stroke){e.strokeStyle=this.stroke;e.lineWidth=this.strokeWidth;e.stroke()}};p.prototype.toPathData=function(t){t=t!==undefined?t:2;function i(e){if(Math.round(e)===e){return""+Math.round(e)}else{return e.toFixed(t)}}function e(){var e=arguments;var t="";for(var n=0;n<arguments.length;n+=1){var r=e[n];if(r>=0&&n>0){t+=" "}t+=i(r)}return t}var n="";for(var r=0;r<this.commands.length;r+=1){var a=this.commands[r];if(a.type==="M"){n+="M"+e(a.x,a.y)}else if(a.type==="L"){n+="L"+e(a.x,a.y)}else if(a.type==="C"){n+="C"+e(a.x1,a.y1,a.x2,a.y2,a.x,a.y)}else if(a.type==="Q"){n+="Q"+e(a.x1,a.y1,a.x,a.y)}else if(a.type==="Z"){n+="Z"}}return n};p.prototype.toSVG=function(e){var t='<path d="';t+=this.toPathData(e);t+='"';if(this.fill&&this.fill!=="black"){if(this.fill===null){t+=' fill="none"'}else{t+=' fill="'+this.fill+'"'}}if(this.stroke){t+=' stroke="'+this.stroke+'" stroke-width="'+this.strokeWidth+'"'}t+="/>";return t};p.prototype.toDOMElement=function(e){var t=this.toPathData(e);var n=document.createElementNS("http://www.w3.org/2000/svg","path");n.setAttribute("d",t);return n};function se(e){throw new Error(e)}function oe(e,t){if(!e){se(t)}}var A={fail:se,argument:oe,assert:oe};var le=32768;var ue=2147483648;var ce={};var y={};var l={};function e(e){return function(){return e}}y.BYTE=function(e){A.argument(e>=0&&e<=255,"Byte value should be between 0 and 255.");return[e]};l.BYTE=e(1);y.CHAR=function(e){return[e.charCodeAt(0)]};l.CHAR=e(1);y.CHARARRAY=function(e){if(typeof e==="undefined"){e="";console.warn("Undefined CHARARRAY encountered and treated as an empty string. This is probably caused by a missing glyph name.")}var t=[];for(var n=0;n<e.length;n+=1){t[n]=e.charCodeAt(n)}return t};l.CHARARRAY=function(e){if(typeof e==="undefined"){return 0}return e.length};y.USHORT=function(e){return[e>>8&255,e&255]};l.USHORT=e(2);y.SHORT=function(e){if(e>=le){e=-(2*le-e)}return[e>>8&255,e&255]};l.SHORT=e(2);y.UINT24=function(e){return[e>>16&255,e>>8&255,e&255]};l.UINT24=e(3);y.ULONG=function(e){return[e>>24&255,e>>16&255,e>>8&255,e&255]};l.ULONG=e(4);y.LONG=function(e){if(e>=ue){e=-(2*ue-e)}return[e>>24&255,e>>16&255,e>>8&255,e&255]};l.LONG=e(4);y.FIXED=y.ULONG;l.FIXED=l.ULONG;y.FWORD=y.SHORT;l.FWORD=l.SHORT;y.UFWORD=y.USHORT;l.UFWORD=l.USHORT;y.LONGDATETIME=function(e){return[0,0,0,0,e>>24&255,e>>16&255,e>>8&255,e&255]};l.LONGDATETIME=e(8);y.TAG=function(e){A.argument(e.length===4,"Tag should be exactly 4 ASCII characters.");return[e.charCodeAt(0),e.charCodeAt(1),e.charCodeAt(2),e.charCodeAt(3)]};l.TAG=e(4);y.Card8=y.BYTE;l.Card8=l.BYTE;y.Card16=y.USHORT;l.Card16=l.USHORT;y.OffSize=y.BYTE;l.OffSize=l.BYTE;y.SID=y.USHORT;l.SID=l.USHORT;y.NUMBER=function(e){if(e>=-107&&e<=107){return[e+139]}else if(e>=108&&e<=1131){e=e-108;return[(e>>8)+247,e&255]}else if(e>=-1131&&e<=-108){e=-e-108;return[(e>>8)+251,e&255]}else if(e>=-32768&&e<=32767){return y.NUMBER16(e)}else{return y.NUMBER32(e)}};l.NUMBER=function(e){return y.NUMBER(e).length};y.NUMBER16=function(e){return[28,e>>8&255,e&255]};l.NUMBER16=e(3);y.NUMBER32=function(e){return[29,e>>24&255,e>>16&255,e>>8&255,e&255]};l.NUMBER32=e(5);y.REAL=function(e){var t=e.toString();var n=/\.(\d*?)(?:9{5,20}|0{5,20})\d{0,2}(?:e(.+)|$)/.exec(t);if(n){var r=parseFloat("1e"+((n[2]?+n[2]:0)+n[1].length));t=(Math.round(e*r)/r).toString()}var i="";for(var a=0,s=t.length;a<s;a+=1){var o=t[a];if(o==="e"){i+=t[++a]==="-"?"c":"b"}else if(o==="."){i+="a"}else if(o==="-"){i+="e"}else{i+=o}}i+=i.length&1?"f":"ff";var l=[30];for(var u=0,c=i.length;u<c;u+=2){l.push(parseInt(i.substr(u,2),16))}return l};l.REAL=function(e){return y.REAL(e).length};y.NAME=y.CHARARRAY;l.NAME=l.CHARARRAY;y.STRING=y.CHARARRAY;l.STRING=l.CHARARRAY;ce.UTF8=function(e,t,n){var r=[];var i=n;for(var a=0;a<i;a++,t+=1){r[a]=e.getUint8(t)}return String.fromCharCode.apply(null,r)};ce.UTF16=function(e,t,n){var r=[];var i=n/2;for(var a=0;a<i;a++,t+=2){r[a]=e.getUint16(t)}return String.fromCharCode.apply(null,r)};y.UTF16=function(e){var t=[];for(var n=0;n<e.length;n+=1){var r=e.charCodeAt(n);t[t.length]=r>>8&255;t[t.length]=r&255}return t};l.UTF16=function(e){return e.length*2};var he={"x-mac-croatian":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø"+"¿¡¬√ƒ≈Ć«Č… ÀÃÕŒœĐ—“”‘’÷◊©⁄€‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ","x-mac-cyrillic":"АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњ"+"јЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю","x-mac-gaelic":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØḂ±≤≥ḃĊċḊḋḞḟĠġṀæø"+"ṁṖṗɼƒſṠ«»… ÀÃÕŒœ–—“”‘’ṡẛÿŸṪ€‹›Ŷŷṫ·Ỳỳ⁊ÂÊÁËÈÍÎÏÌÓÔ♣ÒÚÛÙıÝýŴŵẄẅẀẁẂẃ","x-mac-greek":"Ä¹²É³ÖÜ΅àâä΄¨çéèêë£™îï•½‰ôö¦€ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩ"+"άΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ­","x-mac-icelandic":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüÝ°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø"+"¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-inuit":"ᐃᐄᐅᐆᐊᐋᐱᐲᐳᐴᐸᐹᑉᑎᑏᑐᑑᑕᑖᑦᑭᑮᑯᑰᑲᑳᒃᒋᒌᒍᒎᒐᒑ°ᒡᒥᒦ•¶ᒧ®©™ᒨᒪᒫᒻᓂᓃᓄᓅᓇᓈᓐᓯᓰᓱᓲᓴᓵᔅᓕᓖᓗ"+"ᓘᓚᓛᓪᔨᔩᔪᔫᔭ… ᔮᔾᕕᕖᕗ–—“”‘’ᕘᕙᕚᕝᕆᕇᕈᕉᕋᕌᕐᕿᖀᖁᖂᖃᖄᖅᖏᖐᖑᖒᖓᖔᖕᙱᙲᙳᙴᙵᙶᖖᖠᖡᖢᖣᖤᖥᖦᕼŁł","x-mac-ce":"ÄĀāÉĄÖÜáąČäčĆćéŹźĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅ"+"ņŃ¬√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ",macintosh:"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø"+"¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›ﬁﬂ‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-romanian":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂȘ∞±≤≥¥µ∂∑∏π∫ªºΩăș"+"¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄€‹›Țț‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ","x-mac-turkish":"ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø"+"¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔÒÚÛÙˆ˜¯˘˙˚¸˝˛ˇ"};ce.MACSTRING=function(e,t,n,r){var i=he[r];if(i===undefined){return undefined}var a="";for(var s=0;s<n;s++){var o=e.getUint8(t+s);if(o<=127){a+=String.fromCharCode(o)}else{a+=i[o&127]}}return a};var fe=typeof WeakMap==="function"&&new WeakMap;var de;var pe=function(e){if(!de){de={};for(var t in he){de[t]=new String(t)}}var n=de[e];if(n===undefined){return undefined}if(fe){var r=fe.get(n);if(r!==undefined){return r}}var i=he[e];if(i===undefined){return undefined}var a={};for(var s=0;s<i.length;s++){a[i.charCodeAt(s)]=s+128}if(fe){fe.set(n,a)}return a};y.MACSTRING=function(e,t){var n=pe(t);if(n===undefined){return undefined}var r=[];for(var i=0;i<e.length;i++){var a=e.charCodeAt(i);if(a>=128){a=n[a];if(a===undefined){return undefined}}r[i]=a}return r};l.MACSTRING=function(e,t){var n=y.MACSTRING(e,t);if(n!==undefined){return n.length}else{return 0}};function ge(e){return e>=-128&&e<=127}function me(e,t,n){var r=0;var i=e.length;while(t<i&&r<64&&e[t]===0){++t;++r}n.push(128|r-1);return t}function ve(e,t,n){var r=0;var i=e.length;var a=t;while(a<i&&r<64){var s=e[a];if(!ge(s)){break}if(s===0&&a+1<i&&e[a+1]===0){break}++a;++r}n.push(r-1);for(var o=t;o<a;++o){n.push(e[o]+256&255)}return a}function be(e,t,n){var r=0;var i=e.length;var a=t;while(a<i&&r<64){var s=e[a];if(s===0){break}if(ge(s)&&a+1<i&&ge(e[a+1])){break}++a;++r}n.push(64|r-1);for(var o=t;o<a;++o){var l=e[o];n.push(l+65536>>8&255,l+256&255)}return a}y.VARDELTAS=function(e){var t=0;var n=[];while(t<e.length){var r=e[t];if(r===0){t=me(e,t,n)}else if(r>=-128&&r<=127){t=ve(e,t,n)}else{t=be(e,t,n)}}return n};y.INDEX=function(e){var t=1;var n=[t];var r=[];for(var i=0;i<e.length;i+=1){var a=y.OBJECT(e[i]);Array.prototype.push.apply(r,a);t+=a.length;n.push(t)}if(r.length===0){return[0,0]}var s=[];var o=1+Math.floor(Math.log(t)/Math.log(2))/8|0;var l=[undefined,y.BYTE,y.USHORT,y.UINT24,y.ULONG][o];for(var u=0;u<n.length;u+=1){var c=l(n[u]);Array.prototype.push.apply(s,c)}return Array.prototype.concat(y.Card16(e.length),y.OffSize(o),s,r)};l.INDEX=function(e){return y.INDEX(e).length};y.DICT=function(e){var t=[];var n=Object.keys(e);var r=n.length;for(var i=0;i<r;i+=1){var a=parseInt(n[i],0);var s=e[a];t=t.concat(y.OPERAND(s.value,s.type));t=t.concat(y.OPERATOR(a))}return t};l.DICT=function(e){return y.DICT(e).length};y.OPERATOR=function(e){if(e<1200){return[e]}else{return[12,e-1200]}};y.OPERAND=function(e,t){var n=[];if(Array.isArray(t)){for(var r=0;r<t.length;r+=1){A.argument(e.length===t.length,"Not enough arguments given for type"+t);n=n.concat(y.OPERAND(e[r],t[r]))}}else{if(t==="SID"){n=n.concat(y.NUMBER(e))}else if(t==="offset"){n=n.concat(y.NUMBER32(e))}else if(t==="number"){n=n.concat(y.NUMBER(e))}else if(t==="real"){n=n.concat(y.REAL(e))}else{throw new Error("Unknown operand type "+t)}}return n};y.OP=y.BYTE;l.OP=l.BYTE;var _e=typeof WeakMap==="function"&&new WeakMap;y.CHARSTRING=function(e){if(_e){var t=_e.get(e);if(t!==undefined){return t}}var n=[];var r=e.length;for(var i=0;i<r;i+=1){var a=e[i];n=n.concat(y[a.type](a.value))}if(_e){_e.set(e,n)}return n};l.CHARSTRING=function(e){return y.CHARSTRING(e).length};y.OBJECT=function(e){var t=y[e.type];A.argument(t!==undefined,"No encoding function for type "+e.type);return t(e.value)};l.OBJECT=function(e){var t=l[e.type];A.argument(t!==undefined,"No sizeOf function for type "+e.type);return t(e.value)};y.TABLE=function(e){var t=[];var n=e.fields.length;var r=[];var i=[];for(var a=0;a<n;a+=1){var s=e.fields[a];var o=y[s.type];A.argument(o!==undefined,"No encoding function for field type "+s.type+" ("+s.name+")");var l=e[s.name];if(l===undefined){l=s.value}var u=o(l);if(s.type==="TABLE"){i.push(t.length);t=t.concat([0,0]);r.push(u)}else{t=t.concat(u)}}for(var c=0;c<r.length;c+=1){var h=i[c];var f=t.length;A.argument(f<65536,"Table "+e.tableName+" too big.");t[h]=f>>8;t[h+1]=f&255;t=t.concat(r[c])}return t};l.TABLE=function(e){var t=0;var n=e.fields.length;for(var r=0;r<n;r+=1){var i=e.fields[r];var a=l[i.type];A.argument(a!==undefined,"No sizeOf function for field type "+i.type+" ("+i.name+")");var s=e[i.name];if(s===undefined){s=i.value}t+=a(s);if(i.type==="TABLE"){t+=2}}return t};y.RECORD=y.TABLE;l.RECORD=l.TABLE;y.LITERAL=function(e){return e};l.LITERAL=function(e){return e.length};function i(e,t,n){if(t.length&&(t[0].name!=="coverageFormat"||t[0].value===1)){for(var r=0;r<t.length;r+=1){var i=t[r];this[i.name]=i.value}}this.tableName=e;this.fields=t;if(n){var a=Object.keys(n);for(var s=0;s<a.length;s+=1){var o=a[s];var l=n[o];if(this[o]!==undefined){this[o]=l}}}}i.prototype.encode=function(){return y.TABLE(this)};i.prototype.sizeOf=function(){return l.TABLE(this)};function Ee(e,t,n){if(n===undefined){n=t.length}var r=new Array(t.length+1);r[0]={name:e+"Count",type:"USHORT",value:n};for(var i=0;i<t.length;i++){r[i+1]={name:e+i,type:"USHORT",value:t[i]}}return r}function Fe(e,t,n){var r=t.length;var i=new Array(r+1);i[0]={name:e+"Count",type:"USHORT",value:r};for(var a=0;a<r;a++){i[a+1]={name:e+a,type:"TABLE",value:n(t[a],a)}}return i}function Ce(e,t,n){var r=t.length;var i=[];i[0]={name:e+"Count",type:"USHORT",value:r};for(var a=0;a<r;a++){i=i.concat(n(t[a],a))}return i}function Ae(e){if(e.format===1){i.call(this,"coverageTable",[{name:"coverageFormat",type:"USHORT",value:1}].concat(Ee("glyph",e.glyphs)))}else if(e.format===2){i.call(this,"coverageTable",[{name:"coverageFormat",type:"USHORT",value:2}].concat(Ce("rangeRecord",e.ranges,function(e){return[{name:"startGlyphID",type:"USHORT",value:e.start},{name:"endGlyphID",type:"USHORT",value:e.end},{name:"startCoverageIndex",type:"USHORT",value:e.index}]})))}else{A.assert(false,"Coverage format must be 1 or 2.")}}Ae.prototype=Object.create(i.prototype);Ae.prototype.constructor=Ae;function xe(e){i.call(this,"scriptListTable",Ce("scriptRecord",e,function(e,t){var n=e.script;var r=n.defaultLangSys;A.assert(!!r,"Unable to write GSUB: script "+e.tag+" has no default language system.");return[{name:"scriptTag"+t,type:"TAG",value:e.tag},{name:"script"+t,type:"TABLE",value:new i("scriptTable",[{name:"defaultLangSys",type:"TABLE",value:new i("defaultLangSys",[{name:"lookupOrder",type:"USHORT",value:0},{name:"reqFeatureIndex",type:"USHORT",value:r.reqFeatureIndex}].concat(Ee("featureIndex",r.featureIndexes)))}].concat(Ce("langSys",n.langSysRecords,function(e,t){var n=e.langSys;return[{name:"langSysTag"+t,type:"TAG",value:e.tag},{name:"langSys"+t,type:"TABLE",value:new i("langSys",[{name:"lookupOrder",type:"USHORT",value:0},{name:"reqFeatureIndex",type:"USHORT",value:n.reqFeatureIndex}].concat(Ee("featureIndex",n.featureIndexes)))}]})))}]}))}xe.prototype=Object.create(i.prototype);xe.prototype.constructor=xe;function Te(e){i.call(this,"featureListTable",Ce("featureRecord",e,function(e,t){var n=e.feature;return[{name:"featureTag"+t,type:"TAG",value:e.tag},{name:"feature"+t,type:"TABLE",value:new i("featureTable",[{name:"featureParams",type:"USHORT",value:n.featureParams}].concat(Ee("lookupListIndex",n.lookupListIndexes)))}]}))}Te.prototype=Object.create(i.prototype);Te.prototype.constructor=Te;function Se(e,n){i.call(this,"lookupListTable",Fe("lookup",e,function(e){var t=n[e.lookupType];A.assert(!!t,"Unable to write GSUB lookup type "+e.lookupType+" tables.");return new i("lookupTable",[{name:"lookupType",type:"USHORT",value:e.lookupType},{name:"lookupFlag",type:"USHORT",value:e.lookupFlag}].concat(Fe("subtable",e.subtables,t)))}))}Se.prototype=Object.create(i.prototype);Se.prototype.constructor=Se;var B={Table:i,Record:i,Coverage:Ae,ScriptList:xe,FeatureList:Te,LookupList:Se,ushortList:Ee,tableList:Fe,recordList:Ce};function ye(e,t){return e.getUint8(t)}function Be(e,t){return e.getUint16(t,false)}function Oe(e,t){return e.getInt16(t,false)}function De(e,t){return e.getUint32(t,false)}function Ie(e,t){var n=e.getInt16(t,false);var r=e.getUint16(t+2,false);return n+r/65535}function Me(e,t){var n="";for(var r=t;r<t+4;r+=1){n+=String.fromCharCode(e.getInt8(r))}return n}function Le(e,t,n){var r=0;for(var i=0;i<n;i+=1){r<<=8;r+=e.getUint8(t+i)}return r}function Re(e,t,n){var r=[];for(var i=t;i<n;i+=1){r.push(e.getUint8(i))}return r}function we(e){var t="";for(var n=0;n<e.length;n+=1){t+=String.fromCharCode(e[n])}return t}var Ne={byte:1,uShort:2,short:2,uLong:4,fixed:4,longDateTime:8,tag:4};function c(e,t){this.data=e;this.offset=t;this.relativeOffset=0}c.prototype.parseByte=function(){var e=this.data.getUint8(this.offset+this.relativeOffset);this.relativeOffset+=1;return e};c.prototype.parseChar=function(){var e=this.data.getInt8(this.offset+this.relativeOffset);this.relativeOffset+=1;return e};c.prototype.parseCard8=c.prototype.parseByte;c.prototype.parseUShort=function(){var e=this.data.getUint16(this.offset+this.relativeOffset);this.relativeOffset+=2;return e};c.prototype.parseCard16=c.prototype.parseUShort;c.prototype.parseSID=c.prototype.parseUShort;c.prototype.parseOffset16=c.prototype.parseUShort;c.prototype.parseShort=function(){var e=this.data.getInt16(this.offset+this.relativeOffset);this.relativeOffset+=2;return e};c.prototype.parseF2Dot14=function(){var e=this.data.getInt16(this.offset+this.relativeOffset)/16384;this.relativeOffset+=2;return e};c.prototype.parseULong=function(){var e=De(this.data,this.offset+this.relativeOffset);this.relativeOffset+=4;return e};c.prototype.parseOffset32=c.prototype.parseULong;c.prototype.parseFixed=function(){var e=Ie(this.data,this.offset+this.relativeOffset);this.relativeOffset+=4;return e};c.prototype.parseString=function(e){var t=this.data;var n=this.offset+this.relativeOffset;var r="";this.relativeOffset+=e;for(var i=0;i<e;i++){r+=String.fromCharCode(t.getUint8(n+i))}return r};c.prototype.parseTag=function(){return this.parseString(4)};c.prototype.parseLongDateTime=function(){var e=De(this.data,this.offset+this.relativeOffset+4);e-=2082844800;this.relativeOffset+=8;return e};c.prototype.parseVersion=function(e){var t=Be(this.data,this.offset+this.relativeOffset);var n=Be(this.data,this.offset+this.relativeOffset+2);this.relativeOffset+=4;if(e===undefined){e=4096}return t+n/e/10};c.prototype.skip=function(e,t){if(t===undefined){t=1}this.relativeOffset+=Ne[e]*t};c.prototype.parseULongList=function(e){if(e===undefined){e=this.parseULong()}var t=new Array(e);var n=this.data;var r=this.offset+this.relativeOffset;for(var i=0;i<e;i++){t[i]=n.getUint32(r);r+=4}this.relativeOffset+=e*4;return t};c.prototype.parseOffset16List=c.prototype.parseUShortList=function(e){if(e===undefined){e=this.parseUShort()}var t=new Array(e);var n=this.data;var r=this.offset+this.relativeOffset;for(var i=0;i<e;i++){t[i]=n.getUint16(r);r+=2}this.relativeOffset+=e*2;return t};c.prototype.parseShortList=function(e){var t=new Array(e);var n=this.data;var r=this.offset+this.relativeOffset;for(var i=0;i<e;i++){t[i]=n.getInt16(r);r+=2}this.relativeOffset+=e*2;return t};c.prototype.parseByteList=function(e){var t=new Array(e);var n=this.data;var r=this.offset+this.relativeOffset;for(var i=0;i<e;i++){t[i]=n.getUint8(r++)}this.relativeOffset+=e;return t};c.prototype.parseList=function(e,t){if(!t){t=e;e=this.parseUShort()}var n=new Array(e);for(var r=0;r<e;r++){n[r]=t.call(this)}return n};c.prototype.parseList32=function(e,t){if(!t){t=e;e=this.parseULong()}var n=new Array(e);for(var r=0;r<e;r++){n[r]=t.call(this)}return n};c.prototype.parseRecordList=function(e,t){if(!t){t=e;e=this.parseUShort()}var n=new Array(e);var r=Object.keys(t);for(var i=0;i<e;i++){var a={};for(var s=0;s<r.length;s++){var o=r[s];var l=t[o];a[o]=l.call(this)}n[i]=a}return n};c.prototype.parseRecordList32=function(e,t){if(!t){t=e;e=this.parseULong()}var n=new Array(e);var r=Object.keys(t);for(var i=0;i<e;i++){var a={};for(var s=0;s<r.length;s++){var o=r[s];var l=t[o];a[o]=l.call(this)}n[i]=a}return n};c.prototype.parseStruct=function(e){if(typeof e==="function"){return e.call(this)}else{var t=Object.keys(e);var n={};for(var r=0;r<t.length;r++){var i=t[r];var a=e[i];n[i]=a.call(this)}return n}};c.prototype.parseValueRecord=function(e){if(e===undefined){e=this.parseUShort()}if(e===0){return}var t={};if(e&1){t.xPlacement=this.parseShort()}if(e&2){t.yPlacement=this.parseShort()}if(e&4){t.xAdvance=this.parseShort()}if(e&8){t.yAdvance=this.parseShort()}if(e&16){t.xPlaDevice=undefined;this.parseShort()}if(e&32){t.yPlaDevice=undefined;this.parseShort()}if(e&64){t.xAdvDevice=undefined;this.parseShort()}if(e&128){t.yAdvDevice=undefined;this.parseShort()}return t};c.prototype.parseValueRecordList=function(){var e=this.parseUShort();var t=this.parseUShort();var n=new Array(t);for(var r=0;r<t;r++){n[r]=this.parseValueRecord(e)}return n};c.prototype.parsePointer=function(e){var t=this.parseOffset16();if(t>0){return new c(this.data,this.offset+t).parseStruct(e)}return undefined};c.prototype.parsePointer32=function(e){var t=this.parseOffset32();if(t>0){return new c(this.data,this.offset+t).parseStruct(e)}return undefined};c.prototype.parseListOfLists=function(e){var t=this.parseOffset16List();var n=t.length;var r=this.relativeOffset;var i=new Array(n);for(var a=0;a<n;a++){var s=t[a];if(s===0){i[a]=undefined;continue}this.relativeOffset=s;if(e){var o=this.parseOffset16List();var l=new Array(o.length);for(var u=0;u<o.length;u++){this.relativeOffset=s+o[u];l[u]=e.call(this)}i[a]=l}else{i[a]=this.parseUShortList()}}this.relativeOffset=r;return i};c.prototype.parseCoverage=function(){var e=this.offset+this.relativeOffset;var t=this.parseUShort();var n=this.parseUShort();if(t===1){return{format:1,glyphs:this.parseUShortList(n)}}else if(t===2){var r=new Array(n);for(var i=0;i<n;i++){r[i]={start:this.parseUShort(),end:this.parseUShort(),index:this.parseUShort()}}return{format:2,ranges:r}}throw new Error("0x"+e.toString(16)+": Coverage format must be 1 or 2.")};c.prototype.parseClassDef=function(){var e=this.offset+this.relativeOffset;var t=this.parseUShort();if(t===1){return{format:1,startGlyph:this.parseUShort(),classes:this.parseUShortList()}}else if(t===2){return{format:2,ranges:this.parseRecordList({start:c.uShort,end:c.uShort,classId:c.uShort})}}throw new Error("0x"+e.toString(16)+": ClassDef format must be 1 or 2.")};c.list=function(e,t){return function(){return this.parseList(e,t)}};c.list32=function(e,t){return function(){return this.parseList32(e,t)}};c.recordList=function(e,t){return function(){return this.parseRecordList(e,t)}};c.recordList32=function(e,t){return function(){return this.parseRecordList32(e,t)}};c.pointer=function(e){return function(){return this.parsePointer(e)}};c.pointer32=function(e){return function(){return this.parsePointer32(e)}};c.tag=c.prototype.parseTag;c.byte=c.prototype.parseByte;c.uShort=c.offset16=c.prototype.parseUShort;c.uShortList=c.prototype.parseUShortList;c.uLong=c.offset32=c.prototype.parseULong;c.uLongList=c.prototype.parseULongList;c.struct=c.prototype.parseStruct;c.coverage=c.prototype.parseCoverage;c.classDef=c.prototype.parseClassDef;var Pe={reserved:c.uShort,reqFeatureIndex:c.uShort,featureIndexes:c.uShortList};c.prototype.parseScriptList=function(){return this.parsePointer(c.recordList({tag:c.tag,script:c.pointer({defaultLangSys:c.pointer(Pe),langSysRecords:c.recordList({tag:c.tag,langSys:c.pointer(Pe)})})}))||[]};c.prototype.parseFeatureList=function(){return this.parsePointer(c.recordList({tag:c.tag,feature:c.pointer({featureParams:c.offset16,lookupListIndexes:c.uShortList})}))||[]};c.prototype.parseLookupList=function(r){return this.parsePointer(c.list(c.pointer(function(){var e=this.parseUShort();A.argument(1<=e&&e<=9,"GPOS/GSUB lookup type "+e+" unknown.");var t=this.parseUShort();var n=t&16;return{lookupType:e,lookupFlag:t,subtables:this.parseList(c.pointer(r[e])),markFilteringSet:n?this.parseUShort():undefined}})))||[]};c.prototype.parseFeatureVariationsList=function(){return this.parsePointer32(function(){var e=this.parseUShort();var t=this.parseUShort();A.argument(e===1&&t<1,"GPOS/GSUB feature variations table unknown.");var n=this.parseRecordList32({conditionSetOffset:c.offset32,featureTableSubstitutionOffset:c.offset32});return n})||[]};var U={getByte:ye,getCard8:ye,getUShort:Be,getCard16:Be,getShort:Oe,getULong:De,getFixed:Ie,getTag:Me,getOffset:Le,getBytes:Re,bytesToString:we,Parser:c};function Ue(e,t){t.parseUShort();e.length=t.parseULong();e.language=t.parseULong();var n;e.groupCount=n=t.parseULong();e.glyphIndexMap={};for(var r=0;r<n;r+=1){var i=t.parseULong();var a=t.parseULong();var s=t.parseULong();for(var o=i;o<=a;o+=1){e.glyphIndexMap[o]=s;s++}}}function ke(e,t,n,r,i){e.length=t.parseUShort();e.language=t.parseUShort();var a;e.segCount=a=t.parseUShort()>>1;t.skip("uShort",3);e.glyphIndexMap={};var s=new U.Parser(n,r+i+14);var o=new U.Parser(n,r+i+16+a*2);var l=new U.Parser(n,r+i+16+a*4);var u=new U.Parser(n,r+i+16+a*6);var c=r+i+16+a*8;for(var h=0;h<a-1;h+=1){var f=void 0;var d=s.parseUShort();var p=o.parseUShort();var g=l.parseShort();var m=u.parseUShort();for(var v=p;v<=d;v+=1){if(m!==0){c=u.offset+u.relativeOffset-2;c+=m;c+=(v-p)*2;f=U.getUShort(n,c);if(f!==0){f=f+g&65535}}else{f=v+g&65535}e.glyphIndexMap[v]=f}}}function je(e,t){var n={};n.version=U.getUShort(e,t);A.argument(n.version===0,"cmap table version should be 0.");n.numTables=U.getUShort(e,t+2);var r=-1;for(var i=n.numTables-1;i>=0;i-=1){var a=U.getUShort(e,t+4+i*8);var s=U.getUShort(e,t+4+i*8+2);if(a===3&&(s===0||s===1||s===10)||a===0&&(s===0||s===1||s===2||s===3||s===4)){r=U.getULong(e,t+4+i*8+4);break}}if(r===-1){throw new Error("No valid cmap sub-tables found.")}var o=new U.Parser(e,t+r);n.format=o.parseUShort();if(n.format===12){Ue(n,o)}else if(n.format===4){ke(n,o,e,t,r)}else{throw new Error("Only format 4 and 12 cmap tables are supported (found format "+n.format+").")}return n}function Ge(e,t,n){e.segments.push({end:t,start:t,delta:-(t-n),offset:0,glyphIndex:n})}function Ve(e){e.segments.push({end:65535,start:65535,delta:1,offset:0})}function ze(e){var t=true;var n;for(n=e.length-1;n>0;n-=1){var r=e.get(n);if(r.unicode>65535){console.log("Adding CMAP format 12 (needed!)");t=false;break}}var i=[{name:"version",type:"USHORT",value:0},{name:"numTables",type:"USHORT",value:t?1:2},{name:"platformID",type:"USHORT",value:3},{name:"encodingID",type:"USHORT",value:1},{name:"offset",type:"ULONG",value:t?12:12+8}];if(!t){i=i.concat([{name:"cmap12PlatformID",type:"USHORT",value:3},{name:"cmap12EncodingID",type:"USHORT",value:10},{name:"cmap12Offset",type:"ULONG",value:0}])}i=i.concat([{name:"format",type:"USHORT",value:4},{name:"cmap4Length",type:"USHORT",value:0},{name:"language",type:"USHORT",value:0},{name:"segCountX2",type:"USHORT",value:0},{name:"searchRange",type:"USHORT",value:0},{name:"entrySelector",type:"USHORT",value:0},{name:"rangeShift",type:"USHORT",value:0}]);var a=new B.Table("cmap",i);a.segments=[];for(n=0;n<e.length;n+=1){var s=e.get(n);for(var o=0;o<s.unicodes.length;o+=1){Ge(a,s.unicodes[o],n)}a.segments=a.segments.sort(function(e,t){return e.start-t.start})}Ve(a);var l=a.segments.length;var u=0;var c=[];var h=[];var f=[];var d=[];var p=[];var g=[];for(n=0;n<l;n+=1){var m=a.segments[n];if(m.end<=65535&&m.start<=65535){c=c.concat({name:"end_"+n,type:"USHORT",value:m.end});h=h.concat({name:"start_"+n,type:"USHORT",value:m.start});f=f.concat({name:"idDelta_"+n,type:"SHORT",value:m.delta});d=d.concat({name:"idRangeOffset_"+n,type:"USHORT",value:m.offset});if(m.glyphId!==undefined){p=p.concat({name:"glyph_"+n,type:"USHORT",value:m.glyphId})}}else{u+=1}if(!t&&m.glyphIndex!==undefined){g=g.concat({name:"cmap12Start_"+n,type:"ULONG",value:m.start});g=g.concat({name:"cmap12End_"+n,type:"ULONG",value:m.end});g=g.concat({name:"cmap12Glyph_"+n,type:"ULONG",value:m.glyphIndex})}}a.segCountX2=(l-u)*2;a.searchRange=Math.pow(2,Math.floor(Math.log(l-u)/Math.log(2)))*2;a.entrySelector=Math.log(a.searchRange/2)/Math.log(2);a.rangeShift=a.segCountX2-a.searchRange;a.fields=a.fields.concat(c);a.fields.push({name:"reservedPad",type:"USHORT",value:0});a.fields=a.fields.concat(h);a.fields=a.fields.concat(f);a.fields=a.fields.concat(d);a.fields=a.fields.concat(p);a.cmap4Length=14+c.length*2+2+h.length*2+f.length*2+d.length*2+p.length*2;if(!t){var v=16+g.length*4;a.cmap12Offset=12+2*2+4+a.cmap4Length;a.fields=a.fields.concat([{name:"cmap12Format",type:"USHORT",value:12},{name:"cmap12Reserved",type:"USHORT",value:0},{name:"cmap12Length",type:"ULONG",value:v},{name:"cmap12Language",type:"ULONG",value:0},{name:"cmap12nGroups",type:"ULONG",value:g.length/3}]);a.fields=a.fields.concat(g)}return a}var He={parse:je,make:ze};var Xe=[".notdef","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","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","bracketleft","backslash","bracketright","asciicircum","underscore","quoteleft","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","braceleft","bar","braceright","asciitilde","exclamdown","cent","sterling","fraction","yen","florin","section","currency","quotesingle","quotedblleft","guillemotleft","guilsinglleft","guilsinglright","fi","fl","endash","dagger","daggerdbl","periodcentered","paragraph","bullet","quotesinglbase","quotedblbase","quotedblright","guillemotright","ellipsis","perthousand","questiondown","grave","acute","circumflex","tilde","macron","breve","dotaccent","dieresis","ring","cedilla","hungarumlaut","ogonek","caron","emdash","AE","ordfeminine","Lslash","Oslash","OE","ordmasculine","ae","dotlessi","lslash","oslash","oe","germandbls","onesuperior","logicalnot","mu","trademark","Eth","onehalf","plusminus","Thorn","onequarter","divide","brokenbar","degree","thorn","threequarters","twosuperior","registered","minus","eth","multiply","threesuperior","copyright","Aacute","Acircumflex","Adieresis","Agrave","Aring","Atilde","Ccedilla","Eacute","Ecircumflex","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Ntilde","Oacute","Ocircumflex","Odieresis","Ograve","Otilde","Scaron","Uacute","Ucircumflex","Udieresis","Ugrave","Yacute","Ydieresis","Zcaron","aacute","acircumflex","adieresis","agrave","aring","atilde","ccedilla","eacute","ecircumflex","edieresis","egrave","iacute","icircumflex","idieresis","igrave","ntilde","oacute","ocircumflex","odieresis","ograve","otilde","scaron","uacute","ucircumflex","udieresis","ugrave","yacute","ydieresis","zcaron","exclamsmall","Hungarumlautsmall","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","266 ff","onedotenleader","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","commasuperior","threequartersemdash","periodsuperior","questionsmall","asuperior","bsuperior","centsuperior","dsuperior","esuperior","isuperior","lsuperior","msuperior","nsuperior","osuperior","rsuperior","ssuperior","tsuperior","ff","ffi","ffl","parenleftinferior","parenrightinferior","Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","exclamdownsmall","centoldstyle","Lslashsmall","Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall","Dotaccentsmall","Macronsmall","figuredash","hypheninferior","Ogoneksmall","Ringsmall","Cedillasmall","questiondownsmall","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","zerosuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior","Agravesmall","Aacutesmall","Acircumflexsmall","Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall","Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall","Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall","Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall","Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall","Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall","Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003","Black","Bold","Book","Light","Medium","Regular","Roman","Semibold"];var We=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quoteright","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","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","bracketleft","backslash","bracketright","asciicircum","underscore","quoteleft","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","braceleft","bar","braceright","asciitilde","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","exclamdown","cent","sterling","fraction","yen","florin","section","currency","quotesingle","quotedblleft","guillemotleft","guilsinglleft","guilsinglright","fi","fl","","endash","dagger","daggerdbl","periodcentered","","paragraph","bullet","quotesinglbase","quotedblbase","quotedblright","guillemotright","ellipsis","perthousand","","questiondown","","grave","acute","circumflex","tilde","macron","breve","dotaccent","dieresis","","ring","cedilla","","hungarumlaut","ogonek","caron","emdash","","","","","","","","","","","","","","","","","AE","","ordfeminine","","","","","Lslash","Oslash","OE","ordmasculine","","","","","","ae","","","","dotlessi","","","lslash","oslash","oe","germandbls"];var Ye=["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","space","exclamsmall","Hungarumlautsmall","","dollaroldstyle","dollarsuperior","ampersandsmall","Acutesmall","parenleftsuperior","parenrightsuperior","twodotenleader","onedotenleader","comma","hyphen","period","fraction","zerooldstyle","oneoldstyle","twooldstyle","threeoldstyle","fouroldstyle","fiveoldstyle","sixoldstyle","sevenoldstyle","eightoldstyle","nineoldstyle","colon","semicolon","commasuperior","threequartersemdash","periodsuperior","questionsmall","","asuperior","bsuperior","centsuperior","dsuperior","esuperior","","","isuperior","","","lsuperior","msuperior","nsuperior","osuperior","","","rsuperior","ssuperior","tsuperior","","ff","fi","fl","ffi","ffl","parenleftinferior","","parenrightinferior","Circumflexsmall","hyphensuperior","Gravesmall","Asmall","Bsmall","Csmall","Dsmall","Esmall","Fsmall","Gsmall","Hsmall","Ismall","Jsmall","Ksmall","Lsmall","Msmall","Nsmall","Osmall","Psmall","Qsmall","Rsmall","Ssmall","Tsmall","Usmall","Vsmall","Wsmall","Xsmall","Ysmall","Zsmall","colonmonetary","onefitted","rupiah","Tildesmall","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","exclamdownsmall","centoldstyle","Lslashsmall","","","Scaronsmall","Zcaronsmall","Dieresissmall","Brevesmall","Caronsmall","","Dotaccentsmall","","","Macronsmall","","","figuredash","hypheninferior","","","Ogoneksmall","Ringsmall","Cedillasmall","","","","onequarter","onehalf","threequarters","questiondownsmall","oneeighth","threeeighths","fiveeighths","seveneighths","onethird","twothirds","","","zerosuperior","onesuperior","twosuperior","threesuperior","foursuperior","fivesuperior","sixsuperior","sevensuperior","eightsuperior","ninesuperior","zeroinferior","oneinferior","twoinferior","threeinferior","fourinferior","fiveinferior","sixinferior","seveninferior","eightinferior","nineinferior","centinferior","dollarinferior","periodinferior","commainferior","Agravesmall","Aacutesmall","Acircumflexsmall","Atildesmall","Adieresissmall","Aringsmall","AEsmall","Ccedillasmall","Egravesmall","Eacutesmall","Ecircumflexsmall","Edieresissmall","Igravesmall","Iacutesmall","Icircumflexsmall","Idieresissmall","Ethsmall","Ntildesmall","Ogravesmall","Oacutesmall","Ocircumflexsmall","Otildesmall","Odieresissmall","OEsmall","Oslashsmall","Ugravesmall","Uacutesmall","Ucircumflexsmall","Udieresissmall","Yacutesmall","Thornsmall","Ydieresissmall"];var u=[".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign","dollar","percent","ampersand","quotesingle","parenleft","parenright","asterisk","plus","comma","hyphen","period","slash","zero","one","two","three","four","five","six","seven","eight","nine","colon","semicolon","less","equal","greater","question","at","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","bracketleft","backslash","bracketright","asciicircum","underscore","grave","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","braceleft","bar","braceright","asciitilde","Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis","aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla","eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex","idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde","uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent","sterling","section","bullet","paragraph","germandbls","registered","copyright","trademark","acute","dieresis","notequal","AE","Oslash","infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff","summation","product","pi","integral","ordfeminine","ordmasculine","Omega","ae","oslash","questiondown","exclamdown","logicalnot","radical","florin","approxequal","Delta","guillemotleft","guillemotright","ellipsis","nonbreakingspace","Agrave","Atilde","Otilde","OE","oe","endash","emdash","quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge","ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright","fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase","perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave","Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple","Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde","macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron","Lslash","lslash","Scaron","scaron","Zcaron","zcaron","brokenbar","Eth","eth","Yacute","yacute","Thorn","thorn","minus","multiply","onesuperior","twosuperior","threesuperior","onehalf","onequarter","threequarters","franc","Gbreve","gbreve","Idotaccent","Scedilla","scedilla","Cacute","cacute","Ccaron","ccaron","dcroat"];function qe(e){this.font=e}qe.prototype.charToGlyphIndex=function(e){var t=e.codePointAt(0);var n=this.font.glyphs;if(n){for(var r=0;r<n.length;r+=1){var i=n.get(r);for(var a=0;a<i.unicodes.length;a+=1){if(i.unicodes[a]===t){return r}}}}return null};function Ze(e){this.cmap=e}Ze.prototype.charToGlyphIndex=function(e){return this.cmap.glyphIndexMap[e.codePointAt(0)]||0};function Je(e,t){this.encoding=e;this.charset=t}Je.prototype.charToGlyphIndex=function(e){var t=e.codePointAt(0);var n=this.encoding[t];return this.charset.indexOf(n)};function Qe(e){switch(e.version){case 1:this.names=u.slice();break;case 2:this.names=new Array(e.numberOfGlyphs);for(var t=0;t<e.numberOfGlyphs;t++){if(e.glyphNameIndex[t]<u.length){this.names[t]=u[e.glyphNameIndex[t]]}else{this.names[t]=e.names[e.glyphNameIndex[t]-u.length]}}break;case 2.5:this.names=new Array(e.numberOfGlyphs);for(var n=0;n<e.numberOfGlyphs;n++){this.names[n]=u[n+e.glyphNameIndex[n]]}break;case 3:this.names=[];break;default:this.names=[];break}}Qe.prototype.nameToGlyphIndex=function(e){return this.names.indexOf(e)};Qe.prototype.glyphIndexToName=function(e){return this.names[e]};function Ke(e){var t;var n=e.tables.cmap.glyphIndexMap;var r=Object.keys(n);for(var i=0;i<r.length;i+=1){var a=r[i];var s=n[a];t=e.glyphs.get(s);t.addUnicode(parseInt(a))}for(var o=0;o<e.glyphs.length;o+=1){t=e.glyphs.get(o);if(e.cffEncoding){if(e.isCIDFont){t.name="gid"+o}else{t.name=e.cffEncoding.charset[o]}}else if(e.glyphNames.names){t.name=e.glyphNames.glyphIndexToName(o)}}}function $e(e){e._IndexToUnicodeMap={};var t=e.tables.cmap.glyphIndexMap;var n=Object.keys(t);for(var r=0;r<n.length;r+=1){var i=n[r];var a=t[i];if(e._IndexToUnicodeMap[a]===undefined){e._IndexToUnicodeMap[a]={unicodes:[parseInt(i)]}}else{e._IndexToUnicodeMap[a].unicodes.push(parseInt(i))}}}function et(e,t){if(t.lowMemory){$e(e)}else{Ke(e)}}function tt(e,t,n,r,i){e.beginPath();e.moveTo(t,n);e.lineTo(r,i);e.stroke()}var h={line:tt};function nt(e,t){var n=t||new p;return{configurable:true,get:function(){if(typeof n==="function"){n=n()}return n},set:function(e){n=e}}}function g(e){this.bindConstructorValues(e)}g.prototype.bindConstructorValues=function(e){this.index=e.index||0;this.name=e.name||null;this.unicode=e.unicode||undefined;this.unicodes=e.unicodes||e.unicode!==undefined?[e.unicode]:[];if("xMin"in e){this.xMin=e.xMin}if("yMin"in e){this.yMin=e.yMin}if("xMax"in e){this.xMax=e.xMax}if("yMax"in e){this.yMax=e.yMax}if("advanceWidth"in e){this.advanceWidth=e.advanceWidth}Object.defineProperty(this,"path",nt(this,e.path))};g.prototype.addUnicode=function(e){if(this.unicodes.length===0){this.unicode=e}this.unicodes.push(e)};g.prototype.getBoundingBox=function(){return this.path.getBoundingBox()};g.prototype.getPath=function(e,t,n,r,i){e=e!==undefined?e:0;t=t!==undefined?t:0;n=n!==undefined?n:72;var a;var s;if(!r){r={}}var o=r.xScale;var l=r.yScale;if(r.hinting&&i&&i.hinting){s=this.path&&i.hinting.exec(this,n)}if(s){a=i.hinting.getCommands(s);e=Math.round(e);t=Math.round(t);o=l=1}else{a=this.path.commands;var u=1/(this.path.unitsPerEm||1e3)*n;if(o===undefined){o=u}if(l===undefined){l=u}}var c=new p;for(var h=0;h<a.length;h+=1){var f=a[h];if(f.type==="M"){c.moveTo(e+f.x*o,t+-f.y*l)}else if(f.type==="L"){c.lineTo(e+f.x*o,t+-f.y*l)}else if(f.type==="Q"){c.quadraticCurveTo(e+f.x1*o,t+-f.y1*l,e+f.x*o,t+-f.y*l)}else if(f.type==="C"){c.curveTo(e+f.x1*o,t+-f.y1*l,e+f.x2*o,t+-f.y2*l,e+f.x*o,t+-f.y*l)}else if(f.type==="Z"){c.closePath()}}return c};g.prototype.getContours=function(){if(this.points===undefined){return[]}var e=[];var t=[];for(var n=0;n<this.points.length;n+=1){var r=this.points[n];t.push(r);if(r.lastPointOfContour){e.push(t);t=[]}}A.argument(t.length===0,"There are still points left in the current contour.");return e};g.prototype.getMetrics=function(){var e=this.path.commands;var t=[];var n=[];for(var r=0;r<e.length;r+=1){var i=e[r];if(i.type!=="Z"){t.push(i.x);n.push(i.y)}if(i.type==="Q"||i.type==="C"){t.push(i.x1);n.push(i.y1)}if(i.type==="C"){t.push(i.x2);n.push(i.y2)}}var a={xMin:Math.min.apply(null,t),yMin:Math.min.apply(null,n),xMax:Math.max.apply(null,t),yMax:Math.max.apply(null,n),leftSideBearing:this.leftSideBearing};if(!isFinite(a.xMin)){a.xMin=0}if(!isFinite(a.xMax)){a.xMax=this.advanceWidth}if(!isFinite(a.yMin)){a.yMin=0}if(!isFinite(a.yMax)){a.yMax=0}a.rightSideBearing=this.advanceWidth-a.leftSideBearing-(a.xMax-a.xMin);return a};g.prototype.draw=function(e,t,n,r,i){this.getPath(t,n,r,i).draw(e)};g.prototype.drawPoints=function(a,e,t,n){function r(e,t,n,r){a.beginPath();for(var i=0;i<e.length;i+=1){a.moveTo(t+e[i].x*r,n+e[i].y*r);a.arc(t+e[i].x*r,n+e[i].y*r,2,0,Math.PI*2,false)}a.closePath();a.fill()}e=e!==undefined?e:0;t=t!==undefined?t:0;n=n!==undefined?n:24;var i=1/this.path.unitsPerEm*n;var s=[];var o=[];var l=this.path;for(var u=0;u<l.commands.length;u+=1){var c=l.commands[u];if(c.x!==undefined){s.push({x:c.x,y:-c.y})}if(c.x1!==undefined){o.push({x:c.x1,y:-c.y1})}if(c.x2!==undefined){o.push({x:c.x2,y:-c.y2})}}a.fillStyle="blue";r(s,e,t,i);a.fillStyle="red";r(o,e,t,i)};g.prototype.drawMetrics=function(e,t,n,r){var i;t=t!==undefined?t:0;n=n!==undefined?n:0;r=r!==undefined?r:24;i=1/this.path.unitsPerEm*r;e.lineWidth=1;e.strokeStyle="black";h.line(e,t,-1e4,t,1e4);h.line(e,-1e4,n,1e4,n);var a=this.xMin||0;var s=this.yMin||0;var o=this.xMax||0;var l=this.yMax||0;var u=this.advanceWidth||0;e.strokeStyle="blue";h.line(e,t+a*i,-1e4,t+a*i,1e4);h.line(e,t+o*i,-1e4,t+o*i,1e4);h.line(e,-1e4,n+-s*i,1e4,n+-s*i);h.line(e,-1e4,n+-l*i,1e4,n+-l*i);e.strokeStyle="green";h.line(e,t+u*i,-1e4,t+u*i,1e4)};function rt(t,e,n){Object.defineProperty(t,e,{get:function(){t.path;return t[n]},set:function(e){t[n]=e},enumerable:true,configurable:true})}function it(e,t){this.font=e;this.glyphs={};if(Array.isArray(t)){for(var n=0;n<t.length;n++){var r=t[n];r.path.unitsPerEm=e.unitsPerEm;this.glyphs[n]=r}}this.length=t&&t.length||0}it.prototype.get=function(e){if(this.glyphs[e]===undefined){this.font._push(e);if(typeof this.glyphs[e]==="function"){this.glyphs[e]=this.glyphs[e]()}var t=this.glyphs[e];var n=this.font._IndexToUnicodeMap[e];if(n){for(var r=0;r<n.unicodes.length;r++){t.addUnicode(n.unicodes[r])}}if(this.font.cffEncoding){if(this.font.isCIDFont){t.name="gid"+e}else{t.name=this.font.cffEncoding.charset[e]}}else if(this.font.glyphNames.names){t.name=this.font.glyphNames.glyphIndexToName(e)}this.glyphs[e].advanceWidth=this.font._hmtxTableData[e].advanceWidth;this.glyphs[e].leftSideBearing=this.font._hmtxTableData[e].leftSideBearing}else{if(typeof this.glyphs[e]==="function"){this.glyphs[e]=this.glyphs[e]()}}return this.glyphs[e]};it.prototype.push=function(e,t){this.glyphs[e]=t;this.length++};function at(e,t){return new g({index:t,font:e})}function st(n,e,r,i,a,s){return function(){var t=new g({index:e,font:n});t.path=function(){r(t,i,a);var e=s(n.glyphs,t);e.unitsPerEm=n.unitsPerEm;return e};rt(t,"xMin","_xMin");rt(t,"xMax","_xMax");rt(t,"yMin","_yMin");rt(t,"yMax","_yMax");return t}}function ot(n,e,r,i){return function(){var t=new g({index:e,font:n});t.path=function(){var e=r(n,t,i);e.unitsPerEm=n.unitsPerEm;return e};return t}}var x={GlyphSet:it,glyphLoader:at,ttfGlyphLoader:st,cffGlyphLoader:ot};function lt(e,t){if(e===t){return true}else if(Array.isArray(e)&&Array.isArray(t)){if(e.length!==t.length){return false}for(var n=0;n<e.length;n+=1){if(!lt(e[n],t[n])){return false}}return true}else{return false}}function ut(e){var t;if(e.length<1240){t=107}else if(e.length<33900){t=1131}else{t=32768}return t}function S(e,t,n){var r=[];var i=[];var a=U.getCard16(e,t);var s;var o;if(a!==0){var l=U.getByte(e,t+2);s=t+(a+1)*l+2;var u=t+3;for(var c=0;c<a+1;c+=1){r.push(U.getOffset(e,u,l));u+=l}o=s+r[a]}else{o=t+2}for(var h=0;h<r.length-1;h+=1){var f=U.getBytes(e,s+r[h],s+r[h+1]);if(n){f=n(f)}i.push(f)}return{objects:i,startOffset:t,endOffset:o}}function ct(e,t){var n=[];var r=U.getCard16(e,t);var i;var a;if(r!==0){var s=U.getByte(e,t+2);i=t+(r+1)*s+2;var o=t+3;for(var l=0;l<r+1;l+=1){n.push(U.getOffset(e,o,s));o+=s}a=i+n[r]}else{a=t+2}return{offsets:n,startOffset:t,endOffset:a}}function ht(e,t,n,r,i){var a=U.getCard16(n,r);var s=0;if(a!==0){var o=U.getByte(n,r+2);s=r+(a+1)*o+2}var l=U.getBytes(n,s+t[e],s+t[e+1]);if(i){l=i(l)}return l}function ft(e){var t="";var n=15;var r=["0","1","2","3","4","5","6","7","8","9",".","E","E-",null,"-"];while(true){var i=e.parseByte();var a=i>>4;var s=i&15;if(a===n){break}t+=r[a];if(s===n){break}t+=r[s]}return parseFloat(t)}function dt(e,t){var n;var r;var i;var a;if(t===28){n=e.parseByte();r=e.parseByte();return n<<8|r}if(t===29){n=e.parseByte();r=e.parseByte();i=e.parseByte();a=e.parseByte();return n<<24|r<<16|i<<8|a}if(t===30){return ft(e)}if(t>=32&&t<=246){return t-139}if(t>=247&&t<=250){n=e.parseByte();return(t-247)*256+n+108}if(t>=251&&t<=254){n=e.parseByte();return-(t-251)*256-n-108}throw new Error("Invalid b0 "+t)}function pt(e){var t={};for(var n=0;n<e.length;n+=1){var r=e[n][0];var i=e[n][1];var a=void 0;if(i.length===1){a=i[0]}else{a=i}if(t.hasOwnProperty(r)&&!isNaN(t[r])){throw new Error("Object "+t+" already has key "+r)}t[r]=a}return t}function gt(e,t,n){t=t!==undefined?t:0;var r=new U.Parser(e,t);var i=[];var a=[];n=n!==undefined?n:e.length;while(r.relativeOffset<n){var s=r.parseByte();if(s<=21){if(s===12){s=1200+r.parseByte()}i.push([s,a]);a=[]}else{a.push(dt(r,s))}}return pt(i)}function mt(e,t){if(t<=390){t=Xe[t]}else{t=e[t-391]}return t}function vt(e,t,n){var r={};var i;for(var a=0;a<t.length;a+=1){var s=t[a];if(Array.isArray(s.type)){var o=[];o.length=s.type.length;for(var l=0;l<s.type.length;l++){i=e[s.op]!==undefined?e[s.op][l]:undefined;if(i===undefined){i=s.value!==undefined&&s.value[l]!==undefined?s.value[l]:null}if(s.type[l]==="SID"){i=mt(n,i)}o[l]=i}r[s.name]=o}else{i=e[s.op];if(i===undefined){i=s.value!==undefined?s.value:null}if(s.type==="SID"){i=mt(n,i)}r[s.name]=i}}return r}function bt(e,t){var n={};n.formatMajor=U.getCard8(e,t);n.formatMinor=U.getCard8(e,t+1);n.size=U.getCard8(e,t+2);n.offsetSize=U.getCard8(e,t+3);n.startOffset=t;n.endOffset=t+4;return n}var _t=[{name:"version",op:0,type:"SID"},{name:"notice",op:1,type:"SID"},{name:"copyright",op:1200,type:"SID"},{name:"fullName",op:2,type:"SID"},{name:"familyName",op:3,type:"SID"},{name:"weight",op:4,type:"SID"},{name:"isFixedPitch",op:1201,type:"number",value:0},{name:"italicAngle",op:1202,type:"number",value:0},{name:"underlinePosition",op:1203,type:"number",value:-100},{name:"underlineThickness",op:1204,type:"number",value:50},{name:"paintType",op:1205,type:"number",value:0},{name:"charstringType",op:1206,type:"number",value:2},{name:"fontMatrix",op:1207,type:["real","real","real","real","real","real"],value:[.001,0,0,.001,0,0]},{name:"uniqueId",op:13,type:"number"},{name:"fontBBox",op:5,type:["number","number","number","number"],value:[0,0,0,0]},{name:"strokeWidth",op:1208,type:"number",value:0},{name:"xuid",op:14,type:[],value:null},{name:"charset",op:15,type:"offset",value:0},{name:"encoding",op:16,type:"offset",value:0},{name:"charStrings",op:17,type:"offset",value:0},{name:"private",op:18,type:["number","offset"],value:[0,0]},{name:"ros",op:1230,type:["SID","SID","number"]},{name:"cidFontVersion",op:1231,type:"number",value:0},{name:"cidFontRevision",op:1232,type:"number",value:0},{name:"cidFontType",op:1233,type:"number",value:0},{name:"cidCount",op:1234,type:"number",value:8720},{name:"uidBase",op:1235,type:"number"},{name:"fdArray",op:1236,type:"offset"},{name:"fdSelect",op:1237,type:"offset"},{name:"fontName",op:1238,type:"SID"}];var Et=[{name:"subrs",op:19,type:"offset",value:0},{name:"defaultWidthX",op:20,type:"number",value:0},{name:"nominalWidthX",op:21,type:"number",value:0}];function Ft(e,t){var n=gt(e,0,e.byteLength);return vt(n,_t,t)}function Ct(e,t,n,r){var i=gt(e,t,n);return vt(i,Et,r)}function At(e,t,n,r){var i=[];for(var a=0;a<n.length;a+=1){var s=new DataView(new Uint8Array(n[a]).buffer);var o=Ft(s,r);o._subrs=[];o._subrsBias=0;o._defaultWidthX=0;o._nominalWidthX=0;var l=o.private[0];var u=o.private[1];if(l!==0&&u!==0){var c=Ct(e,u+t,l,r);o._defaultWidthX=c.defaultWidthX;o._nominalWidthX=c.nominalWidthX;if(c.subrs!==0){var h=u+c.subrs;var f=S(e,h+t);o._subrs=f.objects;o._subrsBias=ut(o._subrs)}o._privateDict=c}i.push(o)}return i}function xt(e,t,n,r){var i;var a;var s=new U.Parser(e,t);n-=1;var o=[".notdef"];var l=s.parseCard8();if(l===0){for(var u=0;u<n;u+=1){i=s.parseSID();o.push(mt(r,i))}}else if(l===1){while(o.length<=n){i=s.parseSID();a=s.parseCard8();for(var c=0;c<=a;c+=1){o.push(mt(r,i));i+=1}}}else if(l===2){while(o.length<=n){i=s.parseSID();a=s.parseCard16();for(var h=0;h<=a;h+=1){o.push(mt(r,i));i+=1}}}else{throw new Error("Unknown charset format "+l)}return o}function Tt(e,t,n){var r;var i={};var a=new U.Parser(e,t);var s=a.parseCard8();if(s===0){var o=a.parseCard8();for(var l=0;l<o;l+=1){r=a.parseCard8();i[r]=l}}else if(s===1){var u=a.parseCard8();r=1;for(var c=0;c<u;c+=1){var h=a.parseCard8();var f=a.parseCard8();for(var d=h;d<=h+f;d+=1){i[d]=r;r+=1}}}else{throw new Error("Unknown encoding format "+s)}return new Je(i,n)}function St(g,m,e){var v;var b;var _;var E;var F=new p;var C=[];var A=0;var x=false;var T=false;var S=0;var y=0;var B;var O;var t;var D;if(g.isCIDFont){var n=g.tables.cff.topDict._fdSelect[m.index];var r=g.tables.cff.topDict._fdArray[n];B=r._subrs;O=r._subrsBias;t=r._defaultWidthX;D=r._nominalWidthX}else{B=g.tables.cff.topDict._subrs;O=g.tables.cff.topDict._subrsBias;t=g.tables.cff.topDict._defaultWidthX;D=g.tables.cff.topDict._nominalWidthX}var I=t;function M(e,t){if(T){F.closePath()}F.moveTo(e,t);T=true}function L(){var e;e=C.length%2!==0;if(e&&!x){I=C.shift()+D}A+=C.length>>1;C.length=0;x=true}function R(e){var t;var n;var r;var i;var a;var s;var o;var l;var u;var c;var h;var f;var d=0;while(d<e.length){var p=e[d];d+=1;switch(p){case 1:L();break;case 3:L();break;case 4:if(C.length>1&&!x){I=C.shift()+D;x=true}y+=C.pop();M(S,y);break;case 5:while(C.length>0){S+=C.shift();y+=C.shift();F.lineTo(S,y)}break;case 6:while(C.length>0){S+=C.shift();F.lineTo(S,y);if(C.length===0){break}y+=C.shift();F.lineTo(S,y)}break;case 7:while(C.length>0){y+=C.shift();F.lineTo(S,y);if(C.length===0){break}S+=C.shift();F.lineTo(S,y)}break;case 8:while(C.length>0){v=S+C.shift();b=y+C.shift();_=v+C.shift();E=b+C.shift();S=_+C.shift();y=E+C.shift();F.curveTo(v,b,_,E,S,y)}break;case 10:a=C.pop()+O;s=B[a];if(s){R(s)}break;case 11:return;case 12:p=e[d];d+=1;switch(p){case 35:v=S+C.shift();b=y+C.shift();_=v+C.shift();E=b+C.shift();o=_+C.shift();l=E+C.shift();u=o+C.shift();c=l+C.shift();h=u+C.shift();f=c+C.shift();S=h+C.shift();y=f+C.shift();C.shift();F.curveTo(v,b,_,E,o,l);F.curveTo(u,c,h,f,S,y);break;case 34:v=S+C.shift();b=y;_=v+C.shift();E=b+C.shift();o=_+C.shift();l=E;u=o+C.shift();c=E;h=u+C.shift();f=y;S=h+C.shift();F.curveTo(v,b,_,E,o,l);F.curveTo(u,c,h,f,S,y);break;case 36:v=S+C.shift();b=y+C.shift();_=v+C.shift();E=b+C.shift();o=_+C.shift();l=E;u=o+C.shift();c=E;h=u+C.shift();f=c+C.shift();S=h+C.shift();F.curveTo(v,b,_,E,o,l);F.curveTo(u,c,h,f,S,y);break;case 37:v=S+C.shift();b=y+C.shift();_=v+C.shift();E=b+C.shift();o=_+C.shift();l=E+C.shift();u=o+C.shift();c=l+C.shift();h=u+C.shift();f=c+C.shift();if(Math.abs(h-S)>Math.abs(f-y)){S=h+C.shift()}else{y=f+C.shift()}F.curveTo(v,b,_,E,o,l);F.curveTo(u,c,h,f,S,y);break;default:console.log("Glyph "+m.index+": unknown operator "+1200+p);C.length=0}break;case 14:if(C.length>0&&!x){I=C.shift()+D;x=true}if(T){F.closePath();T=false}break;case 18:L();break;case 19:case 20:L();d+=A+7>>3;break;case 21:if(C.length>2&&!x){I=C.shift()+D;x=true}y+=C.pop();S+=C.pop();M(S,y);break;case 22:if(C.length>1&&!x){I=C.shift()+D;x=true}S+=C.pop();M(S,y);break;case 23:L();break;case 24:while(C.length>2){v=S+C.shift();b=y+C.shift();_=v+C.shift();E=b+C.shift();S=_+C.shift();y=E+C.shift();F.curveTo(v,b,_,E,S,y)}S+=C.shift();y+=C.shift();F.lineTo(S,y);break;case 25:while(C.length>6){S+=C.shift();y+=C.shift();F.lineTo(S,y)}v=S+C.shift();b=y+C.shift();_=v+C.shift();E=b+C.shift();S=_+C.shift();y=E+C.shift();F.curveTo(v,b,_,E,S,y);break;case 26:if(C.length%2){S+=C.shift()}while(C.length>0){v=S;b=y+C.shift();_=v+C.shift();E=b+C.shift();S=_;y=E+C.shift();F.curveTo(v,b,_,E,S,y)}break;case 27:if(C.length%2){y+=C.shift()}while(C.length>0){v=S+C.shift();b=y;_=v+C.shift();E=b+C.shift();S=_+C.shift();y=E;F.curveTo(v,b,_,E,S,y)}break;case 28:t=e[d];n=e[d+1];C.push((t<<24|n<<16)>>16);d+=2;break;case 29:a=C.pop()+g.gsubrsBias;s=g.gsubrs[a];if(s){R(s)}break;case 30:while(C.length>0){v=S;b=y+C.shift();_=v+C.shift();E=b+C.shift();S=_+C.shift();y=E+(C.length===1?C.shift():0);F.curveTo(v,b,_,E,S,y);if(C.length===0){break}v=S+C.shift();b=y;_=v+C.shift();E=b+C.shift();y=E+C.shift();S=_+(C.length===1?C.shift():0);F.curveTo(v,b,_,E,S,y)}break;case 31:while(C.length>0){v=S+C.shift();b=y;_=v+C.shift();E=b+C.shift();y=E+C.shift();S=_+(C.length===1?C.shift():0);F.curveTo(v,b,_,E,S,y);if(C.length===0){break}v=S;b=y+C.shift();_=v+C.shift();E=b+C.shift();S=_+C.shift();y=E+(C.length===1?C.shift():0);F.curveTo(v,b,_,E,S,y)}break;default:if(p<32){console.log("Glyph "+m.index+": unknown operator "+p)}else if(p<247){C.push(p-139)}else if(p<251){t=e[d];d+=1;C.push((p-247)*256+t+108)}else if(p<255){t=e[d];d+=1;C.push(-(p-251)*256-t-108)}else{t=e[d];n=e[d+1];r=e[d+2];i=e[d+3];d+=4;C.push((t<<24|n<<16|r<<8|i)/65536)}}}}R(e);m.advanceWidth=I;return F}function yt(e,t,n,r){var i=[];var a;var s=new U.Parser(e,t);var o=s.parseCard8();if(o===0){for(var l=0;l<n;l++){a=s.parseCard8();if(a>=r){throw new Error("CFF table CID Font FDSelect has bad FD index value "+a+" (FD count "+r+")")}i.push(a)}}else if(o===3){var u=s.parseCard16();var c=s.parseCard16();if(c!==0){throw new Error("CFF Table CID Font FDSelect format 3 range has bad initial GID "+c)}var h;for(var f=0;f<u;f++){a=s.parseCard8();h=s.parseCard16();if(a>=r){throw new Error("CFF table CID Font FDSelect has bad FD index value "+a+" (FD count "+r+")")}if(h>n){throw new Error("CFF Table CID Font FDSelect format 3 range has bad GID "+h)}for(;c<h;c++){i.push(a)}c=h}if(h!==n){throw new Error("CFF Table CID Font FDSelect format 3 range has bad final GID "+h)}}else{throw new Error("CFF Table CID Font FDSelect table has unsupported format "+o)}return i}function Bt(n,r,i,e){i.tables.cff={};var t=bt(n,r);var a=S(n,t.endOffset,U.bytesToString);var s=S(n,a.endOffset);var o=S(n,s.endOffset,U.bytesToString);var l=S(n,o.endOffset);i.gsubrs=l.objects;i.gsubrsBias=ut(i.gsubrs);var u=At(n,r,s.objects,o.objects);if(u.length!==1){throw new Error("CFF table has too many fonts in 'FontSet' - count of fonts NameIndex.length = "+u.length)}var c=u[0];i.tables.cff.topDict=c;if(c._privateDict){i.defaultWidthX=c._privateDict.defaultWidthX;i.nominalWidthX=c._privateDict.nominalWidthX}if(c.ros[0]!==undefined&&c.ros[1]!==undefined){i.isCIDFont=true}if(i.isCIDFont){var h=c.fdArray;var f=c.fdSelect;if(h===0||f===0){throw new Error("Font is marked as a CID font, but FDArray and/or FDSelect information is missing")}h+=r;var d=S(n,h);var p=At(n,r,d.objects,o.objects);c._fdArray=p;f+=r;c._fdSelect=yt(n,f,i.numGlyphs,p.length)}var g=r+c.private[1];var m=Ct(n,g,c.private[0],o.objects);i.defaultWidthX=m.defaultWidthX;i.nominalWidthX=m.nominalWidthX;if(m.subrs!==0){var v=g+m.subrs;var b=S(n,v);i.subrs=b.objects;i.subrsBias=ut(i.subrs)}else{i.subrs=[];i.subrsBias=0}var _;if(e.lowMemory){_=ct(n,r+c.charStrings);i.nGlyphs=_.offsets.length}else{_=S(n,r+c.charStrings);i.nGlyphs=_.objects.length}var E=xt(n,r+c.charset,i.nGlyphs,o.objects);if(c.encoding===0){i.cffEncoding=new Je(We,E)}else if(c.encoding===1){i.cffEncoding=new Je(Ye,E)}else{i.cffEncoding=Tt(n,r+c.encoding,E)}i.encoding=i.encoding||i.cffEncoding;i.glyphs=new x.GlyphSet(i);if(e.lowMemory){i._push=function(e){var t=ht(e,_.offsets,n,r+c.charStrings);i.glyphs.push(e,x.cffGlyphLoader(i,e,St,t))}}else{for(var F=0;F<i.nGlyphs;F+=1){var C=_.objects[F];i.glyphs.push(F,x.cffGlyphLoader(i,F,St,C))}}}function Ot(e,t){var n;var r=Xe.indexOf(e);if(r>=0){n=r}r=t.indexOf(e);if(r>=0){n=r+Xe.length}else{n=Xe.length+t.length;t.push(e)}return n}function Dt(){return new B.Record("Header",[{name:"major",type:"Card8",value:1},{name:"minor",type:"Card8",value:0},{name:"hdrSize",type:"Card8",value:4},{name:"major",type:"Card8",value:1}])}function It(e){var t=new B.Record("Name INDEX",[{name:"names",type:"INDEX",value:[]}]);t.names=[];for(var n=0;n<e.length;n+=1){t.names.push({name:"name_"+n,type:"NAME",value:e[n]})}return t}function Mt(e,t,n){var r={};for(var i=0;i<e.length;i+=1){var a=e[i];var s=t[a.name];if(s!==undefined&&!lt(s,a.value)){if(a.type==="SID"){s=Ot(s,n)}r[a.op]={name:a.name,type:a.type,value:s}}}return r}function Lt(e,t){var n=new B.Record("Top DICT",[{name:"dict",type:"DICT",value:{}}]);n.dict=Mt(_t,e,t);return n}function Rt(e){var t=new B.Record("Top DICT INDEX",[{name:"topDicts",type:"INDEX",value:[]}]);t.topDicts=[{name:"topDict_0",type:"TABLE",value:e}];return t}function wt(e){var t=new B.Record("String INDEX",[{name:"strings",type:"INDEX",value:[]}]);t.strings=[];for(var n=0;n<e.length;n+=1){t.strings.push({name:"string_"+n,type:"STRING",value:e[n]})}return t}function Nt(){return new B.Record("Global Subr INDEX",[{name:"subrs",type:"INDEX",value:[]}])}function Pt(e,t){var n=new B.Record("Charsets",[{name:"format",type:"Card8",value:0}]);for(var r=0;r<e.length;r+=1){var i=e[r];var a=Ot(i,t);n.fields.push({name:"glyph_"+r,type:"SID",value:a})}return n}function Ut(e){var t=[];var n=e.path;t.push({name:"width",type:"NUMBER",value:e.advanceWidth});var r=0;var i=0;for(var a=0;a<n.commands.length;a+=1){var s=void 0;var o=void 0;var l=n.commands[a];if(l.type==="Q"){var u=1/3;var c=2/3;l={type:"C",x:l.x,y:l.y,x1:Math.round(u*r+c*l.x1),y1:Math.round(u*i+c*l.y1),x2:Math.round(u*l.x+c*l.x1),y2:Math.round(u*l.y+c*l.y1)}}if(l.type==="M"){s=Math.round(l.x-r);o=Math.round(l.y-i);t.push({name:"dx",type:"NUMBER",value:s});t.push({name:"dy",type:"NUMBER",value:o});t.push({name:"rmoveto",type:"OP",value:21});r=Math.round(l.x);i=Math.round(l.y)}else if(l.type==="L"){s=Math.round(l.x-r);o=Math.round(l.y-i);t.push({name:"dx",type:"NUMBER",value:s});t.push({name:"dy",type:"NUMBER",value:o});t.push({name:"rlineto",type:"OP",value:5});r=Math.round(l.x);i=Math.round(l.y)}else if(l.type==="C"){var h=Math.round(l.x1-r);var f=Math.round(l.y1-i);var d=Math.round(l.x2-l.x1);var p=Math.round(l.y2-l.y1);s=Math.round(l.x-l.x2);o=Math.round(l.y-l.y2);t.push({name:"dx1",type:"NUMBER",value:h});t.push({name:"dy1",type:"NUMBER",value:f});t.push({name:"dx2",type:"NUMBER",value:d});t.push({name:"dy2",type:"NUMBER",value:p});t.push({name:"dx",type:"NUMBER",value:s});t.push({name:"dy",type:"NUMBER",value:o});t.push({name:"rrcurveto",type:"OP",value:8});r=Math.round(l.x);i=Math.round(l.y)}}t.push({name:"endchar",type:"OP",value:14});return t}function kt(e){var t=new B.Record("CharStrings INDEX",[{name:"charStrings",type:"INDEX",value:[]}]);for(var n=0;n<e.length;n+=1){var r=e.get(n);var i=Ut(r);t.charStrings.push({name:r.name,type:"CHARSTRING",value:i})}return t}function jt(e,t){var n=new B.Record("Private DICT",[{name:"dict",type:"DICT",value:{}}]);n.dict=Mt(Et,e,t);return n}function Gt(e,t){var n=new B.Table("CFF ",[{name:"header",type:"RECORD"},{name:"nameIndex",type:"RECORD"},{name:"topDictIndex",type:"RECORD"},{name:"stringIndex",type:"RECORD"},{name:"globalSubrIndex",type:"RECORD"},{name:"charsets",type:"RECORD"},{name:"charStringsIndex",type:"RECORD"},{name:"privateDict",type:"RECORD"}]);var r=1/t.unitsPerEm;var i={version:t.version,fullName:t.fullName,familyName:t.familyName,weight:t.weightName,fontBBox:t.fontBBox||[0,0,0,0],fontMatrix:[r,0,0,r,0,0],charset:999,encoding:0,charStrings:999,private:[0,999]};var a={};var s=[];var o;for(var l=1;l<e.length;l+=1){o=e.get(l);s.push(o.name)}var u=[];n.header=Dt();n.nameIndex=It([t.postScriptName]);var c=Lt(i,u);n.topDictIndex=Rt(c);n.globalSubrIndex=Nt();n.charsets=Pt(s,u);n.charStringsIndex=kt(e);n.privateDict=jt(a,u);n.stringIndex=wt(u);var h=n.header.sizeOf()+n.nameIndex.sizeOf()+n.topDictIndex.sizeOf()+n.stringIndex.sizeOf()+n.globalSubrIndex.sizeOf();i.charset=h;i.encoding=0;i.charStrings=i.charset+n.charsets.sizeOf();i.private[1]=i.charStrings+n.charStringsIndex.sizeOf();c=Lt(i,u);n.topDictIndex=Rt(c);return n}var Vt={parse:Bt,make:Gt};function zt(e,t){var n={};var r=new U.Parser(e,t);n.version=r.parseVersion();n.fontRevision=Math.round(r.parseFixed()*1e3)/1e3;n.checkSumAdjustment=r.parseULong();n.magicNumber=r.parseULong();A.argument(n.magicNumber===1594834165,"Font header has wrong magic number.");n.flags=r.parseUShort();n.unitsPerEm=r.parseUShort();n.created=r.parseLongDateTime();n.modified=r.parseLongDateTime();n.xMin=r.parseShort();n.yMin=r.parseShort();n.xMax=r.parseShort();n.yMax=r.parseShort();n.macStyle=r.parseUShort();n.lowestRecPPEM=r.parseUShort();n.fontDirectionHint=r.parseShort();n.indexToLocFormat=r.parseShort();n.glyphDataFormat=r.parseShort();return n}function Ht(e){var t=Math.round((new Date).getTime()/1e3)+2082844800;var n=t;if(e.createdTimestamp){n=e.createdTimestamp+2082844800}return new B.Table("head",[{name:"version",type:"FIXED",value:65536},{name:"fontRevision",type:"FIXED",value:65536},{name:"checkSumAdjustment",type:"ULONG",value:0},{name:"magicNumber",type:"ULONG",value:1594834165},{name:"flags",type:"USHORT",value:0},{name:"unitsPerEm",type:"USHORT",value:1e3},{name:"created",type:"LONGDATETIME",value:n},{name:"modified",type:"LONGDATETIME",value:t},{name:"xMin",type:"SHORT",value:0},{name:"yMin",type:"SHORT",value:0},{name:"xMax",type:"SHORT",value:0},{name:"yMax",type:"SHORT",value:0},{name:"macStyle",type:"USHORT",value:0},{name:"lowestRecPPEM",type:"USHORT",value:0},{name:"fontDirectionHint",type:"SHORT",value:2},{name:"indexToLocFormat",type:"SHORT",value:0},{name:"glyphDataFormat",type:"SHORT",value:0}],e)}var Xt={parse:zt,make:Ht};function Wt(e,t){var n={};var r=new U.Parser(e,t);n.version=r.parseVersion();n.ascender=r.parseShort();n.descender=r.parseShort();n.lineGap=r.parseShort();n.advanceWidthMax=r.parseUShort();n.minLeftSideBearing=r.parseShort();n.minRightSideBearing=r.parseShort();n.xMaxExtent=r.parseShort();n.caretSlopeRise=r.parseShort();n.caretSlopeRun=r.parseShort();n.caretOffset=r.parseShort();r.relativeOffset+=8;n.metricDataFormat=r.parseShort();n.numberOfHMetrics=r.parseUShort();return n}function Yt(e){return new B.Table("hhea",[{name:"version",type:"FIXED",value:65536},{name:"ascender",type:"FWORD",value:0},{name:"descender",type:"FWORD",value:0},{name:"lineGap",type:"FWORD",value:0},{name:"advanceWidthMax",type:"UFWORD",value:0},{name:"minLeftSideBearing",type:"FWORD",value:0},{name:"minRightSideBearing",type:"FWORD",value:0},{name:"xMaxExtent",type:"FWORD",value:0},{name:"caretSlopeRise",type:"SHORT",value:1},{name:"caretSlopeRun",type:"SHORT",value:0},{name:"caretOffset",type:"SHORT",value:0},{name:"reserved1",type:"SHORT",value:0},{name:"reserved2",type:"SHORT",value:0},{name:"reserved3",type:"SHORT",value:0},{name:"reserved4",type:"SHORT",value:0},{name:"metricDataFormat",type:"SHORT",value:0},{name:"numberOfHMetrics",type:"USHORT",value:0}],e)}var qt={parse:Wt,make:Yt};function Zt(e,t,n,r,i){var a;var s;var o=new U.Parser(e,t);for(var l=0;l<r;l+=1){if(l<n){a=o.parseUShort();s=o.parseShort()}var u=i.get(l);u.advanceWidth=a;u.leftSideBearing=s}}function Jt(e,t,n,r,i){e._hmtxTableData={};var a;var s;var o=new U.Parser(t,n);for(var l=0;l<i;l+=1){if(l<r){a=o.parseUShort();s=o.parseShort()}e._hmtxTableData[l]={advanceWidth:a,leftSideBearing:s}}}function Qt(e,t,n,r,i,a,s){if(s.lowMemory){Jt(e,t,n,r,i)}else{Zt(t,n,r,i,a)}}function Kt(e){var t=new B.Table("hmtx",[]);for(var n=0;n<e.length;n+=1){var r=e.get(n);var i=r.advanceWidth||0;var a=r.leftSideBearing||0;t.fields.push({name:"advanceWidth_"+n,type:"USHORT",value:i});t.fields.push({name:"leftSideBearing_"+n,type:"SHORT",value:a})}return t}var $t={parse:Qt,make:Kt};function en(e){var t=new B.Table("ltag",[{name:"version",type:"ULONG",value:1},{name:"flags",type:"ULONG",value:0},{name:"numTags",type:"ULONG",value:e.length}]);var n="";var r=12+e.length*4;for(var i=0;i<e.length;++i){var a=n.indexOf(e[i]);if(a<0){a=n.length;n+=e[i]}t.fields.push({name:"offset "+i,type:"USHORT",value:r+a});t.fields.push({name:"length "+i,type:"USHORT",value:e[i].length})}t.fields.push({name:"stringPool",type:"CHARARRAY",value:n});return t}function tn(e,t){var n=new U.Parser(e,t);var r=n.parseULong();A.argument(r===1,"Unsupported ltag table version.");n.skip("uLong",1);var i=n.parseULong();var a=[];for(var s=0;s<i;s++){var o="";var l=t+n.parseUShort();var u=n.parseUShort();for(var c=l;c<l+u;++c){o+=String.fromCharCode(e.getInt8(c))}a.push(o)}return a}var nn={make:en,parse:tn};function rn(e,t){var n={};var r=new U.Parser(e,t);n.version=r.parseVersion();n.numGlyphs=r.parseUShort();if(n.version===1){n.maxPoints=r.parseUShort();n.maxContours=r.parseUShort();n.maxCompositePoints=r.parseUShort();n.maxCompositeContours=r.parseUShort();n.maxZones=r.parseUShort();n.maxTwilightPoints=r.parseUShort();n.maxStorage=r.parseUShort();n.maxFunctionDefs=r.parseUShort();n.maxInstructionDefs=r.parseUShort();n.maxStackElements=r.parseUShort();n.maxSizeOfInstructions=r.parseUShort();n.maxComponentElements=r.parseUShort();n.maxComponentDepth=r.parseUShort()}return n}function an(e){return new B.Table("maxp",[{name:"version",type:"FIXED",value:20480},{name:"numGlyphs",type:"USHORT",value:e}])}var sn={parse:rn,make:an};var on=["copyright","fontFamily","fontSubfamily","uniqueID","fullName","version","postScriptName","trademark","manufacturer","designer","description","manufacturerURL","designerURL","license","licenseURL","reserved","preferredFamily","preferredSubfamily","compatibleFullName","sampleText","postScriptFindFontName","wwsFamily","wwsSubfamily"];var ln={0:"en",1:"fr",2:"de",3:"it",4:"nl",5:"sv",6:"es",7:"da",8:"pt",9:"no",10:"he",11:"ja",12:"ar",13:"fi",14:"el",15:"is",16:"mt",17:"tr",18:"hr",19:"zh-Hant",20:"ur",21:"hi",22:"th",23:"ko",24:"lt",25:"pl",26:"hu",27:"es",28:"lv",29:"se",30:"fo",31:"fa",32:"ru",33:"zh",34:"nl-BE",35:"ga",36:"sq",37:"ro",38:"cz",39:"sk",40:"si",41:"yi",42:"sr",43:"mk",44:"bg",45:"uk",46:"be",47:"uz",48:"kk",49:"az-Cyrl",50:"az-Arab",51:"hy",52:"ka",53:"mo",54:"ky",55:"tg",56:"tk",57:"mn-CN",58:"mn",59:"ps",60:"ks",61:"ku",62:"sd",63:"bo",64:"ne",65:"sa",66:"mr",67:"bn",68:"as",69:"gu",70:"pa",71:"or",72:"ml",73:"kn",74:"ta",75:"te",76:"si",77:"my",78:"km",79:"lo",80:"vi",81:"id",82:"tl",83:"ms",84:"ms-Arab",85:"am",86:"ti",87:"om",88:"so",89:"sw",90:"rw",91:"rn",92:"ny",93:"mg",94:"eo",128:"cy",129:"eu",130:"ca",131:"la",132:"qu",133:"gn",134:"ay",135:"tt",136:"ug",137:"dz",138:"jv",139:"su",140:"gl",141:"af",142:"br",143:"iu",144:"gd",145:"gv",146:"ga",147:"to",148:"el-polyton",149:"kl",150:"az",151:"nn"};var un={0:0,1:0,2:0,3:0,4:0,5:0,6:0,7:0,8:0,9:0,10:5,11:1,12:4,13:0,14:6,15:0,16:0,17:0,18:0,19:2,20:4,21:9,22:21,23:3,24:29,25:29,26:29,27:29,28:29,29:0,30:0,31:4,32:7,33:25,34:0,35:0,36:0,37:0,38:29,39:29,40:0,41:5,42:7,43:7,44:7,45:7,46:7,47:7,48:7,49:7,50:4,51:24,52:23,53:7,54:7,55:7,56:7,57:27,58:7,59:4,60:4,61:4,62:4,63:26,64:9,65:9,66:9,67:13,68:13,69:11,70:10,71:12,72:17,73:16,74:14,75:15,76:18,77:19,78:20,79:22,80:30,81:0,82:0,83:0,84:4,85:28,86:28,87:28,88:0,89:0,90:0,91:0,92:0,93:0,94:0,128:0,129:0,130:0,131:0,132:0,133:0,134:0,135:7,136:4,137:26,138:0,139:0,140:0,141:0,142:0,143:28,144:0,145:0,146:0,147:0,148:6,149:0,150:0,151:0};var cn={1078:"af",1052:"sq",1156:"gsw",1118:"am",5121:"ar-DZ",15361:"ar-BH",3073:"ar",2049:"ar-IQ",11265:"ar-JO",13313:"ar-KW",12289:"ar-LB",4097:"ar-LY",6145:"ary",8193:"ar-OM",16385:"ar-QA",1025:"ar-SA",10241:"ar-SY",7169:"aeb",14337:"ar-AE",9217:"ar-YE",1067:"hy",1101:"as",2092:"az-Cyrl",1068:"az",1133:"ba",1069:"eu",1059:"be",2117:"bn",1093:"bn-IN",8218:"bs-Cyrl",5146:"bs",1150:"br",1026:"bg",1027:"ca",3076:"zh-HK",5124:"zh-MO",2052:"zh",4100:"zh-SG",1028:"zh-TW",1155:"co",1050:"hr",4122:"hr-BA",1029:"cs",1030:"da",1164:"prs",1125:"dv",2067:"nl-BE",1043:"nl",3081:"en-AU",10249:"en-BZ",4105:"en-CA",9225:"en-029",16393:"en-IN",6153:"en-IE",8201:"en-JM",17417:"en-MY",5129:"en-NZ",13321:"en-PH",18441:"en-SG",7177:"en-ZA",11273:"en-TT",2057:"en-GB",1033:"en",12297:"en-ZW",1061:"et",1080:"fo",1124:"fil",1035:"fi",2060:"fr-BE",3084:"fr-CA",1036:"fr",5132:"fr-LU",6156:"fr-MC",4108:"fr-CH",1122:"fy",1110:"gl",1079:"ka",3079:"de-AT",1031:"de",5127:"de-LI",4103:"de-LU",2055:"de-CH",1032:"el",1135:"kl",1095:"gu",1128:"ha",1037:"he",1081:"hi",1038:"hu",1039:"is",1136:"ig",1057:"id",1117:"iu",2141:"iu-Latn",2108:"ga",1076:"xh",1077:"zu",1040:"it",2064:"it-CH",1041:"ja",1099:"kn",1087:"kk",1107:"km",1158:"quc",1159:"rw",1089:"sw",1111:"kok",1042:"ko",1088:"ky",1108:"lo",1062:"lv",1063:"lt",2094:"dsb",1134:"lb",1071:"mk",2110:"ms-BN",1086:"ms",1100:"ml",1082:"mt",1153:"mi",1146:"arn",1102:"mr",1148:"moh",1104:"mn",2128:"mn-CN",1121:"ne",1044:"nb",2068:"nn",1154:"oc",1096:"or",1123:"ps",1045:"pl",1046:"pt",2070:"pt-PT",1094:"pa",1131:"qu-BO",2155:"qu-EC",3179:"qu",1048:"ro",1047:"rm",1049:"ru",9275:"smn",4155:"smj-NO",5179:"smj",3131:"se-FI",1083:"se",2107:"se-SE",8251:"sms",6203:"sma-NO",7227:"sms",1103:"sa",7194:"sr-Cyrl-BA",3098:"sr",6170:"sr-Latn-BA",2074:"sr-Latn",1132:"nso",1074:"tn",1115:"si",1051:"sk",1060:"sl",11274:"es-AR",16394:"es-BO",13322:"es-CL",9226:"es-CO",5130:"es-CR",7178:"es-DO",12298:"es-EC",17418:"es-SV",4106:"es-GT",18442:"es-HN",2058:"es-MX",19466:"es-NI",6154:"es-PA",15370:"es-PY",10250:"es-PE",20490:"es-PR",3082:"es",1034:"es",21514:"es-US",14346:"es-UY",8202:"es-VE",2077:"sv-FI",1053:"sv",1114:"syr",1064:"tg",2143:"tzm",1097:"ta",1092:"tt",1098:"te",1054:"th",1105:"bo",1055:"tr",1090:"tk",1152:"ug",1058:"uk",1070:"hsb",1056:"ur",2115:"uz-Cyrl",1091:"uz",1066:"vi",1106:"cy",1160:"wo",1157:"sah",1144:"ii",1130:"yo"};function hn(e,t,n){switch(e){case 0:if(t===65535){return"und"}else if(n){return n[t]}break;case 1:return ln[t];case 3:return cn[t]}return undefined}var fn="utf-16";var dn={0:"macintosh",1:"x-mac-japanese",2:"x-mac-chinesetrad",3:"x-mac-korean",6:"x-mac-greek",7:"x-mac-cyrillic",9:"x-mac-devanagai",10:"x-mac-gurmukhi",11:"x-mac-gujarati",12:"x-mac-oriya",13:"x-mac-bengali",14:"x-mac-tamil",15:"x-mac-telugu",16:"x-mac-kannada",17:"x-mac-malayalam",18:"x-mac-sinhalese",19:"x-mac-burmese",20:"x-mac-khmer",21:"x-mac-thai",22:"x-mac-lao",23:"x-mac-georgian",24:"x-mac-armenian",25:"x-mac-chinesesimp",26:"x-mac-tibetan",27:"x-mac-mongolian",28:"x-mac-ethiopic",29:"x-mac-ce",30:"x-mac-vietnamese",31:"x-mac-extarabic"};var pn={15:"x-mac-icelandic",17:"x-mac-turkish",18:"x-mac-croatian",24:"x-mac-ce",25:"x-mac-ce",26:"x-mac-ce",27:"x-mac-ce",28:"x-mac-ce",30:"x-mac-icelandic",37:"x-mac-romanian",38:"x-mac-ce",39:"x-mac-ce",40:"x-mac-ce",143:"x-mac-inuit",146:"x-mac-gaelic"};function gn(e,t,n){switch(e){case 0:return fn;case 1:return pn[n]||dn[t];case 3:if(t===1||t===10){return fn}break}return undefined}function mn(e,t,n){var r={};var i=new U.Parser(e,t);var a=i.parseUShort();var s=i.parseUShort();var o=i.offset+i.parseUShort();for(var l=0;l<s;l++){var u=i.parseUShort();var c=i.parseUShort();var h=i.parseUShort();var f=i.parseUShort();var d=on[f]||f;var p=i.parseUShort();var g=i.parseUShort();var m=hn(u,h,n);var v=gn(u,c,h);if(v!==undefined&&m!==undefined){var b=void 0;if(v===fn){b=ce.UTF16(e,o+g,p)}else{b=ce.MACSTRING(e,o+g,p,v)}if(b){var _=r[d];if(_===undefined){_=r[d]={}}_[m]=b}}}var E=0;if(a===1){E=i.parseUShort()}return r}function vn(e){var t={};for(var n in e){t[e[n]]=parseInt(n)}return t}function bn(e,t,n,r,i,a){return new B.Record("NameRecord",[{name:"platformID",type:"USHORT",value:e},{name:"encodingID",type:"USHORT",value:t},{name:"languageID",type:"USHORT",value:n},{name:"nameID",type:"USHORT",value:r},{name:"length",type:"USHORT",value:i},{name:"offset",type:"USHORT",value:a}])}function _n(e,t){var n=e.length;var r=t.length-n+1;e:for(var i=0;i<r;i++){for(;i<r;i++){for(var a=0;a<n;a++){if(t[i+a]!==e[a]){continue e}}return i}}return-1}function En(e,t){var n=_n(e,t);if(n<0){n=t.length;var r=0;var i=e.length;for(;r<i;++r){t.push(e[r])}}return n}function Fn(e,t){var n;var r=[];var i={};var a=vn(on);for(var s in e){var o=a[s];if(o===undefined){o=s}n=parseInt(o);if(isNaN(n)){throw new Error('Name table entry "'+s+'" does not exist, see nameTableNames for complete list.')}i[n]=e[s];r.push(n)}var l=vn(ln);var u=vn(cn);var c=[];var h=[];for(var f=0;f<r.length;f++){n=r[f];var d=i[n];for(var p in d){var g=d[p];var m=1;var v=l[p];var b=un[v];var _=gn(m,b,v);var E=y.MACSTRING(g,_);if(E===undefined){m=0;v=t.indexOf(p);if(v<0){v=t.length;t.push(p)}b=4;E=y.UTF16(g)}var F=En(E,h);c.push(bn(m,b,v,n,E.length,F));var C=u[p];if(C!==undefined){var A=y.UTF16(g);var x=En(A,h);c.push(bn(3,1,C,n,A.length,x))}}}c.sort(function(e,t){return e.platformID-t.platformID||e.encodingID-t.encodingID||e.languageID-t.languageID||e.nameID-t.nameID});var T=new B.Table("name",[{name:"format",type:"USHORT",value:0},{name:"count",type:"USHORT",value:c.length},{name:"stringOffset",type:"USHORT",value:6+c.length*12}]);for(var S=0;S<c.length;S++){T.fields.push({name:"record_"+S,type:"RECORD",value:c[S]})}T.fields.push({name:"strings",type:"LITERAL",value:h});return T}var Cn={parse:mn,make:Fn};var An=[{begin:0,end:127},{begin:128,end:255},{begin:256,end:383},{begin:384,end:591},{begin:592,end:687},{begin:688,end:767},{begin:768,end:879},{begin:880,end:1023},{begin:11392,end:11519},{begin:1024,end:1279},{begin:1328,end:1423},{begin:1424,end:1535},{begin:42240,end:42559},{begin:1536,end:1791},{begin:1984,end:2047},{begin:2304,end:2431},{begin:2432,end:2559},{begin:2560,end:2687},{begin:2688,end:2815},{begin:2816,end:2943},{begin:2944,end:3071},{begin:3072,end:3199},{begin:3200,end:3327},{begin:3328,end:3455},{begin:3584,end:3711},{begin:3712,end:3839},{begin:4256,end:4351},{begin:6912,end:7039},{begin:4352,end:4607},{begin:7680,end:7935},{begin:7936,end:8191},{begin:8192,end:8303},{begin:8304,end:8351},{begin:8352,end:8399},{begin:8400,end:8447},{begin:8448,end:8527},{begin:8528,end:8591},{begin:8592,end:8703},{begin:8704,end:8959},{begin:8960,end:9215},{begin:9216,end:9279},{begin:9280,end:9311},{begin:9312,end:9471},{begin:9472,end:9599},{begin:9600,end:9631},{begin:9632,end:9727},{begin:9728,end:9983},{begin:9984,end:10175},{begin:12288,end:12351},{begin:12352,end:12447},{begin:12448,end:12543},{begin:12544,end:12591},{begin:12592,end:12687},{begin:43072,end:43135},{begin:12800,end:13055},{begin:13056,end:13311},{begin:44032,end:55215},{begin:55296,end:57343},{begin:67840,end:67871},{begin:19968,end:40959},{begin:57344,end:63743},{begin:12736,end:12783},{begin:64256,end:64335},{begin:64336,end:65023},{begin:65056,end:65071},{begin:65040,end:65055},{begin:65104,end:65135},{begin:65136,end:65279},{begin:65280,end:65519},{begin:65520,end:65535},{begin:3840,end:4095},{begin:1792,end:1871},{begin:1920,end:1983},{begin:3456,end:3583},{begin:4096,end:4255},{begin:4608,end:4991},{begin:5024,end:5119},{begin:5120,end:5759},{begin:5760,end:5791},{begin:5792,end:5887},{begin:6016,end:6143},{begin:6144,end:6319},{begin:10240,end:10495},{begin:40960,end:42127},{begin:5888,end:5919},{begin:66304,end:66351},{begin:66352,end:66383},{begin:66560,end:66639},{begin:118784,end:119039},{begin:119808,end:120831},{begin:1044480,end:1048573},{begin:65024,end:65039},{begin:917504,end:917631},{begin:6400,end:6479},{begin:6480,end:6527},{begin:6528,end:6623},{begin:6656,end:6687},{begin:11264,end:11359},{begin:11568,end:11647},{begin:19904,end:19967},{begin:43008,end:43055},{begin:65536,end:65663},{begin:65856,end:65935},{begin:66432,end:66463},{begin:66464,end:66527},{begin:66640,end:66687},{begin:66688,end:66735},{begin:67584,end:67647},{begin:68096,end:68191},{begin:119552,end:119647},{begin:73728,end:74751},{begin:119648,end:119679},{begin:7040,end:7103},{begin:7168,end:7247},{begin:7248,end:7295},{begin:43136,end:43231},{begin:43264,end:43311},{begin:43312,end:43359},{begin:43520,end:43615},{begin:65936,end:65999},{begin:66e3,end:66047},{begin:66208,end:66271},{begin:127024,end:127135}];function xn(e){for(var t=0;t<An.length;t+=1){var n=An[t];if(e>=n.begin&&e<n.end){return t}}return-1}function Tn(e,t){var n={};var r=new U.Parser(e,t);n.version=r.parseUShort();n.xAvgCharWidth=r.parseShort();n.usWeightClass=r.parseUShort();n.usWidthClass=r.parseUShort();n.fsType=r.parseUShort();n.ySubscriptXSize=r.parseShort();n.ySubscriptYSize=r.parseShort();n.ySubscriptXOffset=r.parseShort();n.ySubscriptYOffset=r.parseShort();n.ySuperscriptXSize=r.parseShort();n.ySuperscriptYSize=r.parseShort();n.ySuperscriptXOffset=r.parseShort();n.ySuperscriptYOffset=r.parseShort();n.yStrikeoutSize=r.parseShort();n.yStrikeoutPosition=r.parseShort();n.sFamilyClass=r.parseShort();n.panose=[];for(var i=0;i<10;i++){n.panose[i]=r.parseByte()}n.ulUnicodeRange1=r.parseULong();n.ulUnicodeRange2=r.parseULong();n.ulUnicodeRange3=r.parseULong();n.ulUnicodeRange4=r.parseULong();n.achVendID=String.fromCharCode(r.parseByte(),r.parseByte(),r.parseByte(),r.parseByte());n.fsSelection=r.parseUShort();n.usFirstCharIndex=r.parseUShort();n.usLastCharIndex=r.parseUShort();n.sTypoAscender=r.parseShort();n.sTypoDescender=r.parseShort();n.sTypoLineGap=r.parseShort();n.usWinAscent=r.parseUShort();n.usWinDescent=r.parseUShort();if(n.version>=1){n.ulCodePageRange1=r.parseULong();n.ulCodePageRange2=r.parseULong()}if(n.version>=2){n.sxHeight=r.parseShort();n.sCapHeight=r.parseShort();n.usDefaultChar=r.parseUShort();n.usBreakChar=r.parseUShort();n.usMaxContent=r.parseUShort()}return n}function Sn(e){return new B.Table("OS/2",[{name:"version",type:"USHORT",value:3},{name:"xAvgCharWidth",type:"SHORT",value:0},{name:"usWeightClass",type:"USHORT",value:0},{name:"usWidthClass",type:"USHORT",value:0},{name:"fsType",type:"USHORT",value:0},{name:"ySubscriptXSize",type:"SHORT",value:650},{name:"ySubscriptYSize",type:"SHORT",value:699},{name:"ySubscriptXOffset",type:"SHORT",value:0},{name:"ySubscriptYOffset",type:"SHORT",value:140},{name:"ySuperscriptXSize",type:"SHORT",value:650},{name:"ySuperscriptYSize",type:"SHORT",value:699},{name:"ySuperscriptXOffset",type:"SHORT",value:0},{name:"ySuperscriptYOffset",type:"SHORT",value:479},{name:"yStrikeoutSize",type:"SHORT",value:49},{name:"yStrikeoutPosition",type:"SHORT",value:258},{name:"sFamilyClass",type:"SHORT",value:0},{name:"bFamilyType",type:"BYTE",value:0},{name:"bSerifStyle",type:"BYTE",value:0},{name:"bWeight",type:"BYTE",value:0},{name:"bProportion",type:"BYTE",value:0},{name:"bContrast",type:"BYTE",value:0},{name:"bStrokeVariation",type:"BYTE",value:0},{name:"bArmStyle",type:"BYTE",value:0},{name:"bLetterform",type:"BYTE",value:0},{name:"bMidline",type:"BYTE",value:0},{name:"bXHeight",type:"BYTE",value:0},{name:"ulUnicodeRange1",type:"ULONG",value:0},{name:"ulUnicodeRange2",type:"ULONG",value:0},{name:"ulUnicodeRange3",type:"ULONG",value:0},{name:"ulUnicodeRange4",type:"ULONG",value:0},{name:"achVendID",type:"CHARARRAY",value:"XXXX"},{name:"fsSelection",type:"USHORT",value:0},{name:"usFirstCharIndex",type:"USHORT",value:0},{name:"usLastCharIndex",type:"USHORT",value:0},{name:"sTypoAscender",type:"SHORT",value:0},{name:"sTypoDescender",type:"SHORT",value:0},{name:"sTypoLineGap",type:"SHORT",value:0},{name:"usWinAscent",type:"USHORT",value:0},{name:"usWinDescent",type:"USHORT",value:0},{name:"ulCodePageRange1",type:"ULONG",value:0},{name:"ulCodePageRange2",type:"ULONG",value:0},{name:"sxHeight",type:"SHORT",value:0},{name:"sCapHeight",type:"SHORT",value:0},{name:"usDefaultChar",type:"USHORT",value:0},{name:"usBreakChar",type:"USHORT",value:0},{name:"usMaxContext",type:"USHORT",value:0}],e)}var yn={parse:Tn,make:Sn,unicodeRanges:An,getUnicodeRange:xn};function Bn(e,t){var n={};var r=new U.Parser(e,t);n.version=r.parseVersion();n.italicAngle=r.parseFixed();n.underlinePosition=r.parseShort();n.underlineThickness=r.parseShort();n.isFixedPitch=r.parseULong();n.minMemType42=r.parseULong();n.maxMemType42=r.parseULong();n.minMemType1=r.parseULong();n.maxMemType1=r.parseULong();switch(n.version){case 1:n.names=u.slice();break;case 2:n.numberOfGlyphs=r.parseUShort();n.glyphNameIndex=new Array(n.numberOfGlyphs);for(var i=0;i<n.numberOfGlyphs;i++){n.glyphNameIndex[i]=r.parseUShort()}n.names=[];for(var a=0;a<n.numberOfGlyphs;a++){if(n.glyphNameIndex[a]>=u.length){var s=r.parseChar();n.names.push(r.parseString(s))}}break;case 2.5:n.numberOfGlyphs=r.parseUShort();n.offset=new Array(n.numberOfGlyphs);for(var o=0;o<n.numberOfGlyphs;o++){n.offset[o]=r.parseChar()}break}return n}function On(){return new B.Table("post",[{name:"version",type:"FIXED",value:196608},{name:"italicAngle",type:"FIXED",value:0},{name:"underlinePosition",type:"FWORD",value:0},{name:"underlineThickness",type:"FWORD",value:0},{name:"isFixedPitch",type:"ULONG",value:0},{name:"minMemType42",type:"ULONG",value:0},{name:"maxMemType42",type:"ULONG",value:0},{name:"minMemType1",type:"ULONG",value:0},{name:"maxMemType1",type:"ULONG",value:0}])}var Dn={parse:Bn,make:On};var a=new Array(9);a[1]=function e(){var t=this.offset+this.relativeOffset;var n=this.parseUShort();if(n===1){return{substFormat:1,coverage:this.parsePointer(c.coverage),deltaGlyphId:this.parseUShort()}}else if(n===2){return{substFormat:2,coverage:this.parsePointer(c.coverage),substitute:this.parseOffset16List()}}A.assert(false,"0x"+t.toString(16)+": lookup type 1 format must be 1 or 2.")};a[2]=function e(){var t=this.parseUShort();A.argument(t===1,"GSUB Multiple Substitution Subtable identifier-format must be 1");return{substFormat:t,coverage:this.parsePointer(c.coverage),sequences:this.parseListOfLists()}};a[3]=function e(){var t=this.parseUShort();A.argument(t===1,"GSUB Alternate Substitution Subtable identifier-format must be 1");return{substFormat:t,coverage:this.parsePointer(c.coverage),alternateSets:this.parseListOfLists()}};a[4]=function e(){var t=this.parseUShort();A.argument(t===1,"GSUB ligature table identifier-format must be 1");return{substFormat:t,coverage:this.parsePointer(c.coverage),ligatureSets:this.parseListOfLists(function(){return{ligGlyph:this.parseUShort(),components:this.parseUShortList(this.parseUShort()-1)}})}};var In={sequenceIndex:c.uShort,lookupListIndex:c.uShort};a[5]=function e(){var t=this.offset+this.relativeOffset;var n=this.parseUShort();if(n===1){return{substFormat:n,coverage:this.parsePointer(c.coverage),ruleSets:this.parseListOfLists(function(){var e=this.parseUShort();var t=this.parseUShort();return{input:this.parseUShortList(e-1),lookupRecords:this.parseRecordList(t,In)}})}}else if(n===2){return{substFormat:n,coverage:this.parsePointer(c.coverage),classDef:this.parsePointer(c.classDef),classSets:this.parseListOfLists(function(){var e=this.parseUShort();var t=this.parseUShort();return{classes:this.parseUShortList(e-1),lookupRecords:this.parseRecordList(t,In)}})}}else if(n===3){var r=this.parseUShort();var i=this.parseUShort();return{substFormat:n,coverages:this.parseList(r,c.pointer(c.coverage)),lookupRecords:this.parseRecordList(i,In)}}A.assert(false,"0x"+t.toString(16)+": lookup type 5 format must be 1, 2 or 3.")};a[6]=function e(){var t=this.offset+this.relativeOffset;var n=this.parseUShort();if(n===1){return{substFormat:1,coverage:this.parsePointer(c.coverage),chainRuleSets:this.parseListOfLists(function(){return{backtrack:this.parseUShortList(),input:this.parseUShortList(this.parseShort()-1),lookahead:this.parseUShortList(),lookupRecords:this.parseRecordList(In)}})}}else if(n===2){return{substFormat:2,coverage:this.parsePointer(c.coverage),backtrackClassDef:this.parsePointer(c.classDef),inputClassDef:this.parsePointer(c.classDef),lookaheadClassDef:this.parsePointer(c.classDef),chainClassSet:this.parseListOfLists(function(){return{backtrack:this.parseUShortList(),input:this.parseUShortList(this.parseShort()-1),lookahead:this.parseUShortList(),lookupRecords:this.parseRecordList(In)}})}}else if(n===3){return{substFormat:3,backtrackCoverage:this.parseList(c.pointer(c.coverage)),inputCoverage:this.parseList(c.pointer(c.coverage)),lookaheadCoverage:this.parseList(c.pointer(c.coverage)),lookupRecords:this.parseRecordList(In)}}A.assert(false,"0x"+t.toString(16)+": lookup type 6 format must be 1, 2 or 3.")};a[7]=function e(){var t=this.parseUShort();A.argument(t===1,"GSUB Extension Substitution subtable identifier-format must be 1");var n=this.parseUShort();var r=new c(this.data,this.offset+this.parseULong());return{substFormat:1,lookupType:n,extension:a[n].call(r)}};a[8]=function e(){var t=this.parseUShort();A.argument(t===1,"GSUB Reverse Chaining Contextual Single Substitution Subtable identifier-format must be 1");return{substFormat:t,coverage:this.parsePointer(c.coverage),backtrackCoverage:this.parseList(c.pointer(c.coverage)),lookaheadCoverage:this.parseList(c.pointer(c.coverage)),substitutes:this.parseUShortList()}};function Mn(e,t){t=t||0;var n=new c(e,t);var r=n.parseVersion(1);A.argument(r===1||r===1.1,"Unsupported GSUB table version.");if(r===1){return{version:r,scripts:n.parseScriptList(),features:n.parseFeatureList(),lookups:n.parseLookupList(a)}}else{return{version:r,scripts:n.parseScriptList(),features:n.parseFeatureList(),lookups:n.parseLookupList(a),variations:n.parseFeatureVariationsList()}}}var Ln=new Array(9);Ln[1]=function e(t){if(t.substFormat===1){return new B.Table("substitutionTable",[{name:"substFormat",type:"USHORT",value:1},{name:"coverage",type:"TABLE",value:new B.Coverage(t.coverage)},{name:"deltaGlyphID",type:"USHORT",value:t.deltaGlyphId}])}else{return new B.Table("substitutionTable",[{name:"substFormat",type:"USHORT",value:2},{name:"coverage",type:"TABLE",value:new B.Coverage(t.coverage)}].concat(B.ushortList("substitute",t.substitute)))}};Ln[2]=function e(t){A.assert(t.substFormat===1,"Lookup type 2 substFormat must be 1.");return new B.Table("substitutionTable",[{name:"substFormat",type:"USHORT",value:1},{name:"coverage",type:"TABLE",value:new B.Coverage(t.coverage)}].concat(B.tableList("seqSet",t.sequences,function(e){return new B.Table("sequenceSetTable",B.ushortList("sequence",e))})))};Ln[3]=function e(t){A.assert(t.substFormat===1,"Lookup type 3 substFormat must be 1.");return new B.Table("substitutionTable",[{name:"substFormat",type:"USHORT",value:1},{name:"coverage",type:"TABLE",value:new B.Coverage(t.coverage)}].concat(B.tableList("altSet",t.alternateSets,function(e){return new B.Table("alternateSetTable",B.ushortList("alternate",e))})))};Ln[4]=function e(t){A.assert(t.substFormat===1,"Lookup type 4 substFormat must be 1.");return new B.Table("substitutionTable",[{name:"substFormat",type:"USHORT",value:1},{name:"coverage",type:"TABLE",value:new B.Coverage(t.coverage)}].concat(B.tableList("ligSet",t.ligatureSets,function(e){return new B.Table("ligatureSetTable",B.tableList("ligature",e,function(e){return new B.Table("ligatureTable",[{name:"ligGlyph",type:"USHORT",value:e.ligGlyph}].concat(B.ushortList("component",e.components,e.components.length+1)))}))})))};Ln[6]=function e(t){if(t.substFormat===1){var n=new B.Table("chainContextTable",[{name:"substFormat",type:"USHORT",value:t.substFormat},{name:"coverage",type:"TABLE",value:new B.Coverage(t.coverage)}].concat(B.tableList("chainRuleSet",t.chainRuleSets,function(e){return new B.Table("chainRuleSetTable",B.tableList("chainRule",e,function(e){var n=B.ushortList("backtrackGlyph",e.backtrack,e.backtrack.length).concat(B.ushortList("inputGlyph",e.input,e.input.length+1)).concat(B.ushortList("lookaheadGlyph",e.lookahead,e.lookahead.length)).concat(B.ushortList("substitution",[],e.lookupRecords.length));e.lookupRecords.forEach(function(e,t){n=n.concat({name:"sequenceIndex"+t,type:"USHORT",value:e.sequenceIndex}).concat({name:"lookupListIndex"+t,type:"USHORT",value:e.lookupListIndex})});return new B.Table("chainRuleTable",n)}))})));return n}else if(t.substFormat===2){A.assert(false,"lookup type 6 format 2 is not yet supported.")}else if(t.substFormat===3){var r=[{name:"substFormat",type:"USHORT",value:t.substFormat}];r.push({name:"backtrackGlyphCount",type:"USHORT",value:t.backtrackCoverage.length});t.backtrackCoverage.forEach(function(e,t){r.push({name:"backtrackCoverage"+t,type:"TABLE",value:new B.Coverage(e)})});r.push({name:"inputGlyphCount",type:"USHORT",value:t.inputCoverage.length});t.inputCoverage.forEach(function(e,t){r.push({name:"inputCoverage"+t,type:"TABLE",value:new B.Coverage(e)})});r.push({name:"lookaheadGlyphCount",type:"USHORT",value:t.lookaheadCoverage.length});t.lookaheadCoverage.forEach(function(e,t){r.push({name:"lookaheadCoverage"+t,type:"TABLE",value:new B.Coverage(e)})});r.push({name:"substitutionCount",type:"USHORT",value:t.lookupRecords.length});t.lookupRecords.forEach(function(e,t){r=r.concat({name:"sequenceIndex"+t,type:"USHORT",value:e.sequenceIndex}).concat({name:"lookupListIndex"+t,type:"USHORT",value:e.lookupListIndex})});var i=new B.Table("chainContextTable",r);return i}A.assert(false,"lookup type 6 format must be 1, 2 or 3.")};function Rn(e){return new B.Table("GSUB",[{name:"version",type:"ULONG",value:65536},{name:"scripts",type:"TABLE",value:new B.ScriptList(e.scripts)},{name:"features",type:"TABLE",value:new B.FeatureList(e.features)},{name:"lookups",type:"TABLE",value:new B.LookupList(e.lookups,Ln)}])}var wn={parse:Mn,make:Rn};function Nn(e,t){var n=new U.Parser(e,t);var r=n.parseULong();A.argument(r===1,"Unsupported META table version.");n.parseULong();n.parseULong();var i=n.parseULong();var a={};for(var s=0;s<i;s++){var o=n.parseTag();var l=n.parseULong();var u=n.parseULong();var c=ce.UTF8(e,t+l,u);a[o]=c}return a}function Pn(e){var t=Object.keys(e).length;var n="";var r=16+t*12;var i=new B.Table("meta",[{name:"version",type:"ULONG",value:1},{name:"flags",type:"ULONG",value:0},{name:"offset",type:"ULONG",value:r},{name:"numTags",type:"ULONG",value:t}]);for(var a in e){var s=n.length;n+=e[a];i.fields.push({name:"tag "+a,type:"TAG",value:a});i.fields.push({name:"offset "+a,type:"ULONG",value:r+s});i.fields.push({name:"length "+a,type:"ULONG",value:e[a].length})}i.fields.push({name:"stringPool",type:"CHARARRAY",value:n});return i}var Un={parse:Nn,make:Pn};function kn(e){return Math.log(e)/Math.log(2)|0}function jn(e){while(e.length%4!==0){e.push(0)}var t=0;for(var n=0;n<e.length;n+=4){t+=(e[n]<<24)+(e[n+1]<<16)+(e[n+2]<<8)+e[n+3]}t%=Math.pow(2,32);return t}function Gn(e,t,n,r){return new B.Record("Table Record",[{name:"tag",type:"TAG",value:e!==undefined?e:""},{name:"checkSum",type:"ULONG",value:t!==undefined?t:0},{name:"offset",type:"ULONG",value:n!==undefined?n:0},{name:"length",type:"ULONG",value:r!==undefined?r:0}])}function Vn(e){var t=new B.Table("sfnt",[{name:"version",type:"TAG",value:"OTTO"},{name:"numTables",type:"USHORT",value:0},{name:"searchRange",type:"USHORT",value:0},{name:"entrySelector",type:"USHORT",value:0},{name:"rangeShift",type:"USHORT",value:0}]);t.tables=e;t.numTables=e.length;var n=Math.pow(2,kn(t.numTables));t.searchRange=16*n;t.entrySelector=kn(n);t.rangeShift=t.numTables*16-t.searchRange;var r=[];var i=[];var a=t.sizeOf()+Gn().sizeOf()*t.numTables;while(a%4!==0){a+=1;i.push({name:"padding",type:"BYTE",value:0})}for(var s=0;s<e.length;s+=1){var o=e[s];A.argument(o.tableName.length===4,"Table name"+o.tableName+" is invalid.");var l=o.sizeOf();var u=Gn(o.tableName,jn(o.encode()),a,l);r.push({name:u.tag+" Table Record",type:"RECORD",value:u});i.push({name:o.tableName+" table",type:"RECORD",value:o});a+=l;A.argument(!isNaN(a),"Something went wrong calculating the offset.");while(a%4!==0){a+=1;i.push({name:"padding",type:"BYTE",value:0})}}r.sort(function(e,t){if(e.value.tag>t.value.tag){return 1}else{return-1}});t.fields=t.fields.concat(r);t.fields=t.fields.concat(i);return t}function zn(e,t,n){for(var r=0;r<t.length;r+=1){var i=e.charToGlyphIndex(t[r]);if(i>0){var a=e.glyphs.get(i);return a.getMetrics()}}return n}function Hn(e){var t=0;for(var n=0;n<e.length;n+=1){t+=e[n]}return t/e.length}function Xn(e){var t=[];var n=[];var r=[];var i=[];var a=[];var s=[];var o=[];var l;var u=0;var c=0;var h=0;var f=0;var d=0;for(var p=0;p<e.glyphs.length;p+=1){var g=e.glyphs.get(p);var m=g.unicode|0;if(isNaN(g.advanceWidth)){throw new Error("Glyph "+g.name+" ("+p+"): advanceWidth is not a number.")}if(l>m||l===undefined){if(m>0){l=m}}if(u<m){u=m}var v=yn.getUnicodeRange(m);if(v<32){c|=1<<v}else if(v<64){h|=1<<v-32}else if(v<96){f|=1<<v-64}else if(v<123){d|=1<<v-96}else{throw new Error("Unicode ranges bits > 123 are reserved for internal usage")}if(g.name===".notdef"){continue}var b=g.getMetrics();t.push(b.xMin);n.push(b.yMin);r.push(b.xMax);i.push(b.yMax);s.push(b.leftSideBearing);o.push(b.rightSideBearing);a.push(g.advanceWidth)}var _={xMin:Math.min.apply(null,t),yMin:Math.min.apply(null,n),xMax:Math.max.apply(null,r),yMax:Math.max.apply(null,i),advanceWidthMax:Math.max.apply(null,a),advanceWidthAvg:Hn(a),minLeftSideBearing:Math.min.apply(null,s),maxLeftSideBearing:Math.max.apply(null,s),minRightSideBearing:Math.min.apply(null,o)};_.ascender=e.ascender;_.descender=e.descender;var E=Xt.make({flags:3,unitsPerEm:e.unitsPerEm,xMin:_.xMin,yMin:_.yMin,xMax:_.xMax,yMax:_.yMax,lowestRecPPEM:3,createdTimestamp:e.createdTimestamp});var F=qt.make({ascender:_.ascender,descender:_.descender,advanceWidthMax:_.advanceWidthMax,minLeftSideBearing:_.minLeftSideBearing,minRightSideBearing:_.minRightSideBearing,xMaxExtent:_.maxLeftSideBearing+(_.xMax-_.xMin),numberOfHMetrics:e.glyphs.length});var N=sn.make(e.glyphs.length);var P=yn.make(Object.assign({xAvgCharWidth:Math.round(_.advanceWidthAvg),usFirstCharIndex:l,usLastCharIndex:u,ulUnicodeRange1:c,ulUnicodeRange2:h,ulUnicodeRange3:f,ulUnicodeRange4:d,sTypoAscender:_.ascender,sTypoDescender:_.descender,sTypoLineGap:0,usWinAscent:_.yMax,usWinDescent:Math.abs(_.yMin),ulCodePageRange1:1,sxHeight:zn(e,"xyvw",{yMax:Math.round(_.ascender/2)}).yMax,sCapHeight:zn(e,"HIKLEFJMNTZBDPRAGOQSUVWXY",_).yMax,usDefaultChar:e.hasChar(" ")?32:0,usBreakChar:e.hasChar(" ")?32:0},e.tables.os2));var U=$t.make(e.glyphs);var k=He.make(e.glyphs);var C=e.getEnglishName("fontFamily");var A=e.getEnglishName("fontSubfamily");var x=C+" "+A;var T=e.getEnglishName("postScriptName");if(!T){T=C.replace(/\s/g,"")+"-"+A}var S={};for(var y in e.names){S[y]=e.names[y]}if(!S.uniqueID){S.uniqueID={en:e.getEnglishName("manufacturer")+":"+x}}if(!S.postScriptName){S.postScriptName={en:T}}if(!S.preferredFamily){S.preferredFamily=e.names.fontFamily}if(!S.preferredSubfamily){S.preferredSubfamily=e.names.fontSubfamily}var B=[];var j=Cn.make(S,B);var O=B.length>0?nn.make(B):undefined;var G=Dn.make();var V=Vt.make(e.glyphs,{version:e.getEnglishName("version"),fullName:x,familyName:C,weightName:A,postScriptName:T,unitsPerEm:e.unitsPerEm,fontBBox:[0,_.yMin,_.ascender,_.advanceWidthMax]});var D=e.metas&&Object.keys(e.metas).length>0?Un.make(e.metas):undefined;var I=[E,F,N,P,j,k,G,V,U];if(O){I.push(O)}if(e.tables.gsub){I.push(wn.make(e.tables.gsub))}if(D){I.push(D)}var M=Vn(I);var z=M.encode();var H=jn(z);var L=M.fields;var R=false;for(var w=0;w<L.length;w+=1){if(L[w].name==="head table"){L[w].value.checkSumAdjustment=2981146554-H;R=true;break}}if(!R){throw new Error("Could not find head table with checkSum to adjust.")}return M}var Wn={make:Vn,fontToTable:Xn,computeCheckSum:jn};function Yn(e,t){var n=0;var r=e.length-1;while(n<=r){var i=n+r>>>1;var a=e[i].tag;if(a===t){return i}else if(a<t){n=i+1}else{r=i-1}}return-n-1}function qn(e,t){var n=0;var r=e.length-1;while(n<=r){var i=n+r>>>1;var a=e[i];if(a===t){return i}else if(a<t){n=i+1}else{r=i-1}}return-n-1}function Zn(e,t){var n;var r=0;var i=e.length-1;while(r<=i){var a=r+i>>>1;n=e[a];var s=n.start;if(s===t){return n}else if(s<t){r=a+1}else{i=a-1}}if(r>0){n=e[r-1];if(t>n.end){return 0}return n}}function Jn(e,t){this.font=e;this.tableName=t}Jn.prototype={searchTag:Yn,binSearch:qn,getTable:function(e){var t=this.font.tables[this.tableName];if(!t&&e){t=this.font.tables[this.tableName]=this.createDefaultTable()}return t},getScriptNames:function(){var e=this.getTable();if(!e){return[]}return e.scripts.map(function(e){return e.tag})},getDefaultScriptName:function(){var e=this.getTable();if(!e){return}var t=false;for(var n=0;n<e.scripts.length;n++){var r=e.scripts[n].tag;if(r==="DFLT"){return r}if(r==="latn"){t=true}}if(t){return"latn"}},getScriptTable:function(e,t){var n=this.getTable(t);if(n){e=e||"DFLT";var r=n.scripts;var i=Yn(n.scripts,e);if(i>=0){return r[i].script}else if(t){var a={tag:e,script:{defaultLangSys:{reserved:0,reqFeatureIndex:65535,featureIndexes:[]},langSysRecords:[]}};r.splice(-1-i,0,a);return a.script}}},getLangSysTable:function(e,t,n){var r=this.getScriptTable(e,n);if(r){if(!t||t==="dflt"||t==="DFLT"){return r.defaultLangSys}var i=Yn(r.langSysRecords,t);if(i>=0){return r.langSysRecords[i].langSys}else if(n){var a={tag:t,langSys:{reserved:0,reqFeatureIndex:65535,featureIndexes:[]}};r.langSysRecords.splice(-1-i,0,a);return a.langSys}}},getFeatureTable:function(e,t,n,r){var i=this.getLangSysTable(e,t,r);if(i){var a;var s=i.featureIndexes;var o=this.font.tables[this.tableName].features;for(var l=0;l<s.length;l++){a=o[s[l]];if(a.tag===n){return a.feature}}if(r){var u=o.length;A.assert(u===0||n>=o[u-1].tag,"Features must be added in alphabetical order.");a={tag:n,feature:{params:0,lookupListIndexes:[]}};o.push(a);s.push(u);return a.feature}}},getLookupTables:function(e,t,n,r,i){var a=this.getFeatureTable(e,t,n,i);var s=[];if(a){var o;var l=a.lookupListIndexes;var u=this.font.tables[this.tableName].lookups;for(var c=0;c<l.length;c++){o=u[l[c]];if(o.lookupType===r){s.push(o)}}if(s.length===0&&i){o={lookupType:r,lookupFlag:0,subtables:[],markFilteringSet:undefined};var h=u.length;u.push(o);l.push(h);return[o]}}return s},getGlyphClass:function(e,t){switch(e.format){case 1:if(e.startGlyph<=t&&t<e.startGlyph+e.classes.length){return e.classes[t-e.startGlyph]}return 0;case 2:var n=Zn(e.ranges,t);return n?n.classId:0}},getCoverageIndex:function(e,t){switch(e.format){case 1:var n=qn(e.glyphs,t);return n>=0?n:-1;case 2:var r=Zn(e.ranges,t);return r?r.index+t-r.start:-1}},expandCoverage:function(e){if(e.format===1){return e.glyphs}else{var t=[];var n=e.ranges;for(var r=0;r<n.length;r++){var i=n[r];var a=i.start;var s=i.end;for(var o=a;o<=s;o++){t.push(o)}}return t}}};function Qn(e){Jn.call(this,e,"gpos")}Qn.prototype=Jn.prototype;Qn.prototype.init=function(){var e=this.getDefaultScriptName();this.defaultKerningTables=this.getKerningTables(e)};Qn.prototype.getKerningValue=function(e,t,n){for(var r=0;r<e.length;r++){var i=e[r].subtables;for(var a=0;a<i.length;a++){var s=i[a];var o=this.getCoverageIndex(s.coverage,t);if(o<0){continue}switch(s.posFormat){case 1:var l=s.pairSets[o];for(var u=0;u<l.length;u++){var c=l[u];if(c.secondGlyph===n){return c.value1&&c.value1.xAdvance||0}}break;case 2:var h=this.getGlyphClass(s.classDef1,t);var f=this.getGlyphClass(s.classDef2,n);var d=s.classRecords[h][f];return d.value1&&d.value1.xAdvance||0}}}return 0};Qn.prototype.getKerningTables=function(e,t){if(this.font.tables.gpos){return this.getLookupTables(e,t,"kern",2)}};function t(e){Jn.call(this,e,"gsub")}function Kn(e,t){var n=e.length;if(n!==t.length){return false}for(var r=0;r<n;r++){if(e[r]!==t[r]){return false}}return true}function $n(e,t,n){var r=e.subtables;for(var i=0;i<r.length;i++){var a=r[i];if(a.substFormat===t){return a}}if(n){r.push(n);return n}return undefined}t.prototype=Jn.prototype;t.prototype.createDefaultTable=function(){return{version:1,scripts:[{tag:"DFLT",script:{defaultLangSys:{reserved:0,reqFeatureIndex:65535,featureIndexes:[]},langSysRecords:[]}}],features:[],lookups:[]}};t.prototype.getSingle=function(e,t,n){var r=[];var i=this.getLookupTables(t,n,e,1);for(var a=0;a<i.length;a++){var s=i[a].subtables;for(var o=0;o<s.length;o++){var l=s[o];var u=this.expandCoverage(l.coverage);var c=void 0;if(l.substFormat===1){var h=l.deltaGlyphId;for(c=0;c<u.length;c++){var f=u[c];r.push({sub:f,by:f+h})}}else{var d=l.substitute;for(c=0;c<u.length;c++){r.push({sub:u[c],by:d[c]})}}}}return r};t.prototype.getMultiple=function(e,t,n){var r=[];var i=this.getLookupTables(t,n,e,2);for(var a=0;a<i.length;a++){var s=i[a].subtables;for(var o=0;o<s.length;o++){var l=s[o];var u=this.expandCoverage(l.coverage);var c=void 0;for(c=0;c<u.length;c++){var h=u[c];var f=l.sequences[c];r.push({sub:h,by:f})}}}return r};t.prototype.getAlternates=function(e,t,n){var r=[];var i=this.getLookupTables(t,n,e,3);for(var a=0;a<i.length;a++){var s=i[a].subtables;for(var o=0;o<s.length;o++){var l=s[o];var u=this.expandCoverage(l.coverage);var c=l.alternateSets;for(var h=0;h<u.length;h++){r.push({sub:u[h],by:c[h]})}}}return r};t.prototype.getLigatures=function(e,t,n){var r=[];var i=this.getLookupTables(t,n,e,4);for(var a=0;a<i.length;a++){var s=i[a].subtables;for(var o=0;o<s.length;o++){var l=s[o];var u=this.expandCoverage(l.coverage);var c=l.ligatureSets;for(var h=0;h<u.length;h++){var f=u[h];var d=c[h];for(var p=0;p<d.length;p++){var g=d[p];r.push({sub:[f].concat(g.components),by:g.ligGlyph})}}}}return r};t.prototype.addSingle=function(e,t,n,r){var i=this.getLookupTables(n,r,e,1,true)[0];var a=$n(i,2,{substFormat:2,coverage:{format:1,glyphs:[]},substitute:[]});A.assert(a.coverage.format===1,"Single: unable to modify coverage table format "+a.coverage.format);var s=t.sub;var o=this.binSearch(a.coverage.glyphs,s);if(o<0){o=-1-o;a.coverage.glyphs.splice(o,0,s);a.substitute.splice(o,0,0)}a.substitute[o]=t.by};t.prototype.addMultiple=function(e,t,n,r){A.assert(t.by instanceof Array&&t.by.length>1,'Multiple: "by" must be an array of two or more ids');var i=this.getLookupTables(n,r,e,2,true)[0];var a=$n(i,1,{substFormat:1,coverage:{format:1,glyphs:[]},sequences:[]});A.assert(a.coverage.format===1,"Multiple: unable to modify coverage table format "+a.coverage.format);var s=t.sub;var o=this.binSearch(a.coverage.glyphs,s);if(o<0){o=-1-o;a.coverage.glyphs.splice(o,0,s);a.sequences.splice(o,0,0)}a.sequences[o]=t.by};t.prototype.addAlternate=function(e,t,n,r){var i=this.getLookupTables(n,r,e,3,true)[0];var a=$n(i,1,{substFormat:1,coverage:{format:1,glyphs:[]},alternateSets:[]});A.assert(a.coverage.format===1,"Alternate: unable to modify coverage table format "+a.coverage.format);var s=t.sub;var o=this.binSearch(a.coverage.glyphs,s);if(o<0){o=-1-o;a.coverage.glyphs.splice(o,0,s);a.alternateSets.splice(o,0,0)}a.alternateSets[o]=t.by};t.prototype.addLigature=function(e,t,n,r){var i=this.getLookupTables(n,r,e,4,true)[0];var a=i.subtables[0];if(!a){a={substFormat:1,coverage:{format:1,glyphs:[]},ligatureSets:[]};i.subtables[0]=a}A.assert(a.coverage.format===1,"Ligature: unable to modify coverage table format "+a.coverage.format);var s=t.sub[0];var o=t.sub.slice(1);var l={ligGlyph:t.by,components:o};var u=this.binSearch(a.coverage.glyphs,s);if(u>=0){var c=a.ligatureSets[u];for(var h=0;h<c.length;h++){if(Kn(c[h].components,o)){return}}c.push(l)}else{u=-1-u;a.coverage.glyphs.splice(u,0,s);a.ligatureSets.splice(u,0,[l])}};t.prototype.getFeature=function(e,t,n){if(/ss\d\d/.test(e)){return this.getSingle(e,t,n)}switch(e){case"aalt":case"salt":return this.getSingle(e,t,n).concat(this.getAlternates(e,t,n));case"dlig":case"liga":case"rlig":return this.getLigatures(e,t,n);case"ccmp":return this.getMultiple(e,t,n).concat(this.getLigatures(e,t,n));case"stch":return this.getMultiple(e,t,n)}return undefined};t.prototype.add=function(e,t,n,r){if(/ss\d\d/.test(e)){return this.addSingle(e,t,n,r)}switch(e){case"aalt":case"salt":if(typeof t.by==="number"){return this.addSingle(e,t,n,r)}return this.addAlternate(e,t,n,r);case"dlig":case"liga":case"rlig":return this.addLigature(e,t,n,r);case"ccmp":if(t.by instanceof Array){return this.addMultiple(e,t,n,r)}return this.addLigature(e,t,n,r)}return undefined};function er(){return typeof window!=="undefined"}function tr(e){var t=new ArrayBuffer(e.length);var n=new Uint8Array(t);for(var r=0;r<e.length;++r){n[r]=e[r]}return t}function nr(e){var t=new Buffer(e.byteLength);var n=new Uint8Array(e);for(var r=0;r<t.length;++r){t[r]=n[r]}return t}function rr(e,t){if(!e){throw t}}function ir(e,t,n,r,i){var a;if((t&r)>0){a=e.parseByte();if((t&i)===0){a=-a}a=n+a}else{if((t&i)>0){a=n}else{a=n+e.parseShort()}}return a}function ar(e,t,n){var r=new U.Parser(t,n);e.numberOfContours=r.parseShort();e._xMin=r.parseShort();e._yMin=r.parseShort();e._xMax=r.parseShort();e._yMax=r.parseShort();var i;var a;if(e.numberOfContours>0){var s=e.endPointIndices=[];for(var o=0;o<e.numberOfContours;o+=1){s.push(r.parseUShort())}e.instructionLength=r.parseUShort();e.instructions=[];for(var l=0;l<e.instructionLength;l+=1){e.instructions.push(r.parseByte())}var u=s[s.length-1]+1;i=[];for(var c=0;c<u;c+=1){a=r.parseByte();i.push(a);if((a&8)>0){var h=r.parseByte();for(var f=0;f<h;f+=1){i.push(a);c+=1}}}A.argument(i.length===u,"Bad flags.");if(s.length>0){var d=[];var p;if(u>0){for(var g=0;g<u;g+=1){a=i[g];p={};p.onCurve=!!(a&1);p.lastPointOfContour=s.indexOf(g)>=0;d.push(p)}var m=0;for(var v=0;v<u;v+=1){a=i[v];p=d[v];p.x=ir(r,a,m,2,16);m=p.x}var b=0;for(var _=0;_<u;_+=1){a=i[_];p=d[_];p.y=ir(r,a,b,4,32);b=p.y}}e.points=d}else{e.points=[]}}else if(e.numberOfContours===0){e.points=[]}else{e.isComposite=true;e.points=[];e.components=[];var E=true;while(E){i=r.parseUShort();var F={glyphIndex:r.parseUShort(),xScale:1,scale01:0,scale10:0,yScale:1,dx:0,dy:0};if((i&1)>0){if((i&2)>0){F.dx=r.parseShort();F.dy=r.parseShort()}else{F.matchedPoints=[r.parseUShort(),r.parseUShort()]}}else{if((i&2)>0){F.dx=r.parseChar();F.dy=r.parseChar()}else{F.matchedPoints=[r.parseByte(),r.parseByte()]}}if((i&8)>0){F.xScale=F.yScale=r.parseF2Dot14()}else if((i&64)>0){F.xScale=r.parseF2Dot14();F.yScale=r.parseF2Dot14()}else if((i&128)>0){F.xScale=r.parseF2Dot14();F.scale01=r.parseF2Dot14();F.scale10=r.parseF2Dot14();F.yScale=r.parseF2Dot14()}e.components.push(F);E=!!(i&32)}if(i&256){e.instructionLength=r.parseUShort();e.instructions=[];for(var C=0;C<e.instructionLength;C+=1){e.instructions.push(r.parseByte())}}}}function sr(e,t){var n=[];for(var r=0;r<e.length;r+=1){var i=e[r];var a={x:t.xScale*i.x+t.scale01*i.y+t.dx,y:t.scale10*i.x+t.yScale*i.y+t.dy,onCurve:i.onCurve,lastPointOfContour:i.lastPointOfContour};n.push(a)}return n}function or(e){var t=[];var n=[];for(var r=0;r<e.length;r+=1){var i=e[r];n.push(i);if(i.lastPointOfContour){t.push(n);n=[]}}A.argument(n.length===0,"There are still points left in the current contour.");return t}function lr(e){var t=new p;if(!e){return t}var n=or(e);for(var r=0;r<n.length;++r){var i=n[r];var a=null;var s=i[i.length-1];var o=i[0];if(s.onCurve){t.moveTo(s.x,s.y)}else{if(o.onCurve){t.moveTo(o.x,o.y)}else{var l={x:(s.x+o.x)*.5,y:(s.y+o.y)*.5};t.moveTo(l.x,l.y)}}for(var u=0;u<i.length;++u){a=s;s=o;o=i[(u+1)%i.length];if(s.onCurve){t.lineTo(s.x,s.y)}else{var c=a;var h=o;if(!a.onCurve){c={x:(s.x+a.x)*.5,y:(s.y+a.y)*.5}}if(!o.onCurve){h={x:(s.x+o.x)*.5,y:(s.y+o.y)*.5}}t.quadraticCurveTo(s.x,s.y,h.x,h.y)}}t.closePath()}return t}function ur(e,t){if(t.isComposite){for(var n=0;n<t.components.length;n+=1){var r=t.components[n];var i=e.get(r.glyphIndex);i.getPath();if(i.points){var a=void 0;if(r.matchedPoints===undefined){a=sr(i.points,r)}else{if(r.matchedPoints[0]>t.points.length-1||r.matchedPoints[1]>i.points.length-1){throw Error("Matched points out of range in "+t.name)}var s=t.points[r.matchedPoints[0]];var o=i.points[r.matchedPoints[1]];var l={xScale:r.xScale,scale01:r.scale01,scale10:r.scale10,yScale:r.yScale,dx:0,dy:0};o=sr([o],l)[0];l.dx=s.x-o.x;l.dy=s.y-o.y;a=sr(i.points,l)}t.points=t.points.concat(a)}}}return lr(t.points)}function cr(e,t,n,r){var i=new x.GlyphSet(r);for(var a=0;a<n.length-1;a+=1){var s=n[a];var o=n[a+1];if(s!==o){i.push(a,x.ttfGlyphLoader(r,a,ar,e,t+s,ur))}else{i.push(a,x.glyphLoader(r,a))}}return i}function hr(r,i,a,s){var o=new x.GlyphSet(s);s._push=function(e){var t=a[e];var n=a[e+1];if(t!==n){o.push(e,x.ttfGlyphLoader(s,e,ar,r,i+t,ur))}else{o.push(e,x.glyphLoader(s,e))}};return o}function fr(e,t,n,r,i){if(i.lowMemory){return hr(e,t,n,r)}else{return cr(e,t,n,r)}}var dr={getPath:lr,parse:fr};var pr;var gr;var mr;var vr;function br(e){this.font=e;this.getCommands=function(e){return dr.getPath(e).commands};this._fpgmState=this._prepState=undefined;this._errorState=0}function _r(e){return e}function Er(e){return Math.sign(e)*Math.round(Math.abs(e))}function Fr(e){return Math.sign(e)*Math.round(Math.abs(e*2))/2}function Cr(e){return Math.sign(e)*(Math.round(Math.abs(e)+.5)-.5)}function Ar(e){return Math.sign(e)*Math.ceil(Math.abs(e))}function xr(e){return Math.sign(e)*Math.floor(Math.abs(e))}var Tr=function(e){var t=this.srPeriod;var n=this.srPhase;var r=this.srThreshold;var i=1;if(e<0){e=-e;i=-1}e+=r-n;e=Math.trunc(e/t)*t;e+=n;if(e<0){return n*i}return e*i};var m={x:1,y:0,axis:"x",distance:function(e,t,n,r){return(n?e.xo:e.x)-(r?t.xo:t.x)},interpolate:function(e,t,n,r){var i;var a;var s;var o;var l;var u;var c;if(!r||r===this){i=e.xo-t.xo;a=e.xo-n.xo;l=t.x-t.xo;u=n.x-n.xo;s=Math.abs(i);o=Math.abs(a);c=s+o;if(c===0){e.x=e.xo+(l+u)/2;return}e.x=e.xo+(l*o+u*s)/c;return}i=r.distance(e,t,true,true);a=r.distance(e,n,true,true);l=r.distance(t,t,false,true);u=r.distance(n,n,false,true);s=Math.abs(i);o=Math.abs(a);c=s+o;if(c===0){m.setRelative(e,e,(l+u)/2,r,true);return}m.setRelative(e,e,(l*o+u*s)/c,r,true)},normalSlope:Number.NEGATIVE_INFINITY,setRelative:function(e,t,n,r,i){if(!r||r===this){e.x=(i?t.xo:t.x)+n;return}var a=i?t.xo:t.x;var s=i?t.yo:t.y;var o=a+n*r.x;var l=s+n*r.y;e.x=o+(e.y-l)/r.normalSlope},slope:0,touch:function(e){e.xTouched=true},touched:function(e){return e.xTouched},untouch:function(e){e.xTouched=false}};var v={x:0,y:1,axis:"y",distance:function(e,t,n,r){return(n?e.yo:e.y)-(r?t.yo:t.y)},interpolate:function(e,t,n,r){var i;var a;var s;var o;var l;var u;var c;if(!r||r===this){i=e.yo-t.yo;a=e.yo-n.yo;l=t.y-t.yo;u=n.y-n.yo;s=Math.abs(i);o=Math.abs(a);c=s+o;if(c===0){e.y=e.yo+(l+u)/2;return}e.y=e.yo+(l*o+u*s)/c;return}i=r.distance(e,t,true,true);a=r.distance(e,n,true,true);l=r.distance(t,t,false,true);u=r.distance(n,n,false,true);s=Math.abs(i);o=Math.abs(a);c=s+o;if(c===0){v.setRelative(e,e,(l+u)/2,r,true);return}v.setRelative(e,e,(l*o+u*s)/c,r,true)},normalSlope:0,setRelative:function(e,t,n,r,i){if(!r||r===this){e.y=(i?t.yo:t.y)+n;return}var a=i?t.xo:t.x;var s=i?t.yo:t.y;var o=a+n*r.x;var l=s+n*r.y;e.y=l+r.normalSlope*(e.x-o)},slope:Number.POSITIVE_INFINITY,touch:function(e){e.yTouched=true},touched:function(e){return e.yTouched},untouch:function(e){e.yTouched=false}};Object.freeze(m);Object.freeze(v);function Sr(e,t){this.x=e;this.y=t;this.axis=undefined;this.slope=t/e;this.normalSlope=-e/t;Object.freeze(this)}Sr.prototype.distance=function(e,t,n,r){return this.x*m.distance(e,t,n,r)+this.y*v.distance(e,t,n,r)};Sr.prototype.interpolate=function(e,t,n,r){var i;var a;var s;var o;var l;var u;var c;s=r.distance(e,t,true,true);o=r.distance(e,n,true,true);i=r.distance(t,t,false,true);a=r.distance(n,n,false,true);l=Math.abs(s);u=Math.abs(o);c=l+u;if(c===0){this.setRelative(e,e,(i+a)/2,r,true);return}this.setRelative(e,e,(i*u+a*l)/c,r,true)};Sr.prototype.setRelative=function(e,t,n,r,i){r=r||this;var a=i?t.xo:t.x;var s=i?t.yo:t.y;var o=a+n*r.x;var l=s+n*r.y;var u=r.normalSlope;var c=this.slope;var h=e.x;var f=e.y;e.x=(c*h-u*o+l-f)/(c-u);e.y=c*(e.x-h)+f};Sr.prototype.touch=function(e){e.xTouched=true;e.yTouched=true};function yr(e,t){var n=Math.sqrt(e*e+t*t);e/=n;t/=n;if(e===1&&t===0){return m}else if(e===0&&t===1){return v}else{return new Sr(e,t)}}function E(e,t,n,r){this.x=this.xo=Math.round(e*64)/64;this.y=this.yo=Math.round(t*64)/64;this.lastPointOfContour=n;this.onCurve=r;this.prevPointOnContour=undefined;this.nextPointOnContour=undefined;this.xTouched=false;this.yTouched=false;Object.preventExtensions(this)}E.prototype.nextTouched=function(e){var t=this.nextPointOnContour;while(!e.touched(t)&&t!==this){t=t.nextPointOnContour}return t};E.prototype.prevTouched=function(e){var t=this.prevPointOnContour;while(!e.touched(t)&&t!==this){t=t.prevPointOnContour}return t};var Br=Object.freeze(new E(0,0));var Or={cvCutIn:17/16,deltaBase:9,deltaShift:.125,loop:1,minDis:1,autoFlip:true};function F(e,t){this.env=e;this.stack=[];this.prog=t;switch(e){case"glyf":this.zp0=this.zp1=this.zp2=1;this.rp0=this.rp1=this.rp2=0;case"prep":this.fv=this.pv=this.dpv=m;this.round=Er}}br.prototype.exec=function(e,t){if(typeof t!=="number"){throw new Error("Point size is not a number!")}if(this._errorState>2){return}var n=this.font;var r=this._prepState;if(!r||r.ppem!==t){var i=this._fpgmState;if(!i){F.prototype=Or;i=this._fpgmState=new F("fpgm",n.tables.fpgm);i.funcs=[];i.font=n;if(T.DEBUG){console.log("---EXEC FPGM---");i.step=-1}try{gr(i)}catch(e){console.log("Hinting error in FPGM:"+e);this._errorState=3;return}}F.prototype=i;r=this._prepState=new F("prep",n.tables.prep);r.ppem=t;var a=n.tables.cvt;if(a){var s=r.cvt=new Array(a.length);var o=t/n.unitsPerEm;for(var l=0;l<a.length;l++){s[l]=a[l]*o}}else{r.cvt=[]}if(T.DEBUG){console.log("---EXEC PREP---");r.step=-1}try{gr(r)}catch(e){if(this._errorState<2){console.log("Hinting error in PREP:"+e)}this._errorState=2}}if(this._errorState>1){return}try{return mr(e,r)}catch(e){if(this._errorState<1){console.log("Hinting error:"+e);console.log("Note: further hinting errors are silenced")}this._errorState=1;return undefined}};mr=function(e,t){var n=t.ppem/t.font.unitsPerEm;var r=n;var i=e.components;var a;var s;var o;F.prototype=t;if(!i){o=new F("glyf",e.instructions);if(T.DEBUG){console.log("---EXEC GLYPH---");o.step=-1}vr(e,o,n,r);s=o.gZone}else{var l=t.font;s=[];a=[];for(var u=0;u<i.length;u++){var c=i[u];var h=l.glyphs.get(c.glyphIndex);o=new F("glyf",h.instructions);if(T.DEBUG){console.log("---EXEC COMP "+u+"---");o.step=-1}vr(h,o,n,r);var f=Math.round(c.dx*n);var d=Math.round(c.dy*r);var p=o.gZone;var g=o.contours;for(var m=0;m<p.length;m++){var v=p[m];v.xTouched=v.yTouched=false;v.xo=v.x=v.x+f;v.yo=v.y=v.y+d}var b=s.length;s.push.apply(s,p);for(var _=0;_<g.length;_++){a.push(g[_]+b)}}if(e.instructions&&!o.inhibitGridFit){o=new F("glyf",e.instructions);o.gZone=o.z0=o.z1=o.z2=s;o.contours=a;s.push(new E(0,0),new E(Math.round(e.advanceWidth*n),0));if(T.DEBUG){console.log("---EXEC COMPOSITE---");o.step=-1}gr(o);s.length-=2}}return s};vr=function(e,t,n,r){var i=e.points||[];var a=i.length;var s=t.gZone=t.z0=t.z1=t.z2=[];var o=t.contours=[];var l;for(var u=0;u<a;u++){l=i[u];s[u]=new E(l.x*n,l.y*r,l.lastPointOfContour,l.onCurve)}var c;var h;for(var f=0;f<a;f++){l=s[f];if(!c){c=l;o.push(f)}if(l.lastPointOfContour){l.nextPointOnContour=c;c.prevPointOnContour=l;c=undefined}else{h=s[f+1];l.nextPointOnContour=h;h.prevPointOnContour=l}}if(t.inhibitGridFit){return}if(T.DEBUG){console.log("PROCESSING GLYPH",t.stack);for(var d=0;d<a;d++){console.log(d,s[d].x,s[d].y)}}s.push(new E(0,0),new E(Math.round(e.advanceWidth*n),0));gr(t);s.length-=2;if(T.DEBUG){console.log("FINISHED GLYPH",t.stack);for(var p=0;p<a;p++){console.log(p,s[p].x,s[p].y)}}};gr=function(e){var t=e.prog;if(!t){return}var n=t.length;var r;for(e.ip=0;e.ip<n;e.ip++){if(T.DEBUG){e.step++}r=pr[t[e.ip]];if(!r){throw new Error("unknown instruction: 0x"+Number(t[e.ip]).toString(16))}r(e)}};function Dr(e){var t=e.tZone=new Array(e.gZone.length);for(var n=0;n<t.length;n++){t[n]=new E(0,0)}}function Ir(e,t){var n=e.prog;var r=e.ip;var i=1;var a;do{a=n[++r];if(a===88){i++}else if(a===89){i--}else if(a===64){r+=n[r+1]+1}else if(a===65){r+=2*n[r+1]+1}else if(a>=176&&a<=183){r+=a-176+1}else if(a>=184&&a<=191){r+=(a-184+1)*2}else if(t&&i===1&&a===27){break}}while(i>0);e.ip=r}function Mr(e,t){if(T.DEBUG){console.log(t.step,"SVTCA["+e.axis+"]")}t.fv=t.pv=t.dpv=e}function Lr(e,t){if(T.DEBUG){console.log(t.step,"SPVTCA["+e.axis+"]")}t.pv=t.dpv=e}function Rr(e,t){if(T.DEBUG){console.log(t.step,"SFVTCA["+e.axis+"]")}t.fv=e}function wr(e,t){var n=t.stack;var r=n.pop();var i=n.pop();var a=t.z2[r];var s=t.z1[i];if(T.DEBUG){console.log("SPVTL["+e+"]",r,i)}var o;var l;if(!e){o=s.x-a.x;l=s.y-a.y}else{o=a.y-s.y;l=s.x-a.x}t.pv=t.dpv=yr(o,l)}function Nr(e,t){var n=t.stack;var r=n.pop();var i=n.pop();var a=t.z2[r];var s=t.z1[i];if(T.DEBUG){console.log("SFVTL["+e+"]",r,i)}var o;var l;if(!e){o=s.x-a.x;l=s.y-a.y}else{o=a.y-s.y;l=s.x-a.x}t.fv=yr(o,l)}function Pr(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"SPVFS[]",n,r)}e.pv=e.dpv=yr(r,n)}function Ur(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"SPVFS[]",n,r)}e.fv=yr(r,n)}function kr(e){var t=e.stack;var n=e.pv;if(T.DEBUG){console.log(e.step,"GPV[]")}t.push(n.x*16384);t.push(n.y*16384)}function jr(e){var t=e.stack;var n=e.fv;if(T.DEBUG){console.log(e.step,"GFV[]")}t.push(n.x*16384);t.push(n.y*16384)}function Gr(e){e.fv=e.pv;if(T.DEBUG){console.log(e.step,"SFVTPV[]")}}function Vr(e){var t=e.stack;var n=t.pop();var r=t.pop();var i=t.pop();var a=t.pop();var s=t.pop();var o=e.z0;var l=e.z1;var u=o[n];var c=o[r];var h=l[i];var f=l[a];var d=e.z2[s];if(T.DEBUG){console.log("ISECT[], ",n,r,i,a,s)}var p=u.x;var g=u.y;var m=c.x;var v=c.y;var b=h.x;var _=h.y;var E=f.x;var F=f.y;var C=(p-m)*(_-F)-(g-v)*(b-E);var A=p*v-g*m;var x=b*F-_*E;d.x=(A*(b-E)-x*(p-m))/C;d.y=(A*(_-F)-x*(g-v))/C}function zr(e){e.rp0=e.stack.pop();if(T.DEBUG){console.log(e.step,"SRP0[]",e.rp0)}}function Hr(e){e.rp1=e.stack.pop();if(T.DEBUG){console.log(e.step,"SRP1[]",e.rp1)}}function Xr(e){e.rp2=e.stack.pop();if(T.DEBUG){console.log(e.step,"SRP2[]",e.rp2)}}function Wr(e){var t=e.stack.pop();if(T.DEBUG){console.log(e.step,"SZP0[]",t)}e.zp0=t;switch(t){case 0:if(!e.tZone){Dr(e)}e.z0=e.tZone;break;case 1:e.z0=e.gZone;break;default:throw new Error("Invalid zone pointer")}}function Yr(e){var t=e.stack.pop();if(T.DEBUG){console.log(e.step,"SZP1[]",t)}e.zp1=t;switch(t){case 0:if(!e.tZone){Dr(e)}e.z1=e.tZone;break;case 1:e.z1=e.gZone;break;default:throw new Error("Invalid zone pointer")}}function qr(e){var t=e.stack.pop();if(T.DEBUG){console.log(e.step,"SZP2[]",t)}e.zp2=t;switch(t){case 0:if(!e.tZone){Dr(e)}e.z2=e.tZone;break;case 1:e.z2=e.gZone;break;default:throw new Error("Invalid zone pointer")}}function Zr(e){var t=e.stack.pop();if(T.DEBUG){console.log(e.step,"SZPS[]",t)}e.zp0=e.zp1=e.zp2=t;switch(t){case 0:if(!e.tZone){Dr(e)}e.z0=e.z1=e.z2=e.tZone;break;case 1:e.z0=e.z1=e.z2=e.gZone;break;default:throw new Error("Invalid zone pointer")}}function Jr(e){e.loop=e.stack.pop();if(T.DEBUG){console.log(e.step,"SLOOP[]",e.loop)}}function Qr(e){if(T.DEBUG){console.log(e.step,"RTG[]")}e.round=Er}function Kr(e){if(T.DEBUG){console.log(e.step,"RTHG[]")}e.round=Cr}function $r(e){var t=e.stack.pop();if(T.DEBUG){console.log(e.step,"SMD[]",t)}e.minDis=t/64}function ei(e){if(T.DEBUG){console.log(e.step,"ELSE[]")}Ir(e,false)}function ti(e){var t=e.stack.pop();if(T.DEBUG){console.log(e.step,"JMPR[]",t)}e.ip+=t-1}function ni(e){var t=e.stack.pop();if(T.DEBUG){console.log(e.step,"SCVTCI[]",t)}e.cvCutIn=t/64}function ri(e){var t=e.stack;if(T.DEBUG){console.log(e.step,"DUP[]")}t.push(t[t.length-1])}function ii(e){if(T.DEBUG){console.log(e.step,"POP[]")}e.stack.pop()}function ai(e){if(T.DEBUG){console.log(e.step,"CLEAR[]")}e.stack.length=0}function si(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"SWAP[]")}t.push(n);t.push(r)}function oi(e){var t=e.stack;if(T.DEBUG){console.log(e.step,"DEPTH[]")}t.push(t.length)}function li(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"LOOPCALL[]",n,r)}var i=e.ip;var a=e.prog;e.prog=e.funcs[n];for(var s=0;s<r;s++){gr(e);if(T.DEBUG){console.log(++e.step,s+1<r?"next loopcall":"done loopcall",s)}}e.ip=i;e.prog=a}function ui(e){var t=e.stack.pop();if(T.DEBUG){console.log(e.step,"CALL[]",t)}var n=e.ip;var r=e.prog;e.prog=e.funcs[t];gr(e);e.ip=n;e.prog=r;if(T.DEBUG){console.log(++e.step,"returning from",t)}}function ci(e){var t=e.stack;var n=t.pop();if(T.DEBUG){console.log(e.step,"CINDEX[]",n)}t.push(t[t.length-n])}function hi(e){var t=e.stack;var n=t.pop();if(T.DEBUG){console.log(e.step,"MINDEX[]",n)}t.push(t.splice(t.length-n,1)[0])}function fi(e){if(e.env!=="fpgm"){throw new Error("FDEF not allowed here")}var t=e.stack;var n=e.prog;var r=e.ip;var i=t.pop();var a=r;if(T.DEBUG){console.log(e.step,"FDEF[]",i)}while(n[++r]!==45){}e.ip=r;e.funcs[i]=n.slice(a+1,r)}function di(e,t){var n=t.stack.pop();var r=t.z0[n];var i=t.fv;var a=t.pv;if(T.DEBUG){console.log(t.step,"MDAP["+e+"]",n)}var s=a.distance(r,Br);if(e){s=t.round(s)}i.setRelative(r,Br,s,a);i.touch(r);t.rp0=t.rp1=n}function pi(e,t){var n=t.z2;var r=n.length-2;var i;var a;var s;if(T.DEBUG){console.log(t.step,"IUP["+e.axis+"]")}for(var o=0;o<r;o++){i=n[o];if(e.touched(i)){continue}a=i.prevTouched(e);if(a===i){continue}s=i.nextTouched(e);if(a===s){e.setRelative(i,i,e.distance(a,a,false,true),e,true)}e.interpolate(i,a,s,e)}}function gi(e,t){var n=t.stack;var r=e?t.rp1:t.rp2;var i=(e?t.z0:t.z1)[r];var a=t.fv;var s=t.pv;var o=t.loop;var l=t.z2;while(o--){var u=n.pop();var c=l[u];var h=s.distance(i,i,false,true);a.setRelative(c,c,h,s);a.touch(c);if(T.DEBUG){console.log(t.step,(t.loop>1?"loop "+(t.loop-o)+": ":"")+"SHP["+(e?"rp1":"rp2")+"]",u)}}t.loop=1}function mi(e,t){var n=t.stack;var r=e?t.rp1:t.rp2;var i=(e?t.z0:t.z1)[r];var a=t.fv;var s=t.pv;var o=n.pop();var l=t.z2[t.contours[o]];var u=l;if(T.DEBUG){console.log(t.step,"SHC["+e+"]",o)}var c=s.distance(i,i,false,true);do{if(u!==i){a.setRelative(u,u,c,s)}u=u.nextPointOnContour}while(u!==l)}function vi(e,t){var n=t.stack;var r=e?t.rp1:t.rp2;var i=(e?t.z0:t.z1)[r];var a=t.fv;var s=t.pv;var o=n.pop();if(T.DEBUG){console.log(t.step,"SHZ["+e+"]",o)}var l;switch(o){case 0:l=t.tZone;break;case 1:l=t.gZone;break;default:throw new Error("Invalid zone")}var u;var c=s.distance(i,i,false,true);var h=l.length-2;for(var f=0;f<h;f++){u=l[f];a.setRelative(u,u,c,s)}}function bi(e){var t=e.stack;var n=e.loop;var r=e.fv;var i=t.pop()/64;var a=e.z2;while(n--){var s=t.pop();var o=a[s];if(T.DEBUG){console.log(e.step,(e.loop>1?"loop "+(e.loop-n)+": ":"")+"SHPIX[]",s,i)}r.setRelative(o,o,i);r.touch(o)}e.loop=1}function _i(e){var t=e.stack;var n=e.rp1;var r=e.rp2;var i=e.loop;var a=e.z0[n];var s=e.z1[r];var o=e.fv;var l=e.dpv;var u=e.z2;while(i--){var c=t.pop();var h=u[c];if(T.DEBUG){console.log(e.step,(e.loop>1?"loop "+(e.loop-i)+": ":"")+"IP[]",c,n,"<->",r)}o.interpolate(h,a,s,l);o.touch(h)}e.loop=1}function Ei(e,t){var n=t.stack;var r=n.pop()/64;var i=n.pop();var a=t.z1[i];var s=t.z0[t.rp0];var o=t.fv;var l=t.pv;o.setRelative(a,s,r,l);o.touch(a);if(T.DEBUG){console.log(t.step,"MSIRP["+e+"]",r,i)}t.rp1=t.rp0;t.rp2=i;if(e){t.rp0=i}}function Fi(e){var t=e.stack;var n=e.rp0;var r=e.z0[n];var i=e.loop;var a=e.fv;var s=e.pv;var o=e.z1;while(i--){var l=t.pop();var u=o[l];if(T.DEBUG){console.log(e.step,(e.loop>1?"loop "+(e.loop-i)+": ":"")+"ALIGNRP[]",l)}a.setRelative(u,r,0,s);a.touch(u)}e.loop=1}function Ci(e){if(T.DEBUG){console.log(e.step,"RTDG[]")}e.round=Fr}function Ai(e,t){var n=t.stack;var r=n.pop();var i=n.pop();var a=t.z0[i];var s=t.fv;var o=t.pv;var l=t.cvt[r];if(T.DEBUG){console.log(t.step,"MIAP["+e+"]",r,"(",l,")",i)}var u=o.distance(a,Br);if(e){if(Math.abs(u-l)<t.cvCutIn){u=l}u=t.round(u)}s.setRelative(a,Br,u,o);if(t.zp0===0){a.xo=a.x;a.yo=a.y}s.touch(a);t.rp0=t.rp1=i}function xi(e){var t=e.prog;var n=e.ip;var r=e.stack;var i=t[++n];if(T.DEBUG){console.log(e.step,"NPUSHB[]",i)}for(var a=0;a<i;a++){r.push(t[++n])}e.ip=n}function Ti(e){var t=e.ip;var n=e.prog;var r=e.stack;var i=n[++t];if(T.DEBUG){console.log(e.step,"NPUSHW[]",i)}for(var a=0;a<i;a++){var s=n[++t]<<8|n[++t];if(s&32768){s=-((s^65535)+1)}r.push(s)}e.ip=t}function Si(e){var t=e.stack;var n=e.store;if(!n){n=e.store=[]}var r=t.pop();var i=t.pop();if(T.DEBUG){console.log(e.step,"WS",r,i)}n[i]=r}function yi(e){var t=e.stack;var n=e.store;var r=t.pop();if(T.DEBUG){console.log(e.step,"RS",r)}var i=n&&n[r]||0;t.push(i)}function Bi(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"WCVTP",n,r)}e.cvt[r]=n/64}function Oi(e){var t=e.stack;var n=t.pop();if(T.DEBUG){console.log(e.step,"RCVT",n)}t.push(e.cvt[n]*64)}function Di(e,t){var n=t.stack;var r=n.pop();var i=t.z2[r];if(T.DEBUG){console.log(t.step,"GC["+e+"]",r)}n.push(t.dpv.distance(i,Br,e,false)*64)}function Ii(e,t){var n=t.stack;var r=n.pop();var i=n.pop();var a=t.z1[r];var s=t.z0[i];var o=t.dpv.distance(s,a,e,e);if(T.DEBUG){console.log(t.step,"MD["+e+"]",r,i,"->",o)}t.stack.push(Math.round(o*64))}function Mi(e){if(T.DEBUG){console.log(e.step,"MPPEM[]")}e.stack.push(e.ppem)}function Li(e){if(T.DEBUG){console.log(e.step,"FLIPON[]")}e.autoFlip=true}function Ri(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"LT[]",n,r)}t.push(r<n?1:0)}function wi(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"LTEQ[]",n,r)}t.push(r<=n?1:0)}function Ni(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"GT[]",n,r)}t.push(r>n?1:0)}function Pi(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"GTEQ[]",n,r)}t.push(r>=n?1:0)}function Ui(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"EQ[]",n,r)}t.push(n===r?1:0)}function ki(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"NEQ[]",n,r)}t.push(n!==r?1:0)}function ji(e){var t=e.stack;var n=t.pop();if(T.DEBUG){console.log(e.step,"ODD[]",n)}t.push(Math.trunc(n)%2?1:0)}function Gi(e){var t=e.stack;var n=t.pop();if(T.DEBUG){console.log(e.step,"EVEN[]",n)}t.push(Math.trunc(n)%2?0:1)}function Vi(e){var t=e.stack.pop();if(T.DEBUG){console.log(e.step,"IF[]",t)}if(!t){Ir(e,true);if(T.DEBUG){console.log(e.step,"EIF[]")}}}function zi(e){if(T.DEBUG){console.log(e.step,"EIF[]")}}function Hi(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"AND[]",n,r)}t.push(n&&r?1:0)}function Xi(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"OR[]",n,r)}t.push(n||r?1:0)}function Wi(e){var t=e.stack;var n=t.pop();if(T.DEBUG){console.log(e.step,"NOT[]",n)}t.push(n?0:1)}function Yi(e,t){var n=t.stack;var r=n.pop();var i=t.fv;var a=t.pv;var s=t.ppem;var o=t.deltaBase+(e-1)*16;var l=t.deltaShift;var u=t.z0;if(T.DEBUG){console.log(t.step,"DELTAP["+e+"]",r,n)}for(var c=0;c<r;c++){var h=n.pop();var f=n.pop();var d=o+((f&240)>>4);if(d!==s){continue}var p=(f&15)-8;if(p>=0){p++}if(T.DEBUG){console.log(t.step,"DELTAPFIX",h,"by",p*l)}var g=u[h];i.setRelative(g,g,p*l,a)}}function qi(e){var t=e.stack;var n=t.pop();if(T.DEBUG){console.log(e.step,"SDB[]",n)}e.deltaBase=n}function Zi(e){var t=e.stack;var n=t.pop();if(T.DEBUG){console.log(e.step,"SDS[]",n)}e.deltaShift=Math.pow(.5,n)}function Ji(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"ADD[]",n,r)}t.push(r+n)}function Qi(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"SUB[]",n,r)}t.push(r-n)}function Ki(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"DIV[]",n,r)}t.push(r*64/n)}function $i(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"MUL[]",n,r)}t.push(r*n/64)}function ea(e){var t=e.stack;var n=t.pop();if(T.DEBUG){console.log(e.step,"ABS[]",n)}t.push(Math.abs(n))}function ta(e){var t=e.stack;var n=t.pop();if(T.DEBUG){console.log(e.step,"NEG[]",n)}t.push(-n)}function na(e){var t=e.stack;var n=t.pop();if(T.DEBUG){console.log(e.step,"FLOOR[]",n)}t.push(Math.floor(n/64)*64)}function ra(e){var t=e.stack;var n=t.pop();if(T.DEBUG){console.log(e.step,"CEILING[]",n)}t.push(Math.ceil(n/64)*64)}function ia(e,t){var n=t.stack;var r=n.pop();if(T.DEBUG){console.log(t.step,"ROUND[]")}n.push(t.round(r/64)*64)}function aa(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"WCVTF[]",n,r)}e.cvt[r]=n*e.ppem/e.font.unitsPerEm}function sa(e,t){var n=t.stack;var r=n.pop();var i=t.ppem;var a=t.deltaBase+(e-1)*16;var s=t.deltaShift;if(T.DEBUG){console.log(t.step,"DELTAC["+e+"]",r,n)}for(var o=0;o<r;o++){var l=n.pop();var u=n.pop();var c=a+((u&240)>>4);if(c!==i){continue}var h=(u&15)-8;if(h>=0){h++}var f=h*s;if(T.DEBUG){console.log(t.step,"DELTACFIX",l,"by",f)}t.cvt[l]+=f}}function oa(e){var t=e.stack.pop();if(T.DEBUG){console.log(e.step,"SROUND[]",t)}e.round=Tr;var n;switch(t&192){case 0:n=.5;break;case 64:n=1;break;case 128:n=2;break;default:throw new Error("invalid SROUND value")}e.srPeriod=n;switch(t&48){case 0:e.srPhase=0;break;case 16:e.srPhase=.25*n;break;case 32:e.srPhase=.5*n;break;case 48:e.srPhase=.75*n;break;default:throw new Error("invalid SROUND value")}t&=15;if(t===0){e.srThreshold=0}else{e.srThreshold=(t/8-.5)*n}}function la(e){var t=e.stack.pop();if(T.DEBUG){console.log(e.step,"S45ROUND[]",t)}e.round=Tr;var n;switch(t&192){case 0:n=Math.sqrt(2)/2;break;case 64:n=Math.sqrt(2);break;case 128:n=2*Math.sqrt(2);break;default:throw new Error("invalid S45ROUND value")}e.srPeriod=n;switch(t&48){case 0:e.srPhase=0;break;case 16:e.srPhase=.25*n;break;case 32:e.srPhase=.5*n;break;case 48:e.srPhase=.75*n;break;default:throw new Error("invalid S45ROUND value")}t&=15;if(t===0){e.srThreshold=0}else{e.srThreshold=(t/8-.5)*n}}function ua(e){if(T.DEBUG){console.log(e.step,"ROFF[]")}e.round=_r}function ca(e){if(T.DEBUG){console.log(e.step,"RUTG[]")}e.round=Ar}function ha(e){if(T.DEBUG){console.log(e.step,"RDTG[]")}e.round=xr}function fa(e){var t=e.stack.pop();if(T.DEBUG){console.log(e.step,"SCANCTRL[]",t)}}function da(e,t){var n=t.stack;var r=n.pop();var i=n.pop();var a=t.z2[r];var s=t.z1[i];if(T.DEBUG){console.log(t.step,"SDPVTL["+e+"]",r,i)}var o;var l;if(!e){o=s.x-a.x;l=s.y-a.y}else{o=a.y-s.y;l=s.x-a.x}t.dpv=yr(o,l)}function pa(e){var t=e.stack;var n=t.pop();var r=0;if(T.DEBUG){console.log(e.step,"GETINFO[]",n)}if(n&1){r=35}if(n&32){r|=4096}t.push(r)}function ga(e){var t=e.stack;var n=t.pop();var r=t.pop();var i=t.pop();if(T.DEBUG){console.log(e.step,"ROLL[]")}t.push(r);t.push(n);t.push(i)}function ma(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"MAX[]",n,r)}t.push(Math.max(r,n))}function va(e){var t=e.stack;var n=t.pop();var r=t.pop();if(T.DEBUG){console.log(e.step,"MIN[]",n,r)}t.push(Math.min(r,n))}function ba(e){var t=e.stack.pop();if(T.DEBUG){console.log(e.step,"SCANTYPE[]",t)}}function _a(e){var t=e.stack.pop();var n=e.stack.pop();if(T.DEBUG){console.log(e.step,"INSTCTRL[]",t,n)}switch(t){case 1:e.inhibitGridFit=!!n;return;case 2:e.ignoreCvt=!!n;return;default:throw new Error("invalid INSTCTRL[] selector")}}function n(e,t){var n=t.stack;var r=t.prog;var i=t.ip;if(T.DEBUG){console.log(t.step,"PUSHB["+e+"]")}for(var a=0;a<e;a++){n.push(r[++i])}t.ip=i}function r(e,t){var n=t.ip;var r=t.prog;var i=t.stack;if(T.DEBUG){console.log(t.ip,"PUSHW["+e+"]")}for(var a=0;a<e;a++){var s=r[++n]<<8|r[++n];if(s&32768){s=-((s^65535)+1)}i.push(s)}t.ip=n}function s(e,t,n,r,i,a){var s=a.stack;var o=e&&s.pop();var l=s.pop();var u=a.rp0;var c=a.z0[u];var h=a.z1[l];var f=a.minDis;var d=a.fv;var p=a.dpv;var g;var m;var v;var b;m=g=p.distance(h,c,true,true);v=m>=0?1:-1;m=Math.abs(m);if(e){b=a.cvt[o];if(r&&Math.abs(m-b)<a.cvCutIn){m=b}}if(n&&m<f){m=f}if(r){m=a.round(m)}d.setRelative(h,c,v*m,p);d.touch(h);if(T.DEBUG){console.log(a.step,(e?"MIRP[":"MDRP[")+(t?"M":"m")+(n?">":"_")+(r?"R":"_")+(i===0?"Gr":i===1?"Bl":i===2?"Wh":"")+"]",e?o+"("+a.cvt[o]+","+b+")":"",l,"(d =",g,"->",v*m,")")}a.rp1=a.rp0;a.rp2=l;if(t){a.rp0=l}}pr=[Mr.bind(undefined,v),Mr.bind(undefined,m),Lr.bind(undefined,v),Lr.bind(undefined,m),Rr.bind(undefined,v),Rr.bind(undefined,m),wr.bind(undefined,0),wr.bind(undefined,1),Nr.bind(undefined,0),Nr.bind(undefined,1),Pr,Ur,kr,jr,Gr,Vr,zr,Hr,Xr,Wr,Yr,qr,Zr,Jr,Qr,Kr,$r,ei,ti,ni,undefined,undefined,ri,ii,ai,si,oi,ci,hi,undefined,undefined,undefined,li,ui,fi,undefined,di.bind(undefined,0),di.bind(undefined,1),pi.bind(undefined,v),pi.bind(undefined,m),gi.bind(undefined,0),gi.bind(undefined,1),mi.bind(undefined,0),mi.bind(undefined,1),vi.bind(undefined,0),vi.bind(undefined,1),bi,_i,Ei.bind(undefined,0),Ei.bind(undefined,1),Fi,Ci,Ai.bind(undefined,0),Ai.bind(undefined,1),xi,Ti,Si,yi,Bi,Oi,Di.bind(undefined,0),Di.bind(undefined,1),undefined,Ii.bind(undefined,0),Ii.bind(undefined,1),Mi,undefined,Li,undefined,undefined,Ri,wi,Ni,Pi,Ui,ki,ji,Gi,Vi,zi,Hi,Xi,Wi,Yi.bind(undefined,1),qi,Zi,Ji,Qi,Ki,$i,ea,ta,na,ra,ia.bind(undefined,0),ia.bind(undefined,1),ia.bind(undefined,2),ia.bind(undefined,3),undefined,undefined,undefined,undefined,aa,Yi.bind(undefined,2),Yi.bind(undefined,3),sa.bind(undefined,1),sa.bind(undefined,2),sa.bind(undefined,3),oa,la,undefined,undefined,ua,undefined,ca,ha,ii,ii,undefined,undefined,undefined,undefined,undefined,fa,da.bind(undefined,0),da.bind(undefined,1),pa,undefined,ga,ma,va,ba,_a,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,undefined,n.bind(undefined,1),n.bind(undefined,2),n.bind(undefined,3),n.bind(undefined,4),n.bind(undefined,5),n.bind(undefined,6),n.bind(undefined,7),n.bind(undefined,8),r.bind(undefined,1),r.bind(undefined,2),r.bind(undefined,3),r.bind(undefined,4),r.bind(undefined,5),r.bind(undefined,6),r.bind(undefined,7),r.bind(undefined,8),s.bind(undefined,0,0,0,0,0),s.bind(undefined,0,0,0,0,1),s.bind(undefined,0,0,0,0,2),s.bind(undefined,0,0,0,0,3),s.bind(undefined,0,0,0,1,0),s.bind(undefined,0,0,0,1,1),s.bind(undefined,0,0,0,1,2),s.bind(undefined,0,0,0,1,3),s.bind(undefined,0,0,1,0,0),s.bind(undefined,0,0,1,0,1),s.bind(undefined,0,0,1,0,2),s.bind(undefined,0,0,1,0,3),s.bind(undefined,0,0,1,1,0),s.bind(undefined,0,0,1,1,1),s.bind(undefined,0,0,1,1,2),s.bind(undefined,0,0,1,1,3),s.bind(undefined,0,1,0,0,0),s.bind(undefined,0,1,0,0,1),s.bind(undefined,0,1,0,0,2),s.bind(undefined,0,1,0,0,3),s.bind(undefined,0,1,0,1,0),s.bind(undefined,0,1,0,1,1),s.bind(undefined,0,1,0,1,2),s.bind(undefined,0,1,0,1,3),s.bind(undefined,0,1,1,0,0),s.bind(undefined,0,1,1,0,1),s.bind(undefined,0,1,1,0,2),s.bind(undefined,0,1,1,0,3),s.bind(undefined,0,1,1,1,0),s.bind(undefined,0,1,1,1,1),s.bind(undefined,0,1,1,1,2),s.bind(undefined,0,1,1,1,3),s.bind(undefined,1,0,0,0,0),s.bind(undefined,1,0,0,0,1),s.bind(undefined,1,0,0,0,2),s.bind(undefined,1,0,0,0,3),s.bind(undefined,1,0,0,1,0),s.bind(undefined,1,0,0,1,1),s.bind(undefined,1,0,0,1,2),s.bind(undefined,1,0,0,1,3),s.bind(undefined,1,0,1,0,0),s.bind(undefined,1,0,1,0,1),s.bind(undefined,1,0,1,0,2),s.bind(undefined,1,0,1,0,3),s.bind(undefined,1,0,1,1,0),s.bind(undefined,1,0,1,1,1),s.bind(undefined,1,0,1,1,2),s.bind(undefined,1,0,1,1,3),s.bind(undefined,1,1,0,0,0),s.bind(undefined,1,1,0,0,1),s.bind(undefined,1,1,0,0,2),s.bind(undefined,1,1,0,0,3),s.bind(undefined,1,1,0,1,0),s.bind(undefined,1,1,0,1,1),s.bind(undefined,1,1,0,1,2),s.bind(undefined,1,1,0,1,3),s.bind(undefined,1,1,1,0,0),s.bind(undefined,1,1,1,0,1),s.bind(undefined,1,1,1,0,2),s.bind(undefined,1,1,1,0,3),s.bind(undefined,1,1,1,1,0),s.bind(undefined,1,1,1,1,1),s.bind(undefined,1,1,1,1,2),s.bind(undefined,1,1,1,1,3)];function Ea(e){this.char=e;this.state={};this.activeState=null}function Fa(e,t,n){this.contextName=n;this.startIndex=e;this.endOffset=t}function Ca(e,t,n){this.contextName=e;this.openRange=null;this.ranges=[];this.checkStart=t;this.checkEnd=n}function O(e,t){this.context=e;this.index=t;this.length=e.length;this.current=e[t];this.backtrack=e.slice(0,t);this.lookahead=e.slice(t+1)}function Aa(e){this.eventId=e;this.subscribers=[]}function xa(n){var r=this;var e=["start","end","next","newToken","contextStart","contextEnd","insertToken","removeToken","removeRange","replaceToken","replaceRange","composeRUD","updateContextsRanges"];e.forEach(function(e){Object.defineProperty(r.events,e,{value:new Aa(e)})});if(!!n){e.forEach(function(e){var t=n[e];if(typeof t==="function"){r.events[e].subscribe(t)}})}var t=["insertToken","removeToken","removeRange","replaceToken","replaceRange","composeRUD"];t.forEach(function(e){r.events[e].subscribe(r.updateContextsRanges)})}function b(e){this.tokens=[];this.registeredContexts={};this.contextCheckers=[];this.events={};this.registeredModifiers=[];xa.call(this,e)}Ea.prototype.setState=function(e,t){this.state[e]=t;this.activeState={key:e,value:this.state[e]};return this.activeState};Ea.prototype.getState=function(e){return this.state[e]||null};b.prototype.inboundIndex=function(e){return e>=0&&e<this.tokens.length};b.prototype.composeRUD=function(e){var t=this;var n=true;var r=e.map(function(e){return t[e[0]].apply(t,e.slice(1).concat(n))});var i=function(e){return typeof e==="object"&&e.hasOwnProperty("FAIL")};if(r.every(i)){return{FAIL:"composeRUD: one or more operations hasn't completed successfully",report:r.filter(i)}}this.dispatch("composeRUD",[r.filter(function(e){return!i(e)})])};b.prototype.replaceRange=function(e,t,n,r){t=t!==null?t:this.tokens.length;var i=n.every(function(e){return e instanceof Ea});if(!isNaN(e)&&this.inboundIndex(e)&&i){var a=this.tokens.splice.apply(this.tokens,[e,t].concat(n));if(!r){this.dispatch("replaceToken",[e,t,n])}return[a,n]}else{return{FAIL:"replaceRange: invalid tokens or startIndex."}}};b.prototype.replaceToken=function(e,t,n){if(!isNaN(e)&&this.inboundIndex(e)&&t instanceof Ea){var r=this.tokens.splice(e,1,t);if(!n){this.dispatch("replaceToken",[e,t])}return[r[0],t]}else{return{FAIL:"replaceToken: invalid token or index."}}};b.prototype.removeRange=function(e,t,n){t=!isNaN(t)?t:this.tokens.length;var r=this.tokens.splice(e,t);if(!n){this.dispatch("removeRange",[r,e,t])}return r};b.prototype.removeToken=function(e,t){if(!isNaN(e)&&this.inboundIndex(e)){var n=this.tokens.splice(e,1);if(!t){this.dispatch("removeToken",[n,e])}return n}else{return{FAIL:"removeToken: invalid token index."}}};b.prototype.insertToken=function(e,t,n){var r=e.every(function(e){return e instanceof Ea});if(r){this.tokens.splice.apply(this.tokens,[t,0].concat(e));if(!n){this.dispatch("insertToken",[e,t])}return e}else{return{FAIL:"insertToken: invalid token(s)."}}};b.prototype.registerModifier=function(s,o,l){this.events.newToken.subscribe(function(e,t){var n=[e,t];var r=o===null||o.apply(this,n)===true;var i=[e,t];if(r){var a=l.apply(this,i);e.setState(s,a)}});this.registeredModifiers.push(s)};Aa.prototype.subscribe=function(e){if(typeof e==="function"){return this.subscribers.push(e)-1}else{return{FAIL:"invalid '"+this.eventId+"' event handler"}}};Aa.prototype.unsubscribe=function(e){this.subscribers.splice(e,1)};O.prototype.setCurrentIndex=function(e){this.index=e;this.current=this.context[e];this.backtrack=this.context.slice(0,e);this.lookahead=this.context.slice(e+1)};O.prototype.get=function(e){switch(true){case e===0:return this.current;case e<0&&Math.abs(e)<=this.backtrack.length:return this.backtrack.slice(e)[0];case e>0&&e<=this.lookahead.length:return this.lookahead[e-1];default:return null}};b.prototype.rangeToText=function(e){if(e instanceof Fa){return this.getRangeTokens(e).map(function(e){return e.char}).join("")}};b.prototype.getText=function(){return this.tokens.map(function(e){return e.char}).join("")};b.prototype.getContext=function(e){var t=this.registeredContexts[e];return!!t?t:null};b.prototype.on=function(e,t){var n=this.events[e];if(!!n){return n.subscribe(t)}else{return null}};b.prototype.dispatch=function(e,t){var n=this;var r=this.events[e];if(r instanceof Aa){r.subscribers.forEach(function(e){e.apply(n,t||[])})}};b.prototype.registerContextChecker=function(e,t,n){if(!!this.getContext(e)){return{FAIL:"context name '"+e+"' is already registered."}}if(typeof t!=="function"){return{FAIL:"missing context start check."}}if(typeof n!=="function"){return{FAIL:"missing context end check."}}var r=new Ca(e,t,n);this.registeredContexts[e]=r;this.contextCheckers.push(r);return r};b.prototype.getRangeTokens=function(e){var t=e.startIndex+e.endOffset;return[].concat(this.tokens.slice(e.startIndex,t))};b.prototype.getContextRanges=function(e){var t=this.getContext(e);if(!!t){return t.ranges}else{return{FAIL:"context checker '"+e+"' is not registered."}}};b.prototype.resetContextsRanges=function(){var e=this.registeredContexts;for(var t in e){if(e.hasOwnProperty(t)){var n=e[t];n.ranges=[]}}};b.prototype.updateContextsRanges=function(){this.resetContextsRanges();var e=this.tokens.map(function(e){return e.char});for(var t=0;t<e.length;t++){var n=new O(e,t);this.runContextCheck(n)}this.dispatch("updateContextsRanges",[this.registeredContexts])};b.prototype.setEndOffset=function(e,t){var n=this.getContext(t).openRange.startIndex;var r=new Fa(n,e,t);var i=this.getContext(t).ranges;r.rangeId=t+"."+i.length;i.push(r);this.getContext(t).openRange=null;return r};b.prototype.runContextCheck=function(a){var s=this;var o=a.index;this.contextCheckers.forEach(function(e){var t=e.contextName;var n=s.getContext(t).openRange;if(!n&&e.checkStart(a)){n=new Fa(o,null,t);s.getContext(t).openRange=n;s.dispatch("contextStart",[t,o])}if(!!n&&e.checkEnd(a)){var r=o-n.startIndex+1;var i=s.setEndOffset(r,t);s.dispatch("contextEnd",[t,i])}})};b.prototype.tokenize=function(e){this.tokens=[];this.resetContextsRanges();var t=Array.from(e);this.dispatch("start");for(var n=0;n<t.length;n++){var r=t[n];var i=new O(t,n);this.dispatch("next",[i]);this.runContextCheck(i);var a=new Ea(r);this.tokens.push(a);this.dispatch("newToken",[a,i])}this.dispatch("end",[this.tokens]);return this.tokens};function _(e){return/[\u0600-\u065F\u066A-\u06D2\u06FA-\u06FF]/.test(e)}function Ta(e){return/[\u0630\u0690\u0621\u0631\u0661\u0671\u0622\u0632\u0672\u0692\u06C2\u0623\u0673\u0693\u06C3\u0624\u0694\u06C4\u0625\u0675\u0695\u06C5\u06E5\u0676\u0696\u06C6\u0627\u0677\u0697\u06C7\u0648\u0688\u0698\u06C8\u0689\u0699\u06C9\u068A\u06CA\u066B\u068B\u06CB\u068C\u068D\u06CD\u06FD\u068E\u06EE\u06FE\u062F\u068F\u06CF\u06EF]/.test(e)}function D(e){return/[\u0600-\u0605\u060C-\u060E\u0610-\u061B\u061E\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED]/.test(e)}function Sa(e){return/[A-z]/.test(e)}function ya(e){return/\s/.test(e)}function C(e){this.font=e;this.features={}}function Ba(e){this.id=e.id;this.tag=e.tag;this.substitution=e.substitution}function Oa(e,t){if(!e){return-1}switch(t.format){case 1:return t.glyphs.indexOf(e);case 2:var n=t.ranges;for(var r=0;r<n.length;r++){var i=n[r];if(e>=i.start&&e<=i.end){var a=e-i.start;return i.index+a}}break;default:return-1}return-1}function Da(e,t){var n=Oa(e,t.coverage);if(n===-1){return null}return e+t.deltaGlyphId}function Ia(e,t){var n=Oa(e,t.coverage);if(n===-1){return null}return t.substitute[n]}function Ma(e,t){var n=[];for(var r=0;r<e.length;r++){var i=e[r];var a=t.current;a=Array.isArray(a)?a[0]:a;var s=Oa(a,i);if(s!==-1){n.push(s)}}if(n.length!==e.length){return-1}return n}function La(e,t){var n=t.inputCoverage.length+t.lookaheadCoverage.length+t.backtrackCoverage.length;if(e.context.length<n){return[]}var r=Ma(t.inputCoverage,e);if(r===-1){return[]}var i=t.inputCoverage.length-1;if(e.lookahead.length<t.lookaheadCoverage.length){return[]}var a=e.lookahead.slice(i);while(a.length&&D(a[0].char)){a.shift()}var s=new O(a,0);var o=Ma(t.lookaheadCoverage,s);var l=[].concat(e.backtrack);l.reverse();while(l.length&&D(l[0].char)){l.shift()}if(l.length<t.backtrackCoverage.length){return[]}var u=new O(l,0);var c=Ma(t.backtrackCoverage,u);var h=r.length===t.inputCoverage.length&&o.length===t.lookaheadCoverage.length&&c.length===t.backtrackCoverage.length;var f=[];if(h){for(var d=0;d<t.lookupRecords.length;d++){var p=t.lookupRecords[d];var g=p.lookupListIndex;var m=this.getLookupByIndex(g);for(var v=0;v<m.subtables.length;v++){var b=m.subtables[v];var _=this.getLookupMethod(m,b);var E=this.getSubstitutionType(m,b);if(E==="12"){for(var F=0;F<r.length;F++){var C=e.get(F);var A=_(C);if(A){f.push(A)}}}}}}return f}function Ra(e,t){var n=e.current;var r=Oa(n,t.coverage);if(r===-1){return null}var i;var a=t.ligatureSets[r];for(var s=0;s<a.length;s++){i=a[s];for(var o=0;o<i.components.length;o++){var l=e.lookahead[o];var u=i.components[o];if(l!==u){break}if(o===i.components.length-1){return i}}}return null}function wa(e,t){var n=Oa(e,t.coverage);if(n===-1){return null}return t.sequences[n]}C.prototype.getDefaultScriptFeaturesIndexes=function(){var e=this.font.tables.gsub.scripts;for(var t=0;t<e.length;t++){var n=e[t];if(n.tag==="DFLT"){return n.script.defaultLangSys.featureIndexes}}return[]};C.prototype.getScriptFeaturesIndexes=function(e){var t=this.font.tables;if(!t.gsub){return[]}if(!e){return this.getDefaultScriptFeaturesIndexes()}var n=this.font.tables.gsub.scripts;for(var r=0;r<n.length;r++){var i=n[r];if(i.tag===e&&i.script.defaultLangSys){return i.script.defaultLangSys.featureIndexes}else{var a=i.langSysRecords;if(!!a){for(var s=0;s<a.length;s++){var o=a[s];if(o.tag===e){var l=o.langSys;return l.featureIndexes}}}}}return this.getDefaultScriptFeaturesIndexes()};C.prototype.mapTagsToFeatures=function(e,t){var n={};for(var r=0;r<e.length;r++){var i=e[r].tag;var a=e[r].feature;n[i]=a}this.features[t].tags=n};C.prototype.getScriptFeatures=function(e){var t=this.features[e];if(this.features.hasOwnProperty(e)){return t}var n=this.getScriptFeaturesIndexes(e);if(!n){return null}var r=this.font.tables.gsub;t=n.map(function(e){return r.features[e]});this.features[e]=t;this.mapTagsToFeatures(t,e);return t};C.prototype.getSubstitutionType=function(e,t){var n=e.lookupType.toString();var r=t.substFormat.toString();return n+r};C.prototype.getLookupMethod=function(e,t){var n=this;var r=this.getSubstitutionType(e,t);switch(r){case"11":return function(e){return Da.apply(n,[e,t])};case"12":return function(e){return Ia.apply(n,[e,t])};case"63":return function(e){return La.apply(n,[e,t])};case"41":return function(e){return Ra.apply(n,[e,t])};case"21":return function(e){return wa.apply(n,[e,t])};default:throw new Error("lookupType: "+e.lookupType+" - "+"substFormat: "+t.substFormat+" "+"is not yet supported")}};C.prototype.lookupFeature=function(e){var t=e.contextParams;var n=t.index;var r=this.getFeature({tag:e.tag,script:e.script});if(!r){return new Error("font '"+this.font.names.fullName.en+"' "+"doesn't support feature '"+e.tag+"' "+"for script '"+e.script+"'.")}var i=this.getFeatureLookups(r);var a=[].concat(t.context);for(var s=0;s<i.length;s++){var o=i[s];var l=this.getLookupSubtables(o);for(var u=0;u<l.length;u++){var c=l[u];var h=this.getSubstitutionType(o,c);var f=this.getLookupMethod(o,c);var d=void 0;switch(h){case"11":d=f(t.current);if(d){a.splice(n,1,new Ba({id:11,tag:e.tag,substitution:d}))}break;case"12":d=f(t.current);if(d){a.splice(n,1,new Ba({id:12,tag:e.tag,substitution:d}))}break;case"63":d=f(t);if(Array.isArray(d)&&d.length){a.splice(n,1,new Ba({id:63,tag:e.tag,substitution:d}))}break;case"41":d=f(t);if(d){a.splice(n,1,new Ba({id:41,tag:e.tag,substitution:d}))}break;case"21":d=f(t.current);if(d){a.splice(n,1,new Ba({id:21,tag:e.tag,substitution:d}))}break}t=new O(a,n);if(Array.isArray(d)&&!d.length){continue}d=null}}return a.length?a:null};C.prototype.supports=function(t){if(!t.script){return false}this.getScriptFeatures(t.script);var e=this.features.hasOwnProperty(t.script);if(!t.tag){return e}var n=this.features[t.script].some(function(e){return e.tag===t.tag});return e&&n};C.prototype.getLookupSubtables=function(e){return e.subtables||null};C.prototype.getLookupByIndex=function(e){var t=this.font.tables.gsub.lookups;return t[e]||null};C.prototype.getFeatureLookups=function(e){return e.lookupListIndexes.map(this.getLookupByIndex.bind(this))};C.prototype.getFeature=function e(t){if(!this.font){return{FAIL:"No font was found"}}if(!this.features.hasOwnProperty(t.script)){this.getScriptFeatures(t.script)}var n=this.features[t.script];if(!n){return{FAIL:"No feature for script "+t.script}}if(!n.tags[t.tag]){return null}return this.features[t.script].tags[t.tag]};function Na(e){var t=e.current;var n=e.get(-1);return n===null&&_(t)||!_(n)&&_(t)}function Pa(e){var t=e.get(1);return t===null||!_(t)}var Ua={startCheck:Na,endCheck:Pa};function ka(e){var t=e.current;var n=e.get(-1);return(_(t)||D(t))&&!_(n)}function ja(e){var t=e.get(1);switch(true){case t===null:return true;case!_(t)&&!D(t):var n=ya(t);if(!n){return true}if(n){var r=false;r=e.lookahead.some(function(e){return _(e)||D(e)});if(!r){return true}}break;default:return false}}var Ga={startCheck:ka,endCheck:ja};function Va(e,t,n){t[n].setState(e.tag,e.substitution)}function za(e,t,n){t[n].setState(e.tag,e.substitution)}function Ha(r,i,a){r.substitution.forEach(function(e,t){var n=i[a+t];n.setState(r.tag,e)})}function Xa(e,t,n){var r=t[n];r.setState(e.tag,e.substitution.ligGlyph);var i=e.substitution.components.length;for(var a=0;a<i;a++){r=t[n+a+1];r.setState("deleted",true)}}var Wa={11:Va,12:za,63:Ha,41:Xa};function Ya(e,t,n){if(e instanceof Ba&&Wa[e.id]){Wa[e.id](e,t,n)}}function qa(e){var t=[].concat(e.backtrack);for(var n=t.length-1;n>=0;n--){var r=t[n];var i=Ta(r);var a=D(r);if(!i&&!a){return true}if(i){return false}}return false}function Za(e){if(Ta(e.current)){return false}for(var t=0;t<e.lookahead.length;t++){var n=e.lookahead[t];var r=D(n);if(!r){return true}}return false}function Ja(e){var a=this;var s="arab";var o=this.featuresTags[s];var l=this.tokenizer.getRangeTokens(e);if(l.length===1){return}var u=new O(l.map(function(e){return e.getState("glyphIndex")}),0);var c=new O(l.map(function(e){return e.char}),0);l.forEach(function(e,t){if(D(e.char)){return}u.setCurrentIndex(t);c.setCurrentIndex(t);var n=0;if(qa(c)){n|=1}if(Za(c)){n|=2}var r;switch(n){case 1:r="fina";break;case 2:r="init";break;case 3:r="medi";break}if(o.indexOf(r)===-1){return}var i=a.query.lookupFeature({tag:r,script:s,contextParams:u});if(i instanceof Error){return console.info(i.message)}i.forEach(function(e,t){if(e instanceof Ba){Ya(e,l,t);u.context[t]=e.substitution}})})}function Qa(e,t){var n=e.map(function(e){return e.activeState.value});return new O(n,t||0)}function Ka(e){var r=this;var i="arab";var a=this.tokenizer.getRangeTokens(e);var s=Qa(a);s.context.forEach(function(e,t){s.setCurrentIndex(t);var n=r.query.lookupFeature({tag:"rlig",script:i,contextParams:s});if(n.length){n.forEach(function(e){return Ya(e,a,t)});s=Qa(a)}})}function $a(e){var t=e.current;var n=e.get(-1);return n===null&&Sa(t)||!Sa(n)&&Sa(t)}function es(e){var t=e.get(1);return t===null||!Sa(t)}var ts={startCheck:$a,endCheck:es};function ns(e,t){var n=e.map(function(e){return e.activeState.value});return new O(n,t||0)}function rs(e){var r=this;var i="latn";var a=this.tokenizer.getRangeTokens(e);var s=ns(a);s.context.forEach(function(e,t){s.setCurrentIndex(t);var n=r.query.lookupFeature({tag:"liga",script:i,contextParams:s});if(n.length){n.forEach(function(e){return Ya(e,a,t)});s=ns(a)}})}function I(e){this.baseDir=e||"ltr";this.tokenizer=new b;this.featuresTags={}}I.prototype.setText=function(e){this.text=e};I.prototype.contextChecks={latinWordCheck:ts,arabicWordCheck:Ua,arabicSentenceCheck:Ga};function is(e){var t=this.contextChecks[e+"Check"];return this.tokenizer.registerContextChecker(e,t.startCheck,t.endCheck)}function as(){is.call(this,"latinWord");is.call(this,"arabicWord");is.call(this,"arabicSentence");return this.tokenizer.tokenize(this.text)}function ss(){var n=this;var e=this.tokenizer.getContextRanges("arabicSentence");e.forEach(function(e){var t=n.tokenizer.getRangeTokens(e);n.tokenizer.replaceRange(e.startIndex,e.endOffset,t.reverse())})}I.prototype.registerFeatures=function(t,e){var n=this;var r=e.filter(function(e){return n.query.supports({script:t,tag:e})});if(!this.featuresTags.hasOwnProperty(t)){this.featuresTags[t]=r}else{this.featuresTags[t]=this.featuresTags[t].concat(r)}};I.prototype.applyFeatures=function(e,t){if(!e){throw new Error("No valid font was provided to apply features")}if(!this.query){this.query=new C(e)}for(var n=0;n<t.length;n++){var r=t[n];if(!this.query.supports({script:r.script})){continue}this.registerFeatures(r.script,r.tags)}};I.prototype.registerModifier=function(e,t,n){this.tokenizer.registerModifier(e,t,n)};function os(){if(this.tokenizer.registeredModifiers.indexOf("glyphIndex")===-1){throw new Error("glyphIndex modifier is required to apply "+"arabic presentation features.")}}function ls(){var t=this;var e="arab";if(!this.featuresTags.hasOwnProperty(e)){return}os.call(this);var n=this.tokenizer.getContextRanges("arabicWord");n.forEach(function(e){Ja.call(t,e)})}function us(){var t=this;var e="arab";if(!this.featuresTags.hasOwnProperty(e)){return}var n=this.featuresTags[e];if(n.indexOf("rlig")===-1){return}os.call(this);var r=this.tokenizer.getContextRanges("arabicWord");r.forEach(function(e){Ka.call(t,e)})}function cs(){var t=this;var e="latn";if(!this.featuresTags.hasOwnProperty(e)){return}var n=this.featuresTags[e];if(n.indexOf("liga")===-1){return}os.call(this);var r=this.tokenizer.getContextRanges("latinWord");r.forEach(function(e){rs.call(t,e)})}I.prototype.checkContextReady=function(e){return!!this.tokenizer.getContext(e)};I.prototype.applyFeaturesToContexts=function(){if(this.checkContextReady("arabicWord")){ls.call(this);us.call(this)}if(this.checkContextReady("latinWord")){cs.call(this)}if(this.checkContextReady("arabicSentence")){ss.call(this)}};I.prototype.processText=function(e){if(!this.text||this.text!==e){this.setText(e);as.call(this);this.applyFeaturesToContexts()}};I.prototype.getBidiText=function(e){this.processText(e);return this.tokenizer.getText()};I.prototype.getTextGlyphs=function(e){this.processText(e);var t=[];for(var n=0;n<this.tokenizer.tokens.length;n++){var r=this.tokenizer.tokens[n];if(r.state.deleted){continue}var i=r.activeState.value;t.push(Array.isArray(i)?i[0]:i)}return t};function k(e){e=e||{};e.tables=e.tables||{};if(!e.empty){rr(e.familyName,"When creating a new Font object, familyName is required.");rr(e.styleName,"When creating a new Font object, styleName is required.");rr(e.unitsPerEm,"When creating a new Font object, unitsPerEm is required.");rr(e.ascender,"When creating a new Font object, ascender is required.");rr(e.descender<=0,"When creating a new Font object, negative descender value is required.");this.names={fontFamily:{en:e.familyName||" "},fontSubfamily:{en:e.styleName||" "},fullName:{en:e.fullName||e.familyName+" "+e.styleName},postScriptName:{en:e.postScriptName||(e.familyName+e.styleName).replace(/\s/g,"")},designer:{en:e.designer||" "},designerURL:{en:e.designerURL||" "},manufacturer:{en:e.manufacturer||" "},manufacturerURL:{en:e.manufacturerURL||" "},license:{en:e.license||" "},licenseURL:{en:e.licenseURL||" "},version:{en:e.version||"Version 0.1"},description:{en:e.description||" "},copyright:{en:e.copyright||" "},trademark:{en:e.trademark||" "}};this.unitsPerEm=e.unitsPerEm||1e3;this.ascender=e.ascender;this.descender=e.descender;this.createdTimestamp=e.createdTimestamp;this.tables=Object.assign(e.tables,{os2:Object.assign({usWeightClass:e.weightClass||this.usWeightClasses.MEDIUM,usWidthClass:e.widthClass||this.usWidthClasses.MEDIUM,fsSelection:e.fsSelection||this.fsSelectionValues.REGULAR},e.tables.os2)})}this.supported=true;this.glyphs=new x.GlyphSet(this,e.glyphs||[]);this.encoding=new qe(this);this.position=new Qn(this);this.substitution=new t(this);this.tables=this.tables||{};this._push=null;this._hmtxTableData={};Object.defineProperty(this,"hinting",{get:function(){if(this._hinting){return this._hinting}if(this.outlinesFormat==="truetype"){return this._hinting=new br(this)}}})}k.prototype.hasChar=function(e){return this.encoding.charToGlyphIndex(e)!==null};k.prototype.charToGlyphIndex=function(e){return this.encoding.charToGlyphIndex(e)};k.prototype.charToGlyph=function(e){var t=this.charToGlyphIndex(e);var n=this.glyphs.get(t);if(!n){n=this.glyphs.get(0)}return n};k.prototype.updateFeatures=function(t){return this.defaultRenderOptions.features.map(function(e){if(e.script==="latn"){return{script:"latn",tags:e.tags.filter(function(e){return t[e]})}}else{return e}})};k.prototype.stringToGlyphs=function(e,t){var n=this;var r=new I;var i=function(e){return n.charToGlyphIndex(e.char)};r.registerModifier("glyphIndex",null,i);var a=t?this.updateFeatures(t.features):this.defaultRenderOptions.features;r.applyFeatures(this,a);var s=r.getTextGlyphs(e);var o=s.length;var l=new Array(o);var u=this.glyphs.get(0);for(var c=0;c<o;c+=1){l[c]=this.glyphs.get(s[c])||u}return l};k.prototype.nameToGlyphIndex=function(e){return this.glyphNames.nameToGlyphIndex(e)};k.prototype.nameToGlyph=function(e){var t=this.nameToGlyphIndex(e);var n=this.glyphs.get(t);if(!n){n=this.glyphs.get(0)}return n};k.prototype.glyphIndexToName=function(e){if(!this.glyphNames.glyphIndexToName){return""}return this.glyphNames.glyphIndexToName(e)};k.prototype.getKerningValue=function(e,t){e=e.index||e;t=t.index||t;var n=this.position.defaultKerningTables;if(n){return this.position.getKerningValue(n,e,t)}return this.kerningPairs[e+","+t]||0};k.prototype.defaultRenderOptions={kerning:true,features:[{script:"arab",tags:["init","medi","fina","rlig"]},{script:"latn",tags:["liga","rlig"]}]};k.prototype.forEachGlyph=function(e,t,n,r,i,a){t=t!==undefined?t:0;n=n!==undefined?n:0;r=r!==undefined?r:72;i=Object.assign({},this.defaultRenderOptions,i);var s=1/this.unitsPerEm*r;var o=this.stringToGlyphs(e,i);var l;if(i.kerning){var u=i.script||this.position.getDefaultScriptName();l=this.position.getKerningTables(u,i.language)}for(var c=0;c<o.length;c+=1){var h=o[c];a.call(this,h,t,n,r,i);if(h.advanceWidth){t+=h.advanceWidth*s}if(i.kerning&&c<o.length-1){var f=l?this.position.getKerningValue(l,h.index,o[c+1].index):this.getKerningValue(h,o[c+1]);t+=f*s}if(i.letterSpacing){t+=i.letterSpacing*r}else if(i.tracking){t+=i.tracking/1e3*r}}return t};k.prototype.getPath=function(e,t,n,r,a){var s=new p;this.forEachGlyph(e,t,n,r,a,function(e,t,n,r){var i=e.getPath(t,n,r,a,this);s.extend(i)});return s};k.prototype.getPaths=function(e,t,n,r,a){var s=[];this.forEachGlyph(e,t,n,r,a,function(e,t,n,r){var i=e.getPath(t,n,r,a,this);s.push(i)});return s};k.prototype.getAdvanceWidth=function(e,t,n){return this.forEachGlyph(e,0,0,t,n,function(){})};k.prototype.draw=function(e,t,n,r,i,a){this.getPath(t,n,r,i,a).draw(e)};k.prototype.drawPoints=function(i,e,t,n,r,a){this.forEachGlyph(e,t,n,r,a,function(e,t,n,r){e.drawPoints(i,t,n,r)})};k.prototype.drawMetrics=function(i,e,t,n,r,a){this.forEachGlyph(e,t,n,r,a,function(e,t,n,r){e.drawMetrics(i,t,n,r)})};k.prototype.getEnglishName=function(e){var t=this.names[e];if(t){return t.en}};k.prototype.validate=function(){var n=this;function r(e,t){}function e(e){var t=n.getEnglishName(e);r(t&&t.trim().length>0)}e("fontFamily");e("weightName");e("manufacturer");e("copyright");e("version");r(this.unitsPerEm>0)};k.prototype.toTables=function(){return Wn.fontToTable(this)};k.prototype.toBuffer=function(){console.warn("Font.toBuffer is deprecated. Use Font.toArrayBuffer instead.");return this.toArrayBuffer()};k.prototype.toArrayBuffer=function(){var e=this.toTables();var t=e.encode();var n=new ArrayBuffer(t.length);var r=new Uint8Array(n);for(var i=0;i<t.length;i++){r[i]=t[i]}return n};k.prototype.download=function(e){var t=this.getEnglishName("fontFamily");var n=this.getEnglishName("fontSubfamily");e=e||t.replace(/\s/g,"")+"-"+n+".otf";var r=this.toArrayBuffer();if(er()){window.URL=window.URL||window.webkitURL;if(window.URL){var i=new DataView(r);var a=new Blob([i],{type:"font/opentype"});var s=document.createElement("a");s.href=window.URL.createObjectURL(a);s.download=e;var o=document.createEvent("MouseEvents");o.initEvent("click",true,false);s.dispatchEvent(o)}else{console.warn("Font file could not be downloaded. Try using a different browser.")}}else{var l=require("fs");var u=nr(r);l.writeFileSync(e,u)}};k.prototype.fsSelectionValues={ITALIC:1,UNDERSCORE:2,NEGATIVE:4,OUTLINED:8,STRIKEOUT:16,BOLD:32,REGULAR:64,USER_TYPO_METRICS:128,WWS:256,OBLIQUE:512};k.prototype.usWidthClasses={ULTRA_CONDENSED:1,EXTRA_CONDENSED:2,CONDENSED:3,SEMI_CONDENSED:4,MEDIUM:5,SEMI_EXPANDED:6,EXPANDED:7,EXTRA_EXPANDED:8,ULTRA_EXPANDED:9};k.prototype.usWeightClasses={THIN:100,EXTRA_LIGHT:200,LIGHT:300,NORMAL:400,MEDIUM:500,SEMI_BOLD:600,BOLD:700,EXTRA_BOLD:800,BLACK:900};function hs(e,t){var n=JSON.stringify(e);var r=256;for(var i in t){var a=parseInt(i);if(!a||a<256){continue}if(JSON.stringify(t[i])===n){return a}if(r<=a){r=a+1}}t[r]=e;return r}function fs(e,t,n){var r=hs(t.name,n);return[{name:"tag_"+e,type:"TAG",value:t.tag},{name:"minValue_"+e,type:"FIXED",value:t.minValue<<16},{name:"defaultValue_"+e,type:"FIXED",value:t.defaultValue<<16},{name:"maxValue_"+e,type:"FIXED",value:t.maxValue<<16},{name:"flags_"+e,type:"USHORT",value:0},{name:"nameID_"+e,type:"USHORT",value:r}]}function ds(e,t,n){var r={};var i=new U.Parser(e,t);r.tag=i.parseTag();r.minValue=i.parseFixed();r.defaultValue=i.parseFixed();r.maxValue=i.parseFixed();i.skip("uShort",1);r.name=n[i.parseUShort()]||{};return r}function ps(e,t,n,r){var i=hs(t.name,r);var a=[{name:"nameID_"+e,type:"USHORT",value:i},{name:"flags_"+e,type:"USHORT",value:0}];for(var s=0;s<n.length;++s){var o=n[s].tag;a.push({name:"axis_"+e+" "+o,type:"FIXED",value:t.coordinates[o]<<16})}return a}function gs(e,t,n,r){var i={};var a=new U.Parser(e,t);i.name=r[a.parseUShort()]||{};a.skip("uShort",1);i.coordinates={};for(var s=0;s<n.length;++s){i.coordinates[n[s].tag]=a.parseFixed()}return i}function ms(e,t){var n=new B.Table("fvar",[{name:"version",type:"ULONG",value:65536},{name:"offsetToData",type:"USHORT",value:0},{name:"countSizePairs",type:"USHORT",value:2},{name:"axisCount",type:"USHORT",value:e.axes.length},{name:"axisSize",type:"USHORT",value:20},{name:"instanceCount",type:"USHORT",value:e.instances.length},{name:"instanceSize",type:"USHORT",value:4+e.axes.length*4}]);n.offsetToData=n.sizeOf();for(var r=0;r<e.axes.length;r++){n.fields=n.fields.concat(fs(r,e.axes[r],t))}for(var i=0;i<e.instances.length;i++){n.fields=n.fields.concat(ps(i,e.instances[i],e.axes,t))}return n}function vs(e,t,n){var r=new U.Parser(e,t);var i=r.parseULong();A.argument(i===65536,"Unsupported fvar table version.");var a=r.parseOffset16();r.skip("uShort",1);var s=r.parseUShort();var o=r.parseUShort();var l=r.parseUShort();var u=r.parseUShort();var c=[];for(var h=0;h<s;h++){c.push(ds(e,t+a+h*o,n))}var f=[];var d=t+a+s*o;for(var p=0;p<l;p++){f.push(gs(e,d+p*u,c,n))}return{axes:c,instances:f}}var bs={make:ms,parse:vs};var _s=function(){return{coverage:this.parsePointer(c.coverage),attachPoints:this.parseList(c.pointer(c.uShortList))}};var Es=function(){var e=this.parseUShort();A.argument(e===1||e===2||e===3,"Unsupported CaretValue table version.");if(e===1){return{coordinate:this.parseShort()}}else if(e===2){return{pointindex:this.parseShort()}}else if(e===3){return{coordinate:this.parseShort()}}};var Fs=function(){return this.parseList(c.pointer(Es))};var Cs=function(){return{coverage:this.parsePointer(c.coverage),ligGlyphs:this.parseList(c.pointer(Fs))}};var As=function(){this.parseUShort();return this.parseList(c.pointer(c.coverage))};function xs(e,t){t=t||0;var n=new c(e,t);var r=n.parseVersion(1);A.argument(r===1||r===1.2||r===1.3,"Unsupported GDEF table version.");var i={version:r,classDef:n.parsePointer(c.classDef),attachList:n.parsePointer(_s),ligCaretList:n.parsePointer(Cs),markAttachClassDef:n.parsePointer(c.classDef)};if(r>=1.2){i.markGlyphSets=n.parsePointer(As)}return i}var Ts={parse:xs};var M=new Array(10);M[1]=function e(){var t=this.offset+this.relativeOffset;var n=this.parseUShort();if(n===1){return{posFormat:1,coverage:this.parsePointer(c.coverage),value:this.parseValueRecord()}}else if(n===2){return{posFormat:2,coverage:this.parsePointer(c.coverage),values:this.parseValueRecordList()}}A.assert(false,"0x"+t.toString(16)+": GPOS lookup type 1 format must be 1 or 2.")};M[2]=function e(){var t=this.offset+this.relativeOffset;var n=this.parseUShort();A.assert(n===1||n===2,"0x"+t.toString(16)+": GPOS lookup type 2 format must be 1 or 2.");var r=this.parsePointer(c.coverage);var i=this.parseUShort();var a=this.parseUShort();if(n===1){return{posFormat:n,coverage:r,valueFormat1:i,valueFormat2:a,pairSets:this.parseList(c.pointer(c.list(function(){return{secondGlyph:this.parseUShort(),value1:this.parseValueRecord(i),value2:this.parseValueRecord(a)}})))}}else if(n===2){var s=this.parsePointer(c.classDef);var o=this.parsePointer(c.classDef);var l=this.parseUShort();var u=this.parseUShort();return{posFormat:n,coverage:r,valueFormat1:i,valueFormat2:a,classDef1:s,classDef2:o,class1Count:l,class2Count:u,classRecords:this.parseList(l,c.list(u,function(){return{value1:this.parseValueRecord(i),value2:this.parseValueRecord(a)}}))}}};M[3]=function e(){return{error:"GPOS Lookup 3 not supported"}};M[4]=function e(){return{error:"GPOS Lookup 4 not supported"}};M[5]=function e(){return{error:"GPOS Lookup 5 not supported"}};M[6]=function e(){return{error:"GPOS Lookup 6 not supported"}};M[7]=function e(){return{error:"GPOS Lookup 7 not supported"}};M[8]=function e(){return{error:"GPOS Lookup 8 not supported"}};M[9]=function e(){return{error:"GPOS Lookup 9 not supported"}};function Ss(e,t){t=t||0;var n=new c(e,t);var r=n.parseVersion(1);A.argument(r===1||r===1.1,"Unsupported GPOS table version "+r);if(r===1){return{version:r,scripts:n.parseScriptList(),features:n.parseFeatureList(),lookups:n.parseLookupList(M)}}else{return{version:r,scripts:n.parseScriptList(),features:n.parseFeatureList(),lookups:n.parseLookupList(M),variations:n.parseFeatureVariationsList()}}}var ys=new Array(10);function Bs(e){return new B.Table("GPOS",[{name:"version",type:"ULONG",value:65536},{name:"scripts",type:"TABLE",value:new B.ScriptList(e.scripts)},{name:"features",type:"TABLE",value:new B.FeatureList(e.features)},{name:"lookups",type:"TABLE",value:new B.LookupList(e.lookups,ys)}])}var Os={parse:Ss,make:Bs};function Ds(e){var t={};e.skip("uShort");var n=e.parseUShort();A.argument(n===0,"Unsupported kern sub-table version.");e.skip("uShort",2);var r=e.parseUShort();e.skip("uShort",3);for(var i=0;i<r;i+=1){var a=e.parseUShort();var s=e.parseUShort();var o=e.parseShort();t[a+","+s]=o}return t}function Is(e){var t={};e.skip("uShort");var n=e.parseULong();if(n>1){console.warn("Only the first kern subtable is supported.")}e.skip("uLong");var r=e.parseUShort();var i=r&255;e.skip("uShort");if(i===0){var a=e.parseUShort();e.skip("uShort",3);for(var s=0;s<a;s+=1){var o=e.parseUShort();var l=e.parseUShort();var u=e.parseShort();t[o+","+l]=u}}return t}function Ms(e,t){var n=new U.Parser(e,t);var r=n.parseUShort();if(r===0){return Ds(n)}else if(r===1){return Is(n)}else{throw new Error("Unsupported kern table version ("+r+").")}}var Ls={parse:Ms};function Rs(e,t,n,r){var i=new U.Parser(e,t);var a=r?i.parseUShort:i.parseULong;var s=[];for(var o=0;o<n+1;o+=1){var l=a.call(i);if(r){l*=2}s.push(l)}return s}var ws={parse:Rs};function Ns(e,n){var t=require("fs");t.readFile(e,function(e,t){if(e){return n(e.message)}n(null,tr(t))})}function Ps(e,t){var n=new XMLHttpRequest;n.open("get",e,true);n.responseType="arraybuffer";n.onload=function(){if(n.response){return t(null,n.response)}else{return t("Font could not be loaded: "+n.statusText)}};n.onerror=function(){t("Font could not be loaded")};n.send()}function Us(e,t){var n=[];var r=12;for(var i=0;i<t;i+=1){var a=U.getTag(e,r);var s=U.getULong(e,r+4);var o=U.getULong(e,r+8);var l=U.getULong(e,r+12);n.push({tag:a,checksum:s,offset:o,length:l,compression:false});r+=16}return n}function ks(e,t){var n=[];var r=44;for(var i=0;i<t;i+=1){var a=U.getTag(e,r);var s=U.getULong(e,r+4);var o=U.getULong(e,r+8);var l=U.getULong(e,r+12);var u=void 0;if(o<l){u="WOFF"}else{u=false}n.push({tag:a,offset:s,compression:u,compressedLength:o,length:l});r+=20}return n}function j(e,t){if(t.compression==="WOFF"){var n=new Uint8Array(e.buffer,t.offset+2,t.compressedLength-2);var r=new Uint8Array(t.length);ie(n,r);if(r.byteLength!==t.length){throw new Error("Decompression error: "+t.tag+" decompressed length doesn't match recorded length")}var i=new DataView(r.buffer,0);return{data:i,offset:0}}else{return{data:e,offset:t.offset}}}function js(e,t){t=t===undefined||t===null?{}:t;var n;var r;var i=new k({empty:true});var a=new DataView(e,0);var s;var o=[];var l=U.getTag(a,0);if(l===String.fromCharCode(0,1,0,0)||l==="true"||l==="typ1"){i.outlinesFormat="truetype";s=U.getUShort(a,4);o=Us(a,s)}else if(l==="OTTO"){i.outlinesFormat="cff";s=U.getUShort(a,4);o=Us(a,s)}else if(l==="wOFF"){var u=U.getTag(a,4);if(u===String.fromCharCode(0,1,0,0)){i.outlinesFormat="truetype"}else if(u==="OTTO"){i.outlinesFormat="cff"}else{throw new Error("Unsupported OpenType flavor "+l)}s=U.getUShort(a,12);o=ks(a,s)}else{throw new Error("Unsupported OpenType signature "+l)}var c;var h;var f;var d;var p;var g;var m;var v;var b;var _;var E;var F;for(var C=0;C<s;C+=1){var A=o[C];var x=void 0;switch(A.tag){case"cmap":x=j(a,A);i.tables.cmap=He.parse(x.data,x.offset);i.encoding=new Ze(i.tables.cmap);break;case"cvt ":x=j(a,A);F=new U.Parser(x.data,x.offset);i.tables.cvt=F.parseShortList(A.length/2);break;case"fvar":h=A;break;case"fpgm":x=j(a,A);F=new U.Parser(x.data,x.offset);i.tables.fpgm=F.parseByteList(A.length);break;case"head":x=j(a,A);i.tables.head=Xt.parse(x.data,x.offset);i.unitsPerEm=i.tables.head.unitsPerEm;n=i.tables.head.indexToLocFormat;break;case"hhea":x=j(a,A);i.tables.hhea=qt.parse(x.data,x.offset);i.ascender=i.tables.hhea.ascender;i.descender=i.tables.hhea.descender;i.numberOfHMetrics=i.tables.hhea.numberOfHMetrics;break;case"hmtx":m=A;break;case"ltag":x=j(a,A);r=nn.parse(x.data,x.offset);break;case"maxp":x=j(a,A);i.tables.maxp=sn.parse(x.data,x.offset);i.numGlyphs=i.tables.maxp.numGlyphs;break;case"name":_=A;break;case"OS/2":x=j(a,A);i.tables.os2=yn.parse(x.data,x.offset);break;case"post":x=j(a,A);i.tables.post=Dn.parse(x.data,x.offset);i.glyphNames=new Qe(i.tables.post);break;case"prep":x=j(a,A);F=new U.Parser(x.data,x.offset);i.tables.prep=F.parseByteList(A.length);break;case"glyf":f=A;break;case"loca":b=A;break;case"CFF ":c=A;break;case"kern":v=A;break;case"GDEF":d=A;break;case"GPOS":p=A;break;case"GSUB":g=A;break;case"meta":E=A;break}}var T=j(a,_);i.tables.name=Cn.parse(T.data,T.offset,r);i.names=i.tables.name;if(f&&b){var N=n===0;var S=j(a,b);var P=ws.parse(S.data,S.offset,i.numGlyphs,N);var y=j(a,f);i.glyphs=dr.parse(y.data,y.offset,P,i,t)}else if(c){var B=j(a,c);Vt.parse(B.data,B.offset,i,t)}else{throw new Error("Font doesn't contain TrueType or CFF outlines.")}var O=j(a,m);$t.parse(i,O.data,O.offset,i.numberOfHMetrics,i.numGlyphs,i.glyphs,t);et(i,t);if(v){var D=j(a,v);i.kerningPairs=Ls.parse(D.data,D.offset)}else{i.kerningPairs={}}if(d){var I=j(a,d);i.tables.gdef=Ts.parse(I.data,I.offset)}if(p){var M=j(a,p);i.tables.gpos=Os.parse(M.data,M.offset);i.position.init()}if(g){var L=j(a,g);i.tables.gsub=wn.parse(L.data,L.offset)}if(h){var R=j(a,h);i.tables.fvar=bs.parse(R.data,R.offset,i.names)}if(E){var w=j(a,E);i.tables.meta=Un.parse(w.data,w.offset);i.metas=i.tables.meta}return i}function Gs(e,a,s){s=s===undefined||s===null?{}:s;var t=typeof window==="undefined";var n=t&&!s.isUrl?Ns:Ps;return new Promise(function(r,i){n(e,function(e,t){if(e){if(a){return a(e)}else{i(e)}}var n;try{n=js(t,s)}catch(e){if(a){return a(e,null)}else{i(e)}}if(a){return a(null,n)}else{r(n)}})})}function Vs(e,t){var n=require("fs");var r=n.readFileSync(e);return js(tr(r),t)}var zs=Object.freeze({__proto__:null,Font:k,Glyph:g,Path:p,BoundingBox:o,_parse:U,parse:js,load:Gs,loadSync:Vs});T.BoundingBox=o;T.Font=k;T.Glyph=g;T.Path=p;T._parse=U;T.default=zs;T.load=Gs;T.loadSync=Vs;T.parse=js;Object.defineProperty(T,"__esModule",{value:true})});(function(e){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=e()}else if(typeof define==="function"&&define.amd){define([],e)}else{var t;if(typeof window!=="undefined"){t=window}else if(typeof global!=="undefined"){t=global}else if(typeof self!=="undefined"){t=self}else{t=this}t.earcut=e()}})(function(){var e,t,n;return function(){function c(a,s,o){function l(n,e){if(!s[n]){if(!a[n]){var t="function"==typeof require&&require;if(!e&&t)return t(n,!0);if(u)return u(n,!0);var r=new Error("Cannot find module '"+n+"'");throw r.code="MODULE_NOT_FOUND",r}var i=s[n]={exports:{}};a[n][0].call(i.exports,function(e){var t=a[n][1][e];return l(t||e)},i,i.exports,c,a,s,o)}return s[n].exports}for(var u="function"==typeof require&&require,e=0;e<o.length;e++)l(o[e]);return l}return c}()({1:[function(e,t,n){"use strict";t.exports=r;t.exports.default=r;function r(e,t,n){n=n||2;var r=t&&t.length,i=r?t[0]*n:e.length,a=g(e,0,i,n,true),s=[];if(!a||a.next===a.prev)return s;var o,l,u,c,h,f,d;if(r)a=v(e,t,a,n);if(e.length>80*n){o=u=e[0];l=c=e[1];for(var p=n;p<i;p+=n){h=e[p];f=e[p+1];if(h<o)o=h;if(f<l)l=f;if(h>u)u=h;if(f>c)c=f}d=Math.max(u-o,c-l);d=d!==0?1/d:0}m(a,s,n,o,l,d);return s}function g(e,t,n,r,i){var a,s;if(i===R(e,t,n,r)>0){for(a=t;a<n;a+=r)s=I(a,e[a],e[a+1],s)}else{for(a=n-r;a>=t;a-=r)s=I(a,e[a],e[a+1],s)}if(s&&o(s,s.next)){M(s);s=s.next}return s}function c(e,t){if(!e)return e;if(!t)t=e;var n=e,r;do{r=false;if(!n.steiner&&(o(n,n.next)||T(n.prev,n,n.next)===0)){M(n);n=t=n.prev;if(n===n.next)break;r=true}else{n=n.next}}while(r||n!==t);return t}function m(e,t,n,r,i,a,s){if(!e)return;if(!s&&a)F(e,r,i,a);var o=e,l,u;while(e.prev!==e.next){l=e.prev;u=e.next;if(a?f(e,r,i,a):h(e)){t.push(l.i/n);t.push(e.i/n);t.push(u.i/n);M(e);e=u.next;o=u.next;continue}e=u;if(e===o){if(!s){m(c(e),t,n,r,i,a,1)}else if(s===1){e=d(c(e),t,n);m(e,t,n,r,i,a,2)}else if(s===2){p(e,t,n,r,i,a)}break}}}function h(e){var t=e.prev,n=e,r=e.next;if(T(t,n,r)>=0)return false;var i=e.next.next;while(i!==e.prev){if(x(t.x,t.y,n.x,n.y,r.x,r.y,i.x,i.y)&&T(i.prev,i,i.next)>=0)return false;i=i.next}return true}function f(e,t,n,r){var i=e.prev,a=e,s=e.next;if(T(i,a,s)>=0)return false;var o=i.x<a.x?i.x<s.x?i.x:s.x:a.x<s.x?a.x:s.x,l=i.y<a.y?i.y<s.y?i.y:s.y:a.y<s.y?a.y:s.y,u=i.x>a.x?i.x>s.x?i.x:s.x:a.x>s.x?a.x:s.x,c=i.y>a.y?i.y>s.y?i.y:s.y:a.y>s.y?a.y:s.y;var h=C(o,l,t,n,r),f=C(u,c,t,n,r);var d=e.prevZ,p=e.nextZ;while(d&&d.z>=h&&p&&p.z<=f){if(d!==e.prev&&d!==e.next&&x(i.x,i.y,a.x,a.y,s.x,s.y,d.x,d.y)&&T(d.prev,d,d.next)>=0)return false;d=d.prevZ;if(p!==e.prev&&p!==e.next&&x(i.x,i.y,a.x,a.y,s.x,s.y,p.x,p.y)&&T(p.prev,p,p.next)>=0)return false;p=p.nextZ}while(d&&d.z>=h){if(d!==e.prev&&d!==e.next&&x(i.x,i.y,a.x,a.y,s.x,s.y,d.x,d.y)&&T(d.prev,d,d.next)>=0)return false;d=d.prevZ}while(p&&p.z<=f){if(p!==e.prev&&p!==e.next&&x(i.x,i.y,a.x,a.y,s.x,s.y,p.x,p.y)&&T(p.prev,p,p.next)>=0)return false;p=p.nextZ}return true}function d(e,t,n){var r=e;do{var i=r.prev,a=r.next.next;if(!o(i,a)&&l(i,r,r.next,a)&&B(i,a)&&B(a,i)){t.push(i.i/n);t.push(r.i/n);t.push(a.i/n);M(r);M(r.next);r=e=a}r=r.next}while(r!==e);return c(r)}function p(e,t,n,r,i,a){var s=e;do{var o=s.next.next;while(o!==s.prev){if(s.i!==o.i&&u(s,o)){var l=D(s,o);s=c(s,s.next);l=c(l,l.next);m(s,t,n,r,i,a);m(l,t,n,r,i,a);return}o=o.next}s=s.next}while(s!==e)}function v(e,t,n,r){var i=[],a,s,o,l,u;for(a=0,s=t.length;a<s;a++){o=t[a]*r;l=a<s-1?t[a+1]*r:e.length;u=g(e,o,l,r,false);if(u===u.next)u.steiner=true;i.push(A(u))}i.sort(b);for(a=0;a<i.length;a++){n=_(i[a],n);n=c(n,n.next)}return n}function b(e,t){return e.x-t.x}function _(e,t){var n=a(e,t);if(!n){return t}var r=D(n,e);var i=c(n,n.next);c(r,r.next);return t===n?i:t}function a(e,t){var n=t,r=e.x,i=e.y,a=-Infinity,s;do{if(i<=n.y&&i>=n.next.y&&n.next.y!==n.y){var o=n.x+(i-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(o<=r&&o>a){a=o;if(o===r){if(i===n.y)return n;if(i===n.next.y)return n.next}s=n.x<n.next.x?n:n.next}}n=n.next}while(n!==t);if(!s)return null;if(r===a)return s;var l=s,u=s.x,c=s.y,h=Infinity,f;n=s;do{if(r>=n.x&&n.x>=u&&r!==n.x&&x(i<c?r:a,i,u,c,i<c?a:r,i,n.x,n.y)){f=Math.abs(i-n.y)/(r-n.x);if(B(n,e)&&(f<h||f===h&&(n.x>s.x||n.x===s.x&&E(s,n)))){s=n;h=f}}n=n.next}while(n!==l);return s}function E(e,t){return T(e.prev,e,t.prev)<0&&T(t.next,e,e.next)<0}function F(e,t,n,r){var i=e;do{if(i.z===null)i.z=C(i.x,i.y,t,n,r);i.prevZ=i.prev;i.nextZ=i.next;i=i.next}while(i!==e);i.prevZ.nextZ=null;i.prevZ=null;s(i)}function s(e){var t,n,r,i,a,s,o,l,u=1;do{n=e;e=null;a=null;s=0;while(n){s++;r=n;o=0;for(t=0;t<u;t++){o++;r=r.nextZ;if(!r)break}l=u;while(o>0||l>0&&r){if(o!==0&&(l===0||!r||n.z<=r.z)){i=n;n=n.nextZ;o--}else{i=r;r=r.nextZ;l--}if(a)a.nextZ=i;else e=i;i.prevZ=a;a=i}n=r}a.nextZ=null;u*=2}while(s>1);return e}function C(e,t,n,r,i){e=32767*(e-n)*i;t=32767*(t-r)*i;e=(e|e<<8)&16711935;e=(e|e<<4)&252645135;e=(e|e<<2)&858993459;e=(e|e<<1)&1431655765;t=(t|t<<8)&16711935;t=(t|t<<4)&252645135;t=(t|t<<2)&858993459;t=(t|t<<1)&1431655765;return e|t<<1}function A(e){var t=e,n=e;do{if(t.x<n.x||t.x===n.x&&t.y<n.y)n=t;t=t.next}while(t!==e);return n}function x(e,t,n,r,i,a,s,o){return(i-s)*(t-o)-(e-s)*(a-o)>=0&&(e-s)*(r-o)-(n-s)*(t-o)>=0&&(n-s)*(a-o)-(i-s)*(r-o)>=0}function u(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!i(e,t)&&(B(e,t)&&B(t,e)&&O(e,t)&&(T(e.prev,e,t.prev)||T(e,t.prev,t))||o(e,t)&&T(e.prev,e,e.next)>0&&T(t.prev,t,t.next)>0)}function T(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function o(e,t){return e.x===t.x&&e.y===t.y}function l(e,t,n,r){var i=y(T(e,t,n));var a=y(T(e,t,r));var s=y(T(n,r,e));var o=y(T(n,r,t));if(i!==a&&s!==o)return true;if(i===0&&S(e,n,t))return true;if(a===0&&S(e,r,t))return true;if(s===0&&S(n,e,r))return true;if(o===0&&S(n,t,r))return true;return false}function S(e,t,n){return t.x<=Math.max(e.x,n.x)&&t.x>=Math.min(e.x,n.x)&&t.y<=Math.max(e.y,n.y)&&t.y>=Math.min(e.y,n.y)}function y(e){return e>0?1:e<0?-1:0}function i(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&l(n,n.next,e,t))return true;n=n.next}while(n!==e);return false}function B(e,t){return T(e.prev,e,e.next)<0?T(e,t,e.next)>=0&&T(e,e.prev,t)>=0:T(e,t,e.prev)<0||T(e,e.next,t)<0}function O(e,t){var n=e,r=false,i=(e.x+t.x)/2,a=(e.y+t.y)/2;do{if(n.y>a!==n.next.y>a&&n.next.y!==n.y&&i<(n.next.x-n.x)*(a-n.y)/(n.next.y-n.y)+n.x)r=!r;n=n.next}while(n!==e);return r}function D(e,t){var n=new L(e.i,e.x,e.y),r=new L(t.i,t.x,t.y),i=e.next,a=t.prev;e.next=t;t.prev=e;n.next=i;i.prev=n;r.next=n;n.prev=r;a.next=r;r.prev=a;return r}function I(e,t,n,r){var i=new L(e,t,n);if(!r){i.prev=i;i.next=i}else{i.next=r.next;i.prev=r;r.next.prev=i;r.next=i}return i}function M(e){e.next.prev=e.prev;e.prev.next=e.next;if(e.prevZ)e.prevZ.nextZ=e.nextZ;if(e.nextZ)e.nextZ.prevZ=e.prevZ}function L(e,t,n){this.i=e;this.x=t;this.y=n;this.prev=null;this.next=null;this.z=null;this.prevZ=null;this.nextZ=null;this.steiner=false}r.deviation=function(e,t,n,r){var i=t&&t.length;var a=i?t[0]*n:e.length;var s=Math.abs(R(e,0,a,n));if(i){for(var o=0,l=t.length;o<l;o++){var u=t[o]*n;var c=o<l-1?t[o+1]*n:e.length;s-=Math.abs(R(e,u,c,n))}}var h=0;for(o=0;o<r.length;o+=3){var f=r[o]*n;var d=r[o+1]*n;var p=r[o+2]*n;h+=Math.abs((e[f]-e[p])*(e[d+1]-e[f+1])-(e[f]-e[d])*(e[p+1]-e[f+1]))}return s===0&&h===0?0:Math.abs((h-s)/s)};function R(e,t,n,r){var i=0;for(var a=t,s=n-r;a<n;a+=r){i+=(e[s]-e[a])*(e[a+1]+e[s+1]);s=a}return i}r.flatten=function(e){var t=e[0][0].length,n={vertices:[],holes:[],dimensions:t},r=0;for(var i=0;i<e.length;i++){for(var a=0;a<e[i].length;a++){for(var s=0;s<t;s++)n.vertices.push(e[i][a][s])}if(i>0){r+=e[i-1].length;n.holes.push(r)}}return n}},{}]},{},[1])(1)});(()=>{var r={};(()=>{r.d=(e,t)=>{for(var n in t){if(r.o(t,n)&&!r.o(e,n)){Object.defineProperty(e,n,{enumerable:true,get:t[n]})}}}})();(()=>{r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t)})();(()=>{r.r=e=>{if(typeof Symbol!=="undefined"&&Symbol.toStringTag){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}Object.defineProperty(e,"__esModule",{value:true})}})();var n={};(()=>{"use strict";r.r(n);r.d(n,{VarGetOpWrapper:()=>t,VarSetOpWrapper:()=>e});const s=CABLES;class e{constructor(t,e,n,r,i,a){this._valuePort=n;this._varNamePort=r;this._op=t;this._type=e;this._typeId=-1;this._triggerPort=i;this._nextPort=a;this._var=null;this._btnCreate=t.inTriggerButton("Create new variable");this._btnCreate.setUiAttribs({hidePort:true});this._btnCreate.onTriggered=this._createVar.bind(this);this._helper=t.inUiTriggerButtons("",["Rename"]);this._helper.setUiAttribs({hidePort:true});this._helper.onTriggered=e=>{if(e=="Rename")CABLES.CMD.PATCH.renameVariable(t.varName.get())};this._op.setPortGroup("Variable",[this._helper,this._varNamePort,this._btnCreate]);r.setUiAttribs({_variableSelect:true});this._op.on("uiParamPanel",this._updateVarNamesDropdown.bind(this));this._op.patch.addEventListener("variablesChanged",this._updateName.bind(this));this._op.patch.addEventListener("variableRename",this._renameVar.bind(this));this._varNamePort.onChange=this._updateName.bind(this);this._isTexture=this._valuePort.uiAttribs.objType==="texture";this._valuePort.changeAlways=true;if(this._triggerPort){this._triggerPort.onTriggered=()=>{this._setVarValue(true)}}else{this._valuePort.onChange=this._setVarValue.bind(this)}this._op.init=()=>{this._updateName();if(!this._triggerPort)this._setVarValue();this._updateErrorUi()};if(e=="array")this._typeId=s.Port.TYPE_ARRAY;else if(e=="object")this._typeId=s.Port.TYPE_OBJECT;else if(e=="string")this._typeId=s.Port.TYPE_STRING;else if(e=="texture")this._typeId=s.Port.TYPE_TEXTURE;else this._typeId=s.Port.TYPE_VALUE}_updateErrorUi(){if(CABLES.UI){if(!this._varNamePort.get())this._op.setUiError("novarname","no variable selected");else{if(this._op.hasUiErrors)this._op.setUiError("novarname",null)}}}_updateName(){this._var=null;const e=this._varNamePort.get();this._op.setTitle("var set");this._op.setUiAttrib({extendTitle:"#"+e});this._updateErrorUi();const t=this._op.patch.getVar(e);if(t&&!t.type)t.type=this._type;if(!this._op.patch.hasVar(e)&&e!=0&&!this._triggerPort){this._setVarValue()}if(!this._op.patch.hasVar(e)&&e!=0&&this._triggerPort){if(this._type=="string")this._op.patch.setVarValue(e,"");else if(this._type=="number")this._op.patch.setVarValue(e,"");else this._op.patch.setVarValue(e,null)}if(this._op.isCurrentUiOp()){this._updateVarNamesDropdown();this._op.refreshParams()}this._updateDisplay();this._op.patch.emitEvent("opVariableNameChanged",this._op,this._varNamePort.get())}_createVar(){CABLES.CMD.PATCH.createVariable(this._op,this._type,()=>{this._updateName()})}_updateDisplay(){this._valuePort.setUiAttribs({greyout:!this._varNamePort.get()})}_updateVarNamesDropdown(){if(CABLES.UI&&CABLES.UI.loaded&&CABLES.UI.loaded){const e=gui.uiProfiler.start("[vars] _updateVarNamesDropdown");const t=[];const n=this._op.patch.getVars();for(const e in n)if(n[e].type==this._type&&e!="0")t.push(e);this._varNamePort.uiAttribs.values=t;e.finish()}}_renameVar(e,t){if(e!=this._varNamePort.get())return;this._varNamePort.set(t);this._updateName()}_setVarValue(e){const t=this._valuePort.get();if(!this._var){const n=this._varNamePort.get();if(!n)return;this._op.patch.setVarValue(n,t);this._var=this._op.patch.getVar(n)}if(this._typeId==s.Port.TYPE_VALUE||this._typeId==s.Port.TYPE_STRING){this._var.setValue(t)}else if(this._typeId==s.Port.TYPE_ARRAY){this._arr=[];s.utils.copyArray(t,this._arr);this._var.setValue(this._arr)}else{if(this._typeId==s.Port.TYPE_OBJECT){if(this._isTexture)this._var.setValue(CGL.Texture.getEmptyTexture(this._op.patch.cgl));else this._var.setValue(null);if(t&&t.tex&&t._cgl&&!this._isTexture)this._op.setUiError("texobj","Dont use object variables for textures, use varSetTexture");else this._op.setUiError("texobj",null)}this._var.setValue(t)}if(e&&this._nextPort)this._nextPort.trigger()}}class t{constructor(e,t,n,r){this._op=e;this._type=t;this._varnamePort=n;this._variable=null;this._valueOutPort=r;this._listenerId=null;this._typeId=0;if(t=="array")this._typeId=s.Port.TYPE_ARRAY;else if(t=="object")this._typeId=s.Port.TYPE_OBJECT;else if(t=="texture")this._typeId=s.Port.TYPE_TEXTURE;else if(t=="string")this._typeId=s.Port.TYPE_STRING;else this._typeId=s.Port.TYPE_VALUE;if(r)this._isTexture=r.uiAttribs.objType==="texture";this._op.on("uiParamPanel",this._updateVarNamesDropdown.bind(this));this._op.on("uiErrorChange",this._updateTitle.bind(this));this._op.patch.on("variableRename",this._renameVar.bind(this));this._op.patch.on("variableDeleted",e=>{if(this._op.isCurrentUiOp())this._op.refreshParams()});n.setUiAttribs({_variableSelect:true});n.setUiAttribs({_variableSelectGet:true});this._varnamePort.onChange=this._changeVar.bind(this);this._op.patch.addEventListener("variablesChanged",this._init.bind(this));this._op.onDelete=()=>{if(this._variable&&this._listenerId)this._variable.off(this._listenerId)};this._op.init=()=>{this._init()}}get variable(){return this._variable}_changeVar(){if(this._variable&&this._listenerId){this._variable.off(this._listenerId)}this._init()}_renameVar(e,t){if(e!=this._varnamePort.get())return;this._varnamePort.set(t);this._updateVarNamesDropdown();this._updateTitle();this._listenerId=this._variable.on("change",this._setValueOut.bind(this))}_updateVarNamesDropdown(){if(CABLES.UI&&CABLES.UI.loaded){const t=[];const n=this._op.patch.getVars();for(const e in n)if(n[e].type==this._type&&e!="0")t.push(e);this._op.varName.uiAttribs.values=t}}_setValueOut(e){if(this._valueOutPort)if(this._typeId==s.Port.TYPE_NUMBER||this._typeId==s.Port.TYPE_STRING)this._valueOutPort.set(e);else if(this._typeId==s.Port.TYPE_ARRAY||this._typeId==s.Port.TYPE_OBJECT||this._isTexture)this._valueOutPort.setRef(e);else console.log("unkown type?")}_updateTitle(){if(this._variable){this._op.setUiError("unknownvar",null);this._op.setTitle("var get");this._op.setUiAttrib({extendTitle:"#"+this._varnamePort.get()});if(this._valueOutPort)this._setValueOut(this._variable.getValue())}else{this._op.setUiError("unknownvar","unknown variable! - there is no setVariable with this name ("+this._varnamePort.get()+")");this._op.setUiAttrib({extendTitle:"#invalid"});if(this._valueOutPort)this._setValueOut(0)}}_init(){this._updateVarNamesDropdown();if(this._variable&&this._listenerId)this._variable.off(this._listenerId);this._variable=this._op.patch.getVar(this._op.varName.get());if(this._variable)this._listenerId=this._variable.on("change",this._setValueOut.bind(this));this._updateTitle();this._op.patch.emitEvent("opVariableNameChanged",this._op,this._varnamePort.get())}}})();var e=CABLES=typeof CABLES==="undefined"?{}:CABLES;for(var t in n)e[t]=n[t];if(n.__esModule)Object.defineProperty(e,"__esModule",{value:true})})();(()=>{var r={};(()=>{r.d=(e,t)=>{for(var n in t){if(r.o(t,n)&&!r.o(e,n)){Object.defineProperty(e,n,{enumerable:true,get:t[n]})}}}})();(()=>{r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t)})();(()=>{r.r=e=>{if(typeof Symbol!=="undefined"&&Symbol.toStringTag){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}Object.defineProperty(e,"__esModule",{value:true})}})();var t={};(()=>{"use strict";r.r(t);r.d(t,{InterActionNeededButton:()=>e});class e{constructor(){this.patch=null;this.fsElement=null;this.callbacks={}}add(e,t,n){this.patch=e;this.callbacks[t]=n;this.show()}remove(e){delete this.callbacks[e];if(Object.keys(this.callbacks).length==0){if(this.fsElement)this.fsElement.remove();this.fsElement=null}}show(){if(!this.fsElement){this.fsElement=document.createElement("div");const e=this.patch.cgl.canvas.parentElement;if(e)e.appendChild(this.fsElement);this.fsElement.addEventListener("pointerdown",e=>{for(const e in this.callbacks)this.callbacks[e]()})}this.fsElement.style.padding="10px";this.fsElement.style.position="absolute";this.fsElement.style.right="20px";this.fsElement.style.bottom="20px";this.fsElement.style.width="24px";this.fsElement.style.height="24px";this.fsElement.style.cursor="pointer";this.fsElement.style["border-radius"]="40px";this.fsElement.style.background="#444";this.fsElement.style["z-index"]="9999";this.fsElement.style.display="block";this.fsElement.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather feather-volume-2"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon><path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"></path></svg>'}}CABLES.interActionNeededButton=CABLES.interActionNeededButton||new e})();var e=CABLES=typeof CABLES==="undefined"?{}:CABLES;for(var n in t)e[n]=t[n];if(t.__esModule)Object.defineProperty(e,"__esModule",{value:true})})();(()=>{var Q={};(()=>{Q.d=(e,t)=>{for(var n in t){if(Q.o(t,n)&&!Q.o(e,n)){Object.defineProperty(e,n,{enumerable:true,get:t[n]})}}}})();(()=>{Q.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t)})();(()=>{Q.r=e=>{if(typeof Symbol!=="undefined"&&Symbol.toStringTag){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}Object.defineProperty(e,"__esModule",{value:true})}})();var K={};(()=>{"use strict";Q.r(K);Q.d(K,{CopyTexture:()=>J});const C=CABLES;const c=CABLES.SHARED;const t=8;class n{constructor(e={}){this.id=C.utils.uuid();this.width=0;this.height=0;this.name="unknown";e=e||{};this.pixelFormat=e.pixelFormat||n.PFORMATSTR_RGBA8UB;this.name=e.name||"unknown";if(!e.width)e.width=t;if(!e.height)e.height=t}}n.getDefaultTextureData=(e,a,s={})=>{if(e=="empty"){return new Uint8Array(a*a*4).fill(0)}else if(e=="color"){const i=new Uint8Array(a*a*4);let t=s.r||1;let n=s.g||1;let r=s.b||1;for(let e=0;e<a*a;e++){i[e*4+0]=t;i[e*4+1]=n;i[e*4+2]=r;i[e*4+3]=255}return i}else if(e=="randomUInt"){const i=new Uint8Array(a*a*4);for(let e=0;e<a*a;e++){i[e*4+0]=Math.random()*255;i[e*4+1]=Math.random()*255;i[e*4+2]=Math.random()*255;i[e*4+3]=255}return i}else if(e=="random"||e=="randomFloat"){const i=new Float32Array(a*a*4);for(let e=0;e<a*a;e++){i[e*4+0]=(Math.random()-.5)*2;i[e*4+1]=(Math.random()-.5)*2;i[e*4+2]=(Math.random()-.5)*2;i[e*4+3]=1}return i}else if(e=="stripes"){const o=[];let n=s.r;let r=s.g;let i=s.b;if(n===undefined)n=1;if(r===undefined)r=1;if(i===undefined)i=1;for(let t=0;t<a;t++){for(let e=0;e<a;e++){if((e+t)%64<32){o.push((200+t/a*25+e/a*25)*n);o.push((200+t/a*25+e/a*25)*r);o.push((200+t/a*25+e/a*25)*i)}else{o.push((40+t/a*25+e/a*25)*n);o.push((40+t/a*25+e/a*25)*r);o.push((40+t/a*25+e/a*25)*i)}o.push(255)}}return new Uint8Array(o)}else{console.warn("unknown default texture",e);return n.getDefaultTextureData("stripes",a,{r:1,g:0,b:0})}};n.FILTER_NEAREST=0;n.FILTER_LINEAR=1;n.FILTER_MIPMAP=2;n.WRAP_REPEAT=0;n.WRAP_MIRRORED_REPEAT=1;n.WRAP_CLAMP_TO_EDGE=2;n.TYPE_DEFAULT=0;n.TYPE_DEPTH=1;n.TYPE_FLOAT=2;n.PFORMATSTR_RGB565="RGB 5/6/5bit ubyte";n.PFORMATSTR_R8UB="R 8bit ubyte";n.PFORMATSTR_RG8UB="RG 8bit ubyte";n.PFORMATSTR_RGB8UB="RGB 8bit ubyte";n.PFORMATSTR_RGBA8UB="RGBA 8bit ubyte";n.PFORMATSTR_SRGBA8="SRGBA 8bit ubyte";n.PFORMATSTR_R11FG11FB10F="RGB 11/11/10bit float";n.PFORMATSTR_R16F="R 16bit float";n.PFORMATSTR_RG16F="RG 16bit float";n.PFORMATSTR_RGB16F="RGB 16bit float";n.PFORMATSTR_RGBA16F="RGBA 16bit float";n.PFORMATSTR_R32F="R 32bit float";n.PFORMATSTR_RG32F="RG 32bit float";n.PFORMATSTR_RGB32F="RGB 32bit float";n.PFORMATSTR_RGBA32F="RGBA 32bit float";n.PFORMATSTR_DEPTH="DEPTH";n.PIXELFORMATS=[n.PFORMATSTR_RGB565,n.PFORMATSTR_R8UB,n.PFORMATSTR_RG8UB,n.PFORMATSTR_RGB8UB,n.PFORMATSTR_RGBA8UB,n.PFORMATSTR_SRGBA8,n.PFORMATSTR_R11FG11FB10F,n.PFORMATSTR_R16F,n.PFORMATSTR_RG16F,n.PFORMATSTR_RGBA16F,n.PFORMATSTR_R32F,n.PFORMATSTR_RGBA32F];const r=8;const s=new c.Logger("cgl_texture");class u extends n{constructor(e,t={}){super(t);if(!e)throw new Error("no cgl");this._cgl=e;this._log=new c.Logger("tex");this.tex=this._cgl.gl.createTexture();this.loading=false;this.flip=true;this.flipped=false;this.shadowMap=false;this.deleted=false;this.image=null;this.anisotropic=0;this.filter=u.FILTER_NEAREST;this.wrap=u.WRAP_CLAMP_TO_EDGE;this.texTarget=this._cgl.gl.TEXTURE_2D;if(t&&t.type)this.texTarget=t.type;this.textureType=u.TYPE_DEFAULT;this.unpackAlpha=true;this._fromData=true;this._glDataType=-1;this._glInternalFormat=-1;this._glDataFormat=-1;if(t){if(t.isDepthTexture)this.textureType=u.TYPE_DEPTH;if(t.isFloatingPointTexture===true)this.textureType=u.TYPE_FLOAT;if("textureType"in t)this.textureType=t.textureType;if("filter"in t)this.filter=t.filter;if("wrap"in t)this.wrap=t.wrap;if("unpackAlpha"in t)this.unpackAlpha=t.unpackAlpha;if("flip"in t)this.flip=t.flip;if("shadowMap"in t)this.shadowMap=t.shadowMap;if("anisotropic"in t)this.anisotropic=t.anisotropic}else{t={}}if(!t.pixelFormat&&t.isFloatingPointTexture)this.pixelFormat=u.PFORMATSTR_RGBA32F;if(this.textureType==u.TYPE_DEPTH)this.pixelFormat=u.PFORMATSTR_DEPTH;this._cgl.profileData.profileTextureNew++;this.setFormat(u.setUpGlPixelFormat(this._cgl,this.pixelFormat));this._cgl.profileData.addHeavyEvent("texture created",this.name,t.width+"x"+t.height);this.setSize(t.width,t.height);this.getInfoOneLine()}isFloatingPoint(){return u.isPixelFormatFloat(this.pixelFormat)}compareSettings(e){if(!e)return false;return e.width==this.width&&e.height==this.height&&e.filter==this.filter&&e.wrap==this.wrap&&e.textureType==this.textureType&&e.unpackAlpha==this.unpackAlpha&&e.anisotropic==this.anisotropic&&e.shadowMap==this.shadowMap&&e.texTarget==this.texTarget&&e.flip==this.flip}clone(){const e=new u(this._cgl,{name:this.name,filter:this.filter,anisotropic:this.anisotropic,wrap:this.wrap,textureType:this.textureType,pixelFormat:this.pixelFormat,unpackAlpha:this.unpackAlpha,flip:this.flip,width:this.width,height:this.height});this._cgl.profileData.addHeavyEvent("texture created",this.name,this.width+"x"+this.height);if(!this.compareSettings(e)){this._log.error("Cloned texture settings do not compare!");this._log.error(this);this._log.error(e)}return e}setFormat(e){this.pixelFormat=e.pixelFormat;this._glDataFormat=e.glDataFormat;this._glInternalFormat=e.glInternalFormat;this._glDataType=e.glDataType}setSize(e,t){if(this._cgl.aborted)return;if(e!=e||e<=0||!e)e=r;if(t!=t||t<=0||!t)t=r;if(e>this._cgl.maxTexSize||t>this._cgl.maxTexSize)this._log.error("texture size too big! "+e+"x"+t+" / max: "+this._cgl.maxTexSize);e=Math.min(e,this._cgl.maxTexSize);t=Math.min(t,this._cgl.maxTexSize);e=Math.floor(e);t=Math.floor(t);if(this.width==e&&this.height==t)return;e=this._cgl.checkTextureSize(e);t=this._cgl.checkTextureSize(t);this.width=e;this.height=t;this.deleted=false;this.setFormat(u.setUpGlPixelFormat(this._cgl,this.pixelFormat));this.shortInfoString=this.getInfoOneLine();this._cgl.gl.bindTexture(this.texTarget,this.tex);this._cgl.profileData.profileTextureResize++;const n=null;this._cgl.gl.texImage2D(this.texTarget,0,this._glInternalFormat,e,t,0,this._glDataFormat,this._glDataType,n);this._setFilter();this.updateMipMap();this._cgl.gl.bindTexture(this.texTarget,null)}initFromData(e,t,n,r,i){this.filter=r;this.wrap=i;if(r==undefined)this.filter=u.FILTER_LINEAR;if(i==undefined)this.wrap=u.WRAP_CLAMP_TO_EDGE;this.width=t;this.height=n;this._fromData=true;this.deleted=false;if(this.height>this._cgl.maxTexSize||this.width>this._cgl.maxTexSize){const a=CGL.Texture.getTempTexture(this._cgl);this.width=a.width;this.height=a.height;this.tex=a.tex;this._log.warn("[cgl_texture] texture size too big!",this.width,this.height,this._cgl.maxTexSize);return}if(this.flip)this._cgl.gl.pixelStorei(this._cgl.gl.UNPACK_FLIP_Y_WEBGL,this.flip);this._cgl.gl.bindTexture(this.texTarget,this.tex);this.setFormat(u.setUpGlPixelFormat(this._cgl,this.pixelFormat));this._cgl.gl.texImage2D(this.texTarget,0,this._glInternalFormat,t,n,0,this._glDataFormat,this._glDataType,e);this._setFilter();this.updateMipMap();if(this.flip)this._cgl.gl.pixelStorei(this._cgl.gl.UNPACK_FLIP_Y_WEBGL,false);this._cgl.gl.bindTexture(this.texTarget,null)}updateMipMap(){if((this._cgl.glVersion==2||this.isPowerOfTwo())&&this.filter==u.FILTER_MIPMAP){this._cgl.gl.generateMipmap(this.texTarget);this._cgl.profileData.profileGenMipMap++}}initTexture(e,t=null){this._cgl.printError("before initTexture");this._cgl.checkFrameStarted("texture inittexture");this._fromData=false;this._cgl.gl.pixelStorei(this._cgl.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL,this.unpackAlpha);if(e.width||e.videoWidth)this.width=e.videoWidth||e.width;if(e.height||e.videoHeight)this.height=e.videoHeight||e.height;if(t!==null)this.filter=t;if(e.height>this._cgl.maxTexSize||e.width>this._cgl.maxTexSize){const n=CGL.Texture.getTempTexture(this._cgl);this.width=n.width;this.height=n.height;this.tex=n.tex;this._log.warn("[cgl_texture] texture size too big!",e.width,e.height,this._cgl.maxTexSize);return}this._cgl.gl.bindTexture(this.texTarget,this.tex);this.deleted=false;this.flipped=!this.flip;if(this.flipped)this._cgl.gl.pixelStorei(this._cgl.gl.UNPACK_FLIP_Y_WEBGL,this.flipped);this.setFormat(u.setUpGlPixelFormat(this._cgl,this.pixelFormat));this._cgl.gl.texImage2D(this.texTarget,0,this._glInternalFormat,this._glDataFormat,this._glDataType,e);this._setFilter();this.updateMipMap();this._cgl.gl.bindTexture(this.texTarget,null);this._cgl.gl.pixelStorei(this._cgl.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL,false);if(this.flipped)this._cgl.gl.pixelStorei(this._cgl.gl.UNPACK_FLIP_Y_WEBGL,false);this.getInfoOneLine();this._cgl.printError("initTexture")}dispose(){this.delete()}delete(){if(this.loading){return}this.deleted=true;this.width=0;this.height=0;this._cgl.profileData.profileTextureDelete++;this._cgl.gl.deleteTexture(this.tex);this.image=null;this.tex=null}isPowerOfTwo(){return u.isPowerOfTwo(this.width)&&u.isPowerOfTwo(this.height)}printInfo(){s.log(this.getInfo())}getInfoReadable(){const t=this.getInfo();let n="";t.name=t.name.substr(0,t.name.indexOf("?rnd="));for(const e in t){n+="* "+e+":  **"+t[e]+"**\n"}return n}getInfoOneLine(){let e=""+this.width+"x"+this.height;e+=" ";e+=this.pixelFormat;if(this.filter===u.FILTER_NEAREST)e+=" nearest";if(this.filter===u.FILTER_LINEAR)e+=" linear";if(this.filter===u.FILTER_MIPMAP)e+=" mipmap";if(this.wrap===u.WRAP_CLAMP_TO_EDGE)e+=" clamp";if(this.wrap===u.WRAP_REPEAT)e+=" repeat";if(this.wrap===u.WRAP_MIRRORED_REPEAT)e+=" repeatmir";this.shortInfoString=e;return e}getInfoOneLineShort(){let e=""+this.width+"x"+this.height;e+=" ";e+=this.pixelFormat;this.shortInfoString=e;return e}getInfo(){return u.getTexInfo(this)}_setFilter(){this._cgl.printError("before _setFilter");if(!this._fromData){this._cgl.gl.pixelStorei(this._cgl.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL,this.unpackAlpha)}if(this.shadowMap){this._cgl.gl.texParameteri(this._cgl.gl.TEXTURE_2D,this._cgl.gl.TEXTURE_COMPARE_MODE,this._cgl.gl.COMPARE_REF_TO_TEXTURE);this._cgl.gl.texParameteri(this._cgl.gl.TEXTURE_2D,this._cgl.gl.TEXTURE_COMPARE_FUNC,this._cgl.gl.LEQUAL)}if(this.textureType==u.TYPE_FLOAT&&this.filter==u.FILTER_MIPMAP){this.filter=u.FILTER_LINEAR;this._log.stack("texture: HDR and mipmap filtering at the same time is not possible")}if(this._cgl.glVersion==1&&!this.isPowerOfTwo()){this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_MAG_FILTER,this._cgl.gl.NEAREST);this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_MIN_FILTER,this._cgl.gl.NEAREST);this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_WRAP_S,this._cgl.gl.CLAMP_TO_EDGE);this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_WRAP_T,this._cgl.gl.CLAMP_TO_EDGE);this.filter=u.FILTER_NEAREST;this.wrap=u.WRAP_CLAMP_TO_EDGE}else{if(this.wrap==u.WRAP_CLAMP_TO_EDGE){this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_WRAP_S,this._cgl.gl.CLAMP_TO_EDGE);this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_WRAP_T,this._cgl.gl.CLAMP_TO_EDGE)}else if(this.wrap==u.WRAP_REPEAT){this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_WRAP_S,this._cgl.gl.REPEAT);this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_WRAP_T,this._cgl.gl.REPEAT)}else if(this.wrap==u.WRAP_MIRRORED_REPEAT){this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_WRAP_S,this._cgl.gl.MIRRORED_REPEAT);this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_WRAP_T,this._cgl.gl.MIRRORED_REPEAT)}if(this.filter==u.FILTER_NEAREST){this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_MAG_FILTER,this._cgl.gl.NEAREST);this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_MIN_FILTER,this._cgl.gl.NEAREST)}else if(this.filter==u.FILTER_LINEAR){this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_MIN_FILTER,this._cgl.gl.LINEAR);this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_MAG_FILTER,this._cgl.gl.LINEAR)}else if(this.filter==u.FILTER_MIPMAP){this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_MAG_FILTER,this._cgl.gl.LINEAR);this._cgl.gl.texParameteri(this.texTarget,this._cgl.gl.TEXTURE_MIN_FILTER,this._cgl.gl.LINEAR_MIPMAP_LINEAR)}else{this._log.log("unknown texture filter!",this.filter);throw new Error("unknown texture filter!"+this.filter)}if(this.anisotropic){const e=this._cgl.enableExtension("EXT_texture_filter_anisotropic");if(this._cgl.maxAnisotropic){const t=Math.min(this._cgl.maxAnisotropic,this.anisotropic);this._cgl.gl.texParameterf(this._cgl.gl.TEXTURE_2D,e.TEXTURE_MAX_ANISOTROPY_EXT,t)}}}this.getInfoOneLine();this._cgl.printError("_setFilter")}}u.load=function(n,r,i,e){if(!r)return i({error:true});let a=null;if(!n.patch.loading.existByName(r))a=n.patch.loading.start("cgl.texture",r);const s=new u(n);s.name=r;s.image=new Image;s.image.crossOrigin="anonymous";s.loading=true;if(e&&e.hasOwnProperty("filter"))s.filter=e.filter;if(e&&e.hasOwnProperty("flip"))s.flip=e.flip;if(e&&e.hasOwnProperty("wrap"))s.wrap=e.wrap;if(e&&e.hasOwnProperty("anisotropic"))s.anisotropic=e.anisotropic;if(e&&e.hasOwnProperty("unpackAlpha"))s.unpackAlpha=e.unpackAlpha;if(e&&e.hasOwnProperty("pixelFormat"))s.pixelFormat=e.pixelFormat;s.image.onabort=s.image.onerror=e=>{console.warn("[cgl.texture.load] error loading texture",r,e);s.loading=false;if(a)n.patch.loading.finished(a);const t={error:true};if(i)i(t,s)};s.image.onload=function(e){n.addNextFrameOnceCallback(()=>{s.initTexture(s.image);if(a)n.patch.loading.finished(a);s.loading=false;if(i)i(null,s)})};s.image.src=r;return s};u.getTempTexture=function(e){if(!e)console.error("[getTempTexture] no cgl!");if(!e.tempTexture)e.tempTexture=u.getTemporaryTexture(e,256,u.FILTER_LINEAR,u.REPEAT);return e.tempTexture};u.getErrorTexture=function(e){if(!e)console.error("[getTempTexture] no cgl!");if(!e.errorTexture)e.errorTexture=u.getTemporaryTexture(e,256,u.FILTER_LINEAR,u.REPEAT,1,.2,.2);return e.errorTexture};u.getEmptyTexture=function(e,t){if(t)return u.getEmptyTextureFloat(e);if(!e)console.error("[getEmptyTexture] no cgl!");if(e.tempTextureEmpty)return e.tempTextureEmpty;let n=8;e.tempTextureEmpty=new u(e,{name:"emptyTexture"});const r=u.getDefaultTextureData("empty",n);e.tempTextureEmpty.initFromData(r,n,n,u.FILTER_NEAREST,u.WRAP_REPEAT);return e.tempTextureEmpty};u.getEmptyTextureFloat=function(e){if(!e)console.error("[getEmptyTextureFloat] no cgl!");if(e.tempTextureEmptyFloat)return e.tempTextureEmptyFloat;e.tempTextureEmptyFloat=new u(e,{name:"emptyTexture",isFloatingPointTexture:true});const t=new Float32Array(8*8*4).fill(1);for(let e=0;e<8*8*4;e+=4)t[e+3]=0;e.tempTextureEmptyFloat.initFromData(t,8,8,u.FILTER_NEAREST,u.WRAP_REPEAT);return e.tempTextureEmptyFloat};u.getRandomTexture=function(e){if(!e)console.error("[getRandomTexture] no cgl!");if(e.randomTexture)return e.randomTexture;const t=256;const n=u.getDefaultTextureData("randomUInt",t);e.randomTexture=new u(e);e.randomTexture.initFromData(n,t,t,u.FILTER_NEAREST,u.WRAP_REPEAT);return e.randomTexture};u.getRandomFloatTexture=function(e){if(!e)console.error("[getRandomTexture] no cgl!");if(e.getRandomFloatTexture)return e.getRandomFloatTexture;const t=256;const n=u.getDefaultTextureData("randomFloat",t);e.getRandomFloatTexture=new u(e,{isFloatingPointTexture:true});e.getRandomFloatTexture.initFromData(n,t,t,u.FILTER_NEAREST,u.WRAP_REPEAT);return e.getRandomFloatTexture};u.getBlackTexture=function(e){if(e.blackTexture)return e.blackTexture;const t=8;const n=u.getDefaultTextureData("color",t,{r:0,g:0,b:0});e.blackTexture=new u(e);e.blackTexture.initFromData(n,t,t,u.FILTER_NEAREST,u.WRAP_REPEAT);return e.blackTexture};u.getEmptyCubemapTexture=function(t){const n=[t.gl.TEXTURE_CUBE_MAP_POSITIVE_X,t.gl.TEXTURE_CUBE_MAP_NEGATIVE_X,t.gl.TEXTURE_CUBE_MAP_POSITIVE_Y,t.gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,t.gl.TEXTURE_CUBE_MAP_POSITIVE_Z,t.gl.TEXTURE_CUBE_MAP_NEGATIVE_Z];const e=t.gl.createTexture();const r=t.gl.TEXTURE_CUBE_MAP;const i=u.FILTER_NEAREST;const a=u.WRAP_CLAMP_TO_EDGE;const s=8;const o=8;t.profileData.profileTextureNew++;t.gl.bindTexture(r,e);t.profileData.profileTextureResize++;for(let e=0;e<6;e+=1){const l=new Uint8Array(8*8*4);t.gl.texImage2D(n[e],0,t.gl.RGBA,8,8,0,t.gl.RGBA,t.gl.UNSIGNED_BYTE,l);t.gl.texParameteri(r,t.gl.TEXTURE_MAG_FILTER,t.gl.NEAREST);t.gl.texParameteri(r,t.gl.TEXTURE_MIN_FILTER,t.gl.NEAREST);t.gl.texParameteri(r,t.gl.TEXTURE_WRAP_S,t.gl.CLAMP_TO_EDGE);t.gl.texParameteri(r,t.gl.TEXTURE_WRAP_T,t.gl.CLAMP_TO_EDGE)}t.gl.bindTexture(r,null);return{id:C.utils.uuid(),tex:e,cubemap:e,width:s,height:o,filter:i,wrap:a,unpackAlpha:true,flip:true,_fromData:true,name:"emptyCubemapTexture",anisotropic:0}};u.getTempGradientTexture=function(e){if(!e)console.error("[getTempGradientTexture] no cgl!");return u.getTempTexture(e)};u.getTemporaryTexture=function(e,t,n,r,i,a,s){const o=u.getDefaultTextureData("stripes",256,{r:i,g:a,b:s});const l=new u(e);l.initFromData(o,t,t,n,r);return l};u.createFromImage=function(e,t,n){n=n||{};const r=new u(e,n);r.flip=false;r.image=t;r.width=t.videoWidth||t.width||8;r.height=t.videoHeight||t.height||8;if(n.hasOwnProperty("wrap"))r.wrap=n.wrap;r.initTexture(t,n.filter);return r};u.fromImage=function(e,t,n,r){console.error("deprecated texture from image...");const i=new u(e);i.flip=false;if(n)i.filter=n;if(r)i.wrap=r;i.image=t;i.initTexture(t);return i};u.isPowerOfTwo=function(e){return e==1||e==2||e==4||e==8||e==16||e==32||e==64||e==128||e==256||e==512||e==1024||e==2048||e==4096||e==8192||e==16384};u.getTexInfo=function(e){const t={};t.name=e.name;t["power of two"]=e.isPowerOfTwo();t.size=e.width+" x "+e.height;let n=e.texTarget;if(e.texTarget==e._cgl.gl.TEXTURE_2D)n="TEXTURE_2D";t.target=n;t.unpackAlpha=e.unpackAlpha;if(e.cubemap)t.cubemap=true;if(e.textureType==u.TYPE_FLOAT)t.textureType="TYPE_FLOAT";if(e.textureType==u.TYPE_HALF_FLOAT)t.textureType="TYPE_HALF_FLOAT";else if(e.textureType==u.TYPE_DEPTH)t.textureType="TYPE_DEPTH";else if(e.textureType==u.TYPE_DEFAULT)t.textureType="TYPE_DEFAULT";else t.textureType="UNKNOWN "+this.textureType;if(e.wrap==u.WRAP_CLAMP_TO_EDGE)t.wrap="CLAMP_TO_EDGE";else if(e.wrap==u.WRAP_REPEAT)t.wrap="WRAP_REPEAT";else if(e.wrap==u.WRAP_MIRRORED_REPEAT)t.wrap="WRAP_MIRRORED_REPEAT";else t.wrap="UNKNOWN";if(e.filter==u.FILTER_NEAREST)t.filter="FILTER_NEAREST";else if(e.filter==u.FILTER_LINEAR)t.filter="FILTER_LINEAR";else if(e.filter==u.FILTER_MIPMAP)t.filter="FILTER_MIPMAP";else t.filter="UNKNOWN";t.pixelFormat=e.pixelFormat||"unknown";return t};u.setUpGlPixelFormat=function(e,t){const n={};if(!t){e._log.error("no pixelformatstr!");e._log.log(new Error);t=u.PFORMATSTR_RGBA8UB}n.pixelFormatBase=t;n.pixelFormat=t;n.glDataType=e.gl.UNSIGNED_BYTE;n.glInternalFormat=e.gl.RGBA8;n.glDataFormat=e.gl.RGBA;let r=e.gl.FLOAT;if(e.glUseHalfFloatTex){if(t==u.PFORMATSTR_RGBA32F)t=u.PFORMATSTR_RGBA16F;if(t==u.PFORMATSTR_RG32F)t=u.PFORMATSTR_RG16F;if(t==u.PFORMATSTR_R32F)t=u.PFORMATSTR_R16F}if(t.includes("16bit")){if(e.glVersion==2){const i=e.enableExtension("EXT_color_buffer_half_float");if(!i){console.warn("no 16bit extension, fallback to 32bit",t);if(t==u.PFORMATSTR_RGBA16F)t=u.PFORMATSTR_RGBA32F;if(t==u.PFORMATSTR_RGB16F)t=u.PFORMATSTR_RGB32F;if(t==u.PFORMATSTR_RG16F)t=u.PFORMATSTR_RG32F;if(t==u.PFORMATSTR_R16F)t=u.PFORMATSTR_R32F}else{r=e.gl.HALF_FLOAT}}}if(e.glVersion==1){n.glInternalFormat=e.gl.RGBA;if(t==u.PFORMATSTR_RGBA16F||t==u.PFORMATSTR_RG16F||t==u.PFORMATSTR_R16F){const a=e.enableExtension("OES_texture_half_float");if(!a)throw new Error("no half float texture extension");r=a.HALF_FLOAT_OES}}if(t==u.PFORMATSTR_RGBA8UB){}else if(t==u.PFORMATSTR_RGB565){n.glInternalFormat=e.gl.RGB565;n.glDataFormat=e.gl.RGB}else if(t==u.PFORMATSTR_R8UB){n.glInternalFormat=e.gl.R8;n.glDataFormat=e.gl.RED}else if(t==u.PFORMATSTR_RG8UB){n.glInternalFormat=e.gl.RG8;n.glDataFormat=e.gl.RG}else if(t==u.PFORMATSTR_RGB8UB){n.glInternalFormat=e.gl.RGB8;n.glDataFormat=e.gl.RGB}else if(t==u.PFORMATSTR_SRGBA8){n.glInternalFormat=e.gl.SRGB8_ALPHA8}else if(t==u.PFORMATSTR_R32F){n.glInternalFormat=e.gl.R32F;n.glDataFormat=e.gl.RED;n.glDataType=r}else if(t==u.PFORMATSTR_R16F){n.glInternalFormat=e.gl.R16F;n.glDataType=r;n.glDataFormat=e.gl.RED}else if(t==u.PFORMATSTR_RG16F){n.glInternalFormat=e.gl.RG16F;n.glDataType=r;n.glDataFormat=e.gl.RG}else if(t==u.PFORMATSTR_RGBA16F){if(e.glVersion==1)n.glInternalFormat=e.gl.RGBA;else n.glInternalFormat=e.gl.RGBA16F;n.glDataType=r}else if(t==u.PFORMATSTR_R11FG11FB10F){n.glInternalFormat=e.gl.R11F_G11F_B10F;n.glDataType=r;n.glDataFormat=e.gl.RGB}else if(t==u.PFORMATSTR_RGBA32F){if(e.glVersion==1)n.glInternalFormat=e.gl.RGBA;else n.glInternalFormat=e.gl.RGBA32F;n.glDataType=r}else if(t==u.PFORMATSTR_DEPTH){if(e.glVersion==1){n.glInternalFormat=e.gl.DEPTH_COMPONENT;n.glDataType=e.gl.UNSIGNED_SHORT;n.glDataFormat=e.gl.DEPTH_COMPONENT}else{n.glInternalFormat=e.gl.DEPTH_COMPONENT32F;n.glDataType=e.gl.FLOAT;n.glDataFormat=e.gl.DEPTH_COMPONENT}}else{s.log("unknown pixelformat ",t)}if(t.includes("32bit")||t==u.PFORMATSTR_R11FG11FB10F){if(e.glVersion==2)e.enableExtension("EXT_color_buffer_float");if(e.glVersion==2)e.enableExtension("EXT_float_blend");e.enableExtension("OES_texture_float_linear")}n.numColorChannels=u.getPixelFormatNumChannels(t);if(!n.glDataType||!n.glInternalFormat||!n.glDataFormat)s.log("pixelformat wrong ?!",t,n.glDataType,n.glInternalFormat,n.glDataFormat,this);return n};u.getPixelFormatNumChannels=e=>{if(e.startsWith("RGBA"))return 4;if(e.startsWith("RGB"))return 3;if(e.startsWith("RG"))return 2;return 1};u.isPixelFormatFloat=e=>{return(e||"").includes("float")};u.isPixelFormatHalfFloat=e=>{return(e||"").includes("float")&&(e||"").includes("16bit")};class e{constructor(t,e,n,r){this._log=new c.Logger("cgl_framebuffer2");if(t.glVersion==1)this._log.error("framebuffer2 used on webgl1");this.Framebuffer2DrawTargetsDefault=null;this.Framebuffer2BlittingFramebuffer=null;this.Framebuffer2FinalFramebuffer=null;this._cgl=t;this._cgl.printError("before framebuffer2 constructor");this._width=0;this._height=0;this.valid=true;this._depthRenderbuffer=null;this._frameBuffer=null;this._textureFrameBuffer=null;this._colorRenderbuffers=[];this._drawTargetArray=[];this._disposed=false;if(!this.Framebuffer2BlittingFramebuffer)this.Framebuffer2BlittingFramebuffer=t.gl.createFramebuffer();if(!this.Framebuffer2FinalFramebuffer)this.Framebuffer2FinalFramebuffer=t.gl.createFramebuffer();if(!this.Framebuffer2DrawTargetsDefault)this.Framebuffer2DrawTargetsDefault=[t.gl.COLOR_ATTACHMENT0];this._options=r||{isFloatingPointTexture:false};this.name=this._options.name||"unknown";this._cgl.profileData.addHeavyEvent("framebuffer create",this.name);if(!this._options.hasOwnProperty("numRenderBuffers"))this._options.numRenderBuffers=1;if(!this._options.hasOwnProperty("depth"))this._options.depth=true;if(!this._options.hasOwnProperty("clear"))this._options.clear=true;if(!this._options.hasOwnProperty("multisampling")){this._options.multisampling=false;this._options.multisamplingSamples=0}if(this._options.multisamplingSamples){if(this._cgl.glSlowRenderer)this._options.multisamplingSamples=0;if(!this._cgl.gl.MAX_SAMPLES)this._options.multisamplingSamples=0;else this._options.multisamplingSamples=Math.min(this._cgl.maxSamples,this._options.multisamplingSamples)}if(!this._options.hasOwnProperty("filter"))this._options.filter=u.FILTER_LINEAR;if(!this._options.hasOwnProperty("wrap"))this._options.wrap=u.WRAP_REPEAT;this._numRenderBuffers=this._options.numRenderBuffers;this._colorTextures=[];this.clearColors=[];for(let e=0;e<this._numRenderBuffers;e++)this.clearColors.push([0,0,0,1]);if(!r.pixelFormat){if(r.isFloatingPointTexture)this._options.pixelFormat=u.PFORMATSTR_RGBA32F;else this._options.pixelFormat=u.PFORMATSTR_RGBA8UB}for(let e=0;e<this._numRenderBuffers;e++){this._colorTextures[e]=new u(t,{name:"fb2 "+this.name+" "+e,isFloatingPointTexture:this._options.isFloatingPointTexture,anisotropic:this._options.anisotropic||0,pixelFormat:this._options.pixelFormat,filter:this._options.filter,wrap:this._options.wrap})}let i=u.FILTER_NEAREST;if(this._options.shadowMap)i=u.FILTER_LINEAR;const a=512;if(this._options.depth){this._textureDepth=new u(t,{name:"fb2 depth "+this.name,isDepthTexture:true,filter:i,shadowMap:this._options.shadowMap||false,width:e||a,height:n||a})}if(t.aborted)return;this.setSize(e||a,n||a);this._cgl.printError("framebuffer2 constructor")}getWidth(){return this._width}getHeight(){return this._height}getGlFrameBuffer(){return this._frameBuffer}getDepthRenderBuffer(){return this._depthRenderbuffer}getTextureColor(){return this._colorTextures[0]}getTextureColorNum(e){return this._colorTextures[e]}getTextureDepth(){return this._textureDepth}setFilter(t){for(let e=0;e<this._numRenderBuffers;e++){this._colorTextures[e].filter=t;this._colorTextures[e].setSize(this._width,this._height)}}delete(){this.dispose()}dispose(){this._disposed=true;let e=0;for(e=0;e<this._numRenderBuffers;e++)this._colorTextures[e].delete();if(this._textureDepth)this._textureDepth.delete();for(e=0;e<this._numRenderBuffers;e++)this._cgl.gl.deleteRenderbuffer(this._colorRenderbuffers[e]);this._cgl.gl.deleteRenderbuffer(this._depthRenderbuffer);this._cgl.gl.deleteFramebuffer(this._frameBuffer);this._cgl.gl.deleteFramebuffer(this._textureFrameBuffer)}setSize(e,t){if(this._disposed)return this._log.warn("disposed framebuffer setsize...");this._cgl.profileData.addHeavyEvent("framebuffer resize",this.name);let n=0;this._width=this._cgl.checkTextureSize(e);this._height=this._cgl.checkTextureSize(t);this._cgl.profileData.profileFrameBuffercreate++;if(this._frameBuffer){for(n=0;n<this._numRenderBuffers;n++)this._cgl.gl.deleteRenderbuffer(this._colorRenderbuffers[n]);this._cgl.gl.deleteRenderbuffer(this._depthRenderbuffer);this._cgl.gl.deleteFramebuffer(this._frameBuffer);this._cgl.gl.deleteFramebuffer(this._textureFrameBuffer)}this._frameBuffer=this._cgl.gl.createFramebuffer();this._textureFrameBuffer=this._cgl.gl.createFramebuffer();const r=this._options.depth;for(n=0;n<this._numRenderBuffers;n++){this._colorTextures[n].setSize(this._width,this._height)}for(n=0;n<this._numRenderBuffers;n++){const s=this._cgl.gl.createRenderbuffer();this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,this._frameBuffer);this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER,s);const o=u.setUpGlPixelFormat(this._cgl,this._options.pixelFormat);let e=o.glInternalFormat;if(CGL.Texture.isPixelFormatHalfFloat(o.pixelFormat)){if(!this._cgl.enableExtension("OES_texture_float_linear")){this._options.filter=u.FILTER_NEAREST;this.setFilter(this._options.filter)}}else if(CGL.Texture.isPixelFormatFloat(o.pixelFormat)){if(!this._cgl.enableExtension("OES_texture_float_linear")){this._log.warn("no linear pixelformat,using nearest");this._options.filter=u.FILTER_NEAREST;this.setFilter(this._options.filter)}}if(this._options.multisampling&&this._options.multisamplingSamples){this._cgl.gl.renderbufferStorageMultisample(this._cgl.gl.RENDERBUFFER,this._options.multisamplingSamples,e,this._width,this._height)}else{this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER,e,this._width,this._height)}this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER,this._cgl.gl.COLOR_ATTACHMENT0+n,this._cgl.gl.RENDERBUFFER,s);this._colorRenderbuffers[n]=s}this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,this._textureFrameBuffer);for(n=0;n<this._numRenderBuffers;n++){this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER,this._cgl.gl.COLOR_ATTACHMENT0+n,this._cgl.gl.TEXTURE_2D,this._colorTextures[n].tex,0)}if(this._options.depth){this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER,this._cgl.gl.DEPTH_ATTACHMENT,this._cgl.gl.TEXTURE_2D,this._textureDepth.tex,0)}this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,this._frameBuffer);let i=this._cgl.gl.DEPTH_COMPONENT32F;if(this._cgl.glSlowRenderer)i=this._cgl.gl.DEPTH_COMPONENT16;if(r){this._textureDepth.setSize(this._width,this._height);this._depthRenderbuffer=this._cgl.gl.createRenderbuffer();this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER,this._depthRenderbuffer);if(this._options.isFloatingPointTexture){if(this._options.multisampling)this._cgl.gl.renderbufferStorageMultisample(this._cgl.gl.RENDERBUFFER,this._options.multisamplingSamples,i,this._width,this._height);else this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER,i,this._width,this._height)}else if(this._options.multisampling){this._cgl.gl.renderbufferStorageMultisample(this._cgl.gl.RENDERBUFFER,this._options.multisamplingSamples,i,this._width,this._height)}else{this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER,i,this._width,this._height)}this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER,this._cgl.gl.DEPTH_ATTACHMENT,this._cgl.gl.RENDERBUFFER,this._depthRenderbuffer)}this._drawTargetArray.length=0;for(n=0;n<this._numRenderBuffers;n++)this._drawTargetArray.push(this._cgl.gl.COLOR_ATTACHMENT0+n);if(!this._cgl.gl.isFramebuffer(this._textureFrameBuffer))this._log.warn("invalid framebuffer");const a=this._cgl.gl.checkFramebufferStatus(this._cgl.gl.FRAMEBUFFER);if(a!=this._cgl.gl.FRAMEBUFFER_COMPLETE){this._log.error("framebuffer incomplete: "+this.name,this);this._log.log("options",this._options);this._log.log("options pixelformat",this._options.pixelFormat);switch(a){case this._cgl.gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:this._log.warn("FRAMEBUFFER_INCOMPLETE_ATTACHMENT...",this);throw new Error("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_ATTACHMENT");case this._cgl.gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:this._log.warn("FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");throw new Error("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");case this._cgl.gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:this._log.warn("FRAMEBUFFER_INCOMPLETE_DIMENSIONS");throw new Error("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_DIMENSIONS");case this._cgl.gl.FRAMEBUFFER_UNSUPPORTED:this._log.warn("FRAMEBUFFER_UNSUPPORTED");throw new Error("Incomplete framebuffer: FRAMEBUFFER_UNSUPPORTED");default:this.valid=false;this._log.error("incomplete framebuffer",a,this._frameBuffer);this._cgl.printError();this._frameBuffer=null;throw new Error("Incomplete framebuffer: "+a)}}this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,null);this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER,null)}renderStart(){if(this._disposed)return this._log.warn("disposed framebuffer renderStart...");this._cgl.checkFrameStarted("fb2 renderstart");this._cgl.pushModelMatrix();this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,this._frameBuffer);this._cgl.pushGlFrameBuffer(this._frameBuffer);this._cgl.pushFrameBuffer(this);this._cgl.pushPMatrix();this._cgl.pushViewPort(0,0,this._width,this._height);this._cgl.gl.drawBuffers(this._drawTargetArray);if(this._options.clear){this._cgl.gl.clearColor(0,0,0,0);this._cgl.gl.clear(this._cgl.gl.COLOR_BUFFER_BIT|this._cgl.gl.DEPTH_BUFFER_BIT)}}clear(){if(this._numRenderBuffers<=1){this._cgl.gl.bindFramebuffer(this._cgl.gl.READ_FRAMEBUFFER,this._frameBuffer);this._cgl.gl.bindFramebuffer(this._cgl.gl.DRAW_FRAMEBUFFER,this._textureFrameBuffer)}else this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,this._frameBuffer);this._cgl.gl.drawBuffers(this._drawTargetArray);for(let e=0;e<this._numRenderBuffers;e++){this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER,this._cgl.gl.COLOR_ATTACHMENT0+e,this._cgl.gl.TEXTURE_2D,this._colorTextures[e].tex,0);this._cgl.gl.clearBufferfv(this._cgl.gl.COLOR,e,this.clearColors[e])}this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,null)}renderEnd(){if(this._disposed)return this._log.warn("disposed framebuffer renderEnd...");this._cgl.popPMatrix();this._cgl.profileData.profileFramebuffer++;if(this._numRenderBuffers<=1){this._cgl.gl.bindFramebuffer(this._cgl.gl.READ_FRAMEBUFFER,this._frameBuffer);this._cgl.gl.bindFramebuffer(this._cgl.gl.DRAW_FRAMEBUFFER,this._textureFrameBuffer);this._cgl.gl.clearBufferfv(this._cgl.gl.COLOR,0,[0,0,0,1]);this._cgl.gl.blitFramebuffer(0,0,this._width,this._height,0,0,this._width,this._height,this._cgl.gl.COLOR_BUFFER_BIT|this._cgl.gl.DEPTH_BUFFER_BIT,this._cgl.gl.NEAREST)}else{this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,this.Framebuffer2BlittingFramebuffer);this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER,this._cgl.gl.DEPTH_ATTACHMENT,this._cgl.gl.RENDERBUFFER,this._depthRenderbuffer);this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,this.Framebuffer2FinalFramebuffer);this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER,this._cgl.gl.DEPTH_ATTACHMENT,this._cgl.gl.TEXTURE_2D,this._textureDepth.tex,0);for(let t=0;t<this._numRenderBuffers;t++){this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,this.Framebuffer2BlittingFramebuffer);this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER,this._cgl.gl.COLOR_ATTACHMENT0,this._cgl.gl.RENDERBUFFER,this._colorRenderbuffers[t]);this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,this.Framebuffer2FinalFramebuffer);this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER,this._cgl.gl.COLOR_ATTACHMENT0,this._cgl.gl.TEXTURE_2D,this._colorTextures[t].tex,0);this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,null);this._cgl.gl.bindFramebuffer(this._cgl.gl.READ_FRAMEBUFFER,this.Framebuffer2BlittingFramebuffer);this._cgl.gl.bindFramebuffer(this._cgl.gl.DRAW_FRAMEBUFFER,this.Framebuffer2FinalFramebuffer);let e=this._cgl.gl.COLOR_BUFFER_BIT;if(t==0)e|=this._cgl.gl.DEPTH_BUFFER_BIT;this._cgl.gl.blitFramebuffer(0,0,this._width,this._height,0,0,this._width,this._height,e,this._cgl.gl.NEAREST)}}this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,this._cgl.popGlFrameBuffer());this._cgl.popFrameBuffer();this._cgl.popModelMatrix();this._cgl.popViewPort();if(this._colorTextures[0].filter==u.FILTER_MIPMAP){for(let e=0;e<this._numRenderBuffers;e++){this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D,this._colorTextures[e].tex);this._colorTextures[e].updateMipMap();this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D,null)}}}}const i=function(e){this.draw=function(e,t,n){}};const a=function(e){this.render=function(e,t){}};const o=function(e){this.render=function(e,t,n,r){}};class l{constructor(e,t,n,r,i,a,s,o,l,u){this._log=new c.Logger("cg_uniform");this._type=t;this._name=n;this._shader=e;this._value=1e-5;this._oldValue=null;this._port=null;this._structName=l;this._structUniformName=o;this._propertyName=u;if(this._shader._addUniform)this._shader._addUniform(this);this.needsUpdate=true;this.shaderType=null;this.comment=null;if(t=="f"){this.set=this.setValue=this.setValueF.bind(this);this.updateValue=this.updateValueF.bind(this)}else if(t=="f[]"){this.set=this.setValue=this.setValueArrayF.bind(this);this.updateValue=this.updateValueArrayF.bind(this)}else if(t=="2f[]"){this.set=this.setValue=this.setValueArray2F.bind(this);this.updateValue=this.updateValueArray2F.bind(this)}else if(t=="3f[]"){this.set=this.setValue=this.setValueArray3F.bind(this);this.updateValue=this.updateValueArray3F.bind(this)}else if(t=="4f[]"){this.set=this.setValue=this.setValueArray4F.bind(this);this.updateValue=this.updateValueArray4F.bind(this)}else if(t=="i"){this.set=this.setValue=this.setValueI.bind(this);this.updateValue=this.updateValueI.bind(this)}else if(t=="2i"){this.set=this.setValue=this.setValue2I.bind(this);this.updateValue=this.updateValue2I.bind(this)}else if(t=="3i"){this.set=this.setValue=this.setValue3I.bind(this);this.updateValue=this.updateValue3I.bind(this)}else if(t=="4i"){this.set=this.setValue=this.setValue4I.bind(this);this.updateValue=this.updateValue4I.bind(this)}else if(t=="b"){this.set=this.setValue=this.setValueBool.bind(this);this.updateValue=this.updateValueBool.bind(this)}else if(t=="4f"){this.set=this.setValue=this.setValue4F.bind(this);this.updateValue=this.updateValue4F.bind(this)}else if(t=="3f"){this.set=this.setValue=this.setValue3F.bind(this);this.updateValue=this.updateValue3F.bind(this)}else if(t=="2f"){this.set=this.setValue=this.setValue2F.bind(this);this.updateValue=this.updateValue2F.bind(this)}else if(t=="t"){this.set=this.setValue=this.setValueT.bind(this);this.updateValue=this.updateValueT.bind(this)}else if(t=="sampler"){if(this.setValueAny){this.set=this.setValue=this.setValueAny.bind(this);this.updateValue=this.updateValueAny.bind(this)}}else if(t=="tc"){this.set=this.setValue=this.setValueT.bind(this);this.updateValue=this.updateValueT.bind(this)}else if(t=="t[]"){this.set=this.setValue=this.setValueArrayT.bind(this);this.updateValue=this.updateValueArrayT.bind(this)}else if(t=="m4"||t=="m4[]"){this.set=this.setValue=this.setValueM4.bind(this);this.updateValue=this.updateValueM4.bind(this)}else{this._log.error("Unknown uniform type "+t,n,typeof this._shader)}if(typeof r=="object"&&r instanceof C.Port){this._port=r;this._value=this._port.get();if(i&&a&&s){if(!(i instanceof C.Port)||!(a instanceof C.Port)||!(s instanceof C.Port)){this._log.error("[cgl_uniform] mixed port/value parameter for vec4 ",this._name)}this._value=[0,0,0,0];this._port2=i;this._port3=a;this._port4=s;this._port.on("change",this.updateFromPort4f.bind(this));this._port2.on("change",this.updateFromPort4f.bind(this));this._port3.on("change",this.updateFromPort4f.bind(this));this._port4.on("change",this.updateFromPort4f.bind(this));this.updateFromPort4f()}else if(i&&a){if(!(i instanceof C.Port)||!(a instanceof C.Port)){this._log.error("[cgl_uniform] mixed port/value parameter for vec4 ",this._name)}this._value=[0,0,0];this._port2=i;this._port3=a;this._port.on("change",this.updateFromPort3f.bind(this));this._port2.on("change",this.updateFromPort3f.bind(this));this._port3.on("change",this.updateFromPort3f.bind(this));this.updateFromPort3f()}else if(i){if(!(i instanceof C.Port)){this._log.error("[cgl_uniform] mixed port/value parameter for vec4 ",this._name)}this._value=[0,0];this._port2=i;this._port.on("change",this.updateFromPort2f.bind(this));this._port2.on("change",this.updateFromPort2f.bind(this));this.updateFromPort2f()}else{this._port.on("change",this.updateFromPort.bind(this))}}else this._value=r;if(this._value==undefined){this._value=0}this.setValue(this._value);this.needsUpdate=true}getType(){return this._type}get type(){return this._type}get name(){return this._name}getName(){return this._name}getValue(){return this._value}getShaderType(){return this.shaderType}isStructMember(){return!!this._structName}updateFromPort4f(){this._value[0]=this._port.get();this._value[1]=this._port2.get();this._value[2]=this._port3.get();this._value[3]=this._port4.get();this.setValue(this._value)}updateFromPort3f(){this._value[0]=this._port.get();this._value[1]=this._port2.get();this._value[2]=this._port3.get();this.setValue(this._value)}updateFromPort2f(){this._value[0]=this._port.get();this._value[1]=this._port2.get();this.setValue(this._value)}updateFromPort(){this.setValue(this._port.get())}get port(){return this._port}}class h extends l{constructor(e,t,n,r,i,a,s,o,l,u){super(e,t,n,r,i,a,s,o,l,u);this._loc=-1;this._cgl=e._cgl}get name(){return this._name}copy(e){const t=new h(e,this._type,this._name,this._value,this._port2,this._port3,this._port4,this._structUniformName,this._structName,this._propertyName);t.shaderType=this.shaderType;return t}getGlslTypeString(){return h.glslTypeString(this._type)}_isValidLoc(){return this._loc!=-1}resetLoc(){this._loc=-1;this.needsUpdate=true}bindTextures(){}getLoc(){return this._loc}updateFromPort4f(){this._value[0]=this._port.get();this._value[1]=this._port2.get();this._value[2]=this._port3.get();this._value[3]=this._port4.get();this.setValue(this._value)}updateFromPort3f(){this._value[0]=this._port.get();this._value[1]=this._port2.get();this._value[2]=this._port3.get();this.setValue(this._value)}updateFromPort2f(){this._value[0]=this._port.get();this._value[1]=this._port2.get();this.setValue(this._value)}updateFromPort(){this.setValue(this._port.get())}updateValueF(){if(!this._isValidLoc())this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);else this.needsUpdate=false;this._shader.getCgl().gl.uniform1f(this._loc,this._value);this._cgl.profileData.profileUniformCount++}setValueF(e){if(e!=this._value){this.needsUpdate=true;this._value=e}}updateValueI(){if(!this._isValidLoc())this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);else this.needsUpdate=false;this._shader.getCgl().gl.uniform1i(this._loc,this._value);this._cgl.profileData.profileUniformCount++}updateValue2I(){if(!this._value)return;if(!this._isValidLoc()){this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);this._cgl.profileData.profileShaderGetUniform++;this._cgl.profileData.profileShaderGetUniformName=this._name}this._shader.getCgl().gl.uniform2i(this._loc,this._value[0],this._value[1]);this.needsUpdate=false;this._cgl.profileData.profileUniformCount++}updateValue3I(){if(!this._value)return;if(!this._isValidLoc()){this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);this._cgl.profileData.profileShaderGetUniform++;this._cgl.profileData.profileShaderGetUniformName=this._name}this._shader.getCgl().gl.uniform3i(this._loc,this._value[0],this._value[1],this._value[2]);this.needsUpdate=false;this._cgl.profileData.profileUniformCount++}updateValue4I(){if(!this._isValidLoc()){this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);this._cgl.profileData.profileShaderGetUniform++;this._cgl.profileData.profileShaderGetUniformName=this._name}this._shader.getCgl().gl.uniform4i(this._loc,this._value[0],this._value[1],this._value[2],this._value[3]);this._cgl.profileData.profileUniformCount++}setValueI(e){if(e!=this._value){this.needsUpdate=true;this._value=e}}setValue2I(e){if(!e)return;if(!this._oldValue){this._oldValue=[e[0]-1,1];this.needsUpdate=true}else if(e[0]!=this._oldValue[0]||e[1]!=this._oldValue[1]){this._oldValue[0]=e[0];this._oldValue[1]=e[1];this.needsUpdate=true}this._value=e}setValue3I(e){if(!e)return;if(!this._oldValue){this._oldValue=[e[0]-1,1,2];this.needsUpdate=true}else if(e[0]!=this._oldValue[0]||e[1]!=this._oldValue[1]||e[2]!=this._oldValue[2]){this._oldValue[0]=e[0];this._oldValue[1]=e[1];this._oldValue[2]=e[2];this.needsUpdate=true}this._value=e}setValue4I(e){this.needsUpdate=true;this._value=e||vec4.create()}updateValueBool(){if(!this._isValidLoc())this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);else this.needsUpdate=false;this._shader.getCgl().gl.uniform1i(this._loc,this._value?1:0);this._cgl.profileData.profileUniformCount++}setValueBool(e){if(e!=this._value){this.needsUpdate=true;this._value=e}}setValueArray4F(e){this.needsUpdate=true;this._value=e}updateValueArray4F(){if(!this._isValidLoc())this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);else this.needsUpdate=false;if(!this._value)return;this._shader.getCgl().gl.uniform4fv(this._loc,this._value);this._cgl.profileData.profileUniformCount++}setValueArray3F(e){this.needsUpdate=true;this._value=e}updateValueArray3F(){if(!this._isValidLoc())this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);else this.needsUpdate=false;if(!this._value)return;this._shader.getCgl().gl.uniform3fv(this._loc,this._value);this._cgl.profileData.profileUniformCount++}setValueArray2F(e){this.needsUpdate=true;this._value=e}updateValueArray2F(){if(!this._isValidLoc())this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);else this.needsUpdate=false;if(!this._value)return;this._shader.getCgl().gl.uniform2fv(this._loc,this._value);this._cgl.profileData.profileUniformCount++}setValueArrayF(e){this.needsUpdate=true;this._value=e}updateValueArrayF(){if(!this._isValidLoc())this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);else this.needsUpdate=false;if(!this._value)return;this._shader.getCgl().gl.uniform1fv(this._loc,this._value);this._cgl.profileData.profileUniformCount++}setValueArrayT(e){this.needsUpdate=true;this._value=e}updateValue3F(){if(!this._value)return;if(!this._isValidLoc()){this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);this._cgl.profileData.profileShaderGetUniform++;this._cgl.profileData.profileShaderGetUniformName=this._name}this._shader.getCgl().gl.uniform3f(this._loc,this._value[0],this._value[1],this._value[2]);this.needsUpdate=false;this._cgl.profileData.profileUniformCount++}setValue3F(e){if(!e)return;if(!this._oldValue){this._oldValue=[e[0]-1,1,2];this.needsUpdate=true}else if(e[0]!=this._oldValue[0]||e[1]!=this._oldValue[1]||e[2]!=this._oldValue[2]){this._oldValue[0]=e[0];this._oldValue[1]=e[1];this._oldValue[2]=e[2];this.needsUpdate=true}this._value=e}updateValue2F(){if(!this._value)return;if(!this._isValidLoc()){this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);this._cgl.profileData.profileShaderGetUniform++;this._cgl.profileData.profileShaderGetUniformName=this._name}this._shader.getCgl().gl.uniform2f(this._loc,this._value[0],this._value[1]);this.needsUpdate=false;this._cgl.profileData.profileUniformCount++}setValue2F(e){if(!e)return;if(!this._oldValue){this._oldValue=[e[0]-1,1];this.needsUpdate=true}else if(e[0]!=this._oldValue[0]||e[1]!=this._oldValue[1]){this._oldValue[0]=e[0];this._oldValue[1]=e[1];this.needsUpdate=true}this._value=e}updateValue4F(){if(!this._isValidLoc()){this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);this._cgl.profileData.profileShaderGetUniform++;this._cgl.profileData.profileShaderGetUniformName=this._name}if(!this._value){this._log.warn("no value for uniform",this._name,this);this._value=[0,0,0,0]}this.needsUpdate=false;this._shader.getCgl().gl.uniform4f(this._loc,this._value[0],this._value[1],this._value[2],this._value[3]);this._cgl.profileData.profileUniformCount++}setValue4F(e){if(typeof this.value=="number")this.value=vec4.create();if(!e)return;if(!this._oldValue){this._oldValue=[e[0]-1,1,2,3];this.needsUpdate=true}else if(e[0]!=this._oldValue[0]||e[1]!=this._oldValue[1]||e[2]!=this._oldValue[2]||e[3]!=this._oldValue[3]){this._oldValue[0]=e[0];this._oldValue[1]=e[1];this._oldValue[2]=e[2];this.needsUpdate=true}this._value=e}updateValueM4(){if(!this._isValidLoc()){this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);this._cgl.profileData.profileShaderGetUniform++;this._cgl.profileData.profileShaderGetUniformName=this._name}if(!this._value||this._value.length%16!=0)return console.log("this.name",this._name,this._value);this._shader.getCgl().gl.uniformMatrix4fv(this._loc,false,this._value);this._cgl.profileData.profileUniformCount++}setValueM4(e){this.needsUpdate=true;this._value=e||mat4.create()}updateValueArrayT(){if(!this._isValidLoc())this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);else this.needsUpdate=false;if(!this._value)return;this._shader.getCgl().gl.uniform1iv(this._loc,this._value);this._cgl.profileData.profileUniformCount++}updateValueT(){if(!this._isValidLoc()){this._loc=this._shader.getCgl().gl.getUniformLocation(this._shader.getProgram(),this._name);this._cgl.profileData.profileShaderGetUniform++;this._cgl.profileData.profileShaderGetUniformName=this._name}this._cgl.profileData.profileUniformCount++;this._shader.getCgl().gl.uniform1i(this._loc,this._value);this.needsUpdate=false}setValueT(e){this.needsUpdate=true;this._value=e}}h.glslTypeString=e=>{if(e=="f")return"float";if(e=="b")return"bool";if(e=="i")return"int";if(e=="2i")return"ivec2";if(e=="2f")return"vec2";if(e=="3f")return"vec3";if(e=="4f")return"vec4";if(e=="m4")return"mat4";if(e=="t")return"sampler2D";if(e=="tc")return"samplerCube";if(e=="3f[]")return null;if(e=="m4[]")return null;if(e=="f[]")return null;console.warn("[CGL UNIFORM] unknown glsl type string ",e)};const f={SHADERVAR_VERTEX_POSITION:"vPosition",SHADERVAR_VERTEX_NUMBER:"attrVertIndex",SHADERVAR_VERTEX_NORMAL:"attrVertNormal",SHADERVAR_VERTEX_TEXCOORD:"attrTexCoord",SHADERVAR_INSTANCE_MMATRIX:"instMat",SHADERVAR_VERTEX_COLOR:"attrVertColor",SHADERVAR_INSTANCE_INDEX:"instanceIndex",SHADERVAR_UNI_PROJMAT:"projMatrix",SHADERVAR_UNI_VIEWMAT:"viewMatrix",SHADERVAR_UNI_MODELMAT:"modelMatrix",SHADERVAR_UNI_NORMALMAT:"normalMatrix",SHADERVAR_UNI_INVVIEWMAT:"inverseViewMatrix",SHADERVAR_UNI_INVPROJMAT:"invProjMatrix",SHADERVAR_UNI_MATERIALID:"materialId",SHADERVAR_UNI_OBJECTID:"objectId",SHADERVAR_UNI_VIEWPOS:"camPos"};const d={BLEND_NONE:0,BLEND_NORMAL:1,BLEND_ADD:2,BLEND_SUB:3,BLEND_MUL:4};const p=180/Math.PI;const g=Math.PI/180;const m={MATH:{DEG2RAD:g,RAD2DEG:p},SHADER:f,BLEND_MODES:d};const A="\n";class v{_name="unknown";constructor(){}}const x={};x.lastMesh=null;class b extends v{#cgl=null;#geom=null;#bufVerticesIndizes=null;constructor(e,t,n={}){super();this.#cgl=e;let r=n||{};if(C.utils.isNumeric(r))r={glPrimitive:n};this._log=new c.Logger("cgl_mesh");this._bufVertexAttrib=null;this.#bufVerticesIndizes=this.#cgl.gl.createBuffer();this._indexType=this.#cgl.gl.UNSIGNED_SHORT;this._attributes=[];this._attribLocs={};this._lastShader=null;this._numInstances=0;this._glPrimitive=r.glPrimitive;this.opId=r.opId||"";this._preWireframeGeom=null;this.addVertexNumbers=false;this.feedBackAttributes=[];this.setGeom(t);this._feedBacks=[];this._feedBacksChanged=false;this._transformFeedBackLoc=-1;this._lastAttrUpdate=0;this.memFreed=false;this.#cgl.profileData.addHeavyEvent("mesh constructed",this._name);this._queryExt=null}get geom(){return this.#geom}get numInstances(){return this._numInstances}set numInstances(e){this.setNumInstances(e)}freeMem(){this.memFreed=true;for(let e=0;e<this._attributes.length;e++)this._attributes[e].floatArray=null}updateVertices(e){this.setAttribute(m.SHADER.SHADERVAR_VERTEX_POSITION,e.vertices,3);this._numVerts=e.vertices.length/3}setAttributePointer(t,n,r,i){for(let e=0;e<this._attributes.length;e++){if(this._attributes[e].name==t){if(!this._attributes[e].pointer)this._attributes[e].pointer=[];this._attributes[e].pointer.push({loc:-1,name:n,stride:r,offset:i,instanced:t==m.SHADER.SHADERVAR_INSTANCE_MMATRIX})}}}getAttribute(t){for(let e=0;e<this._attributes.length;e++)if(this._attributes[e].name==t)return this._attributes[e]}setAttributeRange(e,t,n,r){if(!e)return;if(!n&&!r)return;if(!e.name)this._log.stack("no attrname?!");const i=this.#cgl.gl;i.bindBuffer(i.ARRAY_BUFFER,e.buffer);this.#cgl.profileData.profileMeshAttributes+=r-n||0;this.#cgl.profileData.profileSingleMeshAttribute[this._name]=this.#cgl.profileData.profileSingleMeshAttribute[this._name]||0;this.#cgl.profileData.profileSingleMeshAttribute[this._name]+=r-n||0;if(e.numItems<t.length/e.itemSize){this._resizeAttr(t,e)}if(r>t.length&&!this.warned){this.warned=true;this._log.warn(this.#cgl.canvas.id+" "+e.name+" buffersubdata out of bounds ?",t.length,r,n,e);return}i.bufferSubData(i.ARRAY_BUFFER,n*4,t,n,r-n)}_resizeAttr(e,t){const n=this.#cgl.gl;if(t.buffer)n.deleteBuffer(t.buffer);t.buffer=n.createBuffer();n.bindBuffer(n.ARRAY_BUFFER,t.buffer);this._bufferArray(e,t);t.numItems=e.length/t.itemSize}_bufferArray(e,t){let n=t.floatArray||null;if(!e)return;if(this.#cgl.debugOneFrame){console.log("_bufferArray",e.length,t.name)}if(!(e instanceof Float32Array)){if(t&&n&&n.length==e.length){n.set(e)}else{n=new Float32Array(e);if(this.#cgl.debugOneFrame){console.log("_bufferArray create new float32array",e.length,t.name)}if(e.length>1e4){this.#cgl.profileData.profileNonTypedAttrib++;this.#cgl.profileData.profileNonTypedAttribNames="("+this._name+":"+t.name+")"}}}else n=e;t.arrayLength=n.length;t.floatArray=null;this.#cgl.gl.bufferData(this.#cgl.gl.ARRAY_BUFFER,n,this.#cgl.gl.DYNAMIC_DRAW)}addAttribute(e,t,n,r){this.setAttribute(e,t,n,r)}setAttribute(e,t,n,r={}){if(!t){this._log.error("mesh addAttribute - no array given! "+e);throw new Error}let i=null;let a=false;let s=0;const o=t.length/n;this.#cgl.profileData.profileMeshAttributes+=o||0;if(typeof r=="function"){i=r}if(typeof r=="object"){if(r.cb)i=r.cb;if(r.instanced)a=r.instanced}if(e==m.SHADER.SHADERVAR_INSTANCE_MMATRIX)a=true;for(s=0;s<this._attributes.length;s++){const c=this._attributes[s];if(c.name==e){if(c.numItems===o){}else{this._resizeAttr(t,c)}this.#cgl.gl.bindBuffer(this.#cgl.gl.ARRAY_BUFFER,c.buffer);this._bufferArray(t,c);return c}}const l=this.#cgl.gl.createBuffer();this.#cgl.gl.bindBuffer(this.#cgl.gl.ARRAY_BUFFER,l);let u=this.#cgl.gl.FLOAT;if(r&&r.type)u=r.type;const c={buffer:l,name:e,cb:i,itemSize:n,numItems:o,startItem:0,instanced:a,type:u};this._bufferArray(t,c);if(e==m.SHADER.SHADERVAR_VERTEX_POSITION)this._bufVertexAttrib=c;this._attributes.push(c);this._attribLocs={};return c}getAttributes(){return this._attributes}updateTexCoords(e){if(e.texCoords&&e.texCoords.length>0){this.setAttribute(m.SHADER.SHADERVAR_VERTEX_TEXCOORD,e.texCoords,2)}else{const t=new Float32Array(Math.round(e.vertices.length/3*2));this.setAttribute(m.SHADER.SHADERVAR_VERTEX_TEXCOORD,t,2)}}updateNormals(e){if(e.vertexNormals&&e.vertexNormals.length>0){this.setAttribute(m.SHADER.SHADERVAR_VERTEX_NORMAL,e.vertexNormals,3)}else{const t=new Float32Array(Math.round(e.vertices.length));this.setAttribute(m.SHADER.SHADERVAR_VERTEX_NORMAL,t,3)}}_setVertexNumbers(e=null){if(!this._verticesNumbers||this._verticesNumbers.length!=this._numVerts||e){if(e)this._verticesNumbers=e;else{this._verticesNumbers=new Float32Array(this._numVerts);for(let e=0;e<this._numVerts;e++)this._verticesNumbers[e]=e}this.setAttribute(m.SHADER.SHADERVAR_VERTEX_NUMBER,this._verticesNumbers,1,(e,t,n)=>{if(!n.uniformNumVertices)n.uniformNumVertices=new h(n,"f","numVertices",this._numVerts);n.uniformNumVertices.setValue(this._numVerts)})}}setVertexIndices(t){if(!this.#bufVerticesIndizes){this._log.warn("no bufVerticesIndizes: "+this._name);return}if(t.length>0){if(t instanceof Float32Array)this._log.warn("vertIndices float32Array: "+this._name);for(let e=0;e<t.length;e++){if(t[e]>=this._numVerts){this._log.warn("invalid index in "+this._name,e,t[e]);return}}this.#cgl.gl.bindBuffer(this.#cgl.gl.ELEMENT_ARRAY_BUFFER,this.#bufVerticesIndizes);if(t.length>65535){this.vertIndicesTyped=new Uint32Array(t);this._indexType=this.#cgl.gl.UNSIGNED_INT}else if(t instanceof Uint32Array){this.vertIndicesTyped=t;this._indexType=this.#cgl.gl.UNSIGNED_INT}else if(!(t instanceof Uint16Array)){this.vertIndicesTyped=new Uint16Array(t);this._indexType=this.#cgl.gl.UNSIGNED_SHORT}else this.vertIndicesTyped=t;this.#cgl.gl.bufferData(this.#cgl.gl.ELEMENT_ARRAY_BUFFER,this.vertIndicesTyped,this.#cgl.gl.DYNAMIC_DRAW);this.#bufVerticesIndizes.itemSize=1;this.#bufVerticesIndizes.numItems=t.length}else this.#bufVerticesIndizes.numItems=0}setGeom(e,t=false){this.#geom=e;if(e.glPrimitive!=null)this._glPrimitive=e.glPrimitive;if(this.#geom&&this.#geom.name)this._name="mesh "+this.#geom.name;x.lastMesh=null;this.#cgl.profileData.profileMeshSetGeom++;this._disposeAttributes();this.updateVertices(this.#geom);this.setVertexIndices(this.#geom.verticesIndices);if(this.addVertexNumbers)this._setVertexNumbers();const n=this.#geom.getAttributes();const r={texCoords:m.SHADER.SHADERVAR_VERTEX_TEXCOORD,vertexNormals:m.SHADER.SHADERVAR_VERTEX_NORMAL,vertexColors:m.SHADER.SHADERVAR_VERTEX_COLOR,tangents:"attrTangent",biTangents:"attrBiTangent"};for(const i in n)if(n[i].data&&n[i].data.length)this.setAttribute(r[i]||i,n[i].data,n[i].itemSize);if(t){this.#geom=null}}_preBind(t){for(let e=0;e<this._attributes.length;e++)if(this._attributes[e].cb)this._attributes[e].cb(this._attributes[e],this.#geom,t)}_checkAttrLengths(){if(this.memFreed)return;for(let e=0;e<this._attributes.length;e++){if(this._attributes[e].arrayLength/this._attributes[e].itemSize<this._attributes[0].arrayLength/this._attributes[0].itemSize){let e="unknown";if(this.#geom)e=this.#geom.name}}}_bind(t){if(!t)return;if(!t.isValid())return;let n=[];if(this._attribLocs[t.id])n=this._attribLocs[t.id];else this._attribLocs[t.id]=n;this._lastShader=t;if(t.lastCompile>this._lastAttrUpdate||n.length!=this._attributes.length){this._lastAttrUpdate=t.lastCompile;for(let e=0;e<this._attributes.length;e++)n[e]=-1}for(let e=0;e<this._attributes.length;e++){const r=this._attributes[e];if(n[e]==-1){if(r._attrLocationLastShaderTime!=t.lastCompile){r._attrLocationLastShaderTime=t.lastCompile;n[e]=this.#cgl.glGetAttribLocation(t.getProgram(),r.name);this.#cgl.profileData.profileAttrLoc++}}if(n[e]!=-1){this.#cgl.gl.enableVertexAttribArray(n[e]);this.#cgl.gl.bindBuffer(this.#cgl.gl.ARRAY_BUFFER,r.buffer);if(r.instanced){if(r.itemSize<=4){if(!r.itemSize||r.itemSize==0)this._log.warn("instanced attrib itemsize error",this.#geom.name,r);this.#cgl.gl.vertexAttribPointer(n[e],r.itemSize,r.type,false,r.itemSize*4,0);this.#cgl.gl.vertexAttribDivisor(n[e],1)}else if(r.itemSize==16){const i=16*4;this.#cgl.gl.vertexAttribPointer(n[e],4,r.type,false,i,0);this.#cgl.gl.enableVertexAttribArray(n[e]+1);this.#cgl.gl.vertexAttribPointer(n[e]+1,4,r.type,false,i,4*4*1);this.#cgl.gl.enableVertexAttribArray(n[e]+2);this.#cgl.gl.vertexAttribPointer(n[e]+2,4,r.type,false,i,4*4*2);this.#cgl.gl.enableVertexAttribArray(n[e]+3);this.#cgl.gl.vertexAttribPointer(n[e]+3,4,r.type,false,i,4*4*3);this.#cgl.gl.vertexAttribDivisor(n[e],1);this.#cgl.gl.vertexAttribDivisor(n[e]+1,1);this.#cgl.gl.vertexAttribDivisor(n[e]+2,1);this.#cgl.gl.vertexAttribDivisor(n[e]+3,1)}else{this._log.warn("unknown instance attrib size",r.name)}}else{if(!r.itemSize||r.itemSize==0)this._log.warn("attrib itemsize error",this._name,r);this.#cgl.gl.vertexAttribPointer(n[e],r.itemSize,r.type,false,r.itemSize*4,0);if(r.pointer){for(let e=0;e<r.pointer.length;e++){const a=r.pointer[e];if(a.loc==-1)a.loc=this.#cgl.glGetAttribLocation(t.getProgram(),a.name);this.#cgl.profileData.profileAttrLoc++;this.#cgl.gl.enableVertexAttribArray(a.loc);this.#cgl.gl.vertexAttribPointer(a.loc,r.itemSize,r.type,false,a.stride,a.offset)}}if(this.bindFeedback)this.bindFeedback(r)}}}if(this.#bufVerticesIndizes&&this.#bufVerticesIndizes.numItems!==0)this.#cgl.gl.bindBuffer(this.#cgl.gl.ELEMENT_ARRAY_BUFFER,this.#bufVerticesIndizes)}unBind(){const e=this._lastShader;this._lastShader=null;if(!e)return;let t=[];if(this._attribLocs[e.id])t=this._attribLocs[e.id];else this._attribLocs[e.id]=t;x.lastMesh=null;for(let e=0;e<this._attributes.length;e++){if(this._attributes[e].instanced){if(this._attributes[e].itemSize<=4){if(t[e]!=-1)this.#cgl.gl.vertexAttribDivisor(t[e],0);if(t[e]>=0)this.#cgl.gl.disableVertexAttribArray(t[e])}else{this.#cgl.gl.vertexAttribDivisor(t[e],0);this.#cgl.gl.vertexAttribDivisor(t[e]+1,0);this.#cgl.gl.vertexAttribDivisor(t[e]+2,0);this.#cgl.gl.vertexAttribDivisor(t[e]+3,0);this.#cgl.gl.disableVertexAttribArray(t[e]+1);this.#cgl.gl.disableVertexAttribArray(t[e]+2);this.#cgl.gl.disableVertexAttribArray(t[e]+3)}}if(t[e]!=-1)this.#cgl.gl.disableVertexAttribArray(t[e])}}meshChanged(){return this.#cgl.lastMesh&&this.#cgl.lastMesh!=this}printDebug(){console.log("--attributes");for(let e=0;e<this._attributes.length;e++){console.log("attribute "+e+" "+this._attributes[e].name)}}setNumVertices(e){this._bufVertexAttrib.numItems=e}getNumVertices(){return this._bufVertexAttrib.numItems}setNumIndices(e){this.#bufVerticesIndizes.numItems=e}getNumIndices(){return this.#bufVerticesIndizes.numItems}render(n){if(this.#cgl.aborted)return;n=n||this.#cgl.getShader();if(!n){return console.log("shadern not valid")}if(!n.isValid()){n=this.#cgl.getErrorShader()}this._checkAttrLengths();if(this.#geom){if(this._preWireframeGeom&&!n.wireframe&&!this.#geom.isIndexed()){this.setGeom(this._preWireframeGeom);this._preWireframeGeom=null}if(n.wireframe){let e=false;if(this.#geom.isIndexed()){if(!this._preWireframeGeom){this._preWireframeGeom=this.#geom;this.#geom=this.#geom.copy()}this.#geom.unIndex();e=true}if(!this.#geom.getAttribute("attrBarycentric")){if(!this._preWireframeGeom){this._preWireframeGeom=this.#geom;this.#geom=this.#geom.copy()}e=true;this.#geom.calcBarycentric()}if(e)this.setGeom(this.#geom)}}let e=false;if(x.lastMesh!=this){if(x.lastMesh)x.lastMesh.unBind();e=true}if(e)this._preBind(n);if(!n.bind())return;this._bind(n);if(this.addVertexNumbers)this._setVertexNumbers();x.lastMesh=this;let t=this.#cgl.gl.TRIANGLES;if(this._glPrimitive!==undefined)t=this._glPrimitive;if(n.glPrimitive!==null)t=n.glPrimitive;let r=1;let i=this.#cgl.profileData.doProfileGlQuery;let a=false;if(i){let e=this._name+" - "+n.getName()+" #"+n.id;if(this._numInstances)e+=" instanced "+this._numInstances+"x";let t=this.#cgl.profileData.glQueryData[e];if(!t)t={id:e,num:0};if(n.opId)t.shaderOp=n.opId;if(this.opId)t.meshOp=this.opId;this.#cgl.profileData.glQueryData[e]=t;if(!this._queryExt&&this._queryExt!==false)this._queryExt=this.#cgl.enableExtension("EXT_disjoint_timer_query_webgl2")||false;if(this._queryExt){if(t._drawQuery){const s=this.#cgl.gl.getQueryParameter(t._drawQuery,this.#cgl.gl.QUERY_RESULT_AVAILABLE);if(s){const o=this.#cgl.gl.getQueryParameter(t._drawQuery,this.#cgl.gl.QUERY_RESULT);const l=o/1e6;t._times=t._times||0;t._times+=l;t._numcount++;t.when=performance.now();t._drawQuery=null;t.queryStarted=false}}if(!t.queryStarted){t._drawQuery=this.#cgl.gl.createQuery();this.#cgl.gl.beginQuery(this._queryExt.TIME_ELAPSED_EXT,t._drawQuery);a=t.queryStarted=true}}}if(this.hasFeedbacks&&this.hasFeedbacks())this.drawFeedbacks(n,t);else if(!this.#bufVerticesIndizes||this.#bufVerticesIndizes.numItems===0){if(t==this.#cgl.gl.TRIANGLES)r=3;if(this._numInstances===0)this.#cgl.gl.drawArrays(t,this._bufVertexAttrib.startItem,this._bufVertexAttrib.numItems-this._bufVertexAttrib.startItem);else this.#cgl.gl.drawArraysInstanced(t,this._bufVertexAttrib.startItem,this._bufVertexAttrib.numItems,this._numInstances)}else{if(t==this.#cgl.gl.TRIANGLES)r=3;if(this._numInstances===0){this.#cgl.gl.drawElements(t,this.#bufVerticesIndizes.numItems,this._indexType,0)}else{this.#cgl.gl.drawElementsInstanced(t,this.#bufVerticesIndizes.numItems,this._indexType,0,this._numInstances)}}if(this.#cgl.debugOneFrame&&this.#cgl.gl.getError()!=this.#cgl.gl.NO_ERROR){this._log.error("mesh draw gl error");this._log.error("mesh",this);this._log.error("shader",n);const u=[];for(let e=0;e<this.#cgl.gl.getProgramParameter(n.getProgram(),this.#cgl.gl.ACTIVE_ATTRIBUTES);e++){const c=this.#cgl.gl.getActiveAttrib(n.getProgram(),e).name;this._log.error("attrib ",c)}}this.#cgl.profileData.profileMeshNumElements+=this._bufVertexAttrib.numItems/r*(this._numInstances||1);this.#cgl.profileData.profileMeshDraw++;if(i&&a){this.#cgl.gl.endQuery(this._queryExt.TIME_ELAPSED_EXT)}this.#cgl.printError("mesh render "+this._name);this.unBind()}setNumInstances(t){t=Math.max(0,t);if(this._numInstances!=t){this._numInstances=t;const n=new Float32Array(t);for(let e=0;e<t;e++)n[e]=e;this.setAttribute(m.SHADER.SHADERVAR_INSTANCE_INDEX,n,1,{instanced:true})}}_disposeAttributes(){if(!this._attributes)return;for(let e=0;e<this._attributes.length;e++){if(this._attributes[e].buffer){this.#cgl.gl.deleteBuffer(this._attributes[e].buffer);this._attributes[e].buffer=null}}this._attributes.length=0}dispose(){if(this.#cgl.aborted)return;if(this._bufVertexAttrib&&this._bufVertexAttrib.buffer)this.#cgl.gl.deleteBuffer(this._bufVertexAttrib.buffer);if(this.#bufVerticesIndizes)this.#cgl.gl.deleteBuffer(this.#bufVerticesIndizes);this.#bufVerticesIndizes=null;this._disposeAttributes()}}const P=CABLES.GLMatrix;class _{constructor(e){this._init();this._first=true;this._wireMesh=null;if(e)this.applyGeom(e)}_init(){this._max=[-0,-0,-0];this._min=[0,0,0];this._center=[0,0,0];this._size=[0,0,0];this._maxAxis=0;this._first=true}get maxAxis(){return this._maxAxis||1}get size(){return this._size}get center(){return this._center}get x(){return this._center[0]}get y(){return this._center[1]}get z(){return this._center[2]}get minX(){return this._min[0]}get minY(){return this._min[1]}get minZ(){return this._min[2]}get maxX(){return this._max[0]}get maxY(){return this._max[1]}get maxZ(){return this._max[2]}apply(e){return this.applyGeom(e)}applyGeom(t){if(!t)return;if(t instanceof _){const e=t;this.applyPos(e.maxX,e.maxY,e.maxZ);this.applyPos(e.minX,e.minY,e.minZ)}else{if(t.isGeometry)for(let e=0;e<t.vertices.length;e+=3)this.applyPos(t.vertices[e],t.vertices[e+1],t.vertices[e+2])}this.calcCenterSize()}copy(){return new _(this)}get changed(){return!(this._max[0]==-Number.MAX_VALUE&&this._max[1]==-Number.MAX_VALUE&&this._max[2]==-Number.MAX_VALUE)}applyPos(e,t,n){if(e==Number.MAX_VALUE||e==-Number.MAX_VALUE||t==Number.MAX_VALUE||t==-Number.MAX_VALUE||n==Number.MAX_VALUE||n==-Number.MAX_VALUE)return;if(!C.utils.isNumeric(e)||!C.utils.isNumeric(t)||!C.utils.isNumeric(n))return;if(this._first){this._max[0]=e;this._max[1]=t;this._max[2]=n;this._min[0]=e;this._min[1]=t;this._min[2]=n;this._first=false;return}this._max[0]=Math.max(this._max[0],e);this._max[1]=Math.max(this._max[1],t);this._max[2]=Math.max(this._max[2],n);this._min[0]=Math.min(this._min[0],e);this._min[1]=Math.min(this._min[1],t);this._min[2]=Math.min(this._min[2],n)}calcCenterSize(){if(this._first)return;this._size[0]=this._max[0]-this._min[0];this._size[1]=this._max[1]-this._min[1];this._size[2]=this._max[2]-this._min[2];this._center[0]=(this._min[0]+this._max[0])/2;this._center[1]=(this._min[1]+this._max[1])/2;this._center[2]=(this._min[2]+this._max[2])/2;this._maxAxis=Math.max(this._size[2],Math.max(this._size[0],this._size[1]))}mulMat4(e){if(this._first){this._max[0]=0;this._max[1]=0;this._max[2]=0;this._min[0]=0;this._min[1]=0;this._min[2]=0;this._first=false}P.vec3.transformMat4(this._max,this._max,e);P.vec3.transformMat4(this._min,this._min,e);this.calcCenterSize()}render(e,t,n){if(!this._wireMesh)this._wireMesh=new CGL.WireCube(e);e.pushModelMatrix();P.mat4.translate(e.mMatrix,e.mMatrix,this._center);if(CABLES.UI&&n){CABLES.UI.OverlayMeshes.drawCube(n,this._size[0]/2,this._size[1]/2,this._size[2]/2)}e.popModelMatrix()}}class E{isGeometry=true;constructor(e){this.name=e||"unknown";this._log=new c.Logger("cgl_geometry");this.faceVertCount=3;this.glPrimitive=null;this._attributes={};this._vertices=[];this.verticesIndices=[];this.morphTargets=[]}get vertices(){return this._vertices}set vertices(e){this.setVertices(e)}get texCoords(){const e=this.getAttribute("texCoords");if(!e)return[];return e.data}set texCoords(e){this.setAttribute("texCoords",e,2)}get vertexNormals(){const e=this.getAttribute("vertexNormals");if(!e)return[];return e.data}set vertexNormals(e){this.setAttribute("vertexNormals",e,3)}get tangents(){const e=this.getAttribute("tangents");if(!e)return[];return e.data}set tangents(e){this.setAttribute("tangents",e,3)}get biTangents(){const e=this.getAttribute("biTangents");if(!e)return[];return e.data}set biTangents(e){this.setAttribute("biTangents",e,3)}get vertexColors(){const e=this.getAttribute("vertexColors");if(!e)return[];return e.data}set vertexColors(e){this.setAttribute("vertexColors",e,4)}clear(){this._vertices=new Float32Array([]);this.verticesIndices=[];this.texCoords=new Float32Array([]);this.vertexNormals=new Float32Array([]);this.tangents=[];this.biTangents=[];this._attributes={}}getAttributes(){return this._attributes}getAttribute(t){for(const e in this._attributes){if(this._attributes[e].name==t)return this._attributes[e]}return null}setAttribute(e,t,n){let r="";if(!n||n>4){this._log.warn("itemsize wrong?",n,e);this._log.stack("itemsize");n=3}if(n==1)r="float";else if(n==2)r="vec2";else if(n==3)r="vec3";else if(n==4)r="vec4";const i={name:e,data:t,itemSize:n,type:r};this._attributes[e]=i}copyAttribute(e,t){const n=this.getAttribute(e);t.setAttribute(e,new Float32Array(n.data),n.itemSize)}setVertices(e){if(e instanceof Float32Array)this._vertices=e;else this._vertices=new Float32Array(e)}setTexCoords(e){if(e instanceof Float32Array)this.texCoords=e;else this.texCoords=new Float32Array(e)}calcNormals(e){const t={smooth:e};this.calculateNormals(t)}flipNormals(t,n,r){let i=P.vec3.create();if(t==undefined)t=1;if(n==undefined)n=1;if(r==undefined)r=1;for(let e=0;e<this.vertexNormals.length;e+=3){P.vec3.set(i,this.vertexNormals[e+0],this.vertexNormals[e+1],this.vertexNormals[e+2]);i[0]*=-t;i[1]*=-n;i[2]*=-r;P.vec3.normalize(i,i);this.vertexNormals[e+0]=i[0];this.vertexNormals[e+1]=i[1];this.vertexNormals[e+2]=i[2]}}getNumTriangles(){if(this.verticesIndices&&this.verticesIndices.length)return this.verticesIndices.length/3;return this.vertices.length/3}flipVertDir(){const t=[];t.length=this.verticesIndices.length;for(let e=0;e<this.verticesIndices.length;e+=3){t[e]=this.verticesIndices[e+2];t[e+1]=this.verticesIndices[e+1];t[e+2]=this.verticesIndices[e]}this.verticesIndices=t}setPointVertices(t){if(t.length%3!==0){this._log.error("SetPointVertices: Array must be multiple of three.");return}if(!(t instanceof Float32Array))this.vertices=new Float32Array(t);else this.vertices=t;if(!(this.texCoords instanceof Float32Array))this.texCoords=new Float32Array(t.length/3*2);this.verticesIndices.length=t.length/3;for(let e=0;e<t.length/3;e++){this.verticesIndices[e]=e;this.texCoords[e*2]=0;this.texCoords[e*2+1]=0}}merge(t){if(!t)return;if(this.isIndexed()!=t.isIndexed()){if(this.isIndexed()){this.unIndex(false,true)}if(t.isIndexed()){const e=t.copy();e.unIndex(false,true);t=e}}const n=this.verticesIndices.length;const r=this._vertices.length/3;this.verticesIndices.length+=t.verticesIndices.length;for(let e=0;e<t.verticesIndices.length;e++)this.verticesIndices[n+e]=t.verticesIndices[e]+r;this.vertices=C.utils.float32Concat(this._vertices,t.vertices);this.texCoords=C.utils.float32Concat(this.texCoords,t.texCoords);this.vertexNormals=C.utils.float32Concat(this.vertexNormals,t.vertexNormals);this.tangents=C.utils.float32Concat(this.tangents,t.tangents);this.biTangents=C.utils.float32Concat(this.biTangents,t.biTangents)}copy(){const t=new E(this.name+" copy");t.faceVertCount=this.faceVertCount;t.glPrimitive=this.glPrimitive;t.setVertices(this._vertices.slice(0));if(this.verticesIndices){t.verticesIndices.length=this.verticesIndices.length;for(let e=0;e<this.verticesIndices.length;e++)t.verticesIndices[e]=this.verticesIndices[e]}for(let e in this._attributes)this.copyAttribute(e,t);t.morphTargets.length=this.morphTargets.length;for(let e=0;e<this.morphTargets.length;e++)t.morphTargets[e]=this.morphTargets[e];return t}calculateNormals(t=null){t=t||{};if(t.smooth===false)this.unIndex();const n=P.vec3.create();const r=P.vec3.create();const i=P.vec3.create();function a(e){P.vec3.subtract(n,e[0],e[1]);P.vec3.subtract(r,e[0],e[2]);P.vec3.cross(i,n,r);P.vec3.normalize(i,i);if(t&&t.forceZUp){if(i[2]<0){i[0]*=-1;i[1]*=-1;i[2]*=-1}}return i}this.getVertexVec=function(e){const t=[0,0,0];t[0]=this.vertices[e*3+0];t[1]=this.vertices[e*3+1];t[2]=this.vertices[e*3+2];return t};if(!(this.vertexNormals instanceof Float32Array)||this.vertexNormals.length!=this.vertices.length)this.vertexNormals=new Float32Array(this.vertices.length);for(let e=0;e<this.vertices.length;e++){this.vertexNormals[e]=0}if(!this.isIndexed()){const s=[];for(let e=0;e<this.vertices.length;e+=9){const o=[[this.vertices[e+0],this.vertices[e+1],this.vertices[e+2]],[this.vertices[e+3],this.vertices[e+4],this.vertices[e+5]],[this.vertices[e+6],this.vertices[e+7],this.vertices[e+8]]];const l=a(o);s.push(l[0],l[1],l[2],l[0],l[1],l[2],l[0],l[1],l[2])}this.vertexNormals=s}else{const u=[];u.length=Math.floor(this.verticesIndices.length/3);for(let e=0;e<this.verticesIndices.length;e+=3){const o=[this.getVertexVec(this.verticesIndices[e+0]),this.getVertexVec(this.verticesIndices[e+1]),this.getVertexVec(this.verticesIndices[e+2])];u[e/3]=a(o);this.vertexNormals[this.verticesIndices[e+0]*3+0]+=u[e/3][0];this.vertexNormals[this.verticesIndices[e+0]*3+1]+=u[e/3][1];this.vertexNormals[this.verticesIndices[e+0]*3+2]+=u[e/3][2];this.vertexNormals[this.verticesIndices[e+1]*3+0]+=u[e/3][0];this.vertexNormals[this.verticesIndices[e+1]*3+1]+=u[e/3][1];this.vertexNormals[this.verticesIndices[e+1]*3+2]+=u[e/3][2];this.vertexNormals[this.verticesIndices[e+2]*3+0]+=u[e/3][0];this.vertexNormals[this.verticesIndices[e+2]*3+1]+=u[e/3][1];this.vertexNormals[this.verticesIndices[e+2]*3+2]+=u[e/3][2]}for(let t=0;t<this.verticesIndices.length;t+=3){for(let e=0;e<3;e++){const c=[this.vertexNormals[this.verticesIndices[t+e]*3+0],this.vertexNormals[this.verticesIndices[t+e]*3+1],this.vertexNormals[this.verticesIndices[t+e]*3+2]];P.vec3.normalize(c,c);this.vertexNormals[this.verticesIndices[t+e]*3+0]=c[0];this.vertexNormals[this.verticesIndices[t+e]*3+1]=c[1];this.vertexNormals[this.verticesIndices[t+e]*3+2]=c[2]}}}}calcTangentsBitangents(){if(!this.vertices.length){return}if(!this.vertexNormals.length){return}if(!this.texCoords.length){const E=this.vertices.length/3*2;this.texCoords=new Float32Array(E);for(let e=0;e<E;e+=1)this.texCoords[e]=0}if(!this.verticesIndices||!this.verticesIndices.length){return}if(this.verticesIndices.length%3!==0){this._log.error("Vertex indices mismatch!");return}const t=this.verticesIndices.length/3;const n=this.vertices.length/3;this.tangents=new Float32Array(this.vertexNormals.length);this.biTangents=new Float32Array(this.vertexNormals.length);const r=[];r.length=n*2;const i=P.vec3.create();const a=P.vec3.create();const s=P.vec3.create();const o=P.vec2.create();const l=P.vec2.create();const u=P.vec2.create();const c=P.vec3.create();const h=P.vec3.create();for(let e=0;e<t;e+=1){const F=this.verticesIndices[e*3];const C=this.verticesIndices[e*3+1];const A=this.verticesIndices[e*3+2];P.vec3.set(i,this.vertices[F*3],this.vertices[F*3+1],this.vertices[F*3+2]);P.vec3.set(a,this.vertices[C*3],this.vertices[C*3+1],this.vertices[C*3+2]);P.vec3.set(s,this.vertices[A*3],this.vertices[A*3+1],this.vertices[A*3+2]);P.vec2.set(o,this.texCoords[F*2],this.texCoords[F*2+1]);P.vec2.set(l,this.texCoords[C*2],this.texCoords[C*2+1]);P.vec2.set(u,this.texCoords[A*2],this.texCoords[A*2+1]);const x=a[0]-i[0];const T=s[0]-i[0];const S=a[1]-i[1];const y=s[1]-i[1];const B=a[2]-i[2];const O=s[2]-i[2];const D=l[0]-o[0];const I=u[0]-o[0];const M=l[1]-o[1];const L=u[1]-o[1];const R=1/(D*L-I*M);P.vec3.set(c,(L*x-M*T)*R,(L*S-M*y)*R,(L*B-M*O)*R);P.vec3.set(h,(D*T-I*x)*R,(D*y-I*S)*R,(D*O-I*B)*R);r[F]=c;r[C]=c;r[A]=c;r[F+n]=h;r[C+n]=h;r[A+n]=h}const f=P.vec3.create();const d=P.vec3.create();const p=P.vec3.create();const g=P.vec3.create();const m=P.vec3.create();const v=P.vec3.create();const b=P.vec3.create();const _=P.vec3.create();for(let e=0;e<n;e+=1){if(!r[e])continue;P.vec3.set(f,this.vertexNormals[e*3],this.vertexNormals[e*3+1],this.vertexNormals[e*3+2]);P.vec3.set(d,r[e][0],r[e][1],r[e][2]);const w=P.vec3.dot(f,d);P.vec3.scale(m,f,w);P.vec3.subtract(v,d,m);P.vec3.normalize(_,v);P.vec3.cross(b,f,d);const N=1;P.vec3.scale(p,_,1/N);P.vec3.cross(g,f,p);this.tangents[e*3+0]=p[0];this.tangents[e*3+1]=p[1];this.tangents[e*3+2]=p[2];this.biTangents[e*3+0]=g[0];this.biTangents[e*3+1]=g[1];this.biTangents[e*3+2]=g[2]}}isIndexed(){if(this._vertices.length==0)return true;return this.verticesIndices.length!=0}unIndex(e=false,t=false){const n=[];const r=[];let i=0;for(let e in this._attributes){const a=this._attributes[e];let n=[];for(let t=0;t<this.verticesIndices.length;t+=3){for(let e=0;e<3;e++){if(a.itemSize==3)n.push(a.data[this.verticesIndices[t+e]*3+0],a.data[this.verticesIndices[t+e]*3+1],a.data[this.verticesIndices[t+e]*3+2]);else if(a.itemSize==4)n.push(a.data[this.verticesIndices[t+e]*4+0],a.data[this.verticesIndices[t+e]*4+1],a.data[this.verticesIndices[t+e]*4+2],a.data[this.verticesIndices[t+e]*4+3]);else if(a.itemSize==2)n.push(a.data[this.verticesIndices[t+e]*2+0],a.data[this.verticesIndices[t+e]*2+1]);else if(a.itemSize==1)n.push(a.data[this.verticesIndices[t+e]]);else this._log.warn("unknown attr",a)}}this.setAttribute(a.name,n,a.itemSize)}for(let e=0;e<this.verticesIndices.length;e+=3){n.push(this.vertices[this.verticesIndices[e+0]*3+0],this.vertices[this.verticesIndices[e+0]*3+1],this.vertices[this.verticesIndices[e+0]*3+2]);r.push(i);i++;n.push(this.vertices[this.verticesIndices[e+1]*3+0],this.vertices[this.verticesIndices[e+1]*3+1],this.vertices[this.verticesIndices[e+1]*3+2]);r.push(i);i++;n.push(this.vertices[this.verticesIndices[e+2]*3+0],this.vertices[this.verticesIndices[e+2]*3+1],this.vertices[this.verticesIndices[e+2]*3+2]);r.push(i);i++}this.vertices=n;this.verticesIndices=[];if(e)this.verticesIndices=r;if(!t)this.calculateNormals()}calcBarycentric(){let t=[];t.length=this.vertices.length;for(let e=0;e<this.vertices.length;e++)t[e]=0;let n=0;for(let e=0;e<this.vertices.length;e+=3){t[e+n]=1;n++;if(n==3)n=0}this.setAttribute("attrBarycentric",t,3)}getBounds(){return new _(this)}center(e,t,n){if(e===undefined){e=true;t=true;n=true}let r=0;const i=this.getBounds();const a=[i.minX+(i.maxX-i.minX)/2,i.minY+(i.maxY-i.minY)/2,i.minZ+(i.maxZ-i.minZ)/2];for(r=0;r<this.vertices.length;r+=3){if(this.vertices[r+0]==this.vertices[r+0]){if(e)this.vertices[r+0]-=a[0];if(t)this.vertices[r+1]-=a[1];if(n)this.vertices[r+2]-=a[2]}}return a}mapTexCoords2d(){const t=this.getBounds();const n=this.vertices.length/3;this.texCoords=new Float32Array(n*2);for(let e=0;e<n;e++){const r=this.vertices[e*3+0];const i=this.vertices[e*3+1];this.texCoords[e*2+0]=r/(t.maxX-t.minX)+.5;this.texCoords[e*2+1]=1-i/(t.maxY-t.minY)+.5}}getInfoOneLine(){let e="";if(this.faceVertCount==3&&this.verticesIndices)e+=this.verticesIndices.length/3;else e+=0;e+=" tris ";if(this.vertices)e+=this.vertices.length/3;else e+=0;e+=" verts";return e}getInfo(){const e={};e.name=this.name;e.class=this.constructor.name;if(this.faceVertCount==3&&this.verticesIndices)e.numFaces=this.verticesIndices.length/3;else e.numFaces=0;if(this.verticesIndices&&this.verticesIndices.length)e.indices=this.verticesIndices.length;if(this.vertices)e.numVerts=this.vertices.length/3;else e.numVerts=0;if(this.vertexNormals)e.numNormals=this.vertexNormals.length/3;else e.numNormals=0;if(this.texCoords)e.numTexCoords=this.texCoords.length/2;else e.numTexCoords=0;if(this.tangents)e.numTangents=this.tangents.length/3;else e.numTangents=0;if(this.biTangents)e.numBiTangents=this.biTangents.length/3;else e.numBiTangents=0;if(this.biTangents)e.numBiTangents=this.biTangents.length/3;else e.numBiTangents=0;if(this.vertexColors)e.numVertexColors=this.vertexColors.length/4;else e.numVertexColors=0;if(this.getAttributes())e.numAttribs=Object.keys(this.getAttributes()).length;else e.numAttribs=0;e.isIndexed=this.isIndexed();return e}}E.buildFromFaces=function(t,e,n){const r=[];const i=[];for(let e=0;e<t.length;e+=3){const s=t[e+0];const o=t[e+1];const l=t[e+2];const u=[-1,-1,-1];if(n)for(let e=0;e<r.length;e+=3){if(r[e+0]==s[0]&&r[e+1]==s[1]&&r[e+2]==s[2])u[0]=e/3;if(r[e+0]==o[0]&&r[e+1]==o[1]&&r[e+2]==o[2])u[1]=e/3;if(r[e+0]==l[0]&&r[e+1]==l[1]&&r[e+2]==l[2])u[2]=e/3}if(u[0]==-1){r.push(s[0],s[1],s[2]);u[0]=(r.length-1)/3}if(u[1]==-1){r.push(o[0],o[1],o[2]);u[1]=(r.length-1)/3}if(u[2]==-1){r.push(l[0],l[1],l[2]);u[2]=(r.length-1)/3}i.push(u[0]);i.push(u[1]);i.push(u[2])}const a=new E(e);a.name=e;a.vertices=r;a.verticesIndices=i;return a};const F={};F.getSimpleRect=function(e,t,n=1){const r=new E(t);r.vertices=[1*n,1*n,0,-1*n,1*n,0,1*n,-1*n,0,-1*n,-1*n,0];r.texCoords=[1,1,0,1,1,0,0,0];r.verticesIndices=[0,1,2,2,1,3];r.vertexNormals=[0,0,0,0,0,0,0,0,0,0,0,0];return e.createMesh(r)};F.getSimpleCube=function(e,t){const n=new E(t);n.vertices=[-1,-1,1,1,-1,1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,1,-1,-1,1,-1,-1,1,-1,1,1,-1,1,1,1,-1,1,1,-1,-1,-1,1,-1,-1,1,-1,1,-1,-1,1,1,-1,-1,1,-1,1,1,1,1,1,1,-1,-1,-1,-1,-1,-1,1,-1,1,1,-1,1,-1];n.setTexCoords([0,1,1,1,1,0,0,0,1,1,1,0,0,0,0,1,0,0,0,1,1,1,1,0,1,0,0,0,0,1,1,1,1,1,1,0,0,0,0,1,0,1,1,1,1,0,0,0]);n.verticesIndices=[0,1,2,0,2,3,4,5,6,4,6,7,8,9,10,8,10,11,12,13,14,12,14,15,16,17,18,16,18,19,20,21,22,20,22,23];n.vertexNormals=new Float32Array([0,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0]);n.tangents=new Float32Array([0,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1]);n.biTangents=new Float32Array([-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1]);return new b(e,n)};class T{constructor(e,t){this._cgl=e;this._log=new c.Logger("cgl_TextureEffect");if(!e.TextureEffectMesh)this.createMesh();this._textureSource=null;this._options=t;this.name=t.name||"unknown";this.imgCompVer=0;this.aspectRatio=1;this._textureTarget=null;this._frameBuf=this._cgl.gl.createFramebuffer();this._frameBuf2=this._cgl.gl.createFramebuffer();this._renderbuffer=this._cgl.gl.createRenderbuffer();this._renderbuffer2=this._cgl.gl.createRenderbuffer();this.switched=false;this.depth=false}dispose(){if(this._renderbuffer)this._cgl.gl.deleteRenderbuffer(this._renderbuffer);if(this._frameBuf)this._cgl.gl.deleteFramebuffer(this._frameBuf);if(this._renderbuffer2)this._cgl.gl.deleteRenderbuffer(this._renderbuffer2);if(this._frameBuf2)this._cgl.gl.deleteFramebuffer(this._frameBuf2)}getWidth(){return this._textureSource.width}getHeight(){return this._textureSource.height}setSourceTexture(e){if(e===null){this._textureSource=new u(this._cgl);this._textureSource.setSize(16,16)}else{this._textureSource=e}if(!this._textureSource.compareSettings(this._textureTarget)){if(this._textureTarget)this._textureTarget.delete();this._textureTarget=this._textureSource.clone();this._cgl.profileData.profileEffectBuffercreate++;this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,this._frameBuf);this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER,this._renderbuffer);if(this.depth)this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER,this._cgl.gl.DEPTH_COMPONENT16,this._textureSource.width,this._textureSource.height);this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER,this._cgl.gl.COLOR_ATTACHMENT0,this._cgl.gl.TEXTURE_2D,this._textureTarget.tex,0);if(this.depth)this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER,this._cgl.gl.DEPTH_ATTACHMENT,this._cgl.gl.RENDERBUFFER,this._renderbuffer);this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D,null);this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER,null);this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,null);this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,this._frameBuf2);this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER,this._renderbuffer2);if(this.depth)this._cgl.gl.renderbufferStorage(this._cgl.gl.RENDERBUFFER,this._cgl.gl.DEPTH_COMPONENT16,this._textureSource.width,this._textureSource.height);this._cgl.gl.framebufferTexture2D(this._cgl.gl.FRAMEBUFFER,this._cgl.gl.COLOR_ATTACHMENT0,this._cgl.gl.TEXTURE_2D,this._textureSource.tex,0);if(this.depth)this._cgl.gl.framebufferRenderbuffer(this._cgl.gl.FRAMEBUFFER,this._cgl.gl.DEPTH_ATTACHMENT,this._cgl.gl.RENDERBUFFER,this._renderbuffer2);this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D,null);this._cgl.gl.bindRenderbuffer(this._cgl.gl.RENDERBUFFER,null);this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,null)}this.aspectRatio=this._textureSource.width/this._textureSource.height}continueEffect(){this._cgl.pushDepthTest(false);this._cgl.pushModelMatrix();this._cgl.pushPMatrix();this._cgl.pushViewPort(0,0,this.getCurrentTargetTexture().width,this.getCurrentTargetTexture().height);mat4.perspective(this._cgl.pMatrix,45,this.getCurrentTargetTexture().width/this.getCurrentTargetTexture().height,.1,1100);this._cgl.pushPMatrix();mat4.identity(this._cgl.pMatrix);this._cgl.pushViewMatrix();mat4.identity(this._cgl.vMatrix);this._cgl.pushModelMatrix();mat4.identity(this._cgl.mMatrix)}startEffect(e){if(!this._textureTarget){this._log.warn("effect has no target");return}this.switched=false;this.continueEffect();if(e){this._bgTex=e}this._countEffects=0}endEffect(){this._cgl.popDepthTest();this._cgl.popModelMatrix();this._cgl.popPMatrix();this._cgl.popModelMatrix();this._cgl.popViewMatrix();this._cgl.popPMatrix();this._cgl.popViewPort()}bind(){if(this._textureSource===null){this._log.warn("no base texture set!");return}if(!this.switched){this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,this._frameBuf);this._cgl.pushGlFrameBuffer(this._frameBuf)}else{this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,this._frameBuf2);this._cgl.pushGlFrameBuffer(this._frameBuf2)}}finish(){if(this._textureSource===null){this._log.warn("no base texture set!");return}this._cgl.TextureEffectMesh.render(this._cgl.getShader());this._cgl.gl.bindFramebuffer(this._cgl.gl.FRAMEBUFFER,this._cgl.popGlFrameBuffer());this._cgl.profileData.profileTextureEffect++;if(this._textureTarget.filter==u.FILTER_MIPMAP){if(!this.switched){this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D,this._textureTarget.tex);this._textureTarget.updateMipMap()}else{this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D,this._textureSource.tex);this._textureSource.updateMipMap()}this._cgl.gl.bindTexture(this._cgl.gl.TEXTURE_2D,null)}this.switched=!this.switched;this._countEffects++}getCurrentTargetTexture(){if(this.switched)return this._textureSource;return this._textureTarget}getCurrentSourceTexture(){if(this._countEffects==0&&this._bgTex)return this._bgTex;if(this.switched)return this._textureTarget;return this._textureSource}delete(){if(this._textureTarget)this._textureTarget.delete();if(this._textureSource)this._textureSource.delete();this._cgl.gl.deleteRenderbuffer(this._renderbuffer);this._cgl.gl.deleteFramebuffer(this._frameBuf)}createMesh(){this._cgl.TextureEffectMesh=F.getSimpleRect(this._cgl,"texEffectRect")}}T.checkOpNotInTextureEffect=function(e){if(!e.patch.cgl)return true;if(e.uiAttribs.error&&!e.patch.cgl.currentTextureEffect){e.setUiError("textureeffect",null);return true}if(!e.patch.cgl.currentTextureEffect)return true;if(e.patch.cgl.currentTextureEffect&&!e.uiAttribs.error){e.setUiError("textureeffect","This op can not be a child of a ImageCompose/texture effect! imagecompose should only have textureeffect childs.",0);return false}if(e.patch.cgl.currentTextureEffect)return false;return true};T.checkOpInEffect=function(e,t){t=t||0;if(e.patch.cgl.currentTextureEffect){if(e.uiAttribs.uierrors&&e.patch.cgl.currentTextureEffect.imgCompVer>=t){e.setUiError("texeffect",null);return true}if(t&&e.patch.cgl.currentTextureEffect.imgCompVer<t){e.setUiError("texeffect","This op must be a child of an ImageCompose op with version >="+t+' <span class="button-small" onclick="gui.patchView.downGradeOp(\''+e.id+"','"+e.name+"')\">Downgrade</span> to previous version",1)}}if(e.patch.cgl.currentTextureEffect)return true;if(!e.patch.cgl.currentTextureEffect&&(!e.uiAttribs.uierrors||e.uiAttribs.uierrors.length==0)){e.setUiError("texeffect",'This op must be a child of an ImageCompose op! More infos <a href="https://cables.gl/docs/image_composition/image_composition.html" target="_blank">here</a>. ',1);return false}if(!e.patch.cgl.currentTextureEffect)return false;return true};T.getBlendCode=function(e){let t="".endl()+"vec3 _blend(vec3 base,vec3 blend)".endl()+"{".endl()+"   vec3 colNew=blend;".endl()+"   #ifdef BM_MULTIPLY".endl()+"       colNew=base*blend;".endl()+"   #endif".endl()+"   #ifdef BM_MULTIPLY_INV".endl()+"       colNew=base* vec3(1.0)-blend;".endl()+"   #endif".endl()+"   #ifdef BM_AVERAGE".endl()+"       colNew=((base + blend) / 2.0);".endl()+"   #endif".endl()+"   #ifdef BM_ADD".endl()+"       colNew=min(base + blend, vec3(1.0));".endl()+"   #endif".endl()+"   #ifdef BM_SUBTRACT_ONE".endl()+"       colNew=max(base + blend - vec3(1.0), vec3(0.0));".endl()+"   #endif".endl()+"   #ifdef BM_SUBTRACT".endl()+"       colNew=base - blend;".endl()+"   #endif".endl()+"   #ifdef BM_DIFFERENCE".endl()+"       colNew=abs(base - blend);".endl()+"   #endif".endl()+"   #ifdef BM_NEGATION".endl()+"       colNew=(vec3(1.0) - abs(vec3(1.0) - base - blend));".endl()+"   #endif".endl()+"   #ifdef BM_EXCLUSION".endl()+"       colNew=(base + blend - 2.0 * base * blend);".endl()+"   #endif".endl()+"   #ifdef BM_LIGHTEN".endl()+"       colNew=max(blend, base);".endl()+"   #endif".endl()+"   #ifdef BM_DARKEN".endl()+"       colNew=min(blend, base);".endl()+"   #endif".endl()+"   #ifdef BM_OVERLAY".endl()+"      #define BlendOverlayf(base, blend)  (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)))".endl()+"      colNew=vec3(BlendOverlayf(base.r, blend.r),BlendOverlayf(base.g, blend.g),BlendOverlayf(base.b, blend.b));".endl()+"   #endif".endl()+"   #ifdef BM_SCREEN".endl()+"      #define BlendScreenf(base, blend)       (1.0 - ((1.0 - base) * (1.0 - blend)))".endl()+"      colNew=vec3(BlendScreenf(base.r, blend.r),BlendScreenf(base.g, blend.g),BlendScreenf(base.b, blend.b));".endl()+"   #endif".endl()+"   #ifdef BM_SOFTLIGHT".endl()+"      #define BlendSoftLightf(base, blend)    ((blend < 0.5) ? (2.0 * base * blend + base * base * (1.0 - 2.0 * blend)) : (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend)))".endl()+"      colNew=vec3(BlendSoftLightf(base.r, blend.r),BlendSoftLightf(base.g, blend.g),BlendSoftLightf(base.b, blend.b));".endl()+"   #endif".endl()+"   #ifdef BM_HARDLIGHT".endl()+"      #define BlendOverlayf(base, blend)  (base < 0.5 ? (2.0 * base * blend) : (1.0 - 2.0 * (1.0 - base) * (1.0 - blend)))".endl()+"      colNew=vec3(BlendOverlayf(base.r, blend.r),BlendOverlayf(base.g, blend.g),BlendOverlayf(base.b, blend.b));".endl()+"   #endif".endl()+"   #ifdef BM_COLORDODGE".endl()+"      #define BlendColorDodgef(base, blend)   ((blend == 1.0) ? blend : min(base / (1.0 - blend), 1.0))".endl()+"      colNew=vec3(BlendColorDodgef(base.r, blend.r),BlendColorDodgef(base.g, blend.g),BlendColorDodgef(base.b, blend.b));".endl()+"   #endif".endl()+"   #ifdef BM_COLORBURN".endl()+"      #define BlendColorBurnf(base, blend)    ((blend == 0.0) ? blend : max((1.0 - ((1.0 - base) / blend)), 0.0))".endl()+"      colNew=vec3(BlendColorBurnf(base.r, blend.r),BlendColorBurnf(base.g, blend.g),BlendColorBurnf(base.b, blend.b));".endl()+"   #endif".endl()+"   return colNew;".endl()+"}".endl();if(!e)t+="vec4 cgl_blend(vec4 oldColor,vec4 newColor,float amount)".endl()+"{".endl()+"vec4 col=vec4( _blend(oldColor.rgb,newColor.rgb) ,1.0);".endl()+"col=vec4( mix( col.rgb, oldColor.rgb ,1.0-oldColor.a*amount),1.0);".endl()+"return col;".endl()+"}".endl();if(e>=3)t+="vec4 cgl_blendPixel(vec4 base,vec4 col,float amount)".endl()+"{".endl()+"#ifdef BM_MATH_ADD".endl()+"   return vec4(base.rgb+col.rgb*amount,1.0);".endl()+"#endif".endl()+"#ifdef BM_MATH_SUB".endl()+"   return vec4(base.rgb-col.rgb*amount,1.0);".endl()+"#endif".endl()+"#ifdef BM_MATH_MUL".endl()+"   return vec4(base.rgb*col.rgb*amount,1.0);".endl()+"#endif".endl()+"#ifdef BM_MATH_DIV".endl()+"   return vec4(base.rgb/col.rgb*amount,1.0);".endl()+"#endif".endl()+"#ifndef BM_MATH".endl()+"vec3 colNew=_blend(base.rgb,col.rgb);".endl()+"float newA=clamp(base.a+(col.a*amount),0.,1.);".endl()+"#ifdef BM_ALPHAMASKED".endl()+"newA=base.a;".endl()+"#endif".endl()+"return vec4(".endl()+"mix(colNew,base.rgb,1.0-(amount*col.a)),".endl()+"newA);".endl()+"#endif".endl()+"}".endl();return t};T.onChangeBlendSelect=function(e,t,n=false){t=String(t);e.toggleDefine("BM_NORMAL",t=="normal");e.toggleDefine("BM_MULTIPLY",t=="multiply");e.toggleDefine("BM_MULTIPLY_INV",t=="multiply invert");e.toggleDefine("BM_AVERAGE",t=="average");e.toggleDefine("BM_ADD",t=="add");e.toggleDefine("BM_SUBTRACT_ONE",t=="subtract one");e.toggleDefine("BM_SUBTRACT",t=="subtract");e.toggleDefine("BM_DIFFERENCE",t=="difference");e.toggleDefine("BM_NEGATION",t=="negation");e.toggleDefine("BM_EXCLUSION",t=="exclusion");e.toggleDefine("BM_LIGHTEN",t=="lighten");e.toggleDefine("BM_DARKEN",t=="darken");e.toggleDefine("BM_OVERLAY",t=="overlay");e.toggleDefine("BM_SCREEN",t=="screen");e.toggleDefine("BM_SOFTLIGHT",t=="softlight");e.toggleDefine("BM_HARDLIGHT",t=="hardlight");e.toggleDefine("BM_COLORDODGE",t=="color dodge");e.toggleDefine("BM_COLORBURN",t=="color burn");e.toggleDefine("BM_MATH_ADD",t=="Math Add");e.toggleDefine("BM_MATH_SUB",t=="Math Subtract");e.toggleDefine("BM_MATH_MUL",t=="Math Multiply");e.toggleDefine("BM_MATH_DIV",t=="Math Divide");e.toggleDefine("BM_MATH",t.indexOf("Math ")==0);e.toggleDefine("BM_ALPHAMASKED",n)};T.AddBlendSelect=function(e,t,n){const r=e.inValueSelect(t||"Blend Mode",["normal","lighten","darken","multiply","multiply invert","average","add","subtract","difference","negation","exclusion","overlay","screen","color dodge","color burn","softlight","hardlight","subtract one","Math Add","Math Subtract","Math Multiply","Math Divide"],n||"normal");return r};T.AddBlendAlphaMask=function(e,t,n){const r=e.inSwitch(t||"Alpha Mask",["Off","On"],n||"Off");return r};T.setupBlending=function(n,r,i,e,a){const t=()=>{let e=false;if(a)e=a.get()=="On";T.onChangeBlendSelect(r,i.get(),e);let t=i.get();if(t=="normal")t=null;else if(t=="multiply")t="mul";else if(t=="multiply invert")t="mulinv";else if(t=="lighten")t="light";else if(t=="darken")t="darken";else if(t=="average")t="avg";else if(t=="subtract one")t="sub one";else if(t=="subtract")t="sub";else if(t=="difference")t="diff";else if(t=="negation")t="neg";else if(t=="exclusion")t="exc";else if(t=="overlay")t="ovl";else if(t=="color dodge")t="dodge";else if(t=="color burn")t="burn";else if(t=="softlight")t="soft";else if(t=="hardlight")t="hard";else if(t=="Math Add")t="+";else if(t=="Math Subtract")t="-";else if(t=="Math Multiply")t="*";else if(t=="Math Divide")t="/";n.setUiAttrib({extendTitle:t})};n.setPortGroup("Blending",[i,e,a]);let s=false;i.onChange=t;if(a){a.onChange=t;s=a.get()=="On"}T.onChangeBlendSelect(r,i.get(),s)};const S={"CGL.BLENDMODES":function(){this.name="blendmodes";this.srcHeadFrag=T.getBlendCode()},"CGL.BLENDMODES3":function(){this.name="blendmodes3";this.srcHeadFrag=T.getBlendCode(3)},"CGL.LUMINANCE":function(){this.name="luminance";this.srcHeadFrag="".endl()+"float cgl_luminance(vec3 c)".endl()+"{".endl()+"    return dot(vec3(0.2126,0.7152,0.0722),c);".endl()+"}".endl()},"CGL.RANDOM_OLD":function(){this.name="randomNumber";this.srcHeadFrag="".endl()+"float cgl_random(vec2 co)".endl()+"{".endl()+"    return fract(sin(dot(co.xy ,vec2(12.9898,4.1414))) * 432758.5453);".endl()+"}".endl()+"vec3 cgl_random3(vec2 co)".endl()+"{".endl()+"    return vec3( cgl_random(co),cgl_random(co+0.5711),cgl_random(co+1.5711));".endl()+"}"},"CGL.RANDOM_LOW":function(){this.name="randomNumber";this.srcHeadFrag="".endl()+"float cgl_random(vec2 co)".endl()+"{".endl()+"    return fract(sin(dot(co.xy ,vec2(12.9898,4.1414))) * 358.5453);".endl()+"}".endl()+"vec3 cgl_random3(vec2 co)".endl()+"{".endl()+"    return vec3( cgl_random(co),cgl_random(co+0.5711),cgl_random(co+1.5711));".endl()+"}"},"CGL.RANDOM_TEX":function(){this.name="randomNumbertex";this.srcHeadFrag="".endl()+"UNI sampler2D CGLRNDTEX;".endl()+"float cgl_random(vec2 co)".endl()+"{".endl()+"    return texture(CGLRNDTEX,co*5711.0).r;".endl()+"}".endl()+"vec3 cgl_random3(vec2 co)".endl()+"{".endl()+"    return texture(CGLRNDTEX,co*5711.0).rgb;".endl()+"}";this.initUniforms=function(e){return[new h(e,"t","CGLRNDTEX",7)]};this.onBind=function(e,t){u.getRandomTexture(e);e.setTexture(7,u.getRandomTexture(e).tex)}}};class w{constructor(e){this.shader=new CGL.Shader(e,"markermaterial");const t="".endl()+"void main()".endl()+"{".endl()+"    outColor = vec4(color.rgb,1.0);".endl()+"}";const n="".endl()+"IN vec3 vPosition;".endl()+"UNI mat4 projMatrix;".endl()+"UNI mat4 mvMatrix;".endl()+"void main()".endl()+"{".endl()+"   gl_Position = projMatrix * mvMatrix * vec4(vPosition,1.0);".endl()+"}";this.shader.setSource(n,t);this.coloruni=this.shader.addUniformFrag("4f","color",[1,.777,1,1])}setColor(e,t,n,r){this.coloruni.set(e,t,n,r)}}class N extends c.Events{id=C.utils.simpleId();_isValid=true;_defines=[];_moduleNames=[];_moduleNumId=0;_needsRecompile=true;_compileReason="initial";_modules=[];_compileCount=0;logError=true;num=-1;lastCompile=0;constructor(){super()}setWhyCompile(e){this._compileReason=e;this._needsRecompile=true}getWhyCompile(){return this._compileReason}needsRecompile(){return this._needsRecompile}removeUniform(t){for(let e=0;e<this._uniforms.length;e++){if(this._uniforms[e].getName()==t){this._uniforms.splice(e,1)}}this.setWhyCompile("remove uniform "+t)}hasUniformInStage(t,e){let n=this.defaultUniBindingFrag;if(e==GPUShaderStage.VERTEX)n=this.defaultUniBindingVert;if(e==GPUShaderStage.COMPUTE)n=this.defaultUniBindingCompute;for(let e=0;e<this._uniforms.length;e++){console.log("hasuniiiiiiiiiiiiiii",this._uniforms[e].getName(),t);if(this._uniforms[e].getName()==t)return true}return false}hasUniform(e){}toggleDefine(t,e){if(e&&typeof e=="object"&&e.addEventListener){if(e.changeListener)e.off(e.changeListener);e.onToggleDefine=e=>{this.toggleDefine(t,e)};e.changeListener=e.on("change",e.onToggleDefine);e=e.get()}if(e)this.define(t);else this.removeDefine(t)}define(t,n=""){if(n===null||n===undefined)n="";if(typeof n=="object"){n.removeEventListener("change",n.onDefineChange);n.onDefineChange=e=>{this.define(t,e)};n.on("change",n.onDefineChange);n=n.get()}for(let e=0;e<this._defines.length;e++){if(this._defines[e][0]==t&&this._defines[e][1]==n)return;if(this._defines[e][0]==t){this._defines[e][1]=n;this.setWhyCompile("define "+t+" "+n);return}}this.setWhyCompile("define "+t+" "+n);this._defines.push([t,n])}getDefines(){return this._defines}getDefine(t){for(let e=0;e<this._defines.length;e++)if(this._defines[e][0]==t)return this._defines[e][1];return null}hasDefine(t){for(let e=0;e<this._defines.length;e++)if(this._defines[e][0]==t)return true}removeDefine(t){for(let e=0;e<this._defines.length;e++){if(this._defines[e][0]==t){this._defines.splice(e,1);this.setWhyCompile("define removed:"+t);return}}}hasModule(t){for(let e=0;e<this._modules.length;e++)if(this._modules[e].id==t)return true;return false}setModules(e){this._moduleNames=e}removeModule(n){for(let e=0;e<this._modules.length;e++){if(n&&n.id){if(this._modules[e].id==n.id||!this._modules[e]){let t=true;while(t){t=false;for(let e=0;e<this._uniforms.length;e++){if(this._uniforms[e].getName().startsWith(n.prefix)){this._uniforms.splice(e,1);t=true;continue}}}this.setWhyCompile("remove module "+n.title);this._modules.splice(e,1);break}}}}getNumModules(){return this._modules.length}getCurrentModules(){return this._modules}addModule(e,t){if(this.hasModule(e.id))return;if(!e.id)e.id=C.utils.simpleId();if(!e.numId)e.numId=this._moduleNumId;if(!e.num)e.num=this._modules.length;if(t&&!t.group)t.group=C.utils.simpleId();if(!e.group)if(t)e.group=t.group;else e.group=C.utils.simpleId();e.prefix="mod"+e.group+"_";this._modules.push(e);this.setWhyCompile("add module "+e.title);this._moduleNumId++;return e}isValid(){return this._isValid}}const U=`
{{MODULES_HEAD}}
IN vec3 vPosition; //!@
IN vec2 attrTexCoord;
IN vec3 attrVertNormal;
IN vec3 attrTangent,attrBiTangent;

IN float attrVertIndex;

OUT vec2 texCoord;
OUT vec3 norm;
UNI mat4 projMatrix;
UNI mat4 viewMatrix;
UNI mat4 modelMatrix;

void main()
{
    texCoord=attrTexCoord;
    norm=attrVertNormal;
    vec4 pos=vec4(vPosition,  1.0);
    vec3 tangent=attrTangent;
    vec3 bitangent=attrBiTangent;
    mat4 mMatrix=modelMatrix;
    gl_PointSize=10.0;

    {{MODULE_VERTEX_POSITION}}

    mat4 modelViewMatrix=viewMatrix*mMatrix;
    {{MODULE_VERTEX_MODELVIEW}}

    gl_Position = projMatrix * modelViewMatrix * pos;
}
`;let k=0;function y(){return U}function B(e,t,n){if(e==undefined){e=.5;t=.5;n=.5}return""+A+"IN vec2 texCoord;"+A+"{{MODULES_HEAD}}"+A+"void main()"+A+"{"+A+"    vec4 col=vec4("+e+","+t+","+n+",1.0);"+A+"    {{MODULE_COLOR}}"+A+"    outColor = col;"+A+"}"}class O extends N{_uniforms=[];constructor(e,t,n){super();if(!e)throw new Error("shader constructed without cgl "+t);this._log=new c.Logger("cgl_shader");this._cgl=e;if(!t)this._log.stack("no shader name given");this._name=t||"unknown";if(n)this.opId=n.id;this.glslVersion=0;if(e.glVersion>1)this.glslVersion=300;this._materialId=++k;this._program=null;this._drawBuffers=[true];this.error=null;this.ignoreMissingUniforms=false;this._projMatrixUniform=null;this._mvMatrixUniform=null;this._mMatrixUniform=null;this._vMatrixUniform=null;this._camPosUniform=null;this._normalMatrixUniform=null;this._inverseViewMatrixUniform=null;this._fromUserInteraction=false;this._attrVertexPos=-1;this.precision=e.patch.config.glslPrecision||"highp";this._pMatrixState=-1;this._vMatrixState=-1;this._countMissingUniforms=0;this._modGroupCount=0;this._feedBackNames=[];this._attributes=[];this.glPrimitive=null;this.offScreenPass=false;this._extensions=[];this.srcVert=y();this.srcFrag=B();this.lastCompile=0;this._libs=[];this._structNames=[];this._structUniformNames=[];this._textureStackUni=[];this._textureStackTex=[];this._textureStackType=[];this._textureStackTexCgl=[];this._tempNormalMatrix=P.mat4.create();this._tempCamPosMatrix=P.mat4.create();this._tempInverseViewMatrix=P.mat4.create();this._tempInverseProjMatrix=P.mat4.create();this.setModules(["MODULE_VERTEX_POSITION","MODULE_COLOR","MODULE_NORMAL","MODULE_BEGIN_FRAG","MODULE_VERTEX_MODELVIEW"])}isValid(){return this._isValid}getCgl(){return this._cgl}getName(){return this._name}enableExtension(e){this.setWhyCompile("enable extension "+e);this._extensions.push(e)}getAttrVertexPos(){return this._attrVertexPos}hasTextureUniforms(){for(let e=0;e<this._uniforms.length;e++)if(this._uniforms[e].getType()=="t")return true;return false}copyUniformValues(t){for(let e=0;e<t._uniforms.length;e++){if(!this._uniforms[e]){this._log.log("unknown uniform?!");continue}this.getUniform(t._uniforms[e].getName()).set(t._uniforms[e].getValue())}this.popTextures();for(let e=0;e<t._textureStackUni.length;e++){this._textureStackUni[e]=t._textureStackUni[e];this._textureStackTex[e]=t._textureStackTex[e];this._textureStackType[e]=t._textureStackType[e];this._textureStackTexCgl[e]=t._textureStackTexCgl[e]}}copy(){const t=new O(this._cgl,this._name+" copy");t.setSource(this.srcVert,this.srcFrag);t._modules=JSON.parse(JSON.stringify(this._modules));t._defines=JSON.parse(JSON.stringify(this._defines));t._modGroupCount=this._modGroupCount;t._moduleNames=this._moduleNames;t.glPrimitive=this.glPrimitive;t.offScreenPass=this.offScreenPass;t._extensions=this._extensions;t.wireframe=this.wireframe;t._attributes=this._attributes;for(let e=0;e<this._uniforms.length;e++){const n=this._uniforms[e].copy(t);n.resetLoc()}t.setWhyCompile("copy");return t}setSource(e,t,n=false){this._fromUserInteraction=n;this.srcVert=e;this.srcFrag=t;this.setWhyCompile("Source changed");this._isValid=true}_addLibs(e){for(const t in S){if(e.includes(t)){const n=new S[t];e=e.replace("{{"+t+"}}",n.srcHeadFrag);this._libs.push(n);if(n.initUniforms)n.initUniforms(this)}}return e}createStructUniforms(){let r="";let i="";this._structNames=[];this._injectedStringsFrag={};this._injectedStringsVert={};this._structUniformNamesIndicesFrag=[];this._structUniformNamesIndicesVert=[];for(let n=0;n<this._uniforms.length;n++){if(this._uniforms[n].isStructMember()){const a="{{INJECTION_POINT_STRUCT_"+this._uniforms[n]._structName+"}}";if(!this._structNames.includes(this._uniforms[n]._structName)){const s="struct "+this._uniforms[n]._structName+" {"+A+a+"};"+A+A;if(this._uniforms[n].getShaderType()==="both"||this._uniforms[n].getShaderType()==="frag")r=r.concat(s);if(this._uniforms[n].getShaderType()==="both"||this._uniforms[n].getShaderType()==="vert")i=i.concat(s);this._structNames.push(this._uniforms[n]._structName);this._injectedStringsFrag[this._uniforms[n]._structName]=[];this._injectedStringsVert[this._uniforms[n]._structName]=[]}let e="";if(this._uniforms[n].comment)e=" // "+this._uniforms[n].comment;let t="";if(this._uniforms[n].getGlslTypeString()==undefined)t+="//";t+="  "+this._uniforms[n].getGlslTypeString()+" "+this._uniforms[n]._propertyName+";"+e;if(this._uniforms[n].getShaderType()==="both"){if(!this._injectedStringsFrag[this._uniforms[n]._structName].includes(t)&&!this._injectedStringsVert[this._uniforms[n]._structName].includes(t)){const o=r.lastIndexOf(a);const l=i.lastIndexOf(a);r=r.slice(0,o)+t+r.slice(o-1);i=i.slice(0,l)+t+i.slice(l-1);this._injectedStringsFrag[this._uniforms[n]._structName].push(t);this._injectedStringsVert[this._uniforms[n]._structName].push(t)}if(!this._structUniformNamesIndicesFrag.includes(n))this._structUniformNamesIndicesFrag.push(n);if(!this._structUniformNamesIndicesVert.includes(n))this._structUniformNamesIndicesVert.push(n)}else if(this._uniforms[n].getShaderType()==="frag"){if(!this._injectedStringsFrag[this._uniforms[n]._structName].includes(t)){const o=r.lastIndexOf(a);r=r.slice(0,o)+t+r.slice(o-1);this._injectedStringsFrag[this._uniforms[n]._structName].push(t)}if(!this._structUniformNamesIndicesFrag.includes(n))this._structUniformNamesIndicesFrag.push(n)}else if(this._uniforms[n].getShaderType()==="vert"){if(!this._injectedStringsVert[this._uniforms[n]._structName].includes(t)){const l=i.lastIndexOf(a);i=i.slice(0,l)+t+i.slice(l-1);this._injectedStringsVert[this._uniforms[n]._structName].push(t)}if(!this._structUniformNamesIndicesVert.includes(n))this._structUniformNamesIndicesVert.push(n)}}}this._uniDeclarationsFrag=[];this._uniDeclarationsVert=[];for(let e=0;e<this._structUniformNamesIndicesFrag.length;e+=1){const t=this._structUniformNamesIndicesFrag[e];const n="UNI "+this._uniforms[t]._structName+" "+this._uniforms[t]._structUniformName+";"+A;if(!this._uniDeclarationsFrag.includes(n)){const a="{{INJECTION_POINT_STRUCT_"+this._uniforms[t]._structName+"}}";r=r.replace(a,"");r+=n;this._uniDeclarationsFrag.push(n)}}for(let e=0;e<this._structUniformNamesIndicesVert.length;e+=1){const t=this._structUniformNamesIndicesVert[e];const n="UNI "+this._uniforms[t]._structName+" "+this._uniforms[t]._structUniformName+";"+A;if(!this._uniDeclarationsVert.includes(n)){const a="{{INJECTION_POINT_STRUCT_"+this._uniforms[t]._structName+"}}";i=i.replace(a,"");i+=n;this._uniDeclarationsVert.push(n)}}return[i,r]}_getAttrSrc(e,t){const n={};if(e.name&&e.type){n.srcHeadVert="";if(!t)n.srcHeadVert+="#ifndef ATTRIB_"+e.name+A;n.srcHeadVert+="#define ATTRIB_"+e.name+A;n.srcHeadVert+="IN "+e.type+" "+e.name+";"+A;if(!t)n.srcHeadVert+="#endif"+A;if(e.nameFrag){n.srcHeadVert+="";if(!t)n.srcHeadVert+="#ifndef ATTRIB_"+e.nameFrag+A;n.srcHeadVert+="#define ATTRIB_"+e.nameFrag+A;n.srcHeadVert+="OUT "+e.type+" "+e.nameFrag+";"+A;if(!t)n.srcHeadVert+="#endif"+A;n.srcVert=""+A+e.nameFrag+"="+e.name+";";n.srcHeadFrag="";if(!t)n.srcHeadFrag+="#ifndef ATTRIB_"+e.nameFrag+A;n.srcHeadFrag+="#define ATTRIB_"+e.nameFrag+A;n.srcHeadFrag+="IN "+e.type+" "+e.nameFrag+";"+A;if(!t)n.srcHeadFrag+="#endif"+A}}return n}compile(){if(this._cgl.aborted)return;const e=performance.now();this._cgl.profileData.profileShaderCompiles++;this._cgl.profileData.profileShaderCompileName=this._name+" ["+this._compileReason+"]";let t="";if(this._extensions)for(let e=0;e<this._extensions.length;e++)t+="#extension "+this._extensions[e]+" : enable"+A;let n="";if(this._defines.length)n="\n// cgl generated"+A;for(let e=0;e<this._defines.length;e++)n+="#define "+this._defines[e][0]+" "+this._defines[e][1]+""+A;const r=this.createStructUniforms();this._cgl.profileData.addHeavyEvent("shader compile",this._name+" ["+this._compileReason+"]");this._compileReason="";if(this._uniforms){const m=this._uniforms.map(e=>{return e._name});const v=[];for(let e=0;e<this._uniforms.length;e++){const b=this._uniforms[e];const _=m.indexOf(b._name,e+1);if(_>-1)v.push(e)}for(let e=this._uniforms.length-1;e>=0;e-=1){if(v.includes(e))this._uniforms.splice(e,1);else this._uniforms[e].resetLoc()}}this._cgl.printError("uniform resets");this._compileCount++;if(this.hasTextureUniforms())n+="#define HAS_TEXTURES"+A;let i="";let a="";if(!this.srcFrag){this._log.warn("[cgl shader] has no fragment source!",this._name,this);this.srcVert=y();this.srcFrag=B()}i="#version 300 es"+A+"// "+A+"// vertex shader "+this._name+A+"// "+A+"precision "+this.precision+" float;"+A+"precision "+this.precision+" sampler2D;"+A+""+A+"#define WEBGL2"+A+"#define texture2D texture"+A+"#define UNI uniform"+A+"#define IN in"+A+"#define OUT out"+A;a="#version 300 es"+A+"// "+A+"// fragment shader "+this._name+A+"// "+A+"precision "+this.precision+" float;"+A+"precision "+this.precision+" sampler2D;"+A+""+A+"#define WEBGL2"+A+"#define texture2D texture"+A+"#define IN in"+A+"#define OUT out"+A+"#define UNI uniform"+A+"{{DRAWBUFFER}}"+A;let s="\n// cgl generated"+A;let o="\n// cgl generated"+A;a+="\n// active mods: --------------- ";i+="\n// active mods: --------------- ";let l=false;let u=false;for(let t=0;t<this._moduleNames.length;t++){for(let e=0;e<this._modules.length;e++){if(this._modules[e].name==this._moduleNames[t]){if(this._modules[e].srcBodyFrag||this._modules[e].srcHeadFrag){l=true;a+="\n// "+t+"."+e+". "+this._modules[e].title+" ("+this._modules[e].name+")"}if(this._modules[e].srcBodyVert||this._modules[e].srcHeadVert){i+="\n// "+t+"."+e+". "+this._modules[e].title+" ("+this._modules[e].name+")";u=true}}}}if(!u)a+="\n// no mods used...";if(!l)a+="\n// no mods used...";a+="\n";i+="\n";for(let n=0;n<this._uniforms.length;n++){if(this._uniforms[n].shaderType&&!this._uniforms[n].isStructMember()){let e="";if(!this._uniforms[n].getGlslTypeString())e+="// ";e+="UNI "+this._uniforms[n].getGlslTypeString()+" "+this._uniforms[n].getName();let t="";if(this._uniforms[n].comment)t=" // "+this._uniforms[n].comment;if(this._uniforms[n].shaderType=="vert"||this._uniforms[n].shaderType=="both")if(!this.srcVert.includes(e)&&!this.srcVert.includes("uniform "+this._uniforms[n].getGlslTypeString()+" "+this._uniforms[n].getName()))s+=e+";"+t+A;if(this._uniforms[n].shaderType=="frag"||this._uniforms[n].shaderType=="both")if(!this.srcFrag.includes(e)&&!this.srcFrag.includes("uniform "+this._uniforms[n].getGlslTypeString()+" "+this._uniforms[n].getName()))o+=e+";"+t+A}}let c=0;let h=0;for(let e=0;e<this._uniforms.length;e++){if(this._uniforms[e].shaderType&&!this._uniforms[e].isStructMember()){if(this._uniforms[e].shaderType=="vert"||this._uniforms[e].shaderType=="both")h++;if(this._uniforms[e].shaderType=="frag"||this._uniforms[e].shaderType=="both")c++}}if(c>=this._cgl.maxUniformsFrag)this._log.warn("[cgl_shader] num uniforms frag: "+c+" / "+this._cgl.maxUniformsFrag);if(h>=this._cgl.maxUniformsVert)this._log.warn("[cgl_shader] num uniforms vert: "+h+" / "+this._cgl.maxUniformsVert);if(!a.includes("precision"))a="precision "+this.precision+" float;"+A+a;if(!i.includes("precision"))i="precision "+this.precision+" float;"+A+i;if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)){a+="#define MOBILE"+A;i+="#define MOBILE"+A}i=t+i+n+r[0]+s+"\n// -- \n"+this.srcVert;a=t+a+n+r[1]+o+"\n// -- \n"+this.srcFrag;let f="";let d="";this._modules.sort(function(e,t){return e.priority||0-t.priority||0});let p=false;for(let r=0;r<this._moduleNames.length;r++){let t="";let n="";if(!p){p=true;for(let e=0;e<this._attributes.length;e++){const E=this._getAttrSrc(this._attributes[e],true);if(E.srcHeadVert)f+=E.srcHeadVert;if(E.srcVert)t+=E.srcVert;if(E.srcHeadFrag)d+=E.srcHeadFrag}}for(let e=0;e<this._modules.length;e++){const F=this._modules[e];if(F.name==this._moduleNames[r]){f+="\n//---- MOD: group:"+F.group+": idx:"+e+" - prfx:"+F.prefix+" - "+F.title+" ------\n";d+="\n//---- MOD: group:"+F.group+": idx:"+e+" - prfx:"+F.prefix+" - "+F.title+" ------\n";t+="\n\n//---- MOD: "+F.title+" / "+F.priority+" ------\n";n+="\n\n//---- MOD: "+F.title+" / "+F.priority+" ------\n";if(F.attributes)for(let e=0;e<F.attributes.length;e++){const E=this._getAttrSrc(F.attributes[e],false);if(E.srcHeadVert)f+=E.srcHeadVert;if(E.srcVert)t+=E.srcVert;if(E.srcHeadFrag)d+=E.srcHeadFrag}f+=F.srcHeadVert||"";d+=F.srcHeadFrag||"";t+=F.srcBodyVert||"";n+=F.srcBodyFrag||"";f+="\n//---- end mod ------\n";d+="\n//---- end mod ------\n";t+="\n//---- end mod ------\n";n+="\n//---- end mod ------\n";t=t.replace(/{{mod}}/g,F.prefix);n=n.replace(/{{mod}}/g,F.prefix);f=f.replace(/{{mod}}/g,F.prefix);d=d.replace(/{{mod}}/g,F.prefix);t=t.replace(/MOD_/g,F.prefix);n=n.replace(/MOD_/g,F.prefix);f=f.replace(/MOD_/g,F.prefix);d=d.replace(/MOD_/g,F.prefix)}}i=i.replace("{{"+this._moduleNames[r]+"}}",t);a=a.replace("{{"+this._moduleNames[r]+"}}",n)}i=i.replace("{{MODULES_HEAD}}",f);a=a.replace("{{MODULES_HEAD}}",d);i=this._addLibs(i);a=this._addLibs(a);let g="";for(let e=0;e<16;e++)if(a.includes("outColor"+e))this._drawBuffers[e]=true;if(this._drawBuffers.length==1){g="out vec4 outColor;"+A;g+="#define gl_FragColor outColor"+A}else{g+="#define MULTI_COLORTARGETS"+A;g+="vec4 outColor;"+A;let t=0;for(let e=0;e<this._drawBuffers.length;e++){if(t==0)g+="#define gl_FragColor outColor"+e+""+A;g+="layout(location = "+e+") out vec4 outColor"+e+";"+A;t++}}a=a.replace("{{DRAWBUFFER}}",g);if(!this._program){this._program=this._createProgram(i,a)}else{this._program=this._createProgram(i,a);this._projMatrixUniform=null;for(let e=0;e<this._uniforms.length;e++)this._uniforms[e].resetLoc()}this.finalShaderFrag=a;this.finalShaderVert=i;x.lastMesh=null;x.lastShader=null;this._countMissingUniforms=0;this._needsRecompile=false;this.lastCompile=(0,C.now)();this._cgl.profileData.shaderCompileTime+=performance.now()-e}bind(){if(!this._isValid||this._cgl.aborted)return;x.lastShader=this;if(!this._program||this.needsRecompile())this.compile();if(!this._isValid)return;if(!this._projMatrixUniform&&!this.ignoreMissingUniforms){this._countMissingUniforms++;if(this._countMissingUniforms<10){this._projMatrixUniform=this._cgl.gl.getUniformLocation(this._program,m.SHADER.SHADERVAR_UNI_PROJMAT);this._attrVertexPos=this._cgl.glGetAttribLocation(this._program,m.SHADER.SHADERVAR_VERTEX_POSITION);this._mvMatrixUniform=this._cgl.gl.getUniformLocation(this._program,"mvMatrix");this._vMatrixUniform=this._cgl.gl.getUniformLocation(this._program,m.SHADER.SHADERVAR_UNI_VIEWMAT);this._mMatrixUniform=this._cgl.gl.getUniformLocation(this._program,m.SHADER.SHADERVAR_UNI_MODELMAT);this._camPosUniform=this._cgl.gl.getUniformLocation(this._program,m.SHADER.SHADERVAR_UNI_VIEWPOS);this._normalMatrixUniform=this._cgl.gl.getUniformLocation(this._program,m.SHADER.SHADERVAR_UNI_NORMALMAT);this._inverseViewMatrixUniform=this._cgl.gl.getUniformLocation(this._program,m.SHADER.SHADERVAR_UNI_INVVIEWMAT);this._inverseProjMatrixUniform=this._cgl.gl.getUniformLocation(this._program,m.SHADER.SHADERVAR_UNI_INVPROJMAT);this._materialIdUniform=this._cgl.gl.getUniformLocation(this._program,m.SHADER.SHADERVAR_UNI_MATERIALID);this._objectIdUniform=this._cgl.gl.getUniformLocation(this._program,m.SHADER.SHADERVAR_UNI_OBJECTID);for(let e=0;e<this._uniforms.length;e++)this._uniforms[e].needsUpdate=true}}if(this._cgl.currentProgram!=this._program){this._cgl.profileData.profileShaderBinds++;this._cgl.gl.useProgram(this._program);this._cgl.currentProgram=this._program}for(let e=0;e<this._uniforms.length;e++)if(this._uniforms[e].needsUpdate)this._uniforms[e].updateValue();if(this._pMatrixState!=this._cgl.getProjectionMatrixStateCount()){this._pMatrixState=this._cgl.getProjectionMatrixStateCount();this._cgl.gl.uniformMatrix4fv(this._projMatrixUniform,false,this._cgl.pMatrix);this._cgl.profileData.profileMVPMatrixCount++}if(this._objectIdUniform)this._cgl.gl.uniform1f(this._objectIdUniform,++this._cgl.tempData.objectIdCounter);if(this._materialIdUniform)this._cgl.gl.uniform1f(this._materialIdUniform,this._materialId);if(this._vMatrixUniform){if(this._vMatrixState!=this._cgl.getViewMatrixStateCount()){this._cgl.gl.uniformMatrix4fv(this._vMatrixUniform,false,this._cgl.vMatrix);this._cgl.profileData.profileMVPMatrixCount++;this._vMatrixState=this._cgl.getViewMatrixStateCount();if(this._inverseViewMatrixUniform){P.mat4.invert(this._tempInverseViewMatrix,this._cgl.vMatrix);this._cgl.gl.uniformMatrix4fv(this._inverseViewMatrixUniform,false,this._tempInverseViewMatrix);this._cgl.profileData.profileMVPMatrixCount++}if(this._inverseProjMatrixUniform){P.mat4.invert(this._tempInverseProjMatrix,this._cgl.pMatrix);this._cgl.gl.uniformMatrix4fv(this._inverseProjMatrixUniform,false,this._tempInverseProjMatrix);this._cgl.profileData.profileMVPMatrixCount++}}this._cgl.gl.uniformMatrix4fv(this._mMatrixUniform,false,this._cgl.mMatrix);this._cgl.profileData.profileMVPMatrixCount++;if(this._camPosUniform){P.mat4.invert(this._tempCamPosMatrix,this._cgl.vMatrix);this._cgl.gl.uniform3f(this._camPosUniform,this._tempCamPosMatrix[12],this._tempCamPosMatrix[13],this._tempCamPosMatrix[14]);this._cgl.profileData.profileMVPMatrixCount++}}else{const e=P.mat4.create();P.mat4.mul(e,this._cgl.vMatrix,this._cgl.mMatrix);this._cgl.gl.uniformMatrix4fv(this._mvMatrixUniform,false,e);this._cgl.profileData.profileMVPMatrixCount++}if(this._normalMatrixUniform){P.mat4.invert(this._tempNormalMatrix,this._cgl.mMatrix);P.mat4.transpose(this._tempNormalMatrix,this._tempNormalMatrix);this._cgl.gl.uniformMatrix4fv(this._normalMatrixUniform,false,this._tempNormalMatrix);this._cgl.profileData.profileMVPMatrixCount++}for(let e=0;e<this._libs.length;e++){if(this._libs[e].onBind)this._libs[e].onBind.bind(this._libs[e])(this._cgl,this)}this._bindTextures();return this._isValid}unBind(){}dispose(){if(this._program&&this._cgl&&this._cgl.gl)this._cgl.gl.deleteProgram(this._program);this._program=null}setDrawBuffers(e){this._log.warn("useless drawbuffers...?!")}getUniforms(){return this._uniforms}getUniform(t){for(let e=0;e<this._uniforms.length;e++)if(this._uniforms[e].getName()==t)return this._uniforms[e];return null}removeAllUniforms(){this._uniforms=[]}_addUniform(e){this._uniforms.push(e);this.setWhyCompile("add uniform "+name)}addUniformFrag(e,t,n,r,i,a){const s=new h(this,e,t,n,r,i,a);s.shaderType="frag";return s}addUniformVert(e,t,n,r,i,a){const s=new h(this,e,t,n,r,i,a);s.shaderType="vert";return s}addUniformBoth(e,t,n,r,i,a){const s=new h(this,e,t,n,r,i,a);s.shaderType="both";return s}addUniformStructFrag(t,n,r){const i={};if(!r)return i;for(let e=0;e<r.length;e+=1){const a=r[e];if(!this.hasUniform(n+"."+a.name)){const s=new h(this,a.type,n+"."+a.name,a.v1,a.v2,a.v3,a.v4,n,t,a.name);s.shaderType="frag";i[n+"."+a.name]=s}}return i}addUniformStructVert(t,n,r){const i={};if(!r)return i;for(let e=0;e<r.length;e+=1){const a=r[e];if(!this.hasUniform(n+"."+a.name)){const s=new h(this,a.type,n+"."+a.name,a.v1,a.v2,a.v3,a.v4,n,t,a.name);s.shaderType="vert";i[n+"."+a.name]=s}}return i}addUniformStructBoth(t,n,r){const i={};if(!r)return i;for(let e=0;e<r.length;e+=1){const a=r[e];if(a.type==="2i"||a.type==="i"||a.type==="3i")this._log.error("Adding an integer struct member to both shaders can potentially error. Please use different structs for each shader. Error occured in struct:",t," with member:",a.name," of type:",a.type,".");if(!this.hasUniform(n+"."+a.name)){const s=new h(this,a.type,n+"."+a.name,a.v1,a.v2,a.v3,a.v4,n,t,a.name);s.shaderType="both";i[n+"."+a.name]=s}}return i}_createProgram(e,t){this._cgl.printError("before _createprogram");const n=this._cgl.gl.createProgram();this.vshader=O.createShader(this._cgl,e,this._cgl.gl.VERTEX_SHADER,this);this.fshader=O.createShader(this._cgl,t,this._cgl.gl.FRAGMENT_SHADER,this);if(this.vshader&&this.fshader){this._cgl.gl.attachShader(n,this.vshader);this._cgl.gl.attachShader(n,this.fshader);this._linkProgram(n,e,t)}else{this._isValid=false;this._cgl.printError("shader _createProgram");this._log.error("could not link shaderprogram");return null}this._cgl.printError("shader _createProgram");return n}hasErrors(){return this._hasErrors}_linkProgram(e,t,n){this._cgl.printError("before _linkprogram");if(this._feedBackNames.length>0){this._cgl.gl.transformFeedbackVaryings(e,this._feedBackNames,this._cgl.gl.SEPARATE_ATTRIBS)}this._cgl.gl.linkProgram(e);this._cgl.printError("gl.linkprogram");this._isValid=true;this._hasErrors=false;if(this._cgl.patch.config.glValidateShader!==false){this._cgl.gl.validateProgram(e);if(!this._cgl.gl.getProgramParameter(e,this._cgl.gl.VALIDATE_STATUS)){this._log.log("shaderprogram validation failed...");this._cgl.gl.getProgramInfoLog(e)}if(!this._cgl.gl.getProgramParameter(e,this._cgl.gl.LINK_STATUS)){this._hasErrors=true;const r=this._cgl.gl.getShaderInfoLog(this.fshader);const i=this._cgl.gl.getShaderInfoLog(this.vshader);if(this.logError)this._log.error(this._name+" shader linking fail...");else this._log.warn(this._name+" shader linking fail...");if(r)this._log.warn(this._cgl.gl.getShaderInfoLog(this.fshader));if(i)this._log.warn(this._cgl.gl.getShaderInfoLog(this.vshader));this._cgl.gl.getProgramInfoLog(e);if(!CABLES.UI)this._log.log(this);this._isValid=false;this._cgl.printError("shader link err")}}}getProgram(){return this._program}setFeedbackNames(e){this.setWhyCompile("setFeedbackNames");this._feedBackNames=e}addAttribute(t){for(let e=0;e<this._attributes.length;e++){if(this._attributes[e].name==t.name&&this._attributes[e].nameFrag==t.nameFrag)return}this._attributes.push(t);this.setWhyCompile("addAttribute")}bindTextures(){this._bindTextures()}_bindTextures(){if(this._textureStackTex.length>this._cgl.maxTextureUnits){this._log.warn("[shader._bindTextures] too many textures bound",this._textureStackTex.length+"/"+this._cgl.maxTextureUnits)}for(let n=0;n<this._textureStackTex.length;n++){if(!this._textureStackTex[n]&&!this._textureStackTexCgl[n]){this._log.warn("no texture for pushtexture",this._name)}else{let e=this._textureStackTex[n];if(this._textureStackTexCgl[n]){e=this._textureStackTexCgl[n].tex||CGL.Texture.getEmptyTexture(this._cgl).tex}let t=true;if(!this._textureStackUni[n]){this._log.warn("no uniform for pushtexture",this._name);t=this._cgl.setTexture(n,e,this._textureStackType[n])}else{this._textureStackUni[n].setValue(n);t=this._cgl.setTexture(n,e,this._textureStackType[n])}if(!t)this._log.warn("tex bind failed",this.getName(),this._textureStackUni[n])}}}setUniformTexture(t,n){n=n||u.getTempTexture(this._cgl);for(let e=0;e<this._textureStackUni.length;e++)if(this._textureStackUni[e]==t){const r=this._textureStackTex[e]||this._textureStackTexCgl[e];if(n.hasOwnProperty("tex")){this._textureStackTexCgl[e]=n;this._textureStackTex[e]=null}else{this._textureStackTexCgl[e]=null;this._textureStackTex[e]=n}return r}return null}pushTexture(e,t,n){if(!e){return}if(!t){return}if(!t.hasOwnProperty("tex")&&!(t instanceof WebGLTexture)){this._log.warn(new Error("invalid texture").stack);this._log.warn("[cgl_shader] invalid texture...",t);return}this._textureStackUni.push(e);if(t.hasOwnProperty("tex")){this._textureStackTexCgl.push(t);this._textureStackTex.push(null)}else{this._textureStackTexCgl.push(null);this._textureStackTex.push(t)}this._textureStackType.push(n)}popTexture(){this._textureStackUni.pop();this._textureStackTex.pop();this._textureStackTexCgl.pop();this._textureStackType.pop()}popTextures(){this._textureStackTex.length=this._textureStackTexCgl.length=this._textureStackType.length=this._textureStackUni.length=0}getMaterialId(){return this._materialId}getInfo(){const e={};e.name=this._name;e.defines=this.getDefines();e.hasErrors=this.hasErrors();return e}getDefaultFragmentShader(e,t,n,r){return B(e,t,n,r)}getDefaultVertexShader(){return y()}}O.getDefaultVertexShader=y;O.getDefaultFragmentShader=B;O.getErrorFragmentShader=function(){return""+A+"void main()"+A+"{"+A+"   float g=mod((gl_FragCoord.y+gl_FragCoord.x),50.0)/50.0;"+A+"   g= step(0.1,g);"+A+"   outColor = vec4( g+0.5, 0.0, 0.0, 1.0);"+A+"}"};O.createShader=function(e,t,n,r){if(e.aborted)return;const i=e.gl.createShader(n);e.gl.shaderSource(i,t);e.gl.compileShader(i);if(!e.gl.getShaderParameter(i,e.gl.COMPILE_STATUS)){r.error={str:t,infoLog:e.gl.getShaderInfoLog(i)};if(CABLES.UI)gui.emitEvent("ShaderError",r);if(!r.error.infoLog){r._log.warn("empty shader info log",this._name);return}r.setSource(O.getDefaultVertexShader(),O.getErrorFragmentShader())}return i};const j=Math.PI/180;const G=180/Math.PI;const V=null;const z=window.navigator.userAgent.includes("Windows");const D=function(t){let n;if(t.wheelDelta){n=t.wheelDelta%120-0==-0?t.wheelDelta/120:t.wheelDelta/30;n*=-1.5;if(z)n*=2}else{let e=t.deltaY;if(t.shiftKey)e=t.deltaX;const r=e||t.detail;n=-(r%3?r*10:r/3);n*=-3}if(n>20)n=20;if(n<-20)n=-20;return n};const H=D;const X=D;class I{constructor(e){this._cgl=e;this._lastTime=0;this.pause=false;this.profileUniformCount=0;this.profileShaderBinds=0;this.profileUniformCount=0;this.profileShaderCompiles=0;this.profileVideosPlaying=0;this.profileMVPMatrixCount=0;this.profileEffectBuffercreate=0;this.profileShaderGetUniform=0;this.profileFrameBuffercreate=0;this.profileMeshSetGeom=0;this.profileTextureNew=0;this.profileGenMipMap=0;this.profileOnAnimFrameOps=0;this.profileFencedPixelRead=0;this.profileMainloopMs=0;this.profileMeshDraw=0;this.profileTextureEffect=0;this.profileTexPreviews=0;this.shaderCompileTime=0;this.profileMeshNumElements=0;this.profileMeshAttributes=0;this.profileSingleMeshAttribute=[];this.heavyEvents=[];this.doProfileGlQuery=false;this.glQueryData={};this.counts={}}clear(){this.counts={};this.profileSingleMeshAttribute={};this.profileMeshAttributes=0;this.profileUniformCount=0;this.profileShaderGetUniform=0;this.profileShaderCompiles=0;this.profileShaderBinds=0;this.profileTextureResize=0;this.profileFrameBuffercreate=0;this.profileEffectBuffercreate=0;this.profileTextureDelete=0;this.profileMeshSetGeom=0;this.profileVideosPlaying=0;this.profileMVPMatrixCount=0;this.profileNonTypedAttrib=0;this.profileNonTypedAttribNames="";this.profileTextureNew=0;this.profileGenMipMap=0;this.profileFramebuffer=0;this.profileMeshDraw=0;this.profileTextureEffect=0;this.profileTexPreviews=0;this.profileMeshNumElements=0;this.profileFencedPixelRead=0}clearGlQuery(){for(let e in this.glQueryData){if(!this.glQueryData[e].lastClear||performance.now()-this.glQueryData[e].lastClear>1e3){this.glQueryData[e].time=this.glQueryData[e]._times/this.glQueryData[e]._numcount;this.glQueryData[e].num=this.glQueryData[e]._numcount;this.glQueryData[e]._times=0;this.glQueryData[e]._numcount=0;this.glQueryData[e].lastClear=performance.now()}}}count(e,t){this.counts[e]=this.counts[e]||[];this.counts[e].push(t)}addHeavyEvent(e,t,n){const r={event:e,name:t,info:n,date:performance.now()};this.heavyEvents.push(r);this._cgl.emitEvent("heavyEvent",r)}}class M{constructor(){this._arr=[P.mat4.create()];this._index=0;this.stateCounter=0}push(e){this._index++;this.stateCounter++;if(this._index==this._arr.length){const t=P.mat4.create();this._arr.push(t)}P.mat4.copy(this._arr[this._index],e||this._arr[this._index-1]);return this._arr[this._index]}pop(){this.stateCounter++;this._index--;if(this._index<0)this._index=0;return this._arr[this._index]}length(){return this._index}}class W{hasFocus=false;forceAspect=0;constructor(e){this._log=new c.Logger("CgCanvas");if(!e){this._log.error("CgCanvas no options")}else{this._canvasEle=e.canvasEle}if(!e.cg)this._log.error("CgCanvas options has no cg");if(!e.canvasEle)this._log.error("CgCanvas options has no canvasEle");this._cg=e.cg;this.pixelDensity=1;this.canvasWidth=this.canvasEle.clientWidth;this.canvasHeight=this.canvasEle.clientHeight;this._oldWidthRp=-1;this._oldHeightRp=-1;this.setSize(this.canvasWidth,this.canvasHeight);this.canvasEle.addEventListener("focus",()=>{this.hasFocus=true});this.canvasEle.addEventListener("blur",()=>{this.hasFocus=false})}get canvasEle(){return this._canvasEle}setSize(t,n,e=false){let r=0;if(this.forceAspect){let e=t/this.forceAspect;if(e<n)r=(n-e)/2;n=e}if(this._oldWidthRp!=t*this.pixelDensity||this._oldHeightRp!=n*this.pixelDensity){this._oldWidthRp=this.canvasEle.width=t*this.pixelDensity;this._oldHeightRp=this.canvasEle.height=n*this.pixelDensity;if(!e){this.canvasEle.style.width=t+"px";this.canvasEle.style.height=n+"px";this.canvasEle.style.marginTop=r+"px"}this.updateSize();this._cg.emitEvent("resize")}}updateSize(){this.canvasEle.width=this.canvasWidth=this.canvasEle.clientWidth*this.pixelDensity;this.canvasEle.height=this.canvasHeight=this.canvasEle.clientHeight*this.pixelDensity}dispose(){if(this._canvasEle)this._canvasEle.remove();this._canvasEle=null}}class Y extends c.Events{constructor(){super();this._timeStartFrame=0;this._timeStartSecond=0;this._fpsCounter=0;this._msCounter=0;this._frameCount=0;this.logFps=false;this.stats={ms:0,fps:0}}get frameCount(){return this._frameCount}startFrame(){this._timeStartFrame=(0,C.now)()}endFrame(){this._frameCount++;this._fpsCounter++;const e=(0,C.now)()-this._timeStartFrame;this._msCounter+=e;if((0,C.now)()-this._timeStartSecond>1e3)this.endSecond()}endSecond(){this.stats.fps=this._fpsCounter;this.stats.ms=Math.round(this._msCounter/this._fpsCounter*100)/100;this.emitEvent("performance",this.stats);if(this.logFps)console.log(this.stats);this._fpsCounter=0;this._msCounter=0;this._timeStartSecond=(0,C.now)()}}class L extends c.Events{static API_UNKNOWN=0;static API_WEBGL=1;static API_WEBGPU=2;static EVENT_RESIZE="resize";gApi=0;constructor(e){super();this._log=new c.Logger("cg_context",{onError:e.config.onError});this.tempData=this.frameStore=this.frameStore||{};this.fpsCounter=new Y;this._identView=P.vec3.create();this._ident=P.vec3.create();P.vec3.set(this._identView,0,0,-2);P.vec3.set(this._ident,0,0,0);this._onetimeCallbacks=[];this.maxTexSize=2048;this._viewPort=[0,0,1,1];this._viewPortStack=[];this.patch=e;this.autoReSize=true;this.DEPTH_COMPARE_FUNC_NEVER=0;this.DEPTH_COMPARE_FUNC_LESS=1;this.DEPTH_COMPARE_FUNC_EQUAL=2;this.DEPTH_COMPARE_FUNC_LESSEQUAL=3;this.DEPTH_COMPARE_FUNC_GREATER=4;this.DEPTH_COMPARE_FUNC_NOTEQUAL=5;this.DEPTH_COMPARE_FUNC_GREATEREQUAL=6;this.DEPTH_COMPARE_FUNC_ALWAYS=7;this.profileData=new I(this);this.pMatrix=P.mat4.create();this.mMatrix=P.mat4.create();this.vMatrix=P.mat4.create();this._textureslots=[];this._pMatrixStack=new M;this._mMatrixStack=new M;this._vMatrixStack=new M;this.canvasScale=1;P.mat4.identity(this.mMatrix);P.mat4.identity(this.vMatrix);window.matchMedia("screen and (min-resolution: 2dppx)").addEventListener("change",()=>{this.emitEvent("resize")})}get canvasWidth(){return this.cgCanvas.canvasWidth}get canvasHeight(){return this.cgCanvas.canvasHeight}set pixelDensity(e){if(this.cgCanvas.pixelDensity!=e){this.cgCanvas.pixelDensity=e;this.cgCanvas.updateSize();this.emitEvent("resize")}}get pixelDensity(){return this.cgCanvas.pixelDensity}getGApiName(){return["unknown","WebGL","WebGPU"][this.gApi]}get canvas(){return this.cgCanvas.canvasEle}get viewPort(){return[0,0,this.canvasWidth,this.canvasHeight]}setCanvas(e){if(this.cgCanvas&&e==this.cgCanvas.canvasEle)return;if(typeof e==="string")e=document.getElementById(e);this.cgCanvas=new W({canvasEle:e,cg:this});e.parentElement.classList.add("cablesContainer");if(this._setCanvas)this._setCanvas(e);this.updateSize()}_setCanvas(e){}updateSize(){this.cgCanvas.updateSize()}setSize(e,t,n=false){this.cgCanvas.setSize(e,t,n)}_resizeToWindowSize(){if(this.autoReSize){this.setSize(window.innerWidth,window.innerHeight);this.updateSize()}}_resizeToParentSize(){if(this.autoReSize){const e=this.canvas.parentElement;if(!e){this._log.error("cables: can not resize to container element");return}this.setSize(e.clientWidth,e.clientHeight);this.updateSize()}}setAutoResize(e){window.removeEventListener("resize",this._resizeToWindowSize.bind(this));window.removeEventListener("resize",this._resizeToParentSize.bind(this));if(e=="window"){window.addEventListener("resize",this._resizeToWindowSize.bind(this));window.addEventListener("orientationchange",this._resizeToWindowSize.bind(this));this._resizeToWindowSize()}if(e=="parent"){window.addEventListener("resize",this._resizeToParentSize.bind(this));this._resizeToParentSize()}}pushPMatrix(){this.pMatrix=this._pMatrixStack.push(this.pMatrix)}popPMatrix(){this.pMatrix=this._pMatrixStack.pop();return this.pMatrix}getProjectionMatrixStateCount(){return this._pMatrixStack.stateCounter}pushModelMatrix(){this.mMatrix=this._mMatrixStack.push(this.mMatrix)}popModelMatrix(){this.mMatrix=this._mMatrixStack.pop();return this.mMatrix}modelMatrix(){return this.mMatrix}pushViewMatrix(){this.vMatrix=this._vMatrixStack.push(this.vMatrix)}popViewMatrix(){this.vMatrix=this._vMatrixStack.pop()}getViewMatrixStateCount(){return this._vMatrixStack.stateCounter}_startMatrixStacks(e,t){e=e||this._ident;t=t||this._identView;P.mat4.perspective(this.pMatrix,45,this.canvasWidth/this.canvasHeight,.1,1e3);P.mat4.identity(this.mMatrix);P.mat4.identity(this.vMatrix);P.mat4.translate(this.mMatrix,this.mMatrix,e);P.mat4.translate(this.vMatrix,this.vMatrix,t);this.pushPMatrix();this.pushModelMatrix();this.pushViewMatrix()}_endMatrixStacks(){this.popViewMatrix();this.popModelMatrix();this.popPMatrix()}dispose(){this.aborted=true;if(this.cgCanvas)this.cgCanvas.dispose();if(this._dispose)this._dispose()}_dispose(){}shouldDrawHelpers(e){return false}addNextFrameOnceCallback(e){if(e&&this._onetimeCallbacks.indexOf(e)==-1)this._onetimeCallbacks.push(e)}_execOneTimeCallbacks(){if(this._onetimeCallbacks.length>0){for(let e=0;e<this._onetimeCallbacks.length;e++)this._onetimeCallbacks[e]();this._onetimeCallbacks.length=0}}checkTextureSize(e){e=e||1;e=Math.floor(e);e=Math.min(e,this.maxTexSize);e=Math.max(e,1);return e}screenShot(e,t,n,r){console.log("no screenshot function implemented")}saveScreenshot(n,r,e,t,i){this.patch.renderOneFrame();let a=this.canvas.clientWidth*this.pixelDensity;let s=this.canvas.clientHeight*this.pixelDensity;if(e){this.canvas.width=e;a=e}if(t){this.canvas.height=t;s=t}function o(e,t,n){return Array(t-String(e).length+1).join(n||"0")+e}const l=new Date;const u="".concat(String(l.getFullYear())+String(l.getMonth()+1)+String(l.getDate()),"_").concat(o(l.getHours(),2)).concat(o(l.getMinutes(),2)).concat(o(l.getSeconds(),2));if(!n)n="cables_"+u+".png";else n+=".png";this.screenShot(e=>{this.canvas.width=a;this.canvas.height=s;if(e){const t=document.createElement("a");t.download=n;t.href=URL.createObjectURL(e);console.log("scrrenshot");setTimeout(function(){t.click();if(r)r(e)},100)}else{this._log.log("screenshot: no blob")}})}hasFocus(){return this.cgCanvas.hasFocus}}const q={BLEND_NONE:0,BLEND_NORMAL:1,BLEND_ADD:2,BLEND_SUB:3,BLEND_MUL:4};class Z extends L{constructor(e){super(e);this.gApi=L.API_WEBGL;this.aborted=false;this.pushMvMatrix=this.pushModelMatrix;this.popMvMatrix=this.popmMatrix=this.popModelMatrix;this._log=new c.Logger("cgl_context",{onError:e.config.onError});this.glVersion=0;this.glUseHalfFloatTex=false;this.clearCanvasTransparent=true;this.clearCanvasDepth=true;this.debugOneFrame=false;this.checkGlErrors=false;this.maxTextureUnits=0;this.maxVaryingVectors=0;this.currentProgram=null;this._hadStackError=false;this.glSlowRenderer=false;this._isSafariCrap=false;this.temporaryTexture=null;this.gl=null;this._cursor="auto";this._currentCursor="";this._viewPortStack=[];this._glFrameBufferStack=[];this._frameBufferStack=[];this._shaderStack=[];this._stackDepthTest=[];this.mainloopOp=null;this._stackBlendMode=[];this._stackBlendModePremul=[];this._stackBlend=[];this._stackDepthFunc=[];this._stackCullFaceFacing=[];this._stackCullFace=[];this._stackDepthWrite=[];this._stackDepthTest=[];this._stackStencil=[];this._simpleShader=new O(this,"simpleshader");this._simpleShader.setModules(["MODULE_VERTEX_POSITION","MODULE_COLOR","MODULE_BEGIN_FRAG","MODULE_VERTEX_MODELVIEW"]);this._simpleShader.setSource(O.getDefaultVertexShader(),O.getDefaultFragmentShader());this._currentShader=this._simpleShader;this._oldCanvasWidth=-1;this._oldCanvasHeight=-1;this._enabledExtensions={};this.errorShader=null}get viewPort(){if(this._viewPortStack.length>3){const e=this._viewPortStack.length;return[this._viewPortStack[e-4],this._viewPortStack[e-3],this._viewPortStack[e-2],this._viewPortStack[e-1]]}else{return this._viewPort}}get mvMatrix(){return this.mMatrix}set mvMatrix(e){this.mMatrix=e}_setCanvas(e){if(!e)this._log.stack("_setCanvas undef");if(!this.patch.config.canvas)this.patch.config.canvas={};if(!this.patch.config.canvas.hasOwnProperty("preserveDrawingBuffer"))this.patch.config.canvas.preserveDrawingBuffer=true;if(!this.patch.config.canvas.hasOwnProperty("premultipliedAlpha"))this.patch.config.canvas.premultipliedAlpha=false;if(!this.patch.config.canvas.hasOwnProperty("alpha"))this.patch.config.canvas.alpha=false;this.patch.config.canvas.stencil=true;if(this.patch.config.hasOwnProperty("clearCanvasColor"))this.clearCanvasTransparent=this.patch.config.clearCanvasColor;if(this.patch.config.hasOwnProperty("clearCanvasDepth"))this.clearCanvasDepth=this.patch.config.clearCanvasDepth;if(/^((?!chrome|android).)*safari/i.test(navigator.userAgent)&&navigator.userAgent.match(/iPhone/i)){this._isSafariCrap=true;this.glUseHalfFloatTex=true}if(!this.patch.config.canvas.forceWebGl1)this.gl=e.getContext("webgl2",this.patch.config.canvas);if(!this.gl||this.gl.isContextLost()){this.aborted=true;this._log.error("NO_WEBGL","sorry, could not initialize WebGL. Please check if your Browser supports WebGL or try to restart your browser.");return}if(this.gl.getParameter(this.gl.VERSION)!="WebGL 1.0"){this.glVersion=2}else{this.gl=e.getContext("webgl",this.patch.config.canvas)||e.getContext("experimental-webgl",this.patch.config.canvas);this.glVersion=1;if(/iPad|iPhone|iPod/.test(navigator.userAgent)&&!window.MSStream){if(!this.patch.config.canvas.hasOwnProperty("powerPreference"))this.patch.config.canvas.powerPreference="high-performance"}this.enableExtension("OES_standard_derivatives");const n=this.enableExtension("ANGLE_instanced_arrays")||this.gl;if(n.vertexAttribDivisorANGLE){this.gl.vertexAttribDivisor=n.vertexAttribDivisorANGLE.bind(n);this.gl.drawElementsInstanced=n.drawElementsInstancedANGLE.bind(n)}}const t=this.enableExtension("WEBGL_debug_renderer_info");if(t){this.glRenderer=this.gl.getParameter(t.UNMASKED_RENDERER_WEBGL);if(this.glRenderer==="Google SwiftShader")this.glSlowRenderer=true}this.canvas.addEventListener("webglcontextlost",e=>{if(this.aborted)return this._log.warn("[cgl_state] aborted context lost... can be ignored...");this._log.error("canvas lost...",e);this.emitEvent("webglcontextlost");this.aborted=true});this.maxAnisotropic=0;if(this.enableExtension("EXT_texture_filter_anisotropic"))this.maxAnisotropic=this.gl.getParameter(this.enableExtension("EXT_texture_filter_anisotropic").MAX_TEXTURE_MAX_ANISOTROPY_EXT);this.maxVaryingVectors=this.gl.getParameter(this.gl.MAX_VARYING_VECTORS);this.maxTextureUnits=this.gl.getParameter(this.gl.MAX_TEXTURE_IMAGE_UNITS);this.maxTexSize=this.gl.getParameter(this.gl.MAX_TEXTURE_SIZE);this.maxUniformsFrag=this.gl.getParameter(this.gl.MAX_FRAGMENT_UNIFORM_VECTORS);this.maxUniformsVert=this.gl.getParameter(this.gl.MAX_VERTEX_UNIFORM_VECTORS);this.maxSamples=0;if(this.gl.MAX_SAMPLES)this.maxSamples=this.gl.getParameter(this.gl.MAX_SAMPLES);if(this.glVersion==1){this.enableExtension("OES_standard_derivatives");const n=this.enableExtension("ANGLE_instanced_arrays")||this.gl;if(n.vertexAttribDivisorANGLE){this.gl.vertexAttribDivisor=n.vertexAttribDivisorANGLE.bind(n);this.gl.drawElementsInstanced=n.drawElementsInstancedANGLE.bind(n)}}this.DEPTH_FUNCS=[this.gl.NEVER,this.gl.ALWAYS,this.gl.LESS,this.gl.LEQUAL,this.gl.GREATER,this.gl.GEQUAL,this.gl.EQUAL,this.gl.NOTEQUAL];this.CULL_MODES=[null,this.gl.BACK,this.gl.FRONT,this.gl.FRONT_AND_BACK]}getInfo(){return{glVersion:this.glVersion,glRenderer:this.glRenderer,glUseHalfFloatTex:this.glUseHalfFloatTex,maxVaryingVectors:this.maxVaryingVectors,maxTextureUnits:this.maxTextureUnits,maxTexSize:this.maxTexSize,maxUniformsFrag:this.maxUniformsFrag,maxUniformsVert:this.maxUniformsVert,maxSamples:this.maxSamples}}popViewPort(){this._viewPortStack.pop();this._viewPortStack.pop();this._viewPortStack.pop();this._viewPortStack.pop();if(this._viewPortStack.length==0)this.setViewPort(0,0,this.canvasWidth,this.canvasHeight);else this.setViewPort(this._viewPortStack[this._viewPort.length-4],this._viewPortStack[this._viewPort.length-3],this._viewPortStack[this._viewPort.length-2],this._viewPortStack[this._viewPort.length-1])}pushViewPort(e,t,n,r){this._viewPortStack.push(e,t,n,r);this.setViewPort(e,t,n,r)}getViewPort(){return this._viewPort}resetViewPort(){this.gl.viewport(this._viewPort[0],this._viewPort[1],this._viewPort[2],this._viewPort[3])}setViewPort(e,t,n,r){this._viewPort[0]=Math.round(e);this._viewPort[1]=Math.round(t);this._viewPort[2]=Math.round(n);this._viewPort[3]=Math.round(r);this.gl.viewport(this._viewPort[0],this._viewPort[1],this._viewPort[2],this._viewPort[3])}screenShot(t,e,n,r){if(e){this.gl.clearColor(1,1,1,1);this.gl.colorMask(false,false,false,true);this.gl.clear(this.gl.COLOR_BUFFER_BIT);this.gl.colorMask(true,true,true,true)}if(this.canvas&&this.canvas.toBlob){this.canvas.toBlob(e=>{if(t)t(e);else this._log.log("no screenshot callback...")},n,r)}}endFrame(){if(this.patch.isEditorMode())CABLES.GL_MARKER.drawMarkerLayer(this);this.setPreviousShader();if(this._vMatrixStack.length()>0)this.logStackError("view matrix stack length !=0 at end of rendering...");if(this._mMatrixStack.length()>0)this.logStackError("mvmatrix stack length !=0 at end of rendering...");if(this._pMatrixStack.length()>0)this.logStackError("pmatrix stack length !=0 at end of rendering...");if(this._glFrameBufferStack.length>0)this.logStackError("glFrameBuffer stack length !=0 at end of rendering...");if(this._stackDepthTest.length>0)this.logStackError("depthtest stack length !=0 at end of rendering...");if(this._stackDepthWrite.length>0)this.logStackError("depthwrite stack length !=0 at end of rendering...");if(this._stackDepthFunc.length>0)this.logStackError("depthfunc stack length !=0 at end of rendering...");if(this._stackBlend.length>0)this.logStackError("blend stack length !=0 at end of rendering...");if(this._stackBlendMode.length>0)this.logStackError("blendMode stack length !=0 at end of rendering...");if(this._shaderStack.length>0)this.logStackError("this._shaderStack length !=0 at end of rendering...");if(this._stackCullFace.length>0)this.logStackError("this._stackCullFace length !=0 at end of rendering...");if(this._stackCullFaceFacing.length>0)this.logStackError("this._stackCullFaceFacing length !=0 at end of rendering...");if(this._viewPortStack.length>0)this.logStackError("viewport stack length !=0 at end of rendering...");this._frameStarted=false;if(this._oldCanvasWidth!=this.canvasWidth||this._oldCanvasHeight!=this.canvasHeight){this._oldCanvasWidth=this.canvasWidth;this._oldCanvasHeight=this.canvasHeight;this.emitEvent(L.EVENT_RESIZE)}if(this._cursor!=this._currentCursor){this._currentCursor=this.canvas.style.cursor=this._cursor}this.emitEvent("endframe");this.fpsCounter.endFrame()}logStackError(e){if(!this._hadStackError){this._hadStackError=true;this._log.warn("["+this.canvas.id+"]: ",e)}}getShader(){if(this._currentShader)if(!this.tempData||this.tempData.renderOffscreen===true==this._currentShader.offScreenPass===true)return this._currentShader;for(let e=this._shaderStack.length-1;e>=0;e--)if(this._shaderStack[e])if(this.tempData.renderOffscreen==this._shaderStack[e].offScreenPass)return this._shaderStack[e]}getDefaultShader(){return this._simpleShader}setShader(e){this.pushShader(e)}pushShader(t){if(this.tempData.forceShaderMods){for(let e=0;e<this.tempData.forceShaderMods.length;e++){t=this.tempData.forceShaderMods[e].bind(t,false)}}this._shaderStack.push(t);this._currentShader=t}popShader(){this.setPreviousShader()}setPreviousShader(){if(this.tempData.forceShaderMods){for(let e=0;e<this.tempData.forceShaderMods.length;e++){this.tempData.forceShaderMods[e].unbind(false)}}if(this._shaderStack.length===0)throw new Error("Invalid shader stack pop!");this._shaderStack.pop();this._currentShader=this._shaderStack[this._shaderStack.length-1]}pushGlFrameBuffer(e){this._glFrameBufferStack.push(e)}popGlFrameBuffer(){if(this._glFrameBufferStack.length==0)return null;this._glFrameBufferStack.pop();return this._glFrameBufferStack[this._glFrameBufferStack.length-1]}getCurrentGlFrameBuffer(){if(this._glFrameBufferStack.length===0)return null;return this._glFrameBufferStack[this._glFrameBufferStack.length-1]}pushFrameBuffer(e){this._frameBufferStack.push(e)}popFrameBuffer(){if(this._frameBufferStack.length==0)return null;this._frameBufferStack.pop();return this._frameBufferStack[this._frameBufferStack.length-1]}getCurrentFrameBuffer(){if(this._frameBufferStack.length===0)return null;return this._frameBufferStack[this._frameBufferStack.length-1]}renderStart(e,t,n){this.fpsCounter.startFrame();this.pushDepthTest(true);this.pushDepthWrite(true);this.pushDepthFunc(e.gl.LEQUAL);this.pushCullFaceFacing(e.gl.BACK);this.pushCullFace(false);e.setViewPort(0,0,e.canvasWidth,e.canvasHeight);this._startMatrixStacks(t,n);e.pushBlendMode(m.BLEND_MODES.BLEND_NORMAL,false);for(let e=0;e<this._textureslots.length;e++)this._textureslots[e]=null;this.pushShader(this._simpleShader);this._frameStarted=true;this._execOneTimeCallbacks();for(let e=0;e<this._textureslots.length;e++){this.gl.activeTexture(this.gl.TEXTURE0+e);this.gl.bindTexture(this.gl.TEXTURE_2D,null);this._textureslots[e]=null}this.emitEvent("beginFrame")}renderEnd(e){this._endMatrixStacks();this.popDepthTest();this.popDepthWrite();this.popDepthFunc();this.popCullFaceFacing();this.popCullFace();this.popBlend();this.popBlendMode();e.endFrame();this.emitEvent("endFrame")}getTexture(e){return this._textureslots[e]}hasFrameStarted(){return this._frameStarted}checkFrameStarted(e){if(!this._frameStarted){this._log.warn("frame not started "+e);Error.stackTraceLimit=25;C.utils.logStack();this.patch.printTriggerStack()}}setTexture(e,t,n){this.checkFrameStarted("cgl setTexture");if(t===null)t=u.getEmptyTexture(this).tex;if(this._textureslots[e]!=t){this.gl.activeTexture(this.gl.TEXTURE0+e);this.gl.bindTexture(n||this.gl.TEXTURE_2D,t);this._textureslots[e]=t}return true}fullScreen(){if(this.canvas.requestFullscreen)this.canvas.requestFullscreen();else if(this.canvas.mozRequestFullScreen)this.canvas.mozRequestFullScreen();else if(this.canvas.webkitRequestFullscreen)this.canvas.webkitRequestFullscreen();else if(this.canvas.msRequestFullscreen)this.canvas.msRequestFullscreen()}printError(t){if(!this.checkGlErrors)return;let n=false;let r=this.gl.getError();if(r!=this.gl.NO_ERROR){let e="";if(r==this.gl.OUT_OF_MEMORY)e="OUT_OF_MEMORY";if(r==this.gl.INVALID_ENUM)e="INVALID_ENUM";if(r==this.gl.INVALID_OPERATION)e="INVALID_OPERATION";if(r==this.gl.INVALID_FRAMEBUFFER_OPERATION)e="INVALID_FRAMEBUFFER_OPERATION";if(r==this.gl.INVALID_VALUE)e="INVALID_VALUE";if(r==this.gl.CONTEXT_LOST_WEBGL){this.aborted=true;e="CONTEXT_LOST_WEBGL"}if(r==this.gl.NO_ERROR)e="NO_ERROR";n=true;this._log.warn("gl error ["+this.canvas.id+"]: ",t,r,e);if(this.canvas.id.includes("glGuiCanvas"))if(!this._loggedGlError){this.patch.printTriggerStack();this._log.stack("glerror");this._loggedGlError=true}}r=this.gl.getError();return n}_dispose(){this._simpleShader.dispose();this.gl=null}pushDepthTest(e){this._stackDepthTest.push(e);if(!e)this.gl.disable(this.gl.DEPTH_TEST);else this.gl.enable(this.gl.DEPTH_TEST)}stateDepthTest(){return this._stackDepthTest[this._stackDepthTest.length-1]}popDepthTest(){this._stackDepthTest.pop();if(!this._stackDepthTest[this._stackDepthTest.length-1])this.gl.disable(this.gl.DEPTH_TEST);else this.gl.enable(this.gl.DEPTH_TEST)}pushDepthWrite(e){e=e||false;this._stackDepthWrite.push(e);this.gl.depthMask(e)}stateDepthWrite(){return this._stackDepthWrite[this._stackDepthWrite.length-1]}popDepthWrite(){this._stackDepthWrite.pop();this.gl.depthMask(this._stackDepthWrite[this._stackDepthWrite.length-1]||false)}pushCullFace(e){this._stackCullFace.push(e);if(e)this.gl.enable(this.gl.CULL_FACE);else this.gl.disable(this.gl.CULL_FACE)}stateCullFace(){return this._stackCullFace[this._stackCullFace.length-1]}popCullFace(){this._stackCullFace.pop();if(this._stackCullFace[this._stackCullFace.length-1])this.gl.enable(this.gl.CULL_FACE);else this.gl.disable(this.gl.CULL_FACE)}pushCullFaceFacing(e){this._stackCullFaceFacing.push(e);this.gl.cullFace(this._stackCullFaceFacing[this._stackCullFaceFacing.length-1])}stateCullFaceFacing(){return this._stackCullFaceFacing[this._stackCullFaceFacing.length-1]}popCullFaceFacing(){this._stackCullFaceFacing.pop();if(this._stackCullFaceFacing.length>0)this.gl.cullFace(this._stackCullFaceFacing[this._stackCullFaceFacing.length-1])}pushDepthFunc(e){this._stackDepthFunc.push(e);this.gl.depthFunc(e)}stateDepthFunc(){if(this._stackDepthFunc.length>0)return this._stackDepthFunc[this._stackDepthFunc.length-1];return false}popDepthFunc(){this._stackDepthFunc.pop();if(this._stackDepthFunc.length>0)this.gl.depthFunc(this._stackDepthFunc[this._stackDepthFunc.length-1])}pushBlend(e){this._stackBlend.push(e);if(!e)this.gl.disable(this.gl.BLEND);else this.gl.enable(this.gl.BLEND)}popBlend(){this._stackBlend.pop();if(!this._stackBlend[this._stackBlend.length-1])this.gl.disable(this.gl.BLEND);else this.gl.enable(this.gl.BLEND)}stateBlend(){return this._stackBlend[this._stackBlend.length-1]}pushBlendMode(e,t){this._stackBlendMode.push(e);this._stackBlendModePremul.push(t);const n=this._stackBlendMode.length-1;this.pushBlend(this._stackBlendMode[n]!==m.BLEND_MODES.BLEND_NONE);this._setBlendMode(this._stackBlendMode[n],this._stackBlendModePremul[n])}popBlendMode(){this._stackBlendMode.pop();this._stackBlendModePremul.pop();const e=this._stackBlendMode.length-1;this.popBlend();if(e>=0)this._setBlendMode(this._stackBlendMode[e],this._stackBlendModePremul[e])}pushStencil(e){this._stackStencil.push(e);if(!e)this.gl.disable(this.gl.STENCIL_TEST);else this.gl.enable(this.gl.STENCIL_TEST)}popStencil(){this._stackStencil.pop();if(!this._stackStencil[this._stackStencil.length-1])this.gl.disable(this.gl.STENCIL_TEST);else this.gl.enable(this.gl.STENCIL_TEST)}glGetAttribLocation(e,t){const n=this.gl.getAttribLocation(e,t);return n}shouldDrawHelpers(e){if(this.tempData.shadowPass)return false;if(!e.patch.isEditorMode())return false;return gui.shouldDrawOverlay}_setBlendMode(e,t){const n=this.gl;if(e==m.BLEND_MODES.BLEND_NONE){}else if(e==m.BLEND_MODES.BLEND_ADD){if(t){n.blendEquationSeparate(n.FUNC_ADD,n.FUNC_ADD);n.blendFuncSeparate(n.ONE,n.ONE,n.ONE,n.ONE)}else{n.blendEquation(n.FUNC_ADD);n.blendFunc(n.SRC_ALPHA,n.ONE)}}else if(e==m.BLEND_MODES.BLEND_SUB){if(t){n.blendEquationSeparate(n.FUNC_ADD,n.FUNC_ADD);n.blendFuncSeparate(n.ZERO,n.ZERO,n.ONE_MINUS_SRC_COLOR,n.ONE_MINUS_SRC_ALPHA)}else{n.blendEquation(n.FUNC_ADD);n.blendFunc(n.ZERO,n.ONE_MINUS_SRC_COLOR)}}else if(e==m.BLEND_MODES.BLEND_MUL){if(t){n.blendEquationSeparate(n.FUNC_ADD,n.FUNC_ADD);n.blendFuncSeparate(n.ZERO,n.SRC_COLOR,n.ZERO,n.SRC_ALPHA)}else{n.blendEquation(n.FUNC_ADD);n.blendFunc(n.ZERO,n.SRC_COLOR)}}else if(e==m.BLEND_MODES.BLEND_NORMAL){if(t){n.blendEquationSeparate(n.FUNC_ADD,n.FUNC_ADD);n.blendFuncSeparate(n.ONE,n.ONE_MINUS_SRC_ALPHA,n.ONE,n.ONE_MINUS_SRC_ALPHA)}else{n.blendEquationSeparate(n.FUNC_ADD,n.FUNC_ADD);n.blendFuncSeparate(n.SRC_ALPHA,n.ONE_MINUS_SRC_ALPHA,n.ONE,n.ONE_MINUS_SRC_ALPHA)}}else{this._log.log("setblendmode: unknown blendmode")}}createMesh(e,t){if(C.utils.isNumeric(t))t={glPrimitive:t};return new b(this,e,t)}setCursor(e){this._cursor=e}enableExtension(e){if(!this.gl)return null;if(this._enabledExtensions.hasOwnProperty(e))return this._enabledExtensions[e];const t=this.gl.getExtension(e);this._enabledExtensions[e]=t;if(!t)this._log.warn("[cgl_state] extension not available "+e);return t}getErrorShader(){if(this.errorShader)return this.errorShader;this.errorShader=new O(this,"errormaterial");this.errorShader.setSource(O.getDefaultVertexShader(),O.getErrorFragmentShader());return this.errorShader}}const R={Framebuffer2:e,Geometry:E,BoundingBox:_,Marker:i,WirePoint:a,WireCube:o,MatrixStack:M,Mesh:b,MESH:x,ShaderLibMods:S,Shader:O,Uniform:h,MESHES:F,getWheelSpeed:H,getWheelDelta:X,Context:Z,Texture:u,TextureEffect:T,onLoadingAssetsFinished:V,ProfileData:I,UniColorShader:w,...m.BLEND_MODES,...m.SHADER,...m.MATH,...m.BLEND_MODES};window.CABLES=window.CABLES||{};window.CABLES.CGL=window.CABLES.CGL||R;window.CGL=window.CGL||R;C.Anim.slerpQuaternion=function(e,t,n,r,i,a){if(!C.Anim.slerpQuaternion.q1){C.Anim.slerpQuaternion.q1=quat.create();C.Anim.slerpQuaternion.q2=quat.create()}const s=n.getKeyIndex(e);let o=s+1;if(o>=n.keys.length)o=n.keys.length-1;if(s==o){quat.set(t,n.keys[s].value,r.keys[s].value,i.keys[s].value,a.keys[s].value)}else{const l=n.keys[s].time;const u=n.keys[o].time;const c=(e-l)/(u-l);quat.set(C.Anim.slerpQuaternion.q1,n.keys[s].value,r.keys[s].value,i.keys[s].value,a.keys[s].value);quat.set(C.Anim.slerpQuaternion.q2,n.keys[o].value,r.keys[o].value,i.keys[o].value,a.keys[o].value);quat.slerp(t,C.Anim.slerpQuaternion.q1,C.Anim.slerpQuaternion.q2,c)}return t};class J{constructor(e,t,n){this.cgl=e;this._options=n;this.fb=null;let r=n.shader;this._useDefaultShader=true;if(n.shader)this._useDefaultShader=false;n.numRenderBuffers=n.numRenderBuffers||1;if(!r){r="".endl()+"IN vec2 texCoord;";for(let e=0;e<n.numRenderBuffers;e++){r=r.endl()+"UNI sampler2D tex"+e+";".endl()}r=r.endl()+"void main()".endl()+"{";if(n.numRenderBuffers==1){r=r.endl()+"    outColor= texture(tex0,texCoord);".endl()}else for(let e=0;e<n.numRenderBuffers;e++){r=r.endl()+"outColor"+e+" = texture(tex"+e+",texCoord);".endl()}r=r.endl()+"}"}const i=n.vertexShader||"".endl()+"IN vec3 vPosition;".endl()+"IN vec2 attrTexCoord;".endl()+"OUT vec2 texCoord;".endl()+"void main()".endl()+"{".endl()+"   texCoord=attrTexCoord;".endl()+"   gl_Position = vec4(vPosition,  1.0);".endl()+"}";this.bgShader=new R.Shader(e,"corelib copytexture "+t);this.bgShader.setSource(i,r);if(!n.vertexShader)this.bgShader.ignoreMissingUniforms=true;new R.Uniform(this.bgShader,"t","tex",0);new R.Uniform(this.bgShader,"t","tex1",1);new R.Uniform(this.bgShader,"t","tex2",2);new R.Uniform(this.bgShader,"t","tex3",3);this.mesh=R.MESHES.getSimpleRect(this.cgl,"texEffectRect")}setSize(e,t){this._options.width=e;this._options.height=t}copy(e,t,n,r,i){const a=this.cgl;if(!e)e=R.Texture.getEmptyTexture(this.cgl);let s=this._options.width||e.width,o=this._options.height||e.height;if(this.fb){if(s<=0)s=8;if(o<=0)o=8;if(this.fb.getWidth()!=s||this.fb.getHeight()!=o)this.fb.setSize(s,o)}else{let e=R.Texture.FILTER_LINEAR;let t=R.Texture.WRAP_CLAMP_TO_EDGE;if(this._options.isFloatingPointTexture)e=R.Texture.FILTER_NEAREST;if(this._options.hasOwnProperty("filter"))e=this._options.filter;if(this._options.hasOwnProperty("wrap"))t=this._options.wrap;const l={isFloatingPointTexture:this._options.isFloatingPointTexture,pixelFormat:this._options.pixelFormat,numRenderBuffers:this._options.numRenderBuffers||1,filter:e,wrap:t};if(a.glVersion==1)this.fb=new R.Framebuffer(a,s,o,l);else this.fb=new R.Framebuffer2(a,s,o,l)}a.tempData.renderOffscreen=true;this.fb.renderStart(a);a.setTexture(0,e.tex);if(t)a.setTexture(1,t.tex);if(n)a.setTexture(2,n.tex);if(r)a.setTexture(3,r.tex);if(i)a.setTexture(4,i.tex);a.pushShader(this.bgShader);this.mesh.render(this.bgShader);a.popShader();this.fb.renderEnd();a.tempData.renderOffscreen=false;return this.fb.getTextureColor()}dispose(){if(this.fb)this.fb.dispose();if(this.bgShader)this.bgShader.dispose();if(this.mesh)this.mesh.dispose()}}})();var e=CGL=typeof CGL==="undefined"?{}:CGL;for(var t in K)e[t]=K[t];if(K.__esModule)Object.defineProperty(e,"__esModule",{value:true})})();(()=>{var r={};(()=>{r.d=(e,t)=>{for(var n in t){if(r.o(t,n)&&!r.o(e,n)){Object.defineProperty(e,n,{enumerable:true,get:t[n]})}}}})();(()=>{r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t)})();(()=>{r.r=e=>{if(typeof Symbol!=="undefined"&&Symbol.toStringTag){Object.defineProperty(e,Symbol.toStringTag,{value:"Module"})}Object.defineProperty(e,"__esModule",{value:true})}})();var t={};(()=>{"use strict";r.r(t);r.d(t,{ShaderModifier:()=>e});class e{constructor(e,t,n){this._cgl=e;this._name=t;this._origShaders={};this._uniforms=[];this._structUniforms=[];this._definesToggled={};this._defines={};this._mods=[];this._textures=[];this._boundShader=null;this._changedDefines=true;this._changedUniforms=true;this._modulesChanged=false;this.needsTexturePush=false;this._lastShader=null;this._attributes=[];if(n&&n.opId)this.opId=n.opId;if(this._cgl.glVersion==1){this._cgl.enableExtension("OES_texture_float");this._cgl.enableExtension("OES_texture_float_linear");this._cgl.enableExtension("OES_texture_half_float");this._cgl.enableExtension("OES_texture_half_float_linear")}}bind(e,t){const n=e||this._cgl.getShader();if(!n)return;this._boundShader=this._origShaders[n.id];let r=false;if(this._boundShader&&this._lastShader!=this._boundShader.shader){if(!this._boundShader.shader.hasModule(this._mods[0].id))r=true}if(r||!this._boundShader||n.lastCompile!=this._boundShader.lastCompile||this._modulesChanged||n.needsRecompile()){if(this._boundShader)this._boundShader.shader.dispose();if(n.needsRecompile())n.compile();this.needsTexturePush=true;this._boundShader=this._origShaders[n.id]={lastCompile:n.lastCompile,orig:n,shader:n.copy()};this._addModulesToShader(this._boundShader.shader);this._updateDefinesShader(this._boundShader.shader);this._updateUniformsShader(this._boundShader.shader)}this._boundShader.wireframe=n.wireframe;if(this._changedDefines)this._updateDefines();if(this._changedUniforms)this._updateUniforms();if(t!==false)this._cgl.pushShader(this._boundShader.shader);this._boundShader.shader.copyUniformValues(this._boundShader.orig);if(this.needsTexturePush){for(let e=0;e<this._textures.length;e++){const i=this._textures[e][0];const a=this._textures[e][1];const s=this._textures[e][2];if(this._getUniform(i)){const o=this.getPrefixedName(i);const l=this._boundShader.shader.getUniform(o);if(l)this._boundShader.shader.pushTexture(l,a,s)}}this.needsTexturePush=false;this._textures.length=0}this._modulesChanged=false;this._boundShader.shader.fromMod=this;if(this.onBind)this.onBind(this._boundShader.shader);return this._boundShader.shader}unbind(e){if(this._boundShader){if(e!==false)this._cgl.popShader()}this._boundShader=null}_addModulesToShader(t){let n;if(this._mods.length>1)n=this._mods[0];for(let e=0;e<this._mods.length;e++)t.addModule(this._mods[e],n)}_removeModulesFromShader(e){for(const t in this._origShaders)this._origShaders[t].shader.removeModule(e)}addModule(e){this._mods.push(e);this._modulesChanged=true}removeModule(t){const n=[];let r=false;for(let e=0;e<this._mods.length;e++){if(this._mods[e].title==t){r=true;this._removeModulesFromShader(this._mods[e]);n.push(e)}}for(let e=n.length-1;e>=0;e-=1)this._mods.splice(n[e],1);this._modulesChanged=true}_updateUniformsShader(r){for(let e=0;e<this._uniforms.length;e++){const t=this._uniforms[e];const n=this.getPrefixedName(t.name);if(!r.hasUniform(n)&&!t.structName){let e=null;if(t.shaderType==="both"){e=r.addUniformBoth(t.type,n,t.v1,t.v2,t.v3,t.v4);e.comment="mod: "+this._name}else if(t.shaderType==="frag"){e=r.addUniformFrag(t.type,n,t.v1,t.v2,t.v3,t.v4);e.comment="mod: "+this._name}else if(t.shaderType==="vert"){e=r.addUniformVert(t.type,n,t.v1,t.v2,t.v3,t.v4);e.comment="mod: "+this._name}}}for(let n=0;n<this._structUniforms.length;n+=1){const i=this._structUniforms[n];let e=i.uniformName;let t=i.structName;const a=i.members;e=this.getPrefixedName(i.uniformName);t=this.getPrefixedName(i.structName);if(i.shaderType==="frag"){r.addUniformStructFrag(t,e,a)}if(i.shaderType==="vert"){r.addUniformStructVert(t,e,a)}if(i.shaderType==="both"){r.addUniformStructBoth(t,e,a)}}}_updateUniforms(){for(const e in this._origShaders)this._updateUniformsShader(this._origShaders[e].shader);this._changedUniforms=false}_setUniformValue(e,t,n){const r=e.getUniform(t);if(r)r.setValue(n)}setUniformValue(e,t){const n=this._getUniform(e);if(!n)return;const r=this.getPrefixedName(e);for(const i in this._origShaders){this._setUniformValue(this._origShaders[i].shader,r,t)}}hasUniform(e){return this._getUniform(e)}_getUniform(t){for(let e=0;e<this._uniforms.length;e++){if(this._uniforms[e].name==t)return this._uniforms[e];if(this._uniforms[e].structName){if(this._uniforms[e].propertyName==t)return this._uniforms[e]}}return false}_getStructUniform(t){for(let e=0;e<this._structUniforms.length;e+=1)if(this._structUniforms[e].uniformName===t)return this._structUniforms[e];return null}_isStructUniform(t){for(let e=0;e<this._uniforms.length;e++){if(this._uniforms[e].name==t)return false;if(this._uniforms[e].structName){if(this._uniforms[e].propertyName==t)return true}}return false}addUniform(t,n,r,i,a,s,o,l,u,c){if(!this._getUniform(n)){let e="both";if(c)e=c;this._uniforms.push({type:t,name:n,v1:r,v2:i,v3:a,v4:s,structUniformName:o,structName:l,propertyName:u,shaderType:e});this._changedUniforms=true}}addUniformFrag(e,t,n,r,i,a){this.addUniform(e,t,n,r,i,a,null,null,null,"frag");this._changedUniforms=true}addUniformVert(e,t,n,r,i,a){this.addUniform(e,t,n,r,i,a,null,null,null,"vert");this._changedUniforms=true}addUniformBoth(e,t,n,r,i,a){this.addUniform(e,t,n,r,i,a,null,null,null,"both");this._changedUniforms=true}addUniformStruct(t,n,r,i){for(let e=0;e<r.length;e+=1){const a=r[e];if((a.type==="2i"||a.type==="i"||a.type==="3i")&&i==="both")console.error("Adding an integer struct member to both shaders can potentially error. Please use different structs for each shader. Error occured in struct:",t," with member:",a.name," of type:",a.type,".");if(!this._getUniform(n+"."+a.name)){this.addUniform(a.type,n+"."+a.name,a.v1,a.v2,a.v3,a.v4,n,t,a.name,i)}}if(!this._getStructUniform(n)){this._structUniforms.push({structName:t,uniformName:n,members:r,shaderType:i})}}addUniformStructVert(e,t,n){this.addUniformStruct(e,t,n,"vert")}addUniformStructFrag(e,t,n){this.addUniformStruct(e,t,n,"frag")}addUniformStructBoth(e,t,n){this.addUniformStruct(e,t,n,"both")}addAttribute(t){for(let e=0;e<this._attributes.length;e++){if(this._attributes[e].name==t.name&&this._attributes[e].nameFrag==t.nameFrag)return}this._attributes.push(t)}pushTexture(e,t,n){if(!t)throw new Error("no texture given to texturestack");this._textures.push([e,t,n]);this.needsTexturePush=true}_removeUniformFromShader(e,t){if(t.hasUniform(e))t.removeUniform(e)}removeUniform(t){if(this._getUniform(t)){for(let e=this._uniforms.length-1;e>=0;e-=1){const n=t;if(this._uniforms[e].name==t&&!this._uniforms[e].structName){for(const r in this._origShaders){this._removeUniformFromShader(this.getPrefixedName(n),this._origShaders[r].shader)}this._uniforms.splice(e,1)}}this._changedUniforms=true}}removeUniformStruct(t){if(this._getStructUniform(t)){for(let e=this._structUniforms.length-1;e>=0;e-=1){const n=this._structUniforms[e];if(n.uniformName===t){for(const r in this._origShaders){for(let e=0;e<n.members.length;e+=1){const i=n.members[e];this._removeUniformFromShader(this.getPrefixedName(i.name),this._origShaders[r].shader)}}this._structUniforms.splice(e,1)}}this._changedUniforms=true}}getPrefixedName(e){const t=this._mods[0].group;if(t===undefined){return}if(e.startsWith("MOD_")){e=e.substr("MOD_".length);e="mod"+t+"_"+e}return e}_updateDefinesShader(t){for(const e in this._defines){const n=this.getPrefixedName(e);if(this._defines[e]!==null&&this._defines[e]!==undefined)t.define(n,this._defines[e]);else t.removeDefine(n)}for(const e in this._definesToggled){const n=this.getPrefixedName(e);t.toggleDefine(n,this._definesToggled[e])}}_updateDefines(){for(const e in this._origShaders)this._updateDefinesShader(this._origShaders[e].shader);this._changedDefines=false}define(e,t){if(t===undefined)t=true;this._defines[e]=t;this._changedDefines=true}removeDefine(e){this._defines[e]=null;this._changedDefines=true}hasDefine(e){if(this._defines[e]!==null&&this._defines[e]!==undefined)return true;return false}toggleDefine(e,t){this._changedDefines=true;this._definesToggled[e]=t}currentShader(){if(!this._boundShader)return null;return this._boundShader.shader}dispose(){}}})();var e=CGL=typeof CGL==="undefined"?{}:CGL;for(var n in t)e[n]=t[n];if(t.__esModule)Object.defineProperty(e,"__esModule",{value:true})})();