@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
1,773 lines (1,750 loc) • 1.98 MB
JavaScript
/**
* @license
* PlayCanvas Engine v1.36.1-rc.1 revision 76f1ffbc8
* Copyright 2011-2020 PlayCanvas Ltd. All rights reserved.
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.pc = {}));
}(this, (function (exports) { 'use strict';
if (!Array.prototype.find) {
Object.defineProperty(Array.prototype, 'find', {
value: function(predicate) {
if (this == null) {
throw TypeError('"this" is null or not defined');
}
var o = Object(this);
var len = o.length >>> 0;
if (typeof predicate !== 'function') {
throw TypeError('predicate must be a function');
}
var thisArg = arguments[1];
var k = 0;
while (k < len) {
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return kValue;
}
k++;
}
return undefined;
},
configurable: true,
writable: true
});
}
Math.log2 = Math.log2 || function(x) {
return Math.log(x) * Math.LOG2E;
};
if (!Math.sign) {
Math.sign = function(x) {
return ((x > 0) - (x < 0)) || +x;
};
}
if (typeof Object.assign != 'function') {
Object.defineProperty(Object, "assign", {
value: function assign(target, varArgs) {
if (target == null) {
throw new TypeError('Cannot convert undefined or null to object');
}
var to = Object(target);
for (var index = 1; index < arguments.length; index++) {
var nextSource = arguments[index];
if (nextSource != null) {
for (var nextKey in nextSource) {
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
to[nextKey] = nextSource[nextKey];
}
}
}
}
return to;
},
writable: true,
configurable: true
});
}
(function () {
if (typeof navigator === 'undefined' || typeof document === 'undefined') {
return;
}
navigator.pointer = navigator.pointer || navigator.webkitPointer || navigator.mozPointer;
var pointerlockchange = function () {
var e = document.createEvent('CustomEvent');
e.initCustomEvent('pointerlockchange', true, false, null);
document.dispatchEvent(e);
};
var pointerlockerror = function () {
var e = document.createEvent('CustomEvent');
e.initCustomEvent('pointerlockerror', true, false, null);
document.dispatchEvent(e);
};
document.addEventListener('webkitpointerlockchange', pointerlockchange, false);
document.addEventListener('webkitpointerlocklost', pointerlockchange, false);
document.addEventListener('mozpointerlockchange', pointerlockchange, false);
document.addEventListener('mozpointerlocklost', pointerlockchange, false);
document.addEventListener('webkitpointerlockerror', pointerlockerror, false);
document.addEventListener('mozpointerlockerror', pointerlockerror, false);
if (Element.prototype.mozRequestPointerLock) {
Element.prototype.requestPointerLock = function () {
this.mozRequestPointerLock();
};
} else {
Element.prototype.requestPointerLock = Element.prototype.requestPointerLock || Element.prototype.webkitRequestPointerLock || Element.prototype.mozRequestPointerLock;
}
if (!Element.prototype.requestPointerLock && navigator.pointer) {
Element.prototype.requestPointerLock = function () {
var el = this;
document.pointerLockElement = el;
navigator.pointer.lock(el, pointerlockchange, pointerlockerror);
};
}
document.exitPointerLock = document.exitPointerLock || document.webkitExitPointerLock || document.mozExitPointerLock;
if (!document.exitPointerLock) {
document.exitPointerLock = function () {
if (navigator.pointer) {
document.pointerLockElement = null;
navigator.pointer.unlock();
}
};
}
})();
(function() {
if (typeof window === 'undefined') return;
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
|| window[vendors[x]+'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());
if (!String.prototype.endsWith) {
String.prototype.endsWith = function(search, this_len) {
if (this_len === undefined || this_len > this.length) {
this_len = this.length;
}
return this.substring(this_len - search.length, this_len) === search;
};
}
if (!String.prototype.includes) {
String.prototype.includes = function(search, start) {
if (typeof start !== 'number') {
start = 0;
}
if (start + search.length > this.length) {
return false;
} else {
return this.indexOf(search, start) !== -1;
}
};
}
if (!String.prototype.startsWith) {
String.prototype.startsWith = function(search, pos) {
return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search;
};
}
(function() {
var glErrorShadow = { };
function error(msg) {
if (window.console && window.console.error) {
window.console.error(msg);
}
}
function log(msg) {
if (window.console && window.console.log) {
window.console.log(msg);
}
}
function synthesizeGLError(err, opt_msg) {
glErrorShadow[err] = true;
if (opt_msg !== undefined) {
error(opt_msg);
}
}
function wrapGLError(gl) {
var f = gl.getError;
gl.getError = function() {
var err;
do {
err = f.apply(gl);
if (err != gl.NO_ERROR) {
glErrorShadow[err] = true;
}
} while (err != gl.NO_ERROR);
for (var err in glErrorShadow) {
if (glErrorShadow[err]) {
delete glErrorShadow[err];
return parseInt(err);
}
}
return gl.NO_ERROR;
};
}
var WebGLVertexArrayObjectOES = function WebGLVertexArrayObjectOES(ext) {
var gl = ext.gl;
this.ext = ext;
this.isAlive = true;
this.hasBeenBound = false;
this.elementArrayBuffer = null;
this.attribs = new Array(ext.maxVertexAttribs);
for (var n = 0; n < this.attribs.length; n++) {
var attrib = new WebGLVertexArrayObjectOES.VertexAttrib(gl);
this.attribs[n] = attrib;
}
this.maxAttrib = 0;
};
WebGLVertexArrayObjectOES.VertexAttrib = function VertexAttrib(gl) {
this.enabled = false;
this.buffer = null;
this.size = 4;
this.type = gl.FLOAT;
this.normalized = false;
this.stride = 16;
this.offset = 0;
this.cached = "";
this.recache();
};
WebGLVertexArrayObjectOES.VertexAttrib.prototype.recache = function recache() {
this.cached = [this.size, this.type, this.normalized, this.stride, this.offset].join(":");
};
var OESVertexArrayObject = function OESVertexArrayObject(gl) {
var self = this;
this.gl = gl;
wrapGLError(gl);
var original = this.original = {
getParameter: gl.getParameter,
enableVertexAttribArray: gl.enableVertexAttribArray,
disableVertexAttribArray: gl.disableVertexAttribArray,
bindBuffer: gl.bindBuffer,
getVertexAttrib: gl.getVertexAttrib,
vertexAttribPointer: gl.vertexAttribPointer
};
gl.getParameter = function getParameter(pname) {
if (pname == self.VERTEX_ARRAY_BINDING_OES) {
if (self.currentVertexArrayObject == self.defaultVertexArrayObject) {
return null;
} else {
return self.currentVertexArrayObject;
}
}
return original.getParameter.apply(this, arguments);
};
gl.enableVertexAttribArray = function enableVertexAttribArray(index) {
var vao = self.currentVertexArrayObject;
vao.maxAttrib = Math.max(vao.maxAttrib, index);
var attrib = vao.attribs[index];
attrib.enabled = true;
return original.enableVertexAttribArray.apply(this, arguments);
};
gl.disableVertexAttribArray = function disableVertexAttribArray(index) {
var vao = self.currentVertexArrayObject;
vao.maxAttrib = Math.max(vao.maxAttrib, index);
var attrib = vao.attribs[index];
attrib.enabled = false;
return original.disableVertexAttribArray.apply(this, arguments);
};
gl.bindBuffer = function bindBuffer(target, buffer) {
switch (target) {
case gl.ARRAY_BUFFER:
self.currentArrayBuffer = buffer;
break;
case gl.ELEMENT_ARRAY_BUFFER:
self.currentVertexArrayObject.elementArrayBuffer = buffer;
break;
}
return original.bindBuffer.apply(this, arguments);
};
gl.getVertexAttrib = function getVertexAttrib(index, pname) {
var vao = self.currentVertexArrayObject;
var attrib = vao.attribs[index];
switch (pname) {
case gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
return attrib.buffer;
case gl.VERTEX_ATTRIB_ARRAY_ENABLED:
return attrib.enabled;
case gl.VERTEX_ATTRIB_ARRAY_SIZE:
return attrib.size;
case gl.VERTEX_ATTRIB_ARRAY_STRIDE:
return attrib.stride;
case gl.VERTEX_ATTRIB_ARRAY_TYPE:
return attrib.type;
case gl.VERTEX_ATTRIB_ARRAY_NORMALIZED:
return attrib.normalized;
default:
return original.getVertexAttrib.apply(this, arguments);
}
};
gl.vertexAttribPointer = function vertexAttribPointer(indx, size, type, normalized, stride, offset) {
var vao = self.currentVertexArrayObject;
vao.maxAttrib = Math.max(vao.maxAttrib, indx);
var attrib = vao.attribs[indx];
attrib.buffer = self.currentArrayBuffer;
attrib.size = size;
attrib.type = type;
attrib.normalized = normalized;
attrib.stride = stride;
attrib.offset = offset;
attrib.recache();
return original.vertexAttribPointer.apply(this, arguments);
};
if (gl.instrumentExtension) {
gl.instrumentExtension(this, "OES_vertex_array_object");
}
gl.canvas.addEventListener('webglcontextrestored', function() {
log("OESVertexArrayObject emulation library context restored");
self.reset_();
}, true);
this.reset_();
};
OESVertexArrayObject.prototype.VERTEX_ARRAY_BINDING_OES = 0x85B5;
OESVertexArrayObject.prototype.reset_ = function reset_() {
var contextWasLost = this.vertexArrayObjects !== undefined;
if (contextWasLost) {
for (var ii = 0; ii < this.vertexArrayObjects.length; ++ii) {
this.vertexArrayObjects.isAlive = false;
}
}
var gl = this.gl;
this.maxVertexAttribs = gl.getParameter(gl.MAX_VERTEX_ATTRIBS);
this.defaultVertexArrayObject = new WebGLVertexArrayObjectOES(this);
this.currentVertexArrayObject = null;
this.currentArrayBuffer = null;
this.vertexArrayObjects = [this.defaultVertexArrayObject];
this.bindVertexArrayOES(null);
};
OESVertexArrayObject.prototype.createVertexArrayOES = function createVertexArrayOES() {
var arrayObject = new WebGLVertexArrayObjectOES(this);
this.vertexArrayObjects.push(arrayObject);
return arrayObject;
};
OESVertexArrayObject.prototype.deleteVertexArrayOES = function deleteVertexArrayOES(arrayObject) {
arrayObject.isAlive = false;
this.vertexArrayObjects.splice(this.vertexArrayObjects.indexOf(arrayObject), 1);
if (this.currentVertexArrayObject == arrayObject) {
this.bindVertexArrayOES(null);
}
};
OESVertexArrayObject.prototype.isVertexArrayOES = function isVertexArrayOES(arrayObject) {
if (arrayObject && arrayObject instanceof WebGLVertexArrayObjectOES) {
if (arrayObject.hasBeenBound && arrayObject.ext == this) {
return true;
}
}
return false;
};
OESVertexArrayObject.prototype.bindVertexArrayOES = function bindVertexArrayOES(arrayObject) {
var gl = this.gl;
if (arrayObject && !arrayObject.isAlive) {
synthesizeGLError(gl.INVALID_OPERATION, "bindVertexArrayOES: attempt to bind deleted arrayObject");
return;
}
var original = this.original;
var oldVAO = this.currentVertexArrayObject;
this.currentVertexArrayObject = arrayObject || this.defaultVertexArrayObject;
this.currentVertexArrayObject.hasBeenBound = true;
var newVAO = this.currentVertexArrayObject;
if (oldVAO == newVAO) {
return;
}
if (!oldVAO || newVAO.elementArrayBuffer != oldVAO.elementArrayBuffer) {
original.bindBuffer.call(gl, gl.ELEMENT_ARRAY_BUFFER, newVAO.elementArrayBuffer);
}
var currentBinding = this.currentArrayBuffer;
var maxAttrib = Math.max(oldVAO ? oldVAO.maxAttrib : 0, newVAO.maxAttrib);
for (var n = 0; n <= maxAttrib; n++) {
var attrib = newVAO.attribs[n];
var oldAttrib = oldVAO ? oldVAO.attribs[n] : null;
if (!oldVAO || attrib.enabled != oldAttrib.enabled) {
if (attrib.enabled) {
original.enableVertexAttribArray.call(gl, n);
} else {
original.disableVertexAttribArray.call(gl, n);
}
}
if (attrib.enabled) {
var bufferChanged = false;
if (!oldVAO || attrib.buffer != oldAttrib.buffer) {
if (currentBinding != attrib.buffer) {
original.bindBuffer.call(gl, gl.ARRAY_BUFFER, attrib.buffer);
currentBinding = attrib.buffer;
}
bufferChanged = true;
}
if (bufferChanged || attrib.cached != oldAttrib.cached) {
original.vertexAttribPointer.call(gl, n, attrib.size, attrib.type, attrib.normalized, attrib.stride, attrib.offset);
}
}
}
if (this.currentArrayBuffer != currentBinding) {
original.bindBuffer.call(gl, gl.ARRAY_BUFFER, this.currentArrayBuffer);
}
};
window.setupVertexArrayObject = function(gl) {
if (gl.getSupportedExtensions) {
var exts = gl.getSupportedExtensions();
if (exts.indexOf("OES_vertex_array_object") != -1) {
return;
}
} else if (gl.getExtension) {
var vao = gl.getExtension("OES_vertex_array_object");
if (vao) {
return;
}
}
if (gl.getSupportedExtensions) {
var original_getSupportedExtensions = gl.getSupportedExtensions;
gl.getSupportedExtensions = function getSupportedExtensions() {
var list = original_getSupportedExtensions.call(this) || [];
list.push("OES_vertex_array_object");
return list;
};
}
var original_getExtension = gl.getExtension;
gl.getExtension = function getExtension(name) {
if (name == "OES_vertex_array_object") {
if (!gl.__OESVertexArrayObject) {
gl.__OESVertexArrayObject = new OESVertexArrayObject(gl);
}
return gl.__OESVertexArrayObject;
}
if (original_getExtension) {
return original_getExtension.call(this, name);
} else {
return null;
}
};
};
}());
var _typeLookup = function () {
var result = { };
var names = ["Array", "Object", "Function", "Date", "RegExp", "Float32Array"];
for (var i = 0; i < names.length; i++)
result["[object " + names[i] + "]"] = names[i].toLowerCase();
return result;
}();
var version = "1.36.1-rc.1";
var revision = "76f1ffbc8";
var config = { };
var common = { };
var apps = { };
var data = { };
function type(obj) {
if (obj === null) {
return "null";
}
var type = typeof obj;
if (type === "undefined" || type === "number" || type === "string" || type === "boolean") {
return type;
}
return _typeLookup[Object.prototype.toString.call(obj)];
}
function extend(target, ex) {
var prop,
copy;
for (prop in ex) {
copy = ex[prop];
if (type(copy) == "object") {
target[prop] = extend({}, copy);
} else if (type(copy) == "array") {
target[prop] = extend([], copy);
} else {
target[prop] = copy;
}
}
return target;
}
function isDefined(o) {
var a;
return (o !== a);
}
var debug = (function () {
var table = null;
var row = null;
var title = null;
var field = null;
return {
display: function (data) {
function init() {
table = document.createElement('table');
row = document.createElement('tr');
title = document.createElement('td');
field = document.createElement('td');
table.style.cssText = 'position:absolute;font-family:sans-serif;font-size:12px;color:#cccccc';
table.style.top = '0px';
table.style.left = '0px';
table.style.border = 'thin solid #cccccc';
document.body.appendChild(table);
}
if (!table) {
init();
}
table.innerHTML = '';
for (var key in data) {
var r = row.cloneNode();
var t = title.cloneNode();
var f = field.cloneNode();
t.textContent = key;
f.textContent = data[key];
r.appendChild(t);
r.appendChild(f);
table.appendChild(r);
}
}
};
}());
function EventHandler() {
this._callbacks = { };
this._callbackActive = { };
}
Object.assign(EventHandler.prototype, {
_addCallback: function (name, callback, scope, once) {
if (!name || typeof name !== 'string' || !callback)
return;
if (!this._callbacks[name])
this._callbacks[name] = [];
if (this._callbackActive[name] && this._callbackActive[name] === this._callbacks[name])
this._callbackActive[name] = this._callbackActive[name].slice();
this._callbacks[name].push({
callback: callback,
scope: scope || this,
once: once || false
});
},
on: function (name, callback, scope) {
this._addCallback(name, callback, scope, false);
return this;
},
off: function (name, callback, scope) {
if (name) {
if (this._callbackActive[name] && this._callbackActive[name] === this._callbacks[name])
this._callbackActive[name] = this._callbackActive[name].slice();
} else {
for (var key in this._callbackActive) {
if (!this._callbacks[key])
continue;
if (this._callbacks[key] !== this._callbackActive[key])
continue;
this._callbackActive[key] = this._callbackActive[key].slice();
}
}
if (!name) {
this._callbacks = { };
} else if (!callback) {
if (this._callbacks[name])
this._callbacks[name] = [];
} else {
var events = this._callbacks[name];
if (!events)
return this;
var count = events.length;
for (var i = 0; i < count; i++) {
if (events[i].callback !== callback)
continue;
if (scope && events[i].scope !== scope)
continue;
events[i--] = events[--count];
}
events.length = count;
}
return this;
},
fire: function (name, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8) {
if (!name || !this._callbacks[name])
return this;
var callbacks;
if (!this._callbackActive[name]) {
this._callbackActive[name] = this._callbacks[name];
} else {
if (this._callbackActive[name] === this._callbacks[name])
this._callbackActive[name] = this._callbackActive[name].slice();
callbacks = this._callbacks[name].slice();
}
for (var i = 0; (callbacks || this._callbackActive[name]) && (i < (callbacks || this._callbackActive[name]).length); i++) {
var evt = (callbacks || this._callbackActive[name])[i];
evt.callback.call(evt.scope, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
if (evt.once) {
var ind = this._callbacks[name].indexOf(evt);
if (ind !== -1) {
if (this._callbackActive[name] === this._callbacks[name])
this._callbackActive[name] = this._callbackActive[name].slice();
this._callbacks[name].splice(ind, 1);
}
}
}
if (!callbacks)
this._callbackActive[name] = null;
return this;
},
once: function (name, callback, scope) {
this._addCallback(name, callback, scope, true);
return this;
},
hasEvent: function (name) {
return (this._callbacks[name] && this._callbacks[name].length !== 0) || false;
}
});
var events = {
attach: function (target) {
var ev = events;
target._addCallback = ev._addCallback;
target.on = ev.on;
target.off = ev.off;
target.fire = ev.fire;
target.once = ev.once;
target.hasEvent = ev.hasEvent;
target._callbacks = { };
target._callbackActive = { };
return target;
},
_addCallback: EventHandler.prototype._addCallback,
on: EventHandler.prototype.on,
off: EventHandler.prototype.off,
fire: EventHandler.prototype.fire,
once: EventHandler.prototype.once,
hasEvent: EventHandler.prototype.hasEvent
};
var guid = {
create: function () {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
var r = Math.random() * 16 | 0,
v = (c == 'x') ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
}
};
var path = {
delimiter: "/",
join: function () {
var index;
var num = arguments.length;
var result = arguments[0];
for (index = 0; index < num - 1; ++index) {
var one = arguments[index];
var two = arguments[index + 1];
if (!isDefined(one) || !isDefined(two)) {
throw new Error("undefined argument to pc.path.join");
}
if (two[0] === path.delimiter) {
result = two;
continue;
}
if (one && two && one[one.length - 1] !== path.delimiter && two[0] !== path.delimiter) {
result += (path.delimiter + two);
} else {
result += (two);
}
}
return result;
},
normalize: function (pathname) {
var lead = pathname.startsWith(path.delimiter);
var trail = pathname.endsWith(path.delimiter);
var parts = pathname.split('/');
var result = '';
var cleaned = [];
for (var i = 0; i < parts.length; i++) {
if (parts[i] === '') continue;
if (parts[i] === '.') continue;
if (parts[i] === '..' && cleaned.length > 0) {
cleaned = cleaned.slice(0, cleaned.length - 2);
continue;
}
if (i > 0) cleaned.push(path.delimiter);
cleaned.push(parts[i]);
}
result = cleaned.join('');
if (!lead && result[0] === path.delimiter) {
result = result.slice(1);
}
if (trail && result[result.length - 1] !== path.delimiter) {
result += path.delimiter;
}
return result;
},
split: function (pathname) {
var parts = pathname.split(path.delimiter);
var tail = parts.slice(parts.length - 1)[0];
var head = parts.slice(0, parts.length - 1).join(path.delimiter);
return [head, tail];
},
getBasename: function (pathname) {
return path.split(pathname)[1];
},
getDirectory: function (pathname) {
var parts = pathname.split(path.delimiter);
return parts.slice(0, parts.length - 1).join(path.delimiter);
},
getExtension: function (pathname) {
var ext = pathname.split('?')[0].split('.').pop();
if (ext !== pathname) {
return "." + ext;
}
return "";
},
isRelativePath: function (pathname) {
return pathname.charAt(0) !== "/" && pathname.match(/:\/\//) === null;
},
extractPath: function (pathname) {
var result = "";
var parts = pathname.split("/");
var i = 0;
if (parts.length > 1) {
for (i = 0; i < parts.length - 1; ++i) {
result += (i === 0) ? parts[i] : "/" + parts[i];
}
}
return result;
}
};
var platform = {
desktop: false,
mobile: false,
ios: false,
android: false,
windows: false,
xbox: false,
gamepads: false,
touch: false,
workers: false,
passiveEvents: false
};
if (typeof navigator !== 'undefined') {
var ua = navigator.userAgent;
if (/(windows|mac os|linux|cros)/i.test(ua))
platform.desktop = true;
if (/xbox/i.test(ua))
platform.xbox = true;
if (/(windows phone|iemobile|wpdesktop)/i.test(ua)) {
platform.desktop = false;
platform.mobile = true;
platform.windows = true;
} else if (/android/i.test(ua)) {
platform.desktop = false;
platform.mobile = true;
platform.android = true;
} else if (/ip([ao]d|hone)/i.test(ua)) {
platform.desktop = false;
platform.mobile = true;
platform.ios = true;
}
if (typeof window !== 'undefined') {
platform.touch = 'ontouchstart' in window || ('maxTouchPoints' in navigator && navigator.maxTouchPoints > 0);
}
platform.gamepads = 'getGamepads' in navigator;
platform.workers = (typeof(Worker) !== 'undefined');
try {
var opts = Object.defineProperty({}, 'passive', {
get: function () {
platform.passiveEvents = true;
return false;
}
});
window.addEventListener("testpassive", null, opts);
window.removeEventListener("testpassive", null, opts);
} catch (e) {}
}
var ASCII_LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
var ASCII_UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var ASCII_LETTERS = ASCII_LOWERCASE + ASCII_UPPERCASE;
var HIGH_SURROGATE_BEGIN = 0xD800;
var HIGH_SURROGATE_END = 0xDBFF;
var LOW_SURROGATE_BEGIN = 0xDC00;
var LOW_SURROGATE_END = 0xDFFF;
var ZERO_WIDTH_JOINER = 0x200D;
var REGIONAL_INDICATOR_BEGIN = 0x1F1E6;
var REGIONAL_INDICATOR_END = 0x1F1FF;
var FITZPATRICK_MODIFIER_BEGIN = 0x1F3FB;
var FITZPATRICK_MODIFIER_END = 0x1F3FF;
var DIACRITICAL_MARKS_BEGIN = 0x20D0;
var DIACRITICAL_MARKS_END = 0x20FF;
var VARIATION_MODIFIER_BEGIN = 0xFE00;
var VARIATION_MODIFIER_END = 0xFE0F;
function getCodePointData(string, i) {
var size = string.length;
i = i || 0;
if (i < 0 || i >= size) {
return null;
}
var first = string.charCodeAt(i);
var second;
if (size > 1 && first >= HIGH_SURROGATE_BEGIN && first <= HIGH_SURROGATE_END) {
second = string.charCodeAt(i + 1);
if (second >= LOW_SURROGATE_BEGIN && second <= LOW_SURROGATE_END) {
return { code: (first - HIGH_SURROGATE_BEGIN) * 0x400 + second - LOW_SURROGATE_BEGIN + 0x10000, long: true };
}
}
return { code: first, long: false };
}
function isCodeBetween(string, begin, end) {
if (!string)
return false;
var codeData = getCodePointData(string);
if (codeData) {
var code = codeData.code;
return code >= begin && code <= end;
}
return false;
}
function numCharsToTakeForNextSymbol(string, index) {
if (index === string.length - 1) {
return 1;
}
if (isCodeBetween(string[index], HIGH_SURROGATE_BEGIN, HIGH_SURROGATE_END)) {
var first = string.substring(index, index + 2);
var second = string.substring(index + 2, index + 4);
if (isCodeBetween(second, FITZPATRICK_MODIFIER_BEGIN, FITZPATRICK_MODIFIER_END) ||
(isCodeBetween(first, REGIONAL_INDICATOR_BEGIN, REGIONAL_INDICATOR_END) &&
isCodeBetween(second, REGIONAL_INDICATOR_BEGIN, REGIONAL_INDICATOR_END))
) {
return 4;
}
if (isCodeBetween(second, VARIATION_MODIFIER_BEGIN, VARIATION_MODIFIER_END)) {
return 3;
}
return 2;
}
if (isCodeBetween(string[index + 1], VARIATION_MODIFIER_BEGIN, VARIATION_MODIFIER_END)) {
return 2;
}
return 1;
}
var string = {
ASCII_LOWERCASE: ASCII_LOWERCASE,
ASCII_UPPERCASE: ASCII_UPPERCASE,
ASCII_LETTERS: ASCII_LETTERS,
format: function (s) {
for (var i = 1; i < arguments.length; i++) {
s = s.replace('{' + (i - 1) + '}', arguments[i]);
}
return s;
},
toBool: function (s, strict) {
if (s === 'true') {
return true;
}
if (strict) {
if (s === 'false') {
return false;
}
throw new TypeError('Not a boolean string');
}
return false;
},
getCodePoint: function (string, i) {
var codePointData = getCodePointData(string, i);
return codePointData && codePointData.code;
},
getCodePoints: function (string) {
if (typeof string !== 'string') {
throw new TypeError('Not a string');
}
var i = 0;
var arr = [];
var codePoint;
while (!!(codePoint = getCodePointData(string, i))) {
arr.push(codePoint.code);
i += codePoint.long ? 2 : 1;
}
return arr;
},
getSymbols: function (string) {
if (typeof string !== 'string') {
throw new TypeError('Not a string');
}
var index = 0;
var length = string.length;
var output = [];
var take = 0;
var ch;
while (index < length) {
take += numCharsToTakeForNextSymbol(string, index + take);
ch = string[index + take];
if (isCodeBetween(ch, DIACRITICAL_MARKS_BEGIN, DIACRITICAL_MARKS_END)) {
ch = string[index + (take++)];
}
if (isCodeBetween(ch, VARIATION_MODIFIER_BEGIN, VARIATION_MODIFIER_END)) {
ch = string[index + (take++)];
}
if (ch && ch.charCodeAt(0) === ZERO_WIDTH_JOINER) {
ch = string[index + (take++)];
continue;
}
var char = string.substring(index, index + take);
output.push(char);
index += take;
take = 0;
}
return output;
},
fromCodePoint: function () {
var chars = [];
var current;
var codePoint;
var units;
for (var i = 0; i < arguments.length; ++i) {
current = Number(arguments[i]);
codePoint = current - 0x10000;
units = current > 0xFFFF ? [(codePoint >> 10) + 0xD800, (codePoint % 0x400) + 0xDC00] : [current];
chars.push(String.fromCharCode.apply(null, units));
}
return chars.join('');
}
};
var math = {
DEG_TO_RAD: Math.PI / 180,
RAD_TO_DEG: 180 / Math.PI,
clamp: function (value, min, max) {
if (value >= max) return max;
if (value <= min) return min;
return value;
},
intToBytes24: function (i) {
var r, g, b;
r = (i >> 16) & 0xff;
g = (i >> 8) & 0xff;
b = (i) & 0xff;
return [r, g, b];
},
intToBytes32: function (i) {
var r, g, b, a;
r = (i >> 24) & 0xff;
g = (i >> 16) & 0xff;
b = (i >> 8) & 0xff;
a = (i) & 0xff;
return [r, g, b, a];
},
bytesToInt24: function (r, g, b) {
if (r.length) {
b = r[2];
g = r[1];
r = r[0];
}
return ((r << 16) | (g << 8) | b);
},
bytesToInt32: function (r, g, b, a) {
if (r.length) {
a = r[3];
b = r[2];
g = r[1];
r = r[0];
}
return ((r << 24) | (g << 16) | (b << 8) | a) >>> 32;
},
lerp: function (a, b, alpha) {
return a + (b - a) * math.clamp(alpha, 0, 1);
},
lerpAngle: function (a, b, alpha) {
if (b - a > 180 ) {
b -= 360;
}
if (b - a < -180 ) {
b += 360;
}
return math.lerp(a, b, math.clamp(alpha, 0, 1));
},
powerOfTwo: function (x) {
return ((x !== 0) && !(x & (x - 1)));
},
nextPowerOfTwo: function (val) {
val--;
val |= (val >> 1);
val |= (val >> 2);
val |= (val >> 4);
val |= (val >> 8);
val |= (val >> 16);
val++;
return val;
},
random: function (min, max) {
var diff = max - min;
return Math.random() * diff + min;
},
smoothstep: function (min, max, x) {
if (x <= min) return 0;
if (x >= max) return 1;
x = (x - min) / (max - min);
return x * x * (3 - 2 * x);
},
smootherstep: function (min, max, x) {
if (x <= min) return 0;
if (x >= max) return 1;
x = (x - min) / (max - min);
return x * x * x * (x * (x * 6 - 15) + 10);
},
roundUp: function (numToRound, multiple) {
if (multiple === 0)
return numToRound;
return Math.ceil(numToRound / multiple) * multiple;
},
float2Half: (function () {
var floatView = new Float32Array(1);
var int32View = new Int32Array(floatView.buffer);
return function (val) {
floatView[0] = val;
var x = int32View[0];
var bits = (x >> 16) & 0x8000;
var m = (x >> 12) & 0x07ff;
var e = (x >> 23) & 0xff;
if (e < 103) {
return bits;
}
if (e > 142) {
bits |= 0x7c00;
bits |= ((e == 255) ? 0 : 1) && (x & 0x007fffff);
return bits;
}
if (e < 113) {
m |= 0x0800;
bits |= (m >> (114 - e)) + ((m >> (113 - e)) & 1);
return bits;
}
bits |= ((e - 112) << 10) | (m >> 1);
bits += m & 1;
return bits;
};
}())
};
function Color(r, g, b, a) {
var length = r && r.length;
if (length === 3 || length === 4) {
this.r = r[0];
this.g = r[1];
this.b = r[2];
this.a = r[3] !== undefined ? r[3] : 1;
} else {
this.r = r || 0;
this.g = g || 0;
this.b = b || 0;
this.a = a !== undefined ? a : 1;
}
}
Object.assign(Color.prototype, {
clone: function () {
return new Color(this.r, this.g, this.b, this.a);
},
copy: function (rhs) {
this.r = rhs.r;
this.g = rhs.g;
this.b = rhs.b;
this.a = rhs.a;
return this;
},
equals: function (rhs) {
return this.r === rhs.r && this.g === rhs.g && this.b === rhs.b && this.a === rhs.a;
},
set: function (r, g, b, a) {
this.r = r;
this.g = g;
this.b = b;
this.a = (a === undefined) ? 1 : a;
return this;
},
lerp: function (lhs, rhs, alpha) {
this.r = lhs.r + alpha * (rhs.r - lhs.r);
this.g = lhs.g + alpha * (rhs.g - lhs.g);
this.b = lhs.b + alpha * (rhs.b - lhs.b);
this.a = lhs.a + alpha * (rhs.a - lhs.a);
return this;
},
fromString: function (hex) {
var i = parseInt(hex.replace('#', '0x'), 16);
var bytes;
if (hex.length > 7) {
bytes = math.intToBytes32(i);
} else {
bytes = math.intToBytes24(i);
bytes[3] = 255;
}
this.set(bytes[0] / 255, bytes[1] / 255, bytes[2] / 255, bytes[3] / 255);
return this;
},
toString: function (alpha) {
var s = "#" + ((1 << 24) + (Math.round(this.r * 255) << 16) + (Math.round(this.g * 255) << 8) + Math.round(this.b * 255)).toString(16).slice(1);
if (alpha === true) {
var a = Math.round(this.a * 255).toString(16);
if (this.a < 16 / 255) {
s += '0' + a;
} else {
s += a;
}
}
return s;
}
});
Object.defineProperties(Color, {
BLACK: { value: new Color(0, 0, 0, 1) },
WHITE: { value: new Color(1, 1, 1, 1) },
YELLOW: { value: new Color(1, 1, 0, 1) },
RED: { value: new Color(1, 0, 0, 1) },
MAGENTA: { value: new Color(1, 0, 1, 1) },
GREEN: { value: new Color(0, 1, 0, 1) },
GRAY: { value: new Color(0.5, 0.5, 0.5, 1) },
CYAN: { value: new Color(0, 1, 1, 1) },
BLUE: { value: new Color(0, 0, 1, 1) }
});
Object.freeze(Color.BLACK);
Object.freeze(Color.WHITE);
Object.freeze(Color.YELLOW);
Object.freeze(Color.RED);
Object.freeze(Color.MAGENTA);
Object.freeze(Color.GREEN);
Object.freeze(Color.GRAY);
Object.freeze(Color.CYAN);
Object.freeze(Color.BLUE);
function IndexedList() {
this._list = [];
this._index = {};
}
Object.assign(IndexedList.prototype, {
push: function (key, item) {
if (this._index[key]) {
throw Error("Key already in index " + key);
}
var location = this._list.push(item) - 1;
this._index[key] = location;
},
has: function (key) {
return this._index[key] !== undefined;
},
get: function (key) {
var location = this._index[key];
if (location !== undefined) {
return this._list[location];
}
return null;
},
remove: function (key) {
var location = this._index[key];
if (location !== undefined) {
this._list.splice(location, 1);
delete this._index[key];
for (key in this._index) {
var idx = this._index[key];
if (idx > location) {
this._index[key] = idx - 1;
}
}
return true;
}
return false;
},
list: function () {
return this._list;
},
clear: function () {
this._list.length = 0;
for (var prop in this._index) {
delete this._index[prop];
}
}
});
function TagsCache(key) {
this._index = { };
this._key = key || null;
}
Object.assign(TagsCache.prototype, {
addItem: function (item) {
var tags = item.tags._list;
for (var i = 0; i < tags.length; i++)
this.add(tags[i], item);
},
removeItem: function (item) {
var tags = item.tags._list;
for (var i = 0; i < tags.length; i++)
this.remove(tags[i], item);
},
add: function (tag, item) {
if (this._index[tag] && this._index[tag].list.indexOf(item) !== -1)
return;
if (!this._index[tag]) {
this._index[tag] = {
list: []
};
if (this._key)
this._index[tag].keys = { };
}
this._index[tag].list.push(item);
if (this._key)
this._index[tag].keys[item[this._key]] = item;
},
remove: function (tag, item) {
if (!this._index[tag])
return;
if (this._key) {
if (!this._index[tag].keys[item[this._key]])
return;
}
var ind = this._index[tag].list.indexOf(item);
if (ind === -1)
return;
this._index[tag].list.splice(ind, 1);
if (this._key)
delete this._index[tag].keys[item[this._key]];
if (this._index[tag].list.length === 0)
delete this._index[tag];
},
find: function (args) {
var self = this;
var index = { };
var items = [];
var i, n, t;
var item, tag, tags, tagsRest, missingIndex;
var sort = function (a, b) {
return self._index[a].list.length - self._index[b].list.length;
};
for (i = 0; i < args.length; i++) {
tag = args[i];
if (tag instanceof Array) {
if (tag.length === 0)
continue;
if (tag.length === 1) {
tag = tag[0];
} else {
missingIndex = false;
for (t = 0; t < tag.length; t++) {
if (!this._index[tag[t]]) {
missingIndex = true;
break;
}
}
if (missingIndex)
continue;
tags = tag.slice(0).sort(sort);
tagsRest = tags.slice(1);
if (tagsRest.length === 1)
tagsRest = tagsRest[0];
for (n = 0; n < this._index[tags[0]].list.length; n++) {
item = this._index[tags[0]].list[n];
if ((this._key ? !index[item[this._key]] : (items.indexOf(item) === -1)) && item.tags.has(tagsRest)) {
if (this._key)
index[item[this._key]] = true;
items.push(item);
}
}
continue;
}
}
if (tag && typeof tag === 'string' && this._index[tag]) {
for (n = 0; n < this._index[tag].list.length; n++) {
item = this._index[tag].list[n];
if (this._key) {
if (!index[item[this._key]]) {
index[item[this._key]] = true;
items.push(item);
}
} else if (items.indexOf(item) === -1) {
items.push(item);
}
}
}
}
return items;
}
});
function Tags(parent) {
EventHandler.call(this);
this._index = { };
this._list = [];
this._parent = parent;
}
Tags.prototype = Object.create(EventHandler.prototype);
Tags.prototype.constructor = Tags;
Object.assign(Tags.prototype, {
add: function () {
var changed = false;
var tags = this._processArguments(arguments, true);
if (!tags.length)
return changed;
for (var i = 0; i < tags.length; i++) {
if (this._index[tags[i]])
continue;
changed = true;
this._index[tags[i]] = true;
this._list.push(tags[i]);
this.fire('add', tags[i], this._parent);
}
if (changed)
this.fire('change', this._parent);
return changed;
},
remove: function () {
var changed = false;
if (!this._list.length)
return changed;
var tags = this._processArguments(arguments, true);
if (!tags.length)
return changed;
for (var i = 0; i < tags.length; i++) {
if (!this._index[tags[i]])
continue;
changed = true;
delete this._index[tags[i]];
this._list.splice(this._list.indexOf(tags[i]), 1);
this.fire('remove', tags[i], this._parent);
}
if (changed)
this.fire('change', this._parent);
return changed;
},
clear: function () {
if (!this._list.length)
return;
var tags = this._list.slice(0);
this._list = [];
this._index = { };
for (var i = 0; i < tags.length; i++)
this.fire('remove', tags[i], this._parent);
this.fire('change', this._parent);
},
has: function () {
if (!this._list.length)
return false;
return this._has(this._processArguments(arguments));
},
_has: function (tags) {
if (!this._list.length || !tags.length)
return false;
for (var i = 0; i < tags.length; i++) {
if (tags[i].length === 1) {
if (this._index[tags[i][0]])
return true;
} else {
var multiple = true;
for (var t = 0; t < tags[i].length; t++) {
if (this._index[tags[i][t]])
continue;
multiple = false;
break;
}
if (multiple)
return true;
}
}
return false;
},
list: function () {
return this._list.slice(0);
},
_processArguments: function (args, flat) {
var tags = [];
var tmp = [];
if (!args || !args.length)
return tags;
for (var i = 0; i < args.length; i++) {
if (args[i] instanceof Array) {
if (!flat)
tmp = [];
for (var t = 0; t < args[i].length; t++) {
if (typeof args[i][t] !== 'string')
continue;
if (flat) {
tags.push(args[i][t]);
} else {
tmp.push(args[i][t]);
}
}
if (!flat && tmp.length)
tags.push(tmp);
} else if (typeof args[i] === 'string') {
if (flat) {
tags.push(args[i]);
} else {
tags.push([args[i]]);
}
}
}
return tags;
}
});
Object.defineProperty(Tags.prototype, 'size', {
get: function () {
return this._list.length;
}
});
var now = (typeof window !== 'undefined') && window.performance && window.performance.now && window.performance.timing ? function () {
return window.performance.now();
} : Date.now;
function Timer() {
this._isRunning = false;
this._a = 0;
this._b = 0;
}
Object.assign(Timer.prototype, {
start: function () {
this._isRunning = true;
this._a = now();
},
stop: function () {
this._isRunning = false;
this._b = now();
},
getMilliseconds: function () {
return this._b - this._a;
}
});
function createURI(options) {
var s = "";
if ((options.authority || options.scheme) && (options.host || options.hostpath)) {
throw new Error("Can't have 'scheme' or 'authority' and 'host' or 'hostpath' option");
}
if (options.host && options.hostpath) {
throw new Error("Can't have 'host' and 'hostpath' option");
}
if (options.path && options.hostpath) {
throw new Error("Can't have 'path' and 'hostpath' option");
}
if (options.scheme) {
s += options.scheme + ":";
}
if (options.authority) {
s += "//" + options.authority;
}
if (options.host) {
s += options.host;
}
if (options.path) {
s += options.path;
}
if (options.hostpath) {
s += options.hostpath;
}
if (options.query) {
s += "?" + options.query;
}
if (options.fragment) {
s += "#" + options.fragment;
}
return s;
}
function URI(uri) {
var re = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?/,
result = uri.match(re);
this.scheme = result[2];
this.authority = result[4];
this.path = result[5];
this.query = result[7];
this.fragment = result[9];
this.toString = function () {
var s = "";
if (this.scheme) {
s += this.scheme + ":";
}
if (this.authority) {
s += "//" + this.authority;
}
s += this.path;
if (this.query) {
s += "?" + this.query;
}
if (this.fragment) {
s += "#" + this.fragment;
}
return s;
};
this.getQuery = function () {
var vars;
var pair;
var result = {};
if (this.query) {
vars = decodeURIComponent(this.query).split("&");
vars.forEach(function (item, index, arr) {
pair = item.split("=");
result[pair[0]] = pair[1];
}, this);
}
return result;
};
this.setQuery = function (params) {
var q = "";
for (var key in params) {
if (params.hasOwnProperty(key)) {
if (q !== "") {
q += "&";
}
q += encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
}
}
this.query = q;
};
}
function Http() {}
Http.ContentType = {
FORM_URLENCODED: "application/x-www-form-urlencoded",
GIF: "image/gif",
JPEG: "image/jpeg",
DDS: "image/dds",
JSON: "application/json",
PNG: "image/png",
TEXT: "text/plain",
XML: "application/xml",
WAV: "audio/x-wav",
OGG: "audio/ogg",
MP3: "audio/mpeg",
MP4: "audio/mp4",
AAC: "audio/aac",
BIN: "application/octet-stream",
BASIS: "image/basis",
GLB: "model/gltf-binary"
};
Http.ResponseType = {
TEXT: 'text',
ARRAY_BUFFER: 'arraybuffer',
BLOB: 'blob',
DOCUMENT: 'document',
JSON: 'json'
};
Http.binaryExtensions = [
'.model',
'.wav',
'.ogg',
'.mp3',
'.mp4',
'.m4a',
'.aac',
'.dds',
'.basis',
'.glb'
];
Http.retryDelay = 100;
Object.assign(Http.prototype, {
ContentType: Http.ContentType,
ResponseType: Http.ResponseType,
binaryExtensions: Http.binaryExtensions,
get: function (url, options, callback) {
if (typeof options === "function") {
callback = options;
options = {};
}
return this.request("GET", url, options, callback);
},
post: function (url, data, options, callback) {
if (typeof options === "function") {
callback = options;
options = {};
}
options.postdata = data;
return this.request("POST", url, options, callback);
},
put: function (url, data, options, callback) {
if (typeof options === "function") {
callback = options;
options = {};
}
options.postdata = data;
return this.request("PUT", url, options, callback);
},
del: function (url, options, callback) {
if (typeof options === "function") {
callback = options;
options = {};
}
return this.request("DELETE", url, options, callback);
},
request: function (method, url, options, callback) {
var uri, query, timestamp, postdata, xhr;
var errored = false;
if (typeof options === "function") {
callback = options;
options = {};
}
if (options.retry) {
options = Object.assign({
retries: 0,
maxRetries: 5
}, options);
}
options.callback = callback;
if (options.async == null) {
options.async = true;
}
if (options.headers == null) {
options.headers = {};
}
if (options.postdata != null) {
if (options.postdata instanceof Document) {
postdata = options.postdata;
} else if (options.postdata instanceof FormData) {
postdata = options.postdata;
} else if (options.postdata instanceof Object) {
var contentType = options.headers["Content-Type"];
if (contentType === undefined) {
options.headers["Content-Type"] = Http.ContentType.FORM_URLENCODED;
contentType = options.headers["Content-Type"];
}
switch (contentType) {
case Http.ContentType.FORM_URLENCODED:
postdata = "";
var bFirstItem = true;
for (var key in options.postdata) {
if (options.postdata.hasOwnProperty(key)) {
if (bFirstItem) {
bFirstItem = false;
} else {
postdata += "&";
}
postdata += escape(key) + "=" + escape(options.postdata[key]);
}
}
break;
default:
case Http.ContentType.JSON:
if (contentType == null) {
options.headers["Content-Type"] = Http.ContentType.JSON;
}
postdata = JSON.stringify(options.postdata);
break;
}
} else {
postdata = options.postdata;
}
}
if (options.cache === false) {
timestamp = now();
uri = new URI(url);
if (!uri.query) {
uri.query = "ts=" + timestamp;
} else {
uri.query = uri.query + "&ts=" + timestamp;
}
url = uri.toString();
}
if (options.query) {
uri = new URI(url);
query = extend(uri.getQuery(), options.query);
uri.setQuery(query);
url = uri.toString();
}
xhr = new XMLHttpRequest();
xhr.open(method, url, options.async);
xhr.withCredentials = options.withCredentials !== undefined ? options.withCredentials : false;
xhr.responseType = options.responseType || this._guessResponseType(url);
for (var header in options.headers) {
if (options.headers.hasOwnProperty(header)) {
xhr.setRequestHeader(header, options.headers[header]);
}
}
xhr.onreadystatechange = function () {
this._onReadyStateChange(method, url, options, xhr);
}.bind(this);
xhr.onerror = function () {
this._onError(method, url, options, xhr);
errored = true;
}.bind(this);
try {
xhr.send(postdata);
} catch (e) {
if (!errored) {
options.error(xhr.status, xhr, e);
}
}
return xhr;
},
_guessResponseType: function (url) {
var uri = new URI(url);
var ext = path.getExtension(uri.path);
if (Http.binaryExtensions.indexOf(ext) >= 0) {
return Http.ResponseType.ARRAY_BUFFER;
}
if (ext === ".xml") {
return Http.ResponseType.DOCUMENT;
}
return Http.ResponseType.TEXT;
},
_isBinaryContentType: function (contentType) {
var binTypes = [
Http.ContentType.MP4,
Http.ContentType.WAV,
Http.ContentType.OGG,
Http.ContentType.MP3,
Http.ContentType.BIN,
Http.ContentType.DDS,
Http.ContentType.BASIS,
Http.ContentType.GLB
];
if (binTypes.indexOf(contentType) >= 0) {
return true;
}
return false;
},
_onReadyStateChange: function (method, url, options, xhr) {
if (xhr.readyState === 4) {
switch (xhr.status) {
case 0: {
if (url[0] != '/') {
this._onSuccess(method, url, options, xhr);
} else {
this._onError(method, url, options, xhr);
}
break;
}
case 200:
case 201:
case 206:
case 304: {
this._onSuccess(method, url, options, xhr);
break;
}
default: {
this._onError(method, url, options, xhr);
break;
}
}
}
},
_onSuccess: function (method, url, options, xhr) {
var response;
var header;
var contentType;
var parts;
header = xhr.getResponseHeader("Content-Type");
if (header) {
parts = header.split(";");
contentType = parts[0].trim();
}
try {
if (contentType === this.ContentType.JSON || url.split('?')[0].endsWith(".json")) {
response = JSON.parse(xhr.responseText);
} else if (this._isBinaryContentType(contentType)) {
response = xhr.response;
} else {
if (contentType) {
console.warn("responseType: " + xhr.responseType + " being served with Content-Type: " + contentType);
}
if (xhr.responseType === Http.ResponseType.ARRAY_BUFFER) {
response = xhr.response;
} else if (xhr.responseType === Http.ResponseType.BLOB || xhr.responseType === Http.ResponseType.JSON) {
response = xhr.response;
} else {
if (xhr.responseType === Http.ResponseType.DOCUMENT || contentType === this.ContentType.XML) {
response = xhr.responseXML;
} else {
response = xhr.responseText;
}
}
}
options.callback(null, response);
} catch (err) {
options.callback(err);
}
},
_onError: function (method, url, options, xhr) {
if (options.retrying) {
return;
}
if (options.retry && options.retries < options.maxRetries) {
options.retries++;